Index: src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- src/NHibernate.Test/NHibernate.Test.csproj	(revision 4680)
+++ src/NHibernate.Test/NHibernate.Test.csproj	(working copy)
@@ -546,6 +546,8 @@
     <Compile Include="NHSpecificTest\NH1899\SampleTest.cs" />
     <Compile Include="NHSpecificTest\NH1907\MyType.cs" />
     <Compile Include="NHSpecificTest\NH1907\Fixture.cs" />
+    <Compile Include="NHSpecificTest\NH1908ThreadSafety\Fixture.cs" />
+    <Compile Include="NHSpecificTest\NH1908ThreadSafety\Model.cs" />
     <Compile Include="NHSpecificTest\NH1908\Fixture.cs" />
     <Compile Include="NHSpecificTest\NH1908\Model.cs" />
     <Compile Include="NHSpecificTest\NH473\Child.cs" />
@@ -1958,6 +1960,7 @@
     <EmbeddedResource Include="Bytecode\Lightweight\ProductLine.hbm.xml" />
     <EmbeddedResource Include="DriverTest\MultiTypeEntity.hbm.xml" />
     <Content Include="DynamicEntity\package.html" />
+    <EmbeddedResource Include="NHSpecificTest\NH1908ThreadSafety\Mappings.hbm.xml" />
     <EmbeddedResource Include="NHSpecificTest\NH1908\Mappings.hbm.xml" />
     <EmbeddedResource Include="FilterTest\WrongFilterDefInClass.hbm.xml" />
     <EmbeddedResource Include="FilterTest\SimpleFiltered.hbm.xml" />

Property changes on: src\NHibernate.Test\NHSpecificTest\NH1908ThreadSafety
___________________________________________________________________
Added: bugtraq:url
   + http://jira.nhibernate.org/browse/%BUGID%
Added: bugtraq:logregex
   + NH-\d+


