public IEnumerable Enumerable( string query, QueryParameters parameters )
		{
			CheckIsOpen();

			if( log.IsDebugEnabled )
			{
				log.Debug( "GetEnumerable: " + query );
				parameters.LogParameters( factory );
			}

			QueryTranslator[ ] q = GetQueries( query, true );

			if( q.Length == 0 )
			{
				return new ArrayList();
			}

			IEnumerable result = null;
			IEnumerable[ ] results = null;
			bool many = q.Length > 1;
			if( many )
			{
				results = new IEnumerable[q.Length];
			}

			dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
			//execute the queries and return all results as a single enumerable
			try
			{
				for( int i = 0; i < q.Length; i++ )
				{
					try
					{
						result = q[ i ].GetEnumerable( parameters, this );
					}
					catch( HibernateException )
					{
						// Do not call Convert on HibernateExceptions
						throw;
					}
					catch( Exception sqle )
					{
						throw Convert( sqle, "Could not execute query" );
					}
					if( many )
					{
						results[ i ] = result;
					}
				}

				return many ? new JoinedEnumerable( results ) : result;
			}
			finally
			{
				dontFlushFromFind--;
			}
		}
		/// <summary>
		/// 1. determine the collection role of the given collection (this may require a flush, if the collection is recorded as unreferenced)
		/// 2. obtain a compiled filter query
		/// 3. autoflush if necessary
		/// </summary>
		/// <param name="collection"></param>
		/// <param name="filter"></param>
		/// <param name="parameters"></param>
		/// <param name="scalar"></param>
		/// <returns></returns>
		private FilterTranslator GetFilterTranslator( object collection, string filter, QueryParameters parameters, bool scalar )
		{
			if( collection == null )
			{
				throw new ArgumentNullException( "collection", "null collection passed to Filter" );
			}

			if( log.IsDebugEnabled )
			{
				log.Debug( "filter: " + filter );
				parameters.LogParameters( factory );
			}

			CollectionEntry entry = GetCollectionEntryOrNull( collection );
			ICollectionPersister roleBeforeFlush = ( entry == null ) ? null : entry.loadedPersister;

			FilterTranslator filterTranslator;
			if( roleBeforeFlush == null )
			{
				// if it was previously unreferenced, we need
				// to flush in order to get its state into the
				// database to query
				Flush();
				entry = GetCollectionEntryOrNull( collection );
				ICollectionPersister roleAfterFlush = ( entry == null ) ? null : entry.loadedPersister;

				if( roleAfterFlush == null )
				{
					throw new QueryException( "the collection was unreferenced" );
				}
				filterTranslator = factory.GetFilter( filter, roleAfterFlush.Role, scalar );
			}
			else
			{
				// otherwise, we only need to flush if there are
				// in-memory changes to the queried tables
				filterTranslator = factory.GetFilter( filter, roleBeforeFlush.Role, scalar );
				if( AutoFlushIfRequired( filterTranslator.QuerySpaces ) )
				{
					// might need to run a different filter entirely after the flush
					// because the collection role may have changed
					entry = GetCollectionEntryOrNull( collection );
					ICollectionPersister roleAfterFlush = ( entry == null ) ? null : entry.loadedPersister;
					if( roleBeforeFlush != roleAfterFlush )
					{
						if( roleAfterFlush == null )
						{
							throw new QueryException( "The collection was dereferenced" );
						}
					}
					filterTranslator = factory.GetFilter( filter, roleAfterFlush.Role, scalar );
				}
			}

			parameters.PositionalParameterValues[ 0 ] = entry.loadedKey;
			parameters.PositionalParameterTypes[ 0 ] = entry.loadedPersister.KeyType;

			return filterTranslator;

		}
		public IList Find( string query, QueryParameters parameters )
		{
			CheckIsOpen();

			if( log.IsDebugEnabled )
			{
				log.Debug( "find: " + query );
				parameters.LogParameters( factory );
			}

			parameters.ValidateParameters();

			QueryTranslator[ ] q = GetQueries( query, false );

			IList results = new ArrayList();

			dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called

			//execute the queries and return all result lists as a single list
			try
			{
				for( int i = 0; i < q.Length; i++ )
				{
					IList currentResults;
					try
					{
						currentResults = q[ i ].List( this, parameters );
					}
					catch( Exception e )
					{
						throw new ADOException( "Could not execute query", e );
					}

					for( int j = 0; j < results.Count; j++ )
					{
						currentResults.Add( results[ j ] );
					}
					results = currentResults;
				}
			}
			finally
			{
				dontFlushFromFind--;
			}
			return results;
		}