/// <summary>
		/// Does the put data set to cache.
		/// </summary>
		/// <param name="computedKey">The computed key.</param>
		/// <param name="ds">The ds.</param>
		/// <param name="cacheItemInfo">The cache item info.</param>
		protected virtual void DoPutDataSetToCache(
			string computedKey,
			DataSet ds,
			AdoNetCacheItemInformation cacheItemInfo )
		{
			// Must add my base group name.
			if ( cacheItemInfo == null ||
				cacheItemInfo.Group.IsEmpty )
			{
				cacheItemInfo.Group = prefixCacheItemGroup;
			}
			else
			{
				cacheItemInfo.Group =
					new CacheItemGroup(
					prefixCacheItemGroup.Name + cacheItemInfo.Group.Name );
			}

			// Put into cache, with correct expiration values.
			cacheManager.Set( computedKey, ds, cacheItemInfo );
		}
		/// <summary>
		/// Try to put a data value into the cache.
		/// Does nothing if the cache is deactivated.
		/// </summary>
		/// <param name="ds">The ds.</param>
		/// <param name="connectionString">The connection string.</param>
		/// <param name="sql">The SQL.</param>
		/// <param name="cacheItemInfo">The cache item info.</param>
		public void PutDataValueToCache(
			object ds,
			SmartConnectionString connectionString,
			string sql,
			AdoNetCacheItemInformation cacheItemInfo )
		{
			if ( CheckPutToCache( cacheItemInfo ) )
			{
				string computedKey = ComputeKey(
					@"dv",
					cacheItemInfo,
					connectionString,
					sql );

				lock ( thisLock )
				{
					// Clean before, if applicable.
					RemoveAll( sql, cacheItemInfo );

					// Put to cache.
					DoPutDataValueToCache( computedKey, ds, cacheItemInfo );
				}
			}
		}
		// ------------------------------------------------------------------
		#endregion

		#region Protected methods.
		// ------------------------------------------------------------------

		/// <summary>
		/// Does the get data set from cache.
		/// </summary>
		/// <param name="computedKey">The computed key.</param>
		/// <param name="cacheItemInfo">The cache item info.</param>
		/// <returns></returns>
		protected virtual DataSet DoGetDataSetFromCache(
			string computedKey,
			AdoNetCacheItemInformation cacheItemInfo )
		{
			return cacheManager.Get( computedKey ) as DataSet;
		}
		/// <summary>
		/// Try to read a data value from the cache.
		/// </summary>
		/// <param name="connectionString">The connection string.</param>
		/// <param name="sql">The SQL.</param>
		/// <param name="cacheItemInfo">The cache item info.</param>
		/// <returns>
		/// Returns NULL if not found or cache is deactivated.
		/// </returns>
		public object GetDataValueFromCache(
			SmartConnectionString connectionString,
			string sql,
			AdoNetCacheItemInformation cacheItemInfo )
		{
			object result;

			if ( CheckCanGetFromCache( cacheItemInfo ) )
			{
				string computedKey = ComputeKey(
					@"dv",
					cacheItemInfo,
					connectionString,
					sql );

				result =
					DoGetDataValueFromCache( computedKey, cacheItemInfo );
			}
			else
			{
				result = null;
			}

			// --

			if ( result == null )
			{
				totalMissCount++;
				LogCentral.Current.LogDebug(
					string.Format(
					@"AdoNetCache data value CACHE MISS ({0} hits, {1} misses totally).",
					totalHitCount,
					totalMissCount ) );
			}
			else
			{
				totalHitCount++;
				LogCentral.Current.LogDebug(
					string.Format(
					@"AdoNetCache data value CACHE HIT ({0} hits, {1} misses totally).",
					totalHitCount,
					totalMissCount ) );
			}

			// --

			return result;
		}
		/// <summary>
		/// Try to put a data value into the cache.
		/// Does nothing if the cache is deactivated.
		/// </summary>
		/// <param name="ds">The ds.</param>
		/// <param name="connectionString">The connection string.</param>
		/// <param name="spName">Name of the sp.</param>
		/// <param name="spParameters">The sp parameters.</param>
		/// <param name="cacheItemInfo">The cache item info.</param>
		public void PutDataValueToCache(
			object ds,
			SmartConnectionString connectionString,
			string spName,
			ICollection spParameters,
			AdoNetCacheItemInformation cacheItemInfo )
		{
			if ( CheckPutToCache( cacheItemInfo ) )
			{
				string pseudoSql =
					AdoNetBaseHelper<
						OleDbCommand,
						OleDbCommandBuilder,
						OleDbConnection,
						OleDbDataAdapter,
						OleDbParameter,
						AdoNetOleDBParamCollection>.
					QuickCreatePseudoSqlFromSP(
					spName,
					spParameters );

				PutDataValueToCache(
					ds,
					connectionString,
					pseudoSql,
					cacheItemInfo );
			}
		}
		/// <summary>
		/// Try to put a DataTable into the cache.
		/// Does nothing if the cache is deactivated.
		/// </summary>
		/// <param name="ds">The ds.</param>
		/// <param name="connectionString">The connection string.</param>
		/// <param name="sql">The SQL.</param>
		/// <param name="startIndex">The start index.</param>
		/// <param name="maxCount">The max count.</param>
		/// <param name="cacheItemInfo">The cache item info.</param>
		public void PutDataTableToCache(
			DataTable ds,
			SmartConnectionString connectionString,
			string sql,
			int startIndex,
			int maxCount,
			AdoNetCacheItemInformation cacheItemInfo )
		{
			if ( CheckPutToCache( cacheItemInfo ) )
			{
				string computedKey = ComputeKey(
					@"dt",
					cacheItemInfo,
					connectionString,
					sql,
					startIndex,
					maxCount );

				lock ( thisLock )
				{
					// Clean before, if applicable.
					RemoveAll( sql, cacheItemInfo );

					// Put to cache.
					DoPutDataTableToCache( computedKey, ds, cacheItemInfo );
				}
			}
		}
		// ------------------------------------------------------------------
		#endregion

		#region Caching Data values.
		// ------------------------------------------------------------------

		/// <summary>
		/// Try to read a data value from the cache.
		/// </summary>
		/// <param name="connectionString">The connection string.</param>
		/// <param name="spName">Name of the sp.</param>
		/// <param name="spParameters">The sp parameters.</param>
		/// <param name="cacheItemInfo">The cache item info.</param>
		/// <returns>
		/// Returns NULL if not found or cache is deactivated.
		/// </returns>
		public object GetDataValueFromCache(
			SmartConnectionString connectionString,
			string spName,
			ICollection spParameters,
			AdoNetCacheItemInformation cacheItemInfo )
		{
			if ( CheckCanGetFromCache( cacheItemInfo ) )
			{
				string pseudoSql =
					AdoNetBaseHelper<
						OleDbCommand,
						OleDbCommandBuilder,
						OleDbConnection,
						OleDbDataAdapter,
						OleDbParameter,
						AdoNetOleDBParamCollection>.
					QuickCreatePseudoSqlFromSP(
					spName,
					spParameters );

				return GetDataValueFromCache(
					connectionString,
					pseudoSql,
					cacheItemInfo );
			}
			else
			{
				return null;
			}
		}
		/// <summary>
		/// Clears the cache if the SQL is modifying or the cache item
		/// info says so (AdoNetCacheDBOperation.Modifying).
		/// </summary>
		/// <param name="sql">The SQL.</param>
		/// <param name="cacheItemInfo">The cache item info.</param>
		public void RemoveAll(
			string sql,
			AdoNetCacheItemInformation cacheItemInfo )
		{
			bool canClear;

			// --

			if ( AdoNetSqlHelper.IsModifyingQuery( sql ) )
			{
				canClear = true;
			}
			else
			{
				if ( cacheItemInfo != null &&
					cacheItemInfo.Operation ==
					AdoNetCacheDBOperation.Modifying )
				{
					canClear = true;
				}
				else
				{
					canClear = false;
				}
			}

			// --

			if ( canClear )
			{
				RemoveAll( cacheItemInfo );
			}
		}
		/// <summary>
		/// Try to read a DataTable from the cache.
		/// </summary>
		/// <param name="connectionString">The connection string.</param>
		/// <param name="sql">The SQL.</param>
		/// <param name="startIndex">The start index.</param>
		/// <param name="maxCount">The max count.</param>
		/// <param name="cacheItemInfo">The cache item info.</param>
		/// <returns>
		/// Returns NULL if not found or cache is deactivated.
		/// </returns>
		public DataTable GetDataTableFromCache(
			SmartConnectionString connectionString,
			string sql,
			int startIndex,
			int maxCount,
			AdoNetCacheItemInformation cacheItemInfo )
		{
			DataTable result;

			if ( CheckCanGetFromCache( cacheItemInfo ) )
			{
				string computedKey = ComputeKey(
					@"dt",
					cacheItemInfo,
					connectionString,
					sql,
					startIndex,
					maxCount );

				result =
					DoGetDataTableFromCache( computedKey, cacheItemInfo );
			}
			else
			{
				result = null;
			}

			// --

			if ( result == null )
			{
				totalMissCount++;
				LogCentral.Current.LogDebug(
					string.Format(
					@"AdoNetCache DataTable CACHE MISS ({0} hits, {1} misses totally).",
					totalHitCount,
					totalMissCount ) );
			}
			else
			{
				totalHitCount++;
				LogCentral.Current.LogDebug(
					string.Format(
					@"AdoNetCache DataTable CACHE HIT ({0} hits, {1} misses totally).",
					totalHitCount,
					totalMissCount ) );
			}

			// --

			return result;
		}
		/// <summary>
		/// Makes a unique key from the given spParameters.
		/// </summary>
		/// <param name="prefix">The prefix.</param>
		/// <param name="cacheItemInfo">The cache item info.</param>
		/// <param name="connectionString">The connection string.</param>
		/// <param name="sql">The SQL.</param>
		/// <returns></returns>
		private static string ComputeKey(
			string prefix,
			AdoNetCacheItemInformation cacheItemInfo,
			SmartConnectionString connectionString,
			string sql )
		{
			StringBuilder keyComputer = new StringBuilder();

			keyComputer.Length = 0;

			keyComputer.Append( prefix );
			keyComputer.Append( connectionString );
			keyComputer.Append( sql );

			return StringHelper.GenerateHash( keyComputer.ToString() );
		}
		/// <summary>
		/// Checks whether something should be get from the cache.
		/// </summary>
		/// <param name="cacheItemInfo">The cache item info.</param>
		/// <returns></returns>
		protected bool CheckPutToCache(
			AdoNetCacheItemInformation cacheItemInfo )
		{
			if ( cacheManager == null )
			{
				return false;
			}
			else
			{
				if ( CacheBehaviour ==
					LibraryConfiguration.DatabaseConfiguration.
					DatabaseCacheSqlBehavior.Off )
				{
					return false;
				}
				else
				{
					if ( CacheBehaviour ==
						LibraryConfiguration.DatabaseConfiguration.
						DatabaseCacheSqlBehavior.On )
					{
						if ( cacheItemInfo == null ||
							cacheItemInfo.Usage == CacheUsage.IgnoreCache )
						{
							return false;
						}
						else
						{
							return true;
						}
					}
					else
					{
						if ( cacheItemInfo != null &&
							cacheItemInfo.Usage == CacheUsage.UseCache )
						{
							return true;
						}
						else
						{
							return false;
						}
					}
				}
			}
		}
		/// <summary>
		/// Clear more selectively.
		/// </summary>
		/// <param name="cacheItemInfo">Uses the 'cacheKeyPrefix' member,
		/// if given, to delete only the specified keys. If the
		/// 'cacheKeyPrefix' member is null, all ADO.NET entries
		/// are cleared.</param>
		public void RemoveAll(
			AdoNetCacheItemInformation cacheItemInfo )
		{
			if ( CheckCanClearCache( cacheItemInfo ) )
			{
				if ( cacheItemInfo != null && !cacheItemInfo.Group.IsEmpty )
				{
					cacheManager.RemoveAll(
						new CacheItemGroup(
						prefixCacheItemGroup.Name + cacheItemInfo.Group.Name ) );
				}
				else
				{
					cacheManager.RemoveAll(
						prefixCacheItemGroup );
				}
			}
		}
		/// <summary>
		/// Checks whether the cache should be cleared.
		/// </summary>
		/// <param name="cacheItemInfo">The cache item info.</param>
		/// <returns></returns>
		private bool CheckCanClearCache(
			AdoNetCacheItemInformation cacheItemInfo )
		{
			if ( cacheManager == null )
			{
				return false;
			}
			else
			{
				if ( CacheBehaviour ==
					LibraryConfiguration.DatabaseConfiguration.
					DatabaseCacheSqlBehavior.Off )
				{
					return false;
				}
				else
				{
					if ( cacheItemInfo == null )
					{
						return false;
					}
					else
					{
						if (
							cacheItemInfo.Usage == CacheUsage.DontClear ||
							cacheItemInfo.Usage == CacheUsage.IgnoreCache )
						{
							return false;
						}
						else
						{
							return true;
						}
					}
				}
			}
		}
		/// <summary>
		/// Does the get data value from cache.
		/// </summary>
		/// <param name="computedKey">The computed key.</param>
		/// <param name="cacheItemInfo">The cache item info.</param>
		/// <returns></returns>
		protected virtual object DoGetDataValueFromCache(
			string computedKey,
			AdoNetCacheItemInformation cacheItemInfo )
		{
			return cacheManager.Get( computedKey ) as object;
		}