Index: src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Fixture.cs
===================================================================
--- src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Fixture.cs	(revision 0)
+++ src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Fixture.cs	(revision 0)
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH1908ThreadSafety
+{
+	[TestFixture]
+	public class Fixture : BugTestCase
+	{
+        [Test]
+        public void CanExecuteJustFineWithoutThreading()
+        {
+            ScenarioRunningWithMultiThreading();
+        }
+
+        [Test]
+        public void UsingFiltersIsThreadSafe()
+        {
+            var errors = new List<Exception>();
+            var threads = new List<Thread>();
+            for (int i = 0; i < 50; i++)
+            {
+                var thread = new Thread(() =>
+                {
+                    try
+                    {
+                        ScenarioRunningWithMultiThreading();
+                    }
+                    catch (Exception ex)
+                    {
+                        lock (errors)
+                            errors.Add(ex);
+                    }
+                });
+                thread.Start();
+                threads.Add(thread);
+            }
+
+            foreach (var thread in threads)
+            {
+                thread.Join();
+            }
+
+            Assert.AreEqual(0, errors.Count);
+        }
+
+	    private void ScenarioRunningWithMultiThreading()
+	    {
+            using (var session = sessions.OpenSession())
+            {
+                session
+                    .EnableFilter("CurrentOnly")
+                    .SetParameter("date", DateTime.Now);
+
+                session.CreateQuery(
+                   @"
+                select u
+                from Order u
+                    left join fetch u.ActiveOrderLines
+                where
+                    u.Email = :email
+                ")
+                   .SetString("email", "stupid@bugs.com")
+                   .UniqueResult<Order>();
+            }
+	    }
+	}
+}
Index: src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Mappings.hbm.xml
===================================================================
--- src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Mappings.hbm.xml	(revision 0)
+++ src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Mappings.hbm.xml	(revision 0)
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+									 assembly="NHibernate.Test"
+									 namespace="NHibernate.Test.NHSpecificTest.NH1908ThreadSafety">
+
+  <class name="Order" table="Orders">
+    <id name="Id" type="Int64" unsaved-value="none">
+      <generator class="assigned"/>
+    </id>
+    <property name="Email" type="String" not-null="true"/>
+    <bag name="ActiveOrderLines" inverse="true" cascade="none" lazy="true"
+         optimistic-lock="false">
+      <key column="OrderId"/>
+      <one-to-many class="OrderLine"/>
+      <filter name="CurrentOnly"/>
+    </bag>
+  </class>
+
+  <class name="OrderLine" discriminator-value="null">
+    <id name="Id" type="Int64" unsaved-value="none">
+      <generator class="assigned"/>
+    </id>
+    <property name="ValidUntil"/>
+    <filter name="CurrentOnly"/>
+  </class>
+
+  <filter-def name="CurrentOnly" condition="ValidUntil > :date">
+    <filter-param name="date" type="DateTime"/>
+  </filter-def>
+</hibernate-mapping>
Index: src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Model.cs
===================================================================
--- src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Model.cs	(revision 0)
+++ src/NHibernate.Test/NHSpecificTest/NH1908ThreadSafety/Model.cs	(revision 0)
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+
+namespace NHibernate.Test.NHSpecificTest.NH1908ThreadSafety
+{
+    public class Order
+    {
+        public virtual long Id { get; set; }
+        public virtual IList<OrderLine> ActiveOrderLines { get; set;}
+        public virtual string Email { get; set; }
+	}
+
+    public class OrderLine
+    {
+        public virtual long Id { get; set; }
+        public virtual DateTime ValidUntil { get; set; }
+    }
+}
Index: src/NHibernate/Engine/ISessionImplementor.cs
===================================================================
--- src/NHibernate/Engine/ISessionImplementor.cs	(revision 4680)
+++ src/NHibernate/Engine/ISessionImplementor.cs	(working copy)
@@ -19,7 +19,7 @@
 	/// Defines the internal contract between the <c>Session</c> and other parts of Hibernate
 	/// such as implementors of <c>Type</c> or <c>ClassPersister</c>
 	/// </summary>
-	public interface ISessionImplementor
+	public interface ISessionImplementor : ISessionScopedState
 	{
 		/// <summary>
 		/// Initialize the session after its construction was complete
Index: src/NHibernate/Engine/ISessionScopedState.cs
===================================================================
--- src/NHibernate/Engine/ISessionScopedState.cs	(revision 0)
+++ src/NHibernate/Engine/ISessionScopedState.cs	(revision 0)
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+
+namespace NHibernate.Engine
+{
+	public interface ISessionScopedState
+	{
+		/// <summary>
+		/// This collection provide a place to put session scoped items
+		/// </summary>
+		IDictionary<string, object> Items { get; }
+
+	}
+}
\ No newline at end of file
Index: src/NHibernate/Engine/Query/HQLQueryPlan.cs
===================================================================
--- src/NHibernate/Engine/Query/HQLQueryPlan.cs	(revision 4680)
+++ src/NHibernate/Engine/Query/HQLQueryPlan.cs	(working copy)
@@ -80,7 +80,7 @@
 			}
 			else
 			{
-				parameterMetadata = BuildParameterMetadata(translators[0].GetParameterTranslations(), hql);
+				parameterMetadata = BuildParameterMetadata(translators[0].GetParameterTranslations(), hql, new SessionScopedStateWhenWeHaveNoSession());
 				if (translators[0].IsManipulationStatement)
 				{
 					returnMetadata = null;
@@ -155,7 +155,7 @@
 			}
 		}
 
-		private static ParameterMetadata BuildParameterMetadata(IParameterTranslations parameterTranslations, string hql)
+		private static ParameterMetadata BuildParameterMetadata(IParameterTranslations parameterTranslations, string hql, ISessionScopedState session)
 		{
 			long start = DateTime.Now.Ticks;
 			ParamLocationRecognizer recognizer = ParamLocationRecognizer.ParseLocations(hql);
@@ -165,7 +165,7 @@
 				log.Debug("HQL param location recognition took " + (end - start) + " mills (" + hql + ")");
 			}
 
-			int ordinalParamCount = parameterTranslations.OrdinalParameterCount;
+			int ordinalParamCount = parameterTranslations.GetOrdinalParameterCount(session);
 			int[] locations = recognizer.OrdinalParameterLocationList.ToArray();
 			if (parameterTranslations.SupportsOrdinalParameterMetadata && locations.Length != ordinalParamCount)
 			{
@@ -178,7 +178,7 @@
 				ordinalParamDescriptors[i - 1] =
 					new OrdinalParameterDescriptor(i,
 					                               parameterTranslations.SupportsOrdinalParameterMetadata
-					                               	? parameterTranslations.GetOrdinalParameterExpectedType(i)
+					                               	? parameterTranslations.GetOrdinalParameterExpectedType(i, session)
 					                               	: null, locations[i - 1]);
 			}
 
@@ -188,7 +188,7 @@
 				string name = entry.Key;
 				ParamLocationRecognizer.NamedParameterDescription description = entry.Value;
 				namedParamDescriptorMap[name] =
-					new NamedParameterDescriptor(name, parameterTranslations.GetNamedParameterExpectedType(name),
+					new NamedParameterDescriptor(name, parameterTranslations.GetNamedParameterExpectedType(name, session),
 					                             description.BuildPositionsArray(), description.JpaStyle);
 
 			}
@@ -330,5 +330,14 @@
 			return result;
 		}
 
