public int BindParameters(IDbCommand command, GetNamedParameterLocations getNamedParameterLocations, int start,
		                          ISessionImplementor session)
		{
			var values = new List<object>();
			var types = new List<IType>();
			var sources = new List<string>();

			for (int i = 0; i < _positionalParameterLocations.Length; i++)
			{
				int location = FindAdjustedParameterLocation(_positionalParameterLocations[i]);
				object value = _positionalParameterValues[i];
				IType type = _positionalParameterTypes[i];
				ArrayHelper.SafeSetValue(values, location, value);
				ArrayHelper.SafeSetValue(types, location, type);
				ArrayHelper.SafeSetValue(sources, location, "Positional" + i);
			}

			for (int i = 0; i < filteredParameterLocations.Count; i++)
			{
				int location = filteredParameterLocations[i];
				object value = filteredParameterValues[i];
				IType type = filteredParameterTypes[i];
				ArrayHelper.SafeSetValue(values, location, value);
				ArrayHelper.SafeSetValue(types, location, type);
				ArrayHelper.SafeSetValue(sources, location, "Filter" + i);
			}

			if ((_namedParameters != null) && (_namedParameters.Count > 0))
			{
				foreach (var namedParameter in _namedParameters)
				{
					string name = namedParameter.Key;
					TypedValue typedval = namedParameter.Value;
					int[] locations = getNamedParameterLocations(name);
					for (int i = 0; i < locations.Length; i++)
					{
						int location = FindAdjustedParameterLocation(locations[i]);

						// can still clash with positional parameters
						//  could consider throwing an exception to locate problem (NH-1098)
						while ((location < types.Count) && (types[location] != null))
						{
							location++;
						}

						ArrayHelper.SafeSetValue(values, location, typedval.Value);
						ArrayHelper.SafeSetValue(types, location, typedval.Type);
						ArrayHelper.SafeSetValue(sources, location, "name" + i);
					}
				}
			}

			int span = 0;
			for (int i = 0; i < values.Count; i++)
			{
				IType type = types[i];
				object value = values[i];
				if (log.IsDebugEnabled)
				{
					log.Debug(string.Format("BindParameters({0}:{1}) {2} -> [{3}]", "Named", type, value, i));
				}
				type.NullSafeSet(command, value, start + span, session);
				span += type.GetColumnSpan(session.Factory);
			}

			return span;
		}
		public SqlType[] PrepareParameterTypes(SqlString sqlString, ISessionFactoryImplementor factory, GetNamedParameterLocations getNamedParameterLocations, int startParameterIndex, bool addLimit, bool addOffset)
		{
			List<IType> paramTypeList = new List<IType>();
			int parameterIndex = 0;
			int totalSpan = 0;

			CreatePositionalParameterLocations(factory);

			IList<Parameter> sqlParameters = FindParametersIn(sqlString);

			for (int index = 0; index < PositionalParameterTypes.Length; index++)
			{
				IType type = PositionalParameterTypes[index];
				ArrayHelper.SafeSetValue(paramTypeList, parameterIndex, type);

				int location = PositionalParameterLocations[index];
				location = FindAdjustedParameterLocation(location);
				int span = type.GetColumnSpan(factory);
				SetParameterLocation(sqlParameters, startParameterIndex + totalSpan, location, span);

				totalSpan += span;
				parameterIndex++;
			}

			for (int index = 0; index < FilteredParameterTypes.Count; index++)
			{
				IType type = FilteredParameterTypes[index];
				ArrayHelper.SafeSetValue(paramTypeList, parameterIndex, type);

				int location = FilteredParameterLocations[index];
				int span = type.GetColumnSpan(factory);
				SetParameterLocation(sqlParameters, startParameterIndex + totalSpan, location, span);

				totalSpan += span;
				parameterIndex++;
			}

			if (NamedParameters != null && NamedParameters.Count > 0)
			{
				// convert the named parameters to an array of types
				foreach (KeyValuePair<string, TypedValue> namedParameter in NamedParameters)
				{
					TypedValue typedval = namedParameter.Value;
					ArrayHelper.SafeSetValue(paramTypeList, parameterIndex, typedval.Type);

					int span = typedval.Type.GetColumnSpan(factory);
					string name = namedParameter.Key;
					int[] locs = getNamedParameterLocations(name);
					for (int i = 0; i < locs.Length; i++)
					{
						int location = locs[i];
						location = FindAdjustedParameterLocation(location);

						// can still clash with positional parameters
						//  could consider throwing an exception to locate problem (NH-1098)
						while ((location < sqlParameters.Count) && (sqlParameters[location].ParameterPosition != null))
							location++;

						SetParameterLocation(sqlParameters, startParameterIndex + totalSpan, location, span);
					}

					totalSpan += span;
					parameterIndex++;
				}
			}

			if (_tempPagingParameterIndexes != null)
			{
				_pagingParameterIndexMap = new Dictionary<int, int>();

				var pagingParameters =
					sqlString.Parts
						.Cast<object>()
						.Where(p => p is Parameter)
						.Cast<Parameter>()
						.Where(p => p.ParameterPosition.HasValue && p.ParameterPosition < 0)
						.ToList();

				foreach (Parameter pagingParameter in pagingParameters)
				{
					int pagingValue = _tempPagingParameterIndexes[pagingParameter.ParameterPosition.Value];
					int position = parameterIndex + startParameterIndex;
					_pagingParameterIndexMap.Add(position, pagingValue);
					pagingParameter.ParameterPosition = position;
					paramTypeList.Add(NHibernateUtil.Int32);
					parameterIndex++;
					totalSpan++;
				}
			}

			if (addLimit && factory.Dialect.SupportsVariableLimit)
			{
				if (factory.Dialect.BindLimitParametersFirst)
				{
					paramTypeList.Insert(0, NHibernateUtil.Int32);
					limitParameterIndex = startParameterIndex - 1;
					if (addOffset)
					{
						paramTypeList.Insert(0, NHibernateUtil.Int32);
						offsetParameterIndex = startParameterIndex - 2;
					}
				}
				else
				{
					paramTypeList.Add(NHibernateUtil.Int32);
					limitParameterIndex = totalSpan;
					if (addOffset)
					{
						paramTypeList.Add(NHibernateUtil.Int32);
						offsetParameterIndex = totalSpan;
						limitParameterIndex = totalSpan + 1;
					}
				}

				if (addOffset && factory.Dialect.BindLimitParametersInReverseOrder)
				{
					int? temp = limitParameterIndex;
					limitParameterIndex = offsetParameterIndex;
					offsetParameterIndex = temp;
				}

				totalSpan += addOffset ? 2 : 1;
			}

			return ConvertITypesToSqlTypes(paramTypeList, factory, totalSpan);
		}
		public SqlType[] PrepareParameterTypes(SqlString sqlString, ISessionFactoryImplementor factory, GetNamedParameterLocations getNamedParameterLocations, int startParameterIndex, bool addLimit, bool addOffset)
		{
			List<IType> paramTypeList = new List<IType>();
			int parameterIndex = 0;
			int totalSpan = 0;

			IList<Parameter> sqlParameters = FindParametersIn(sqlString);

			for (int index = 0; index < PositionalParameterTypes.Length; index++)
			{
				IType type = PositionalParameterTypes[index];
				ArrayHelper.SafeSetValue(paramTypeList, parameterIndex, type);

				int location = PositionalParameterLocations[index];
				location = FindAdjustedParameterLocation(location);
				int span = type.GetColumnSpan(factory);
				SetParameterLocation(sqlParameters, startParameterIndex + parameterIndex, location, span);

				totalSpan += span;
				parameterIndex++;
			}

			for (int index = 0; index < FilteredParameterTypes.Count; index++)
			{
				IType type = FilteredParameterTypes[index];
				ArrayHelper.SafeSetValue(paramTypeList, parameterIndex, type);

				int location = FilteredParameterLocations[index];
				int span = type.GetColumnSpan(factory);
				SetParameterLocation(sqlParameters, startParameterIndex + parameterIndex, location, span);

				totalSpan += span;
				parameterIndex++;
			}

			if (NamedParameters != null && NamedParameters.Count > 0)
			{
				// convert the named parameters to an array of types
				foreach (KeyValuePair<string, TypedValue> namedParameter in NamedParameters)
				{
					TypedValue typedval = namedParameter.Value;
					ArrayHelper.SafeSetValue(paramTypeList, parameterIndex, typedval.Type);

					int span = typedval.Type.GetColumnSpan(factory);
					string name = namedParameter.Key;
					int[] locs = getNamedParameterLocations(name);
					for (int i = 0; i < locs.Length; i++)
					{
						int location = locs[i];
						location = FindAdjustedParameterLocation(location);

						// can still clash with positional parameters
						//  could consider throwing an exception to locate problem (NH-1098)
						while ((location < sqlParameters.Count) && (sqlParameters[location].ParameterPosition != null))
							location++;

						SetParameterLocation(sqlParameters, startParameterIndex + parameterIndex, location, span);
					}

					totalSpan += span;
					parameterIndex++;
				}
			}

			if (addLimit && factory.Dialect.SupportsVariableLimit)
			{
				if (factory.Dialect.BindLimitParametersFirst)
				{
					paramTypeList.Insert(0, NHibernateUtil.Int32);
					if (addOffset)
					{
						paramTypeList.Insert(0, NHibernateUtil.Int32);
					}
				}
				else
				{
					paramTypeList.Add(NHibernateUtil.Int32);
					if (addOffset)
					{
						paramTypeList.Add(NHibernateUtil.Int32);
					}
				}

				totalSpan += addOffset ? 2 : 1;
			}

			return ConvertITypesToSqlTypes(paramTypeList, factory, totalSpan);
		}