public SQLQueryReturnProcessor(
			ISQLQueryReturn[] queryReturns,
			ISessionFactoryImplementor factory)
		{
			this.queryReturns = queryReturns;
			this.factory = factory;
		}
		public NamedSQLQueryDefinition(
			string query,
			ISQLQueryReturn[] queryReturns,
			IList querySpaces,
			bool cacheable,
			string cacheRegion,
			int timeout,
			int fetchSize,
			FlushMode flushMode,
			bool readOnly,
			string comment,
			IDictionary parameterTypes,
			bool callable)
			: base(
				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;
		}
		public NativeSQLQuerySpecification(
			string queryString,
			ISQLQueryReturn[] sqlQueryReturns,
			ICollection querySpaces)
		{
			this.queryString = queryString;
			this.sqlQueryReturns = sqlQueryReturns;

			if (querySpaces == null)
			{
				this.querySpaces = new HashedSet();
			}
			else
			{
				ISet tmp = new HashedSet();
				tmp.AddAll(querySpaces);
				// Can't use ImmutableSet here because it doesn't implement GetHashCode properly.
				this.querySpaces = tmp;
			}

			// pre-determine and cache the hashcode
			int hashCode = queryString.GetHashCode();
			unchecked
			{
				hashCode = 29 * hashCode + this.querySpaces.GetHashCode();
				if (this.sqlQueryReturns != null)
				{
					hashCode = 29 * hashCode + sqlQueryReturns.Length;
				}
			}

			this.hashCode = hashCode;
		}
		public SQLCustomQuery(
			ISQLQueryReturn[] queryReturns,
			string sqlQuery,
			ICollection additionalQuerySpaces,
			ISessionFactoryImplementor factory)
		{
			log.Debug("starting processing of sql query [" + sqlQuery + "]");
			SQLQueryReturnProcessor processor = new SQLQueryReturnProcessor(queryReturns, factory);
			SQLQueryReturnProcessor.ResultAliasContext aliasContext = processor.Process();

			SQLQueryParser parser = new SQLQueryParser(sqlQuery, new ParserContext(aliasContext));
			this.sql = parser.Process();
			ArrayHelper.AddAll(this.namedParameterBindPoints, parser.NamedParameters);
			ArrayHelper.AddAll(customQueryReturns, processor.GenerateCustomReturns(parser.QueryHasAliases));

			if (additionalQuerySpaces != null)
			{
				querySpaces.AddAll(additionalQuerySpaces);
			}
		}
		public ISQLQueryReturn[] GetQueryReturns()
		{
			ISQLQueryReturn[] result = new ISQLQueryReturn[queryReturns.Count];
			queryReturns.CopyTo(result, 0);
			return result;
		}
		public void AddQueryReturn(ISQLQueryReturn queryReturn)
		{
			queryReturns.Add(queryReturn);
		}
		private void ProcessReturn(ISQLQueryReturn rtn)
		{
			if (rtn is SQLQueryScalarReturn)
			{
				ProcessScalarReturn((SQLQueryScalarReturn) rtn);
			}
			else if (rtn is SQLQueryRootReturn)
			{
				ProcessRootReturn((SQLQueryRootReturn) rtn);
			}
			else if (rtn is SQLQueryCollectionReturn)
			{
				ProcessCollectionReturn((SQLQueryCollectionReturn) rtn);
			}
			else
			{
				ProcessJoinReturn((SQLQueryJoinReturn) rtn);
			}
		}