+		private class SessionScopedStateWhenWeHaveNoSession : ISessionScopedState
+		{
+			private readonly IDictionary<string, object> items = new Dictionary<string, object>();
+
+			public IDictionary<string, object> Items
+			{
+				get { return items; }
+			}
+		}
 	}
 }
Index: src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs
===================================================================
--- src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs	(revision 4680)
+++ src/NHibernate/Hql/Ast/ANTLR/Loader/QueryLoader.cs	(working copy)
@@ -58,9 +58,9 @@
 			get { return HasSubselectLoadableCollections(); }
 		}
 
-		protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters)
+		protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters, ISessionImplementor session)
 		{
-			_queryTranslator.AdjustNamedParameterLocationsForQueryParameters(parameters);
+			_queryTranslator.AdjustNamedParameterLocationsForQueryParameters(parameters, session);
 		}
 
 		protected override SqlString ApplyLocks(SqlString sql, IDictionary<string, LockMode> lockModes,
@@ -161,9 +161,9 @@
 		/// </summary>
 		/// <param name="name"></param>
 		/// <returns></returns>
-		public override int[] GetNamedParameterLocs(string name)
+		public override int[] GetNamedParameterLocs(string name, ISessionScopedState session)
 		{
-			return _queryTranslator.GetParameterTranslations().GetNamedParameterSqlLocations(name);
+			return _queryTranslator.GetParameterTranslations().GetNamedParameterSqlLocations(name, session);
 		}
 
 		/// <summary>
Index: src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs
===================================================================
--- src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs	(revision 4680)
+++ src/NHibernate/Hql/Ast/ANTLR/QueryTranslatorImpl.cs	(working copy)
@@ -443,9 +443,9 @@
 			}
 		}
 
-	    public void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters)
+	    public void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters, ISessionImplementor session)
 	    {
-	        ((ParameterTranslationsImpl) GetParameterTranslations()).AdjustNamedParameterLocationsForQueryParameters(parameters);
+	        ((ParameterTranslationsImpl) GetParameterTranslations()).AdjustNamedParameterLocationsForQueryParameters(parameters, session);
 	    }
 	}
 
Index: src/NHibernate/Hql/Classic/QueryTranslator.cs
===================================================================
--- src/NHibernate/Hql/Classic/QueryTranslator.cs	(revision 4680)
+++ src/NHibernate/Hql/Classic/QueryTranslator.cs	(working copy)
@@ -693,7 +693,7 @@
 			}
 		}
 
-		public override int[] GetNamedParameterLocs(string name)
+		public override int[] GetNamedParameterLocs(string name, ISessionScopedState session)
 		{
 			List<int> o;
 			if (!namedParameters.TryGetValue(name, out o))
@@ -705,7 +705,7 @@
 			return o.ToArray();
 		}
 
-		protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters)
+		protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters, ISessionImplementor session)
 		{
 			foreach (int existingParameterLocation in parameters.FilteredParameterLocations)
 			{
@@ -1715,32 +1715,32 @@
 				get { return false; }
 			}
 
-			public int OrdinalParameterCount
+			public int GetOrdinalParameterCount(ISessionScopedState session)
 			{
-				get { return 0; }
+				return 0;
 			}
 
-			public int GetOrdinalParameterSqlLocation(int ordinalPosition)
+			public int GetOrdinalParameterSqlLocation(int ordinalPosition, ISessionScopedState session)
 			{
 				return 0;
 			}
 
-			public IType GetOrdinalParameterExpectedType(int ordinalPosition)
+			public IType GetOrdinalParameterExpectedType(int ordinalPosition, ISessionScopedState session)
 			{
 				return null;
 			}
 
-			public IEnumerable<string> GetNamedParameterNames()
+			public IEnumerable<string> GetNamedParameterNames(ISessionScopedState session)
 			{
 				return queryTraslator.namedParameters.Keys;
 			}
 
-			public int[] GetNamedParameterSqlLocations(string name)
+			public int[] GetNamedParameterSqlLocations(string name, ISessionScopedState session)
 			{
-				return queryTraslator.GetNamedParameterLocs(name);
+				return queryTraslator.GetNamedParameterLocs(name, session);
 			}
 
-			public IType GetNamedParameterExpectedType(string name)
+			public IType GetNamedParameterExpectedType(string name, ISessionScopedState session)
 			{
 				return null;
 			}
Index: src/NHibernate/Hql/IParameterTranslations.cs
===================================================================
--- src/NHibernate/Hql/IParameterTranslations.cs	(revision 4680)
+++ src/NHibernate/Hql/IParameterTranslations.cs	(working copy)
@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using NHibernate.Engine;
 using NHibernate.Type;
 
 namespace NHibernate.Hql
@@ -7,16 +8,16 @@
 	{
 		bool SupportsOrdinalParameterMetadata { get; }
 
-		int OrdinalParameterCount { get; }
+		int GetOrdinalParameterCount(ISessionScopedState session);
 
-		int GetOrdinalParameterSqlLocation(int ordinalPosition);
+		int GetOrdinalParameterSqlLocation(int ordinalPosition, ISessionScopedState session);
 
-		IType GetOrdinalParameterExpectedType(int ordinalPosition);
+		IType GetOrdinalParameterExpectedType(int ordinalPosition, ISessionScopedState session);
 
-		IEnumerable<string> GetNamedParameterNames();
+		IEnumerable<string> GetNamedParameterNames(ISessionScopedState session);
 
-		int[] GetNamedParameterSqlLocations(string name);
+		int[] GetNamedParameterSqlLocations(string name, ISessionScopedState session);
 
-		IType GetNamedParameterExpectedType(string name);
+		IType GetNamedParameterExpectedType(string name, ISessionScopedState session);
 	}
 }
\ No newline at end of file
Index: src/NHibernate/Impl/AbstractSessionImpl.cs
===================================================================
--- src/NHibernate/Impl/AbstractSessionImpl.cs	(revision 4680)
+++ src/NHibernate/Impl/AbstractSessionImpl.cs	(working copy)
@@ -37,6 +37,7 @@
 		private bool isAlreadyDisposed;
 
 		private static readonly ILog logger = LogManager.GetLogger(typeof(AbstractSessionImpl));
+		private readonly IDictionary<string, object> items = new Dictionary<string, object>();
 
 		public Guid SessionId
 		{
@@ -74,6 +75,11 @@
 
 		public abstract IBatcher Batcher { get; }
 		public abstract void CloseSessionFromDistributedTransaction();
+		public IDictionary<string, object> Items
+		{
+			get { return items; }
+		}
+
 		public abstract IList List(string query, QueryParameters parameters);
 		public abstract void List(string query, QueryParameters parameters, IList results);
 		public abstract IList<T> List<T>(string query, QueryParameters queryParameters);
Index: src/NHibernate/Impl/MultiCriteriaImpl.cs
===================================================================
--- src/NHibernate/Impl/MultiCriteriaImpl.cs	(revision 4680)
+++ src/NHibernate/Impl/MultiCriteriaImpl.cs	(working copy)
@@ -323,7 +323,10 @@
 			for (int i = 0; i < loaders.Count; i++)
 			{
 				QueryParameters parameter = parameters[i];
-				colIndex += parameter.BindParameters(command, loaders[i].GetNamedParameterLocs, colIndex, session);
+				colIndex += parameter.BindParameters(command, delegate(string name)
+				{
+					return loaders[i].GetNamedParameterLocs(name, session);
+				}, colIndex, session);
 			}
 			return colIndex;
 		}
Index: src/NHibernate/Impl/MultiQueryImpl.cs
===================================================================
--- src/NHibernate/Impl/MultiQueryImpl.cs	(revision 4680)
+++ src/NHibernate/Impl/MultiQueryImpl.cs	(working copy)
@@ -631,12 +631,12 @@
 			}
 		}
 
-		private static QueryParameters GetFilteredQueryParameters(QueryParameters queryParameters, IQueryTranslator translator)
+		private QueryParameters GetFilteredQueryParameters(QueryParameters queryParameters, IQueryTranslator translator)
 		{
 			QueryParameters filteredQueryParameters = queryParameters;
 			Dictionary<string, TypedValue> namedParameters = new Dictionary<string, TypedValue>(queryParameters.NamedParameters);
 			filteredQueryParameters.NamedParameters.Clear();
-			foreach (string paramName in translator.GetParameterTranslations().GetNamedParameterNames())
+			foreach (string paramName in translator.GetParameterTranslations().GetNamedParameterNames(session))
 			{
 				TypedValue v;
 				if (namedParameters.TryGetValue(paramName, out v))
@@ -676,7 +676,10 @@
 			{
 				IQueryTranslator translator = Translators[i];
 				QueryParameters parameter = Parameters[i];
-				colIndex += parameter.BindParameters(command, translator.Loader.GetNamedParameterLocs, colIndex, session);
+				colIndex += parameter.BindParameters(command, delegate(string parameterName)
+				{
+					return translator.Loader.GetNamedParameterLocs(parameterName, session);
+				}, colIndex, session);
 			}
 			return colIndex;
 		}
Index: src/NHibernate/Loader/Collection/SubselectCollectionLoader.cs
===================================================================
--- src/NHibernate/Loader/Collection/SubselectCollectionLoader.cs	(revision 4680)
+++ src/NHibernate/Loader/Collection/SubselectCollectionLoader.cs	(working copy)
@@ -39,12 +39,12 @@
 			LoadCollectionSubselect(session, keys, values, types, namedParameters, KeyType);
 		}
 
-		public override int[] GetNamedParameterLocs(string name)
+		public override int[] GetNamedParameterLocs(string name, ISessionScopedState session)
 		{
 			return namedParameterLocMap[name];
 		}
 
-		protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters)
+		protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters, ISessionImplementor session)
 		{
 			if (namedParameterLocMap == null)
 				return;
Index: src/NHibernate/Loader/Collection/SubselectOneToManyLoader.cs
===================================================================
--- src/NHibernate/Loader/Collection/SubselectOneToManyLoader.cs	(revision 4680)
+++ src/NHibernate/Loader/Collection/SubselectOneToManyLoader.cs	(working copy)
@@ -41,12 +41,12 @@
 			LoadCollectionSubselect(session, keys, values, types, namedParameters, KeyType);
 		}
 
-		public override int[] GetNamedParameterLocs(string name)
+		public override int[] GetNamedParameterLocs(string name, ISessionScopedState session)
 		{
 			return namedParameterLocMap[name];
 		}
 
-		protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters)
+		protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters, ISessionImplementor session)
 		{
 			if (namedParameterLocMap == null)
 				return;
Index: src/NHibernate/Loader/Custom/CustomLoader.cs
===================================================================
--- src/NHibernate/Loader/Custom/CustomLoader.cs	(revision 4680)
+++ src/NHibernate/Loader/Custom/CustomLoader.cs	(working copy)
@@ -302,7 +302,7 @@
 			}
 		}
 
-		public override int[] GetNamedParameterLocs(string name)
+		public override int[] GetNamedParameterLocs(string name, ISessionScopedState session)
 		{
 			object loc = namedParameterBindPoints[name];
 			if (loc == null)
@@ -320,7 +320,7 @@
 			}
 		}
 
-		protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters)
+		protected override void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters, ISessionImplementor session)
 		{
 			var existingParameterLocations = parameters.FilteredParameterLocations.GetEnumerator();
 			while (existingParameterLocations.MoveNext())
Index: src/NHibernate/Loader/Loader.cs
===================================================================
--- src/NHibernate/Loader/Loader.cs	(revision 4680)
+++ src/NHibernate/Loader/Loader.cs	(working copy)
@@ -503,7 +503,7 @@
 
 				ISet<EntityKey>[] keySets = Transpose(keys);
 
-				IDictionary<string, int[]> namedParameterLocMap = BuildNamedParameterLocMap(queryParameters);
+				IDictionary<string, int[]> namedParameterLocMap = BuildNamedParameterLocMap(queryParameters, session);
 
 				ILoadable[] loadables = EntityPersisters;
 				string[] aliases = Aliases;
@@ -524,14 +524,14 @@
 			}
 		}
 
-		private IDictionary<string, int[]> BuildNamedParameterLocMap(QueryParameters queryParameters)
+		private IDictionary<string, int[]> BuildNamedParameterLocMap(QueryParameters queryParameters, ISessionImplementor session)
 		{
 			if (queryParameters.NamedParameters != null)
 			{
 				IDictionary<string, int[]> namedParameterLocMap = new Dictionary<string, int[]>();
 				foreach (string name in queryParameters.NamedParameters.Keys)
 				{
-					namedParameterLocMap[name] = GetNamedParameterLocs(name);
+					namedParameterLocMap[name] = GetNamedParameterLocs(name, session);
 				}
 				return namedParameterLocMap;
 			}
@@ -1114,7 +1114,7 @@
 			// TODO NH: Callable for SP -> PrepareCallableQueryCommand
 			IDbCommand command =
 				session.Batcher.PrepareQueryCommand(CommandType.Text, sqlString,
-				                                    GetParameterTypes(queryParameters, useLimit, useOffset));
+				                                    GetParameterTypes(queryParameters, useLimit, useOffset,session));
 
 			try
 			{
@@ -1174,7 +1174,7 @@
 		protected virtual SqlString ProcessFilters(QueryParameters parameters, ISessionImplementor session)
 		{
 			parameters.ProcessFilters(SqlString, session);
-			AdjustNamedParameterLocationsForQueryParameters(parameters);
+			AdjustNamedParameterLocationsForQueryParameters(parameters, session);
 			return parameters.FilteredSQL;
 		}
 
@@ -1261,15 +1261,18 @@
 			// NH Different behavior:
 			// The responsibility of parameter binding was entirely moved to QueryParameters
 			// to deal with positionslParameter+NamedParameter+ParameterOfFilters
-			return queryParameters.BindParameters(statement, GetNamedParameterLocs, 0, session);
+			return queryParameters.BindParameters(statement, delegate(string name)
+			{
+				return GetNamedParameterLocs(name, session);
+			}, 0, session);
 		}
 
-		public virtual int[] GetNamedParameterLocs(string name)
+		public virtual int[] GetNamedParameterLocs(string name, ISessionScopedState session)
 		{
 			throw new AssertionFailure("no named parameters");
 		}
 
-		protected virtual void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters)
+		protected virtual void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters, ISessionImplementor session)
 		{
 			// if you support named parameter locations (by overriding GetNamedParameterLocs), then you might need to
 			//  allow for the locations to be adjusted by introduced filtered parameters by overriding
@@ -1707,7 +1710,7 @@
 			}
 
 			sqlString = PreprocessSQL(sqlString, parameters, dialect);
-			return new SqlCommandInfo(sqlString, GetParameterTypes(parameters, useLimit, useOffset));
+			return new SqlCommandInfo(sqlString, GetParameterTypes(parameters, useLimit, useOffset, session));
 		}
 
 		protected SqlType[] ConvertITypesToSqlTypes(List<IType> nhTypes, int totalSpan)
@@ -1726,7 +1729,7 @@
 		}
 
 		/// <returns><see cref="IList" /> of <see cref="IType" /></returns>
-		protected SqlType[] GetParameterTypes(QueryParameters parameters, bool addLimit, bool addOffset)
+		protected SqlType[] GetParameterTypes(QueryParameters parameters, bool addLimit, bool addOffset, ISessionImplementor session)
 		{
 			List<IType> paramTypeList = new List<IType>();
 			int span = 0;
@@ -1754,7 +1757,7 @@
 				{
 					string name = namedParameter.Key;
 					TypedValue typedval = namedParameter.Value;
-					int[] locs = GetNamedParameterLocs(name);
+					int[] locs = GetNamedParameterLocs(name, session);
 					span += typedval.Type.GetColumnSpan(Factory) * locs.Length;
 
 					for (int i = 0; i < locs.Length; i++)
@@ -1798,4 +1801,4 @@
 
 		#endregion
 	}
-}
+}
\ No newline at end of file
Index: src/NHibernate/NHibernate.csproj
===================================================================
--- src/NHibernate/NHibernate.csproj	(revision 4680)
+++ src/NHibernate/NHibernate.csproj	(working copy)
@@ -478,6 +478,7 @@
     <Compile Include="Dialect\SybaseASA9Dialect.cs" />
     <Compile Include="Driver\IfxDriver.cs" />
     <Compile Include="Driver\OracleLiteDataClientDriver.cs" />
+    <Compile Include="Engine\ISessionScopedState.cs" />
     <Compile Include="EntityModeEqualityComparer.cs" />
     <Compile Include="Event\AbstractPreDatabaseOperationEvent.cs" />
     <Compile Include="Event\IDestructible.cs" />
Index: src/NHibernate/Param/ParameterTranslationsImpl.cs
===================================================================
--- src/NHibernate/Param/ParameterTranslationsImpl.cs	(revision 4680)
+++ src/NHibernate/Param/ParameterTranslationsImpl.cs	(working copy)
@@ -15,9 +15,41 @@
 	/// </summary>
 	public class ParameterTranslationsImpl : IParameterTranslations
 	{
-		private readonly Dictionary<string, ParameterInfo> _namedParameters;
-		private readonly ParameterInfo[] _ordinalParameters;
+		private readonly Dictionary<string, ParameterInfo> _namedParameters1;
+		private readonly ParameterInfo[] _ordinalParameters1;
 
+		private readonly string id = Guid.NewGuid().ToString();
+
+		private Dictionary<string, ParameterInfo> GetNamedParameters(ISessionScopedState session)
+		{
+			object val;
+			var key = id + "-NamedParameters";
+			if (session.Items.TryGetValue(key, out val))
+				return (Dictionary<string, ParameterInfo>) val;
+			var clone = new Dictionary<string, ParameterInfo>();
+			foreach (var kvp in _namedParameters1)
+			{
+				clone[kvp.Key] = kvp.Value.Clone();
+			}
+			session.Items[key] = clone;
+			return clone;
+		}
+
+		private ParameterInfo[] GetOrdinalParameters(ISessionScopedState session)
+		{
+			object val;
+			var key = id + "-OrdinalParameters";
+			if (session.Items.TryGetValue(key, out val))
+				return (ParameterInfo[])val;
+			var clone = new ParameterInfo[_ordinalParameters1.Length];
+			for (int i = 0; i < _ordinalParameters1.Length; i++)
+			{
+				clone[i] = _ordinalParameters1[i].Clone();
+			}
+			session.Items[key] = clone;
+			return clone;
+		}
+
 		public ParameterTranslationsImpl(IEnumerable<IParameterSpecification> parameterSpecifications)
 		{
 			List<ParameterInfo> ordinalParameterList = new List<ParameterInfo>();
@@ -58,53 +90,53 @@
 				i++;
 			}
 
-			_ordinalParameters = ordinalParameterList.ToArray();
-			_namedParameters = new Dictionary<string, ParameterInfo>();
+			_ordinalParameters1 = ordinalParameterList.ToArray();
+			_namedParameters1 = new Dictionary<string, ParameterInfo>();
 
 			foreach (NamedParamTempHolder holder in namedParameterMap.Values)
 			{
-				_namedParameters.Add(holder.name, new ParameterInfo( ArrayHelper.ToIntArray( holder.positions ), holder.type ));
+				_namedParameters1.Add(holder.name, new ParameterInfo( ArrayHelper.ToIntArray( holder.positions ), holder.type ));
 			}
 		}
 
-		public void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters)
+		public void AdjustNamedParameterLocationsForQueryParameters(QueryParameters parameters, ISessionScopedState session)
 		{
 			// NH Different behaviour NH-1776
 			// Analyze all named parameters declared after filters 
 			// in general all named parameters but depend on the complexity of the query (see sub query)
-			RestoreOriginalParameterLocations();
+			RestoreOriginalParameterLocations(session);
 			foreach (int filterParameterLocation in parameters.FilteredParameterLocations)
 			{
-				foreach (ParameterInfo entry in _namedParameters.Values)
+				foreach (ParameterInfo entry in GetNamedParameters(session).Values)
 				{
 					entry.IncrementLocationAfterFilterLocation(filterParameterLocation);
 				}
 			}
 		}
 
-		public int GetOrdinalParameterSqlLocation(int ordinalPosition)
+		public int GetOrdinalParameterSqlLocation(int ordinalPosition, ISessionScopedState session)
 		{
-			return GetOrdinalParameterInfo(ordinalPosition).SqlLocations[0];
+			return GetOrdinalParameterInfo(ordinalPosition, session).SqlLocations[0];
 		}
 
-		public IType GetOrdinalParameterExpectedType(int ordinalPosition)
+		public IType GetOrdinalParameterExpectedType(int ordinalPosition, ISessionScopedState session)
 		{
-			return GetOrdinalParameterInfo(ordinalPosition).ExpectedType;
+			return GetOrdinalParameterInfo(ordinalPosition, session).ExpectedType;
 		}
 
-		public IEnumerable<string> GetNamedParameterNames()
+		public IEnumerable<string> GetNamedParameterNames(ISessionScopedState session)
 		{
-			return _namedParameters.Keys;
+			return GetNamedParameters(session).Keys;
 		}
 
-		public int[] GetNamedParameterSqlLocations(string name)
+		public int[] GetNamedParameterSqlLocations(string name, ISessionScopedState session)
 		{
-			return GetNamedParameterInfo(name).SqlLocations;
+			return GetNamedParameterInfo(name, session).SqlLocations;
 		}
 
-		public IType GetNamedParameterExpectedType(string name)
+		public IType GetNamedParameterExpectedType(string name, ISessionScopedState session)
 		{
-			return GetNamedParameterInfo(name).ExpectedType;
+			return GetNamedParameterInfo(name, session).ExpectedType;
 		}
 
 		public bool SupportsOrdinalParameterMetadata
@@ -112,28 +144,28 @@
 			get { return true; }
 		}
 
-		public int OrdinalParameterCount
+		public int GetOrdinalParameterCount(ISessionScopedState session)
 		{
-			get { return _ordinalParameters.Length; }
+			return GetOrdinalParameters(session).Length;
 		}
 
-		private void RestoreOriginalParameterLocations()
+		private void RestoreOriginalParameterLocations(ISessionScopedState session)
 		{
-			foreach (ParameterInfo entry in _namedParameters.Values)
+			foreach (ParameterInfo entry in GetNamedParameters(session).Values)
 			{
 				entry.RestoreOriginalParameterLocations();
 			}
 		}
 
-		private ParameterInfo GetOrdinalParameterInfo(int ordinalPosition)
+		private ParameterInfo GetOrdinalParameterInfo(int ordinalPosition, ISessionScopedState session)
 		{
 			// remember that ordinal parameters numbers are 1-based!!!
-			return _ordinalParameters[ordinalPosition - 1];
+			return GetOrdinalParameters(session)[ordinalPosition - 1];
 		}
 
-		private ParameterInfo GetNamedParameterInfo(String name)
+		private ParameterInfo GetNamedParameterInfo(String name, ISessionScopedState session)
 		{
-			return _namedParameters[name];
+			return GetNamedParameters(session)[name];
 		}
 
 		class NamedParamTempHolder
@@ -150,6 +182,14 @@
 		private readonly int[] originalLocation;
 		private readonly int[] sqlLocations;
 
+		public ParameterInfo Clone()
+		{
+			return new ParameterInfo((int[])originalLocation.Clone(), (int[])sqlLocations.Clone())
+			{
+				ExpectedType = ExpectedType
+			};
+		}
+
 		public ParameterInfo(int[] sqlPositions, IType expectedType) 
 		{
 			originalLocation = (int[])sqlPositions.Clone();
@@ -164,6 +204,12 @@
 			ExpectedType = expectedType;
 		}
 
+		private ParameterInfo(int[] positions, int[] locations)
+		{
+			originalLocation = positions;
+			sqlLocations = locations;
+		}
+
 		public int[] SqlLocations
 		{
 			get { return sqlLocations; }
