text:
#region Using directives
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Nettiers.AdventureWorks.Entities;
using Nettiers.AdventureWorks.Data;
using Nettiers.AdventureWorks.Data.Bases;
#endregion

namespace Nettiers.AdventureWorks.Web.Data
{
	/// <summary>
	/// Represents a business object that provides data to data-bound
	/// controls in multi-tier Web application architectures.
	/// </summary>
	/// <typeparam name="Entity">The class of the business object being accessed.</typeparam>
	/// <typeparam name="EntityKey">The class of the key
	/// property of the specified business object class.</typeparam>
	[CLSCompliant(true)]
	[ParseChildren(true), PersistChildren(false)]
	public abstract class BaseDataSource<Entity, EntityKey> : DataSourceControl, IListDataSource, IDataSourceEvents
		where Entity : new()
		where EntityKey : new()
	{
		#region Declarations

		/// <summary>
		/// The name used for the associated DataSourceView class.
		/// </summary>
		public static readonly String DefaultViewName = "DefaultView";

		private BaseDataSourceView<Entity, EntityKey> _view;
		private ParameterCollection _parameters;

		#endregion Declarations

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the BaseDataSource class.
		/// </summary>
		public BaseDataSource()
		{
		}

		#endregion Constructors

		#region Properties

		/// <summary>
		/// Gets a reference to the BaseDataSourceView used by the BaseDataSource.
		/// </summary>
		protected BaseDataSourceView<Entity, EntityKey> View
		{
			get
			{
				if ( _view == null )
				{
					_view = GetNewDataSourceView();
				}

				return _view;
			}
		}

		/// <summary>
		/// Gets the parameters collection that contains the parameters that
		/// are used by the BaseDataSource.SelectMethod method.
		/// </summary>
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public ParameterCollection Parameters
		{
			get
			{
				if ( _parameters == null )
				{
					_parameters = new ParameterCollection();
					_parameters.ParametersChanged += new EventHandler(this.OnParametersChanged);

					if ( IsTrackingViewState )
					{
						( (IStateManager) _parameters ).TrackViewState();
					}
				}

				return _parameters;
			}
		}

		/// <summary>
		/// Gets a value indicating if any Parameter objects have been specified.
		/// </summary>
		internal bool HasParameters
		{
			get { return ( _parameters != null ); }
		}

		/// <summary>
		/// Gets or sets a value indicating whether the data source control
		/// supports paging through the set of data that it retrieves.
		/// </summary>
		public bool EnablePaging
		{
			get { return View.EnablePaging; }
			set { View.EnablePaging = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether the data source control
		/// supports sorting the set of data that it retrieves.
		/// </summary>
		public bool EnableSorting
		{
			get { return View.EnableSorting; }
			set { View.EnableSorting = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether the data source control
		/// should access the EntityTransactionModule.TransactionManager property.
		/// </summary>
		/// <remarks>When this property is set to true, the EntityTransactionModule.TransactionManager
		/// object will be the first parameter passed to any data retrieval operation.</remarks>
		public bool EnableTransaction
		{
			get { return View.EnableTransaction; }
			set { View.EnableTransaction = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether the data source control should
		/// perform a recursive deep load when the DeepLoad method is called.
		/// </summary>
		public bool EnableRecursiveDeepLoad
		{
			get { return View.EnableRecursiveDeepLoad; }
			set { View.EnableRecursiveDeepLoad = value; }
		}

		/// <summary>
		/// Gets or sets a reference to an existing TransactionManager object
		/// to use when the EnableTransaction property is set to false.
		/// </summary>
		/// <remarks>When a value is supplied and EnableTransaction is set to false,
		/// the BaseDataSource.TransactionManager object will be the first
		/// parameter passed to any data retrieval operation.</remarks>
		[Browsable(false)]
		public ITransactionManager TransactionManager
		{
			get { return View.TransactionManager; }
			set { View.TransactionManager = value; }
		}

		/// <summary>
		/// Gets or sets the name of the custom stored procedure output parameter
		/// that returns the total record count when the method that is specified
		/// by the SelectMethod property is called.
		/// </summary>
		public String CustomMethodRecordCountParamName
		{
			get { return ((String) ViewState["CustomMethodRecordCountParamName"]) ?? String.Empty; }
			set { ViewState["CustomMethodRecordCountParamName"] = value; }
		}

		/// <summary>
		/// Gets or sets a filtering expression that is applied when the method that
		/// is specified by the SelectMethod property is called. This only applies
		/// if EnablePaging and EnableSorting are both false.
		/// </summary>
		public String Filter
		{
			get { return ((String) ViewState["Filter"]) ?? String.Empty; }
			set { ViewState["Filter"] = value; }
		}

		/// <summary>
		/// Gets or sets a sorting expression that is applied when the method that
		/// is specified by the SelectMethod property is called. This only applies
		/// if EnablePaging and EnableSorting are both false.
		/// </summary>
		public String Sort
		{
			get { return ((String) ViewState["Sort"]) ?? String.Empty; }
			set { ViewState["Sort"] = value; }
		}

		/// <summary>
		/// Gets or sets the value to be used as the whereClause parameter for
		/// any data retrieval operation.
		/// </summary>
		internal String WhereClause
		{
			get { return ((String) ViewState["WhereClause"]) ?? String.Empty; }
			set { ViewState["WhereClause"] = value; }
		}

		/// <summary>
		/// Gets or sets the value to be used as the orderBy parameter for
		/// any data retrieval operation.
		/// </summary>
		internal String OrderBy
		{
			get { return ((String) ViewState["OrderBy"]) ?? String.Empty; }
			set { ViewState["OrderBy"] = value; }
		}

		/// <summary>
		/// Gets or sets the value that represents the SortExpression argument that
		/// is supplied by DataBoundControls via a DataSourceSelectArguments object.
		/// </summary>
		internal String SortExpression
		{
			get { return ((String) ViewState["SortExpression"]) ?? String.Empty; }
			set { ViewState["SortExpression"] = value; }
		}

		/// <summary>
		/// Gets or sets the value that represents the StartRowIndex argument that
		/// is supplied by DataBoundControls via a DataSourceSelectArguments object.
		/// </summary>
		internal int StartIndex
		{
			get
			{
				Object value = ViewState["StartIndex"];
				return value != null ? (int) value : 0;
			}
			set { ViewState["StartIndex"] = value; }
		}

		/// <summary>
		/// Gets or sets the value that represents the MaximumRows argument that
		/// is supplied by DataBoundControls via a DataSourceSelectArguments object.
		/// </summary>
		internal int PageSize
		{
			get
			{
				Object value = ViewState["PageSize"];
				int intValue = 0;

				if ( value != null )
				{
					intValue = (int) value;
				}
				if ( intValue < 1 )
				{
					intValue = Int32.MaxValue;
				}

				return intValue;
			}
			set { ViewState["PageSize"] = value; }
		}

		/// <summary>
		/// Gets or sets the collection of <see cref="SqlFilterParameter"/> objects.
		/// </summary>
		internal SqlFilterParameterCollection FilterParameters
		{
			get { return ViewState["FilterParameters"] as SqlFilterParameterCollection; }
			set { ViewState["FilterParameters"] = value; }
		}

		/// <summary>
		/// Gets or sets the value of the unique identifer used when retreiving a single Entity object.
		/// </summary>
		[Browsable(false)]
		public EntityKey EntityId
		{
			get
			{
				Object value = ViewState["EntityId"];
				return value != null ? (EntityKey) value : default(EntityKey);
			}
			set { ViewState["EntityId"] = value; }
		}

		/// <summary>
		/// Gets or sets a comma-separated list of the entity's property names that
		/// will be initialized to the current system time during an insert operation.
		/// </summary>
		public String InsertDateTimeNames
		{
			get { return View.InsertDateTimeNames; }
			set { View.InsertDateTimeNames = value; }
		}

		/// <summary>
		/// Gets or sets a comma-separated list of the entity's property names that
		/// will be initialized to the current system time during an update operation.
		/// </summary>
		public String UpdateDateTimeNames
		{
			get { return View.UpdateDateTimeNames; }
			set { View.UpdateDateTimeNames = value; }
		}

		/// <summary>
		/// Gets or sets a comma-separated list of the entity's property names that will
		/// be initialized to the current user identity's name during an insert operation.
		/// </summary>
		public String InsertUserNames
		{
			get { return View.InsertUserNames; }
			set { View.InsertUserNames = value; }
		}

		/// <summary>
		/// Gets or sets a comma-separated list of the entity's property names that will
		/// be initialized to the current user identity's name during an update operation.
		/// </summary>
		public String UpdateUserNames
		{
			get { return View.UpdateUserNames; }
			set { View.UpdateUserNames = value; }
		}

		/// <summary>
		/// Gets or sets a comma-separated list of the entity's property names that will
		/// be set to String.Empty if they contain null values prior to executing an
		/// insert or update operation.
		/// </summary>
		public String ConvertNullToEmptyStringNames
		{
			get { return View.ConvertNullToEmptyStringNames; }
			set { View.ConvertNullToEmptyStringNames = value; }
		}

		#endregion Properties

		#region Methods

		/// <summary>
		/// Retrieves the data source view that is associated with the data source control.
		/// </summary>
		/// <param name="viewName">The name of the view to retrieve.</param>
		/// <returns>The BaseDataSourceView that is associated with the BaseDataSource.</returns>
		protected override DataSourceView GetView(string viewName)
		{
			return View;
		}

		/// <summary>
		/// Creates a new instance of the BaseDataSourceView class that is to be
		/// used by the BaseDataSource.
		/// </summary>
		/// <returns>An instance of the BaseDataSourceView class.</returns>
		/// <remarks>This method should be overridden by sub-classes who need to provide
		/// additional functionality through the use of a sub-classed BaseDataSourceView.</remarks>
		protected virtual BaseDataSourceView<Entity, EntityKey> GetNewDataSourceView()
		{
			return new BaseDataSourceView<Entity, EntityKey>(this, DefaultViewName);
		}

		/// <summary>
		/// Performs the ExecuteSelect operation using a default DataSourceSelectArguments object.
		/// </summary>
		/// <returns>A collection of Entity objects returned by the method specified
		/// by the SelectMethod property.</returns>
		public IList<Entity> Select()
		{
			DataSourceSelectArguments arguments = new DataSourceSelectArguments();
			return Select(arguments);
		}

		/// <summary>
		/// Performs the ExecuteSelect operation using the specified DataSourceSelectArguments object.
		/// </summary>
		/// <param name="arguments">A <see cref="DataSourceSelectArguments"/> object.</param>
		/// <returns>A collection of Entity objects returned by the method specified
		/// by the SelectMethod property.</returns>
		public IList<Entity> Select(DataSourceSelectArguments arguments)
		{
			if (this.DesignMode)
			{
				IList<Entity> list = new List<Entity>();
				list.Add(new Entity());
				return list;
			}
			else
			{
				return View.Select(arguments);
			}
		}

		/// <summary>
		/// Performs the ExecuteInsert operation using the specified name/value pairs.
		/// </summary>
		/// <param name="values">An <see cref="IDictionary"/> object.</param>
		/// <returns>The number of rows successfully inserted.</returns>
		public int Insert(IDictionary values)
		{
			return View.Insert(values);
		}

		#endregion Methods

		#region Events

		/// <summary>
		/// Occurs before a select operation.
		/// </summary>
		public event ObjectDataSourceSelectingEventHandler Selecting
		{
			add { View.Selecting += value; }
			remove { View.Selecting -= value; }
		}

		/// <summary>
		/// Occurs when a select operation has completed.
		/// </summary>
		public event ObjectDataSourceStatusEventHandler Selected
		{
			add { View.Selected += value; }
			remove { View.Selected -= value; }
		}

		/// <summary>
		/// Occurs before an insert operation.
		/// </summary>
		public event ObjectDataSourceMethodEventHandler Inserting
		{
			add { View.Inserting += value; }
			remove { View.Inserting -= value; }
		}

		/// <summary>
		/// Occurs when an insert operation has completed.
		/// </summary>
		public event ObjectDataSourceStatusEventHandler Inserted
		{
			add { View.Inserted += value; }
			remove { View.Inserted -= value; }
		}

		/// <summary>
		/// Occurs before an update operation
		/// </summary>
		public event ObjectDataSourceMethodEventHandler Updating
		{
			add { View.Updating += value; }
			remove { View.Updating -= value; }
		}

		/// <summary>
		/// Occurs when an update operation has completed.
		/// </summary>
		public event ObjectDataSourceStatusEventHandler Updated
		{
			add { View.Updated += value; }
			remove { View.Updated -= value; }
		}

		/// <summary>
		/// Occurs before a delete operation.
		/// </summary>
		public event ObjectDataSourceMethodEventHandler Deleting
		{
			add { View.Deleting += value; }
			remove { View.Deleting -= value; }
		}

		/// <summary>
		/// Occurs when a delete operation has completed.
		/// </summary>
		public event ObjectDataSourceStatusEventHandler Deleted
		{
			add { View.Deleted += value; }
			remove { View.Deleted -= value; }
		}

		#endregion

		#region Caching

		/// <summary>
		/// Gets or sets a value indicating whether the
		/// DataSource control has data caching enabled.
		/// </summary>
		public bool EnableCaching
		{
			get { return View.EnableCaching; }
			set { View.EnableCaching = value; }
		}

		private int _cacheDuration = 30;

		/// <summary>
		/// The cache duration in minutes.
		/// </summary>
		public int CacheDuration
		{
			get { return this._cacheDuration; }
			set { this._cacheDuration = value; }
		}

		/// <summary>
		/// Returns an entry from the cache. Entries are stored partially based on the start and page value.
		/// </summary>
		/// <param name="start"></param>
		/// <param name="page"></param>
		/// <returns></returns>
		internal CachedDataSource<Entity, EntityKey> GetDataFromCache(int start, int page)
		{
			// check for design time
			if ( DesignMode ) return null;

			Hashtable cachedData = (Hashtable) Context.Cache.Get(GetType().Name);
			CachedDataSource<Entity, EntityKey> data = null;
			string hashKey = CacheHashKey(start, page);

			if ( cachedData != null && cachedData.ContainsKey(hashKey) )
			{
				Context.Trace.Write(GetType().Name, "Getting Cached Data " + hashKey);
				data = cachedData[hashKey] as CachedDataSource<Entity, EntityKey>;
			}

			return data;
		}

		/// <summary>
		/// Saves an entry to the cache, partially based on start and page value
		/// </summary>
		/// <param name="data"></param>
		/// <param name="start"></param>
		/// <param name="page"></param>
		internal void SaveDataToCache(CachedDataSource<Entity, EntityKey> data, int start, int page)
		{
			// check for design time
			if ( DesignMode ) return;

			Context.Trace.Write(GetType().Name, "Saving Cache Data");
			Hashtable cacheData = (Hashtable) Context.Cache.Get(GetType().Name);
			string hashKey = CacheHashKey(start, page);

			if ( cacheData == null )
			{
				cacheData = CreateCacheEntry();
			}
			if ( !cacheData.ContainsKey(hashKey) )
			{
				Context.Trace.Write(GetType().Name, "Adding Data to Cache " + hashKey);
				cacheData.Add(hashKey, data);
			}
		}

		/// <summary>
		/// Initializes the dictionary used for caching by this control.
		/// </summary>
		private Hashtable CreateCacheEntry()
		{
			Hashtable cacheObject = new Hashtable();
			Context.Cache.Insert(GetType().Name, cacheObject, null, DateTime.Now.AddMinutes(CacheDuration), TimeSpan.Zero);
			return cacheObject;
		}

		/// <summary>
		/// Creates a cache hashing key based on the startIndex, pageSize.
		/// </summary>
		/// <param name="startIndex">The current start row index.</param>
		/// <param name="pageSize">The current page size.</param>
		/// <returns>A string that can be used as a key for caching purposes.</returns>
		/// <remarks>Currently abstract becuase using the enum name as part of the cache key.</remarks>
		protected abstract string CacheHashKey(int startIndex, int pageSize);

        #endregion

		#region Parameter Helper Methods

		/// <summary>
		/// Raises the System.Web.UI.Control.Init event.
		/// </summary>
		/// <param name="e">An System.EventArgs object that contains the event data.</param>
		protected override void OnInit(EventArgs e)
		{
			Page.LoadComplete += new EventHandler(this.OnPageLoadComplete);
		}

		/// <summary>
		/// Handles the Page.LoadComplete event.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">An System.EventArgs object that contains the event data.</param>
		private void OnPageLoadComplete(object sender, EventArgs e)
		{
			if ( _parameters != null )
			{
				_parameters.UpdateValues(Context, this);
			}
		}

		/// <summary>
		/// Handles the ParameterCollection.ParametersChanged event.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">An System.EventArgs object that contains the event data.</param>
		private void OnParametersChanged(object sender, EventArgs e)
		{
			View.RaiseChangedEvent();
		}

		/// <summary>
		/// Loads the previously saved view state of the BaseDataSource control.
		/// </summary>
		/// <param name="state">An object that contains the saved view state values for the control.</param>
		protected override void LoadViewState(object state)
		{
			object baseState = null;

			if ( state != null )
			{
				Pair p = (Pair) state;
				baseState = p.First;

				if ( p.Second != null )
				{
					( (IStateManager) Parameters ).LoadViewState(p.Second);
				}
			}

			base.LoadViewState(baseState);
		}

		/// <summary>
		/// Saves the state of the BaseDataSource control.
		/// </summary>
		/// <returns>Returns the server control's current view state; otherwise,
		/// null, if there is no view state associated with the control.</returns>
		protected override object SaveViewState()
		{
			object baseState = base.SaveViewState();
			object parameterState = null;

			if ( _parameters != null )
			{
				parameterState = ( (IStateManager) _parameters ).SaveViewState();
			}

			if ( ( baseState != null ) || ( parameterState != null ) )
			{
				return new Pair(baseState, parameterState);
			}

			return null;
		}

		/// <summary>
		/// Tracks view-state changes to the BaseDataSource control so
		/// that they can be stored in the System.Web.UI.StateBag object.
		/// </summary>
		protected override void TrackViewState()
		{
			base.TrackViewState();
			if ( _parameters != null )
			{
				( (IStateManager) _parameters ).TrackViewState();
			}
		}

		/// <summary>
		/// Gets a collection of values supplied by the current Parameter objects.
		/// </summary>
		/// <returns>An IOrderedDictionary of name/value pairs.</returns>
		internal IOrderedDictionary GetParameterValues()
		{
			IOrderedDictionary values = null;

			if ( HasParameters )
			{
				values = Parameters.GetValues(Context, this);
			}
			else
			{
				values = new OrderedDictionary(0);
			}

			return values;
		}

		#endregion Parameter Helper Methods

		#region ILinkedDataSource Members

		#region Methods

		/// <summary>
		/// Performs the ExecuteUpdate operation on the specified Entity object
		/// using the supplied name/value pairs.
		/// </summary>
		/// <param name="entity">The Entity object to update.</param>
		/// <param name="values">An <see cref="IDictionary"/> object.</param>
		/// <returns>The number of rows successfully updated.</returns>
		public int Update(Object entity, IDictionary values)
		{
			return View.Update((Entity) entity, values);
		}

		/// <summary>
		/// Performs the ExecuteDelete operation on the specified Entity object.
		/// </summary>
		/// <param name="entity">The Entity object to delete.</param>
		/// <returns>The number of rows successfully deleted.</returns>
		public int Delete(Object entity)
		{
			return View.Delete((Entity) entity);
		}

		/// <summary>
		/// Gets a reference to the current list of entities.
		/// </summary>
		/// <returns>The current list of entities if present, otherwise
		/// the data will be retreived by the Provider and cached for future use.</returns>
		public IEnumerable GetEntityList()
		{
			return Select();
		}

		/// <summary>
		/// Gets a specific entry from the cached list of entities
		/// based on the value of the EntityIndex property.
		/// </summary>
		/// <returns>The current business object.</returns>
		public Object GetCurrentEntity()
		{
			return View.GetCurrentEntity();
		}

		/// <summary>
		/// Gets a comma-separated-list of values representing the
		/// current entity's unique identifier.
		/// </summary>
		/// <returns>Returns a comma-separated-list of values.</returns>
		public String GetSelectedEntityId()
		{
			return View.GetSelectedEntityId();
		}

		/// <summary>
		/// Performs a DeepLoad operation for the current entity if it has
		/// not already been performed.
		/// </summary>
		public void DeepLoad()
		{
			View.DeepLoad();
		}

		#endregion Methods

		#region Events

		/// <summary>
		/// Occurs when a select operation has completed.
		/// </summary>
		public event LinkedDataSourceEventHandler AfterSelected
		{
			add { View.AfterSelected += value; }
			remove { View.AfterSelected -= value; }
		}

		/// <summary>
		/// Occurs before an insert operation.
		/// </summary>
		public event LinkedDataSourceEventHandler AfterInserting
		{
			add { View.AfterInserting += value; }
			remove { View.AfterInserting -= value; }
		}

		/// <summary>
		/// Occurs when an insert operation has completed.
		/// </summary>
		public event LinkedDataSourceEventHandler AfterInserted
		{
			add { View.AfterInserted += value; }
			remove { View.AfterInserted -= value; }
		}

		/// <summary>
		/// Occurs before an update operation.
		/// </summary>
		public event LinkedDataSourceEventHandler AfterUpdating
		{
			add { View.AfterUpdating += value; }
			remove { View.AfterUpdating -= value; }
		}

		/// <summary>
		/// Occurs when an update operation has completed.
		/// </summary>
		public event LinkedDataSourceEventHandler AfterUpdated
		{
			add { View.AfterUpdated += value; }
			remove { View.AfterUpdated -= value; }
		}

		#endregion Events

		#endregion ILinkedDataSource Members
	}

	/// <summary>
	/// Supports the BaseDataSource control and provides an interface for
	/// data-bound controls to perform data operations with business and data objects.
	/// </summary>
	/// <typeparam name="Entity">The class of the business object being accessed.</typeparam>
	/// <typeparam name="EntityKey">The class of the EntityId
	/// property of the specified business object class.</typeparam>
	public class BaseDataSourceView<Entity, EntityKey> : DataSourceView
		where Entity : new()
		where EntityKey : new()
	{
		#region Declarations

		private BaseDataSource<Entity, EntityKey> _owner;
		private ITransactionManager _transactionManager;
		private IList<Entity> _prevTempList;
		private IList<Entity> _tempList;
		private EntityKey _prevEntityId;
		private int _prevRowCount;
		private int _totalRowCount;

		private String _insertDateTimeNames;
		private String _updateDateTimeNames;
		private String _insertUserNames;
		private String _updateUserNames;
		private String _convertNullToEmptyStringNames;

		private bool _enableTransaction = true;
		private bool _enableRecursiveDeepLoad;
		private bool _enableCaching;
		private bool _enablePaging;
		private bool _enableSorting;
		private bool _isDeepLoaded;

		#endregion Declarations

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the BaseDataSourceView class.
		/// </summary>
		/// <param name="owner">A reference to the BaseDataSource which created this instance.</param>
		/// <param name="viewName">The name of the view.</param>
		public BaseDataSourceView(BaseDataSource<Entity, EntityKey> owner, String viewName)
			: base(owner, viewName)
		{
			_owner = owner;
		}

		#endregion Constructors

		#region Properties

		/// <summary>
		/// Gets a reference to the associated BaseDataSource object.
		/// </summary>
		internal BaseDataSource<Entity, EntityKey> Owner
		{
			get { return _owner; }
		}

		/// <summary>
		/// Gets or sets a reference to an existing TransactionManager object
		/// to use when the EnableTransaction property is set to false.
		/// </summary>
		/// <remarks>When a value is supplied and EnableTransaction is set to false,
		/// the BaseDataSource.TransactionManager object will be the first
		/// parameter passed to any data retrieval operation.</remarks>
		internal ITransactionManager TransactionManager
		{
			get { return _transactionManager; }
			set { _transactionManager = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether the
		/// data source control has data caching enabled.
		/// </summary>
		internal bool EnableCaching
		{
			get { return _enableCaching; }
			set { _enableCaching = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether the data source control
		/// supports paging through the set of data that it retrieves.
		/// </summary>
		internal bool EnablePaging
		{
			get { return _enablePaging; }
			set { _enablePaging = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether the data source control
		/// supports sorting the set of data that it retrieves.
		/// </summary>
		internal bool EnableSorting
		{
			get { return _enableSorting; }
			set { _enableSorting = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether the data source control
		/// should access the EntityTransactionModule.TransactionManager property.
		/// </summary>
		/// <remarks>When this property is set to true, the EntityTransactionModule.TransactionManager
		/// object will be the first parameter passed to any data retrieval operation.</remarks>
		internal bool EnableTransaction
		{
			get { return _enableTransaction; }
			set { _enableTransaction = value; }
		}

		/// <summary>
		/// Gets or sets a value indicating whether the data source control should
		/// perform a recursive deep load when the DeepLoad method is called.
		/// </summary>
		internal bool EnableRecursiveDeepLoad
		{
			get { return _enableRecursiveDeepLoad; }
			set { _enableRecursiveDeepLoad = value; }
		}

		/// <summary>
		/// Gets or sets the value of the unique identifer used when retreiving a single Entity object.
		/// </summary>
		internal EntityKey EntityId
		{
			get { return _owner.EntityId; }
			set { _owner.EntityId = value; }
		}

		/// <summary>
		/// Gets or sets the name of the custom stored procedure output parameter
		/// that returns the total record count when the method that is specified
		/// by the SelectMethod property is called.
		/// </summary>
		internal String CustomMethodRecordCountParamName
		{
			get { return _owner.CustomMethodRecordCountParamName; }
			set { _owner.CustomMethodRecordCountParamName = value; }
		}

		/// <summary>
		/// Gets or sets the collection of <see cref="SqlFilterParameter"/> objects.
		/// </summary>
		internal SqlFilterParameterCollection FilterParameters
		{
			get { return _owner.FilterParameters; }
			set { _owner.FilterParameters = value; }
		}

		/// <summary>
		/// Gets or sets a comma-separated list of the entity's property names that
		/// will be initialized to the current system time during an insert operation.
		/// </summary>
		internal String InsertDateTimeNames
		{
			get { return _insertDateTimeNames; }
			set { _insertDateTimeNames = value; }
		}

		/// <summary>
		/// Gets or sets a comma-separated list of the entity's property names that
		/// will be initialized to the current system time during an update operation.
		/// </summary>
		internal String UpdateDateTimeNames
		{
			get { return _updateDateTimeNames; }
			set { _updateDateTimeNames = value; }
		}

		/// <summary>
		/// Gets or sets a comma-separated list of the entity's property names that will
		/// be initialized to the current user identity's name during an insert operation.
		/// </summary>
		internal String InsertUserNames
		{
			get { return _insertUserNames; }
			set { _insertUserNames = value; }
		}

		/// <summary>
		/// Gets or sets a comma-separated list of the entity's property names that will
		/// be initialized to the current user identity's name during an update operation.
		/// </summary>
		internal String UpdateUserNames
		{
			get { return _updateUserNames; }
			set { _updateUserNames = value; }
		}

		/// <summary>
		/// Gets or sets a comma-separated list of the entity's property names that will
		/// be set to String.Empty if they contain null values prior to executing an
		/// insert or update operation.
		/// </summary>
		internal String ConvertNullToEmptyStringNames
		{
			get { return _convertNullToEmptyStringNames; }
			set { _convertNullToEmptyStringNames = value; }
		}

		/// <summary>
		/// Gets or sets the IsDeepLoaded property.
		/// </summary>
		internal bool IsDeepLoaded
		{
			get { return _isDeepLoaded; }
			set { _isDeepLoaded = value; }
		}

		/// <summary>
		/// Gets or sets a filtering expression that is applied when the method that
		/// is specified by the SelectMethod property is called. This only applies
		/// if EnablePaging and EnableSorting are both false.
		/// </summary>
		internal String Filter
		{
			get { return _owner.Filter; }
			set { _owner.Filter = value; }
		}

		/// <summary>
		/// Gets or sets a sorting expression that is applied when the method that
		/// is specified by the SelectMethod property is called. This only applies
		/// if EnablePaging and EnableSorting are both false.
		/// </summary>
		internal String Sort
		{
			get { return _owner.Sort; }
			set { _owner.Sort = value; }
		}

		/// <summary>
		/// Gets or sets the value to be used as the whereClause parameter for
		/// any data retrieval operation.
		/// </summary>
		internal String WhereClause
		{
			get { return _owner.WhereClause; }
			set { _owner.WhereClause = value; }
		}

		/// <summary>
		/// Gets or sets the value to be used as the orderBy parameter for
		/// any data retrieval operation.
		/// </summary>
		internal String OrderBy
		{
			get { return _owner.OrderBy; }
			set { _owner.OrderBy = value; }
		}

		/// <summary>
		/// Gets or sets the value that represents the SortExpression argument that
		/// is supplied by DataBoundControls via a DataSourceSelectArguments object.
		/// </summary>
		internal String SortExpression
		{
			get { return _owner.SortExpression; }
			set { _owner.SortExpression = value; }
		}

		/// <summary>
		/// Gets or sets the value that represents the StartRowIndex argument that
		/// is supplied by DataBoundControls via a DataSourceSelectArguments object.
		/// </summary>
		internal int StartIndex
		{
			get { return _owner.StartIndex; }
			set { _owner.StartIndex = value; }
		}

		/// <summary>
		/// Gets or sets the value that represents the MaximumRows argument that
		/// is supplied by DataBoundControls via a DataSourceSelectArguments object.
		/// </summary>
		internal int PageSize
		{
			get { return _owner.PageSize; }
			set { _owner.PageSize = value; }
		}

		/// <summary>
		/// Gets or sets the value indicating the current PageIndex as
		/// determined by the following equation: StartIndex/PageSize
		/// </summary>
		internal int PageIndex
		{
			get { return ( StartIndex / PageSize ); }
			set { StartIndex = ( value * PageSize ); }
		}

		/// <summary>
		/// Gets a value indicating whether the BaseDataSourceView object
		/// associated with the current BaseDataSource object supports the
		/// ExecuteInsert(IDictionary) operation.
		/// </summary>
		public override bool CanInsert
		{
			get { return true; }
		}

		/// <summary>
		/// Gets a value indicating whether the BaseDataSourceView object
		/// associated with the current BaseDataSource object supports the
		/// ExecuteUpdate(IDictionary, IDictionary, IDictionary) operation.
		/// </summary>
		public override bool CanUpdate
		{
			get { return true; }
		}

		/// <summary>
		/// Gets a value indicating whether the BaseDataSourceView object
		/// associated with the current BaseDataSource object supports the
		/// ExecuteDelete(IDictionary, IDictionary) operation.
		/// </summary>
		public override bool CanDelete
		{
			get { return true; }
		}

		/// <summary>
		/// Gets a value indicating whether the BaseDataSourceView object associated
		/// with the current BaseDataSource object supports paging through the data
		/// retrieved by the ExecuteSelect(DataSourceSelectArguments) method.
		/// </summary>
		public override bool CanPage
		{
			get { return true; }
		}

		/// <summary>
		/// Gets a value indicating whether the BaseDataSourceView object
		/// associated with the current BaseDataSource object supports a
		/// sorted view on the underlying data source.
		/// </summary>
		public override bool CanSort
		{
			get { return true; }
		}

		/// <summary>
		/// Gets a value indicating whether the BaseDataSourceView object
		/// associated with the current BaseDataSource object supports
		/// retrieving the total number of data rows, instead of the data.
		/// </summary>
		public override bool CanRetrieveTotalRowCount
		{
			get { return true; }
		}

		#endregion Properties

		#region Select Methods

		/// <summary>
		/// Gets a list of data from the underlying data storage.
		/// </summary>
		/// <param name="arguments">A System.Web.UI.DataSourceSelectArguments that
		/// is used to request operations on the data beyond basic data retrieval.</param>
		/// <returns>A collection of Entity objects from the underlying data storage.</returns>
		internal IList<Entity> Select(DataSourceSelectArguments arguments)
		{
			return ExecuteSelectCore(arguments);
		}

		/// <summary>
		/// Gets a list of data from the underlying data storage.
		/// </summary>
		/// <param name="arguments">A System.Web.UI.DataSourceSelectArguments that
		/// is used to request operations on the data beyond basic data retrieval.</param>
		/// <returns>An System.Collections.IEnumerable list of data from the underlying data storage.</returns>
		protected override IEnumerable ExecuteSelect(DataSourceSelectArguments arguments)
		{
			return ExecuteSelectCore(arguments);
		}

		/// <summary>
		/// Gets a list of data from the underlying data storage.
		/// </summary>
		/// <param name="arguments">A System.Web.UI.DataSourceSelectArguments that
		/// is used to request operations on the data beyond basic data retrieval.</param>
		/// <returns>A collection of Entity objects from the underlying data storage.</returns>
		private IList<Entity> ExecuteSelectCore(DataSourceSelectArguments arguments)
		{
			arguments.RaiseUnsupportedCapabilitiesError(this);

			IOrderedDictionary values = GetParameterValues();
			IList<Entity> entityList = null;

			ObjectDataSourceSelectingEventArgs methodArgs = new ObjectDataSourceSelectingEventArgs(values, arguments, true);
			OnSelecting(methodArgs);

			if ( methodArgs.Cancel )
			{
				return null;
			}

			try
			{
				entityList = GetEntityList(arguments, values);
				EntityId = default(EntityKey);

				ObjectDataSourceStatusEventArgs statusArgs = new ObjectDataSourceStatusEventArgs(entityList, values);
				statusArgs.AffectedRows = arguments.TotalRowCount;
				OnSelected(statusArgs);

				if ( arguments.TotalRowCount > 0 && entityList.Count > 0 )
				{
					Entity entity = entityList[0];
					EntityId = GetEntityId(entity);

					// raise linked event
					OnAfterSelected(new LinkedDataSourceEventArgs(entity, values, 0));
				}
			}
			catch ( Exception ex )
			{
				ObjectDataSourceStatusEventArgs statusArgs = new ObjectDataSourceStatusEventArgs(entityList, values, ex);
				OnSelected(statusArgs);

				if ( !statusArgs.ExceptionHandled )
				{
					throw;
				}
			}

			return entityList;
		}

		/// <summary>
		/// Gets a collection of Entity objects.  Provides internal caching of values
		/// specified in the supplied DataSourceSelectArguments object.
		/// </summary>
		/// <param name="arguments">A System.Web.UI.DataSourceSelectArguments that
		/// is used to request operations on the data beyond basic data retrieval.</param>
		/// <param name="values">An IDictionary object of name/value pairs.</param>
		/// <returns>A collection of Entity objects from the underlying data storage.</returns>
		private IList<Entity> GetEntityList(DataSourceSelectArguments arguments, IDictionary values)
		{
			StartIndex = arguments.StartRowIndex;
			PageSize = arguments.MaximumRows;
			SortExpression = arguments.SortExpression;

			if ( !String.IsNullOrEmpty(SortExpression) )
			{
				OrderBy = SortExpression;
			}

			// allow case-insensitive parameter names
			values = CollectionsUtil.CreateCaseInsensitiveHashtable(values);

			// known parameters
			WhereClause = (String) values["WhereClause"];

			if ( values["OrderBy"] != null )
			{
				OrderBy = (String) values["OrderBy"];
			}
			if ( values["PageSize"] != null )
			{
				PageSize = (int) values["PageSize"];
			}
			if (values["PageIndex"] != null)
			{
				PageIndex = (int)values["PageIndex"];
			}
			if ( values["Parameters"] != null )
			{
				FilterParameters = (SqlFilterParameterCollection) values["Parameters"];
			}

			GetSelectParameters(values);

			int count = 0;
			IList<Entity> entityList = GetCachedData(out count);
			arguments.TotalRowCount = count;
			return entityList;
		}

		/// <summary>
		/// Gets a collection of previously selected Entity objects.
		/// </summary>
		/// <returns>A collection of Entity objects from the underlying data storage.</returns>
		private IList<Entity> GetEntityList()
		{
			int count = 0;
			return GetCachedData(out count);
		}

		/// <summary>
		/// Gets a collection of previously selected Entity objects.
		/// </summary>
		/// <param name="count">The total number of rows in the DataSource.</param>
		/// <returns>A collection of Entity objects from the underlying data storage.</returns>
		private IList<Entity> GetCachedData(out int count)
		{
			// check temporary cache first
			IList<Entity> entityList = _tempList;
			count = _totalRowCount;

			if ( entityList == null )
			{
				if ( EnableCaching )
				{
					//get cached datasource
					CachedDataSource<Entity, EntityKey> data = Owner.GetDataFromCache(StartIndex, PageSize);
					//if there is cached data use it and the record count returned and
					if (data != null)
					{
						count = data.VirtualRecordCount;
						entityList = data.Data;
					}
				}
				if ( entityList == null )
				{
					// init transaction manager
					GetTransactionManager();
					// execute select method
					entityList = GetSelectData(out count);

					// make sure paging and sorting were not enabled
					if ( entityList is ListBase<Entity> && !EnablePaging && !EnableSorting )
					{
						// apply filter
						if ( !String.IsNullOrEmpty(Filter) )
						{
							((ListBase<Entity>) entityList).Filter = Filter;
						}
						// apply sort
						if ( !String.IsNullOrEmpty(Sort) )
						{
							((ListBase<Entity>) entityList).Sort(Sort);
						}
					}

					if ( EnableCaching )
					{
						Owner.SaveDataToCache(new CachedDataSource<Entity,EntityKey>(entityList, count), StartIndex, PageSize);
					}
				}

				// place in temporary cache
				_tempList = entityList;
				_totalRowCount = count;

			}

			return entityList;
		}

		/// <summary>
		/// Gets a collection of Entity objects based on the value of the SelectMethod property.
		/// </summary>
		/// <param name="count">The total number of rows in the DataSource.</param>
		/// <returns>A collection of Entity objects.</returns>
		/// <remarks>This method can be overridden by sub-classes needing to provide
		/// additional data retrieval functionality.</remarks>
		protected virtual IList<Entity> GetSelectData(out int count)
		{
			count = 0;
			return null;
		}

		/// <summary>
		/// Gets the values of any supplied parameters for internal caching.
		/// </summary>
		/// <param name="values">An IDictionary object of name/value pairs.</param>
		/// <remarks>This method can be overridden by sub-classes needing to provide
		/// additional data retrieval functionality.</remarks>
		protected virtual void GetSelectParameters(IDictionary values)
		{
		}

		#endregion Select Methods

		#region Insert Methods

		/// <summary>
		/// Performs an insert operation.
		/// </summary>
		/// <param name="values">A System.Collections.IDictionary of
		/// name/value pairs used during an insert operation.</param>
		/// <returns>The number of items that were inserted into the underlying data storage.</returns>
		internal int Insert(IDictionary values)
		{
			int count = 0;

			if ( values != null )
			{
				SetPreviousValues();

				count = ExecuteInsert(values);

				ResetPreviousValues();
			}

			return count;
		}

		/// <summary>
		/// Performs an insert operation on the list of data
		/// that the BaseDataSourceView object represents.
		/// </summary>
		/// <param name="values">A System.Collections.IDictionary of
		/// name/value pairs used during an insert operation.</param>
		/// <returns>The number of items that were inserted into the underlying data storage.</returns>
		protected override int ExecuteInsert(IDictionary values)
		{
			values = GetOrderedDictionary(values);
			ObjectDataSourceMethodEventArgs methodArgs = new ObjectDataSourceMethodEventArgs(values as IOrderedDictionary);
			OnInserting(methodArgs);

			if ( methodArgs.Cancel )
			{
				return 0;
			}

			// get new entity
			Entity entity = new Entity();
			int count = 0;

			// raise linked event
			OnAfterInserting(new LinkedDataSourceEventArgs(entity, values, 0));

			// convert null properties to empty strings
			InitConvertNullToEmptyStringValues(entity, values);
			// set date/time values
			EntityUtil.InitEntityDateTimeValues(entity, GetInsertDateTimeNames());
			// set user name values
			InitEntityUserNameValues(entity, GetInsertUserNames());
			// set property values
			SetPropertyValues(entity, values);
			SetEntityKeyValues(entity);

			try
			{
				// init transaction manager
				GetTransactionManager();

				// insert entity
				if ( ExecuteInsert(entity) )
				{
					ObjectDataSourceStatusEventArgs statusArgs = new ObjectDataSourceStatusEventArgs(entity, values);
					statusArgs.AffectedRows = 1;
					EntityId = GetEntityId(entity);
					count = 1;

					OnInserted(statusArgs);
					OnAfterInserted(new LinkedDataSourceEventArgs(entity, values, 0));
					RaiseChangedEvent();
				}
			}
			catch ( Exception ex )
			{
				ObjectDataSourceStatusEventArgs statusArgs = new ObjectDataSourceStatusEventArgs(entity, values, ex);
				OnInserted(statusArgs);

				if ( !statusArgs.ExceptionHandled )
				{
					throw;
				}
			}

			return count;
		}

		/// <summary>
		/// Performs an insert operation on the specified Entity object.
		/// </summary>
		/// <param name="entity">The Entity object to insert.</param>
		/// <returns>Returns true if successful, otherwise false.</returns>
		/// <remarks>Sub-classes should implement this method to provide specific insert functionality.</remarks>
		protected virtual bool ExecuteInsert(Entity entity)
		{
			return false;
		}

		#endregion Insert Methods

		#region Update Methods

		/// <summary>
		/// Performs an update operation on the specified Entity object.
		/// </summary>
		/// <param name="entity">The Entity object to update.</param>
		/// <param name="values">An System.Collections.IDictionary of name/value
		/// pairs that represent data elements and their new values.</param>
		/// <returns>The number of items that were updated in the underlying data storage.</returns>
		internal int Update(Entity entity, IDictionary values)
		{
			int count = 0;

			if ( entity != null && values != null )
			{
				SetPreviousValues();

				// set temporary reference
				SetTempCache(entity);

				// perform delete operation
				count = ExecuteUpdate(null, values, null);

				ResetPreviousValues();
			}

			return count;
		}

		/// <summary>
		/// Performs an update operation on the list of data
		/// that the BaseDataSourceView object represents.
		/// </summary>
		/// <param name="keys">An System.Collections.IDictionary of object or
		/// row keys to be updated by the update operation.</param>
		/// <param name="values">An System.Collections.IDictionary of name/value
		/// pairs that represent data elements and their new values.</param>
		/// <param name="oldValues">An System.Collections.IDictionary of name/value
		/// pairs that represent data elements and their original values.</param>
		/// <returns>The number of items that were updated in the underlying data storage.</returns>
		protected override int ExecuteUpdate(IDictionary keys, IDictionary values, IDictionary oldValues)
		{
			values = GetOrderedDictionary(values);
			ObjectDataSourceMethodEventArgs methodArgs = new ObjectDataSourceMethodEventArgs(values as IOrderedDictionary);
			OnUpdating(methodArgs);

			if ( methodArgs.Cancel )
			{
				return 0;
			}

			IList<Entity> entityList = GetEntityList();

			Entity entity = GetCurrentEntity(entityList, keys);
			int count = 0;

			ValidateEntity(entity, keys);

			// raise linked event
			int entityIndex = entityList.IndexOf(entity);
			OnAfterUpdating(new LinkedDataSourceEventArgs(entity, values, entityIndex));

			// convert null properties to empty strings
			InitConvertNullToEmptyStringValues(entity, values);
			// set date/time values
			EntityUtil.InitEntityDateTimeValues(entity, GetUpdateDateTimeNames());
			// set user name values
			InitEntityUserNameValues(entity, GetUpdateUserNames());
			// set property values
			SetPropertyValues(entity, values);

			// update entity
			try
			{
				// init transaction manager
				GetTransactionManager();

				if ( ExecuteUpdate(entity) )
				{
					ObjectDataSourceStatusEventArgs statusArgs = new ObjectDataSourceStatusEventArgs(entity, values);
					statusArgs.AffectedRows = 1;
					EntityId = GetEntityId(entity);
					count = 1;

					OnUpdated(statusArgs);
					OnAfterUpdated(new LinkedDataSourceEventArgs(entity, values, entityIndex));
					RaiseChangedEvent();
				}
			}
			catch ( Exception ex )
			{
				ObjectDataSourceStatusEventArgs statusArgs = new ObjectDataSourceStatusEventArgs(entity, values, ex);
				OnUpdated(statusArgs);

				if ( !statusArgs.ExceptionHandled )
				{
					throw;
				}
			}

			return count;
		}

		/// <summary>
		/// Performs an update operation on the specified Entity object.
		/// </summary>
		/// <param name="entity">The Entity object to update.</param>
		/// <returns>Returns true if successful, otherwise false.</returns>
		/// <remarks>Sub-classes should implement this method to provide specific update functionality.</remarks>
		protected virtual bool ExecuteUpdate(Entity entity)
		{
			return false;
		}

		#endregion UpdateMethods

		#region Delete Methods

		/// <summary>
		/// Performs a delete operation on the specified Entity object.
		/// </summary>
		/// <param name="entity">The Entity object to delete.</param>
		/// <returns>The number of items that were deleted from the underlying data storage.</returns>
		internal int Delete(Entity entity)
		{
			int count = 0;

			if ( entity != null )
			{
				SetPreviousValues();

				// set temporary reference
				SetTempCache(entity);

				// perform delete operation
				count = ExecuteDelete(null, new Hashtable());

				ResetPreviousValues();
			}

			return count;
		}

		/// <summary>
		/// Performs a delete operation on the list of data
		/// that the BaseDataSourceView object represents.
		/// </summary>
		/// <param name="keys">A System.Collections.IDictionary of object or
		/// row keys to be deleted by the ExecuteDelete operation.</param>
		/// <param name="oldValues">An System.Collections.IDictionary of name/value
		/// pairs that represent data elements and their original values.</param>
		/// <returns>The number of items that were deleted from the underlying data storage.</returns>
		protected override int ExecuteDelete(IDictionary keys, IDictionary oldValues)
		{
			oldValues = GetOrderedDictionary(oldValues);
			ObjectDataSourceMethodEventArgs methodArgs = new ObjectDataSourceMethodEventArgs(oldValues as IOrderedDictionary);
			OnDeleting(methodArgs);

			if ( methodArgs.Cancel )
			{
				return 0;
			}

			IList<Entity> entityList = GetEntityList();
			Entity entity = GetCurrentEntity(entityList, keys);
			int count = 0;

			ValidateEntity(entity, keys);

			// delete entity
			try
			{
				// init transaction manager
				GetTransactionManager();

				if ( ExecuteDelete(entity) )
				{
					ObjectDataSourceStatusEventArgs statusArgs = new ObjectDataSourceStatusEventArgs(entity, oldValues);
					statusArgs.AffectedRows = 1;
					count = 1;

					OnDeleted(statusArgs);
					RaiseChangedEvent();
				}
			}
			catch ( Exception ex )
			{
				ObjectDataSourceStatusEventArgs statusArgs = new ObjectDataSourceStatusEventArgs(entity, oldValues, ex);
				OnDeleted(statusArgs);

				if ( !statusArgs.ExceptionHandled )
				{
					throw;
				}
			}

			return count;
		}

		/// <summary>
		/// Performs a delete operation on the specified Entity object.
		/// </summary>
		/// <param name="entity">The Entity object to delete.</param>
		/// <returns>Returns true if successful, otherwise false.</returns>
		/// <remarks>Sub-classes should implement this method to provide specific delete functionality.</remarks>
		protected virtual bool ExecuteDelete(Entity entity)
		{
			return false;
		}

		#endregion Delete Methods

		#region ILinkedDataSource Members

		#region Methods

		/// <summary>
		/// Gets a specific entry from the cached list of entities
		/// based on the value of the EntityIndex property.
		/// </summary>
		/// <returns>The current business object.</returns>
		internal Entity GetCurrentEntity()
		{
			return GetCurrentEntity(Owner.Select(), EntityId);
		}

		/// <summary>
		/// Gets a comma-separated-list of values representing the
		/// current entity's unique identifier.
		/// </summary>
		/// <returns>Returns a comma-separated-list of values.</returns>
		internal virtual String GetSelectedEntityId()
		{
			IEntityKey key = EntityId as IEntityKey;
			StringBuilder id = new StringBuilder();
			IDictionary values = null;
			String value;

			if ( key != null )
			{
				values = key.ToDictionary();
			}
			else
			{
				values = EntityId as IDictionary;
			}

			if ( values != null )
			{
				foreach ( DictionaryEntry entry in values )
				{
					if ( id.Length > 0 ) id.Append("&");
					value = String.Format("{0}", entry.Value);
					id.AppendFormat("{0}={1}", entry.Key, HttpContext.Current.Server.UrlEncode(value));
				}
			}
			else
			{
				id.AppendFormat("{0}", EntityId);
			}

			return id.ToString();
		}

		/// <summary>
		/// Performs a DeepLoad operation for the current entity if it has
		/// not already been performed.
		/// </summary>
		/// <remarks>To be implemented by subclasses requiring DeepLoad functionality</remarks>
		internal virtual void DeepLoad()
		{
		}

		#endregion Methods

		#region Events

		/// <summary>
		/// Occurs when a select operation has completed.
		/// </summary>
		internal event LinkedDataSourceEventHandler AfterSelected;

		/// <summary>
		/// Occurs before an insert operation.
		/// </summary>
		internal event LinkedDataSourceEventHandler AfterInserting;

		/// <summary>
		/// Occurs when an insert operation has completed.
		/// </summary>
		internal event LinkedDataSourceEventHandler AfterInserted;

		/// <summary>
		/// Occurs before an update operation.
		/// </summary>
		internal event LinkedDataSourceEventHandler AfterUpdating;

		/// <summary>
		/// Occurs when an update operation has completed.
		/// </summary>
		internal event LinkedDataSourceEventHandler AfterUpdated;

		/// <summary>
		/// Raises the AfterSelected event.
		/// </summary>
		/// <param name="e">An instance of LinkedDataSourceEventArgs containing the event data.</param>
		internal virtual void OnAfterSelected(LinkedDataSourceEventArgs e)
		{
			if ( AfterSelected != null )
			{
				AfterSelected(Owner, e);
			}
		}

		/// <summary>
		/// Raises the AfterInserting event.
		/// </summary>
		/// <param name="e">An instance of LinkedDataSourceEventArgs containing the event data.</param>
		internal virtual void OnAfterInserting(LinkedDataSourceEventArgs e)
		{
			if ( AfterInserting != null )
			{
				AfterInserting(Owner, e);
			}
		}

		/// <summary>
		/// Raises the AfterInserted event.
		/// </summary>
		/// <param name="e">An instance of LinkedDataSourceEventArgs containing the event data.</param>
		internal virtual void OnAfterInserted(LinkedDataSourceEventArgs e)
		{
			if ( AfterInserted != null )
			{
				AfterInserted(Owner, e);
			}
		}

		/// <summary>
		/// Raises the AfterUpdating event.
		/// </summary>
		/// <param name="e">An instance of LinkedDataSourceEventArgs containing the event data.</param>
		internal virtual void OnAfterUpdating(LinkedDataSourceEventArgs e)
		{
			if ( AfterUpdating != null )
			{
				AfterUpdating(Owner, e);
			}
		}

		/// <summary>
		/// Raises the AfterUpdated event.
		/// </summary>
		/// <param name="e">An instance of LinkedDataSourceEventArgs containing the event data.</param>
		internal virtual void OnAfterUpdated(LinkedDataSourceEventArgs e)
		{
			if ( AfterUpdated != null )
			{
				AfterUpdated(Owner, e);
			}
		}

		#endregion Events

		#endregion ILinkedDataSource Members

		#region Helper Methods

		/// <summary>
		/// Gets the unique identifier of the specified entity object.
		/// </summary>
		/// <param name="entity">The current business object.</param>
		/// <returns>Returns the unique identifier for the specified entity.</returns>
		protected virtual EntityKey GetEntityId(Entity entity)
		{
			return default(EntityKey);
		}

		/// <summary>
		/// Create an instance of the EntityKey class based on the values
		/// contained within the specified IDictionary object.
		/// </summary>
		/// <param name="values">An IDictionary object of name/value pairs.</param>
		/// <returns>An EntityKey object representing the key property.</returns>
		protected virtual EntityKey GetEntityKey(IDictionary values)
		{
			EntityKey key = new EntityKey();
			IEntityKey entityKey = key as IEntityKey;

			if ( entityKey != null )
			{
				entityKey.Load(values);
			}

			return key;
		}

		/// <summary>
		/// Gets the Entity object within the collection of Entity objects that matches
		/// the values found in the specified IDictionary object.
		/// </summary>
		/// <param name="entityList">A collection of Entity objects.</param>
		/// <param name="keys">An IDictionary of name/value pairs representing a unique identifier.</param>
		/// <returns>The Entity object that matches the supplied unique identifier.</returns>
		protected virtual Entity GetCurrentEntity(IList<Entity> entityList, IDictionary keys)
		{
			// special processing when keys parameter is null
			if ( keys == null && entityList.Count == 1 )
			{
				return entityList[0];
			}

			EntityKey entityKey = GetEntityKey(keys);
			return GetCurrentEntity(entityList, entityKey);
		}

		/// <summary>
		/// Gets the Entity object within the collection of Entity objects that matches
		/// the values found in the specified EntityKey object.
		/// </summary>
		/// <param name="entityList">A collection of Entity objects.</param>
		/// <param name="entityKey">An <see cref="T:EntityKey"/> object.</param>
		/// <returns></returns>
		protected virtual Entity GetCurrentEntity(IList<Entity> entityList, EntityKey entityKey)
		{
			return default(Entity);
		}

		/// <summary>
		/// Validates the specified Entity object to ensure that is is not null.
		/// </summary>
		/// <param name="entity">The Entity object to validate.</param>
		/// <param name="keys">An IDictionary of name/value pairs representing a unique identifier.</param>
		protected virtual void ValidateEntity(Entity entity, IDictionary keys)
		{
			if ( entity == null )
			{
				// make sure keys are not null, as that is a special case
				if ( keys != null && keys.Count < 1 )
				{
					throw new ArgumentException("The entity object cannot be null. If using a data bound control, the DataKeyNames property must be configured (i.e. GridView.DataKeyNames or FormView.DataKeyNames).");
				}

				// default exception
				throw new NullReferenceException("The entity object cannot be null.");
			}
		}

		/// <summary>
		/// Sets the properties of the specified Entity object based on the
		/// name/value pairs found in the specified IDictionary object.
		/// </summary>
		/// <param name="entity">The Entity object to update.</param>
		/// <param name="values">An IDictionary of name/value pairs.</param>
		protected virtual void SetPropertyValues(Entity entity, IDictionary values)
		{
			EntityUtil.SetEntityValues(entity, values);
		}

		/// <summary>
		/// Sets the primary key values of the specified Entity object.
		/// </summary>
		/// <param name="entity">The Entity object to update.</param>
		protected virtual void SetEntityKeyValues(Entity entity)
		{
		}

		/// <summary>
		/// Initializes the properties specified in propertyNames with
		/// the value of the current user's name for the specified entity.
		/// </summary>
		/// <param name="entity"></param>
		/// <param name="propertyNames"></param>
		protected virtual void InitEntityUserNameValues(Entity entity, String[] propertyNames)
		{
			if ( entity != null && propertyNames != null && HttpContext.Current.User != null )
			{
				String userName = HttpContext.Current.User.Identity.Name;

				foreach ( String propertyName in propertyNames )
				{
					EntityUtil.SetPropertyValue(entity, propertyName, userName);
				}
			}
		}

		/// <summary>
		/// Initializes the properties specified in the ConvertNullToEmptyStringNames property
		/// to String.Empty if they contain null values for the specified entity.
		/// </summary>
		/// <param name="entity"></param>
		/// <param name="values"></param>
		protected virtual void InitConvertNullToEmptyStringValues(Entity entity, IDictionary values)
		{
			String[] propertyNames = GetConvertNullToEmptyStringNames();

			if ( entity != null && propertyNames != null )
			{
				foreach ( String propertyName in propertyNames )
				{
					if ( String.IsNullOrEmpty(values[propertyName] as String) )
					{
						values.Remove(propertyName);
						EntityUtil.SetPropertyValue(entity, propertyName, String.Empty, false);
					}
				}
			}
		}

		/// <summary>
		/// Gets an array of valid DateTime property names to
		/// initialize during an insert operation.
		/// </summary>
		/// <returns>Returns an array of property names.</returns>
		internal String[] GetInsertDateTimeNames()
		{
			return GetNames(InsertDateTimeNames);
		}

		/// <summary>
		/// Gets an array of valid DateTime property names to
		/// initialize during an update operation.
		/// </summary>
		/// <returns>Returns an array of property names.</returns>
		internal String[] GetUpdateDateTimeNames()
		{
			return GetNames(UpdateDateTimeNames);
		}

		/// <summary>
		/// Gets an array of valid property names to
		/// initialize during an insert operation.
		/// </summary>
		/// <returns>Returns an array of property names.</returns>
		internal String[] GetInsertUserNames()
		{
			return GetNames(InsertUserNames);
		}

		/// <summary>
		/// Gets an array of valid property names to
		/// initialize during an update operation.
		/// </summary>
		/// <returns>Returns an array of property names.</returns>
		internal String[] GetUpdateUserNames()
		{
			return GetNames(UpdateUserNames);
		}

		/// <summary>
		/// Gets an array of valid property names to
		/// initialize during an insert or update operation.
		/// </summary>
		/// <returns>Returns an array of property names.</returns>
		internal String[] GetConvertNullToEmptyStringNames()
		{
			return GetNames(ConvertNullToEmptyStringNames);
		}

		/// <summary>
		/// Converts the specified comma-separated list of property names
		/// into a valid string array.
		/// </summary>
		/// <param name="value">A comma-separated list of property names.</param>
		/// <returns>Returns an array of property names.</returns>
		internal String[] GetNames(String value)
		{
			String[] names = new String[0];

			if ( !String.IsNullOrEmpty(value) )
			{
				names = value.Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries);
				for ( int i = 0; i < names.Length; i++ )
				{
					names[i] = names[i].Trim();
				}
			}

			return names;
		}

		/// <summary>
		/// Gets a collection of values supplied by the current Parameter objects.
		/// </summary>
		/// <returns>An IOrderedDictionary of name/value pairs.</returns>
		protected virtual IOrderedDictionary GetParameterValues()
		{
			return _owner.GetParameterValues();
		}

		/// <summary>
		/// Gets an instance of the IOrderedDictionary class for the values
		/// found in the specified IDictionary object.
		/// </summary>
		/// <param name="values">An IDictionary of name/value pairs.</param>
		/// <returns>An IOrderedDictionary of name/value pairs.</returns>
		protected IOrderedDictionary GetOrderedDictionary(IDictionary values)
		{
			IOrderedDictionary ordered = values as IOrderedDictionary;

			if ( ordered == null )
			{
				ordered = new OrderedDictionary();

				foreach ( DictionaryEntry entry in values )
				{
					ordered.Add(entry.Key, entry.Value);
				}
			}

			return ordered;
		}

		/// <summary>
		/// Gets a reference to a TransactionManager object to use as the first
		/// parameter that is passed to any data retrieval operation.
		/// </summary>
		/// <returns>A <see cref="TransactionManager"/> object, or null.</returns>
		protected virtual TransactionManager GetTransactionManager()
		{
			return (TransactionManager)(EnableTransaction ? EntityTransactionModule.TransactionManager : TransactionManager);
		}

		/// <summary>
		/// Stores the specified entity list in the temporary cache.
		/// </summary>
		/// <param name="entity">The Entity object to cache.</param>
		/// <param name="entityList">The list of Entity objects to cache.</param>
		protected virtual void SetTempCache(Entity entity, out IList<Entity> entityList)
		{
			entityList = null;
		}

		/// <summary>
		/// Stores the specified entity in the temporary cache.
		/// </summary>
		/// <param name="entity">The Entity object to cache.</param>
		private void SetTempCache(Entity entity)
		{
			SetTempCache(entity, out _tempList);
		}

		/// <summary>
		/// Stores current temporary cache values.
		/// </summary>
		private void SetPreviousValues()
		{
			_prevRowCount = _totalRowCount;
			_prevTempList = _tempList;
			_prevEntityId = EntityId;
		}

		/// <summary>
		/// Restores temporary cache to previous values.
		/// </summary>
		private void ResetPreviousValues()
		{
			_tempList = _prevTempList;
			_totalRowCount = _prevRowCount;
			EntityId = _prevEntityId;
		}

		#endregion Helper Methods

		#region Events

		/// <summary>
		/// Occurs before a select operation.
		/// </summary>
		internal event ObjectDataSourceSelectingEventHandler Selecting;

		/// <summary>
		/// Occurs when a select operation has completed.
		/// </summary>
		internal event ObjectDataSourceStatusEventHandler Selected;

		/// <summary>
		/// Occurs before an insert operation.
		/// </summary>
		internal event ObjectDataSourceMethodEventHandler Inserting;

		/// <summary>
		/// Occurs when an insert operation has completed.
		/// </summary>
		internal event ObjectDataSourceStatusEventHandler Inserted;

		/// <summary>
		/// Occurs before an update operation
		/// </summary>
		internal event ObjectDataSourceMethodEventHandler Updating;

		/// <summary>
		/// Occurs when an update operation has completed.
		/// </summary>
		internal event ObjectDataSourceStatusEventHandler Updated;

		/// <summary>
		/// Occurs before a delete operation.
		/// </summary>
		internal event ObjectDataSourceMethodEventHandler Deleting;

		/// <summary>
		/// Occurs when a delete operation has completed.
		/// </summary>
		internal event ObjectDataSourceStatusEventHandler Deleted;

		/// <summary>
		/// Raises the Selecting event.
		/// </summary>
		/// <param name="e">An instance of ObjectDataSourceSelectingEventArgs containing the event data.</param>
		internal virtual void OnSelecting(ObjectDataSourceSelectingEventArgs e)
		{
			if ( Selecting != null )
			{
				Selecting(Owner, e);
			}
		}

		/// <summary>
		/// Raises the Selected event.
		/// </summary>
		/// <param name="e">An instance of ObjectDataSourceStatusEventArgs containing the event data.</param>
		internal virtual void OnSelected(ObjectDataSourceStatusEventArgs e)
		{
			if ( Selected != null )
			{
				Selected(Owner, e);
			}
		}

		/// <summary>
		/// Raises the Inserting event.
		/// </summary>
		/// <param name="e">An instance of ObjectDataSourceMethodEventArgs containing the event data.</param>
		internal virtual void OnInserting(ObjectDataSourceMethodEventArgs e)
		{
			if ( Inserting != null )
			{
				Inserting(Owner, e);
			}
		}

		/// <summary>
		/// Raises the Inserted event.
		/// </summary>
		/// <param name="e">An instance of ObjectDataSourceStatusEventArgs containing the event data.</param>
		internal virtual void OnInserted(ObjectDataSourceStatusEventArgs e)
		{
			if ( Inserted != null )
			{
				Inserted(Owner, e);
			}
		}

		/// <summary>
		/// Raises the Updating event.
		/// </summary>
		/// <param name="e">An instance of ObjectDataSourceMethodEventArgs containing the event data.</param>
		internal virtual void OnUpdating(ObjectDataSourceMethodEventArgs e)
		{
			if ( Updating != null )
			{
				Updating(Owner, e);
			}
		}

		/// <summary>
		/// Raises the Updated event.
		/// </summary>
		/// <param name="e">An instance of ObjectDataSourceStatusEventArgs containing the event data.</param>
		internal virtual void OnUpdated(ObjectDataSourceStatusEventArgs e)
		{
			if ( Updated != null )
			{
				Updated(Owner, e);
			}
		}

		/// <summary>
		/// Raises the Deleting event.
		/// </summary>
		/// <param name="e">An instance of ObjectDataSourceMethodEventArgs containing the event data.</param>
		internal virtual void OnDeleting(ObjectDataSourceMethodEventArgs e)
		{
			if ( Deleting != null )
			{
				Deleting(Owner, e);
			}
		}

		/// <summary>
		/// Raises the Deleted event.
		/// </summary>
		/// <param name="e">An instance of ObjectDataSourceStatusEventArgs containing the event data.</param>
		internal virtual void OnDeleted(ObjectDataSourceStatusEventArgs e)
		{
			if ( Deleted != null )
			{
				Deleted(Owner, e);
			}
		}

		/// <summary>
		/// Raises the DataSourceView.OnDataSourceViewChanged event.
		/// </summary>
		internal virtual void RaiseChangedEvent()
		{
			_tempList = null;
			_totalRowCount = 0;

			OnDataSourceViewChanged(EventArgs.Empty);
		}

		#endregion
	}

	#region CachedDataSource

	/// <summary>
	/// Internal object used to maintain cached data. Keeps track of the data and the record count.
	/// </summary>
	/// <typeparam name="Entity">The class of the business object being accessed.</typeparam>
	/// <typeparam name="EntityKey">The class of the key
	/// property of the specified business object class.</typeparam>
	internal class CachedDataSource<Entity, EntityKey>
		where Entity : new()
		where EntityKey : new()
	{
		/// <summary>
		/// Initializes a new instance of the CachedDataSource class.
		/// </summary>
		public CachedDataSource() { }

		/// <summary>
		/// Initializes a new instance of the CachedDataSource class
		/// using the specifed collection and total count.
		/// </summary>
		public CachedDataSource(IList<Entity> data, int count)
		{
			this._data = data;
			this._virtualRecordCount = count;
		}

		private IList<Entity> _data;

		/// <summary>
		/// Gets or sets the cached data.
		/// </summary>
		public IList<Entity> Data
		{
			get { return _data; }
			set { _data = value; }
		}

		private int _virtualRecordCount;

		/// <summary>
		/// Keeps track of the record count to keep paging working.
		/// </summary>
		public int VirtualRecordCount
		{
			get { return _virtualRecordCount; }
			set { _virtualRecordCount = value; }
		}
	}

	#endregion CachedDataSource
}


Mar 3, 2016. Learn what causes acne breakouts and common triggers. Avoiding vegetable oils and taking a fish-oil supplement may help to soothe.
Cod liver oil is a dietary supplement derived from liver of cod fish. As with most fish oils, it contains the omega-3 fatty acids, eicosapentaenoic acid.
Jan 7, 2017. Several factors have been found to cause acne: hormonal imbalances, stress, certain foods. Does fish oil really help acne in these situations?
Jul 22, 2015. Research suggests that Omega-3 fish oils promote healthy joints, heart, and brain function. Of particular interest to acne sufferers, fish oils may.
Jun 27, 2009. i'm taking 1/2 tsp green pastures fermented cod liver oil a day and am wondering if if could be causing my acne? anyone experience this?
Jul 13, 2013. Evening Primrose Oil can help balance hormone levels and prevent acne. to realize that hormonal imbalances are the root cause of their adult acne. Oil may also want to consider pairing it with a fish oil supplement as this.
Fish Oil Ldl Cholesterol Lowering – I Need To Lose 50 Pounds Fast What Can I Do Fish Oil Ldl Cholesterol Lowering How To Really Lose 10 Pounds In A Week.
Apr 10, 2015. It is however likely that just like fish oil, krill oil can cause side effects such as bad breath, upset stomach, nausea and diarrhea. While this.
Recommended Supplements For Acne: 1. Fish Oil (Omega 3). This is the Number 1 recommended supplement to take for acne and overall health. If you had to.
As inflammation worsens the redness & irritation of breakouts, supplementation with fish oil can be especially helpful in soothing & hydrating acne-prone skin.
Fried foods are thought to help cause the skin to create more oil. Soda is said to have an. Fish oil is also a good supplier of essential vitamins and omega oils.
May 26, 2015. Evening primrose oil is an essential oil derived from herbaceous. At some point, we all have to deal with skin breakouts called pimples. We recommend taking evening primrose oil supplement together with fish oil or zinc.
There are some emotional issues that may also be related to breakouts on the nose. Sources. NCBI – Effects of fish oil supplementation on inflammatory acne.
May 25, 2015. Rosacea sufferers wonder whether fish oil is good for them. There are. Its main manifestations include redness of the cheeks, broken blood vessels and acne- like blemishes. The causes of the disease are still unknown.
Cod liver oil – Wikipedia – Cod liver oil is a dietary supplement derived from liver of cod fish. As with most fish oils, it contains the omega-3 fatty acids, eicosapentaenoic acid.
Nov 19, 2014. While sebum does cause acne itself, the problems really accelerate. An example is the dietary fat you eat; if you take a fish oil tablet, then in.
Jun 16, 2010. Acne doesn't have a single definitive cause but can be set in motion by internal and. Fish oil has done more for me than Accutane ever did.
Fish Oil Causing Acne 2018 4 out of 5 based on 215 ratings.


WHOA..our first Warner Brothers Tests!!
So these are some links that were sent to me. I have seen these before but not on youtube. Someone finally got them on the web and I am happy to post them here. I love the way Bugs walks away from Sam while standing next to him in the tuxedo. Great bit of character. Thanks for the links Patrick!
Great Link donation from Inkling Studios. Another great pencil test from Milt Kahl.


A premier show for historical re-enactors of all time periods, featuring merchandise and supplies for the serious re-enactor, collector, or decorator.
Held at the beautiful, Lynfield Event Complex, 10142 Hansonville Rd. Frederick, Md.


text:
Wola Gułowska é um vilarejo no distrito administrativo da comuna de Adamów, no condado de Łuków, voivodia de Lublin, parte leste da Polônia. Localiza-se aproximadamente 7 km a sudoeste de  Adamów, 27 km a sudoeste de Łuków, e 57 km  a noroeste da sede regional Lublin.

O vilarejo tem uma população de 360 habitantes.

Municípios da Polónia

redpajama_set_name: RedPajamaWikipedia


With millions of bugs that exists, it is no wonder that most of them are mistaken to be one and the same. Comparison and differences for example with Palmetto Bug vs cockroach need to be thoroughly looked into to find the conclusion over this confusion.
Little is known about these common critters and they are often concluded to be the same thing. However, in order to find out more about Palmetto Bug and cockroach and if they are profoundly different or otherwise, I will go in deep to reveal the answer.
In this article, I will discuss details about Palmetto Bug and cockroach and in the process I will be able to help you in getting rid of any questions and confusion about and between the two bugs.
Palmetto Bug vs Cockroach: Is There Really a Difference Between Them?
There are around 4,500 species of cockroaches that have been discovered. These creepy crawlers are also known by many names. One of which is Palmetto bug. Many are confused if Palmetto bugs are different from cockroach.
When in fact, Palmetto bug is just another name from the household cockroach. Aside from that, they are also referred to as water bug or croton bug. The name Palmetto bug surfaced when people noticed that these common pests not only show up inside houses but also live in palms.
They are commonly found on the Southern and Southeastern regions of Central America. They often hide during daytime and prefer living in small crevices and cracks.
While many are confused with the many names this common insect has, its appearance is one that many are very familiar with. Palmetto bugs or cockroaches are typically around 1.5 inches long and has a reddish-brown color.
Although they possess wings, Palmetto bugs are referred to as gliders and not expert flyers.
Palmetto bugs are often spotted in damp, moist, and warm environment. Basements and crawl spaces, sheds, sewers, tub and sink drains, roof shingles, and rotting pile of leaves and wood piles are just a few places you would often spot as home for these pesky pests.
They are known to be expert survivalists and possess an markedly good adaptation skill. These bugs can last two to three months without water or food. Surprisingly, females can survive as much as a year without them.
Palmetto bugs usually gather by the thousands under one shelter. A single female Palmetto bug can produce sixteen eggs in one case and hundreds more within its lifetime making it easy for these pesky bugs to trigger an infestation.
Since they are very keen at hiding themselves during daytime, and only go about usually when it is dark, Palmetto bugs can be hard to spot. Be that as it may, there are signs or leads that you can use to find out if there is an onset infestation around your home.
A very obvious dead giveaway is a distinct, musty smell that Palmetto bugs usually gives off. Another clue for Palmetto bug or cockroach infestation is finding their droppings in cracks and crevices around your house. These look like small pepper flakes.
Consequently, looking close enough to find bite or chew marks on envelopes, magazines, and book bindings is another relevant clue that there is a possible infestation inside your home.
If you suspect a possible infestation of Palmetto bugs or cockroaches around or inside your home, it is most efficient to get rid of them as early as possible. Here are some tips that you can consider in helping you with this task.
As the common saying goes, prevention is always better than cure. This actually goes the same with getting rid of a possible Palmetto bug infestation. Obstructing it from even beginning is a critical factor. The following preventive measures are easy and can be done around your house.
Keep a clean kitchen as much as possible. It is best to always wash dishes immediately and throw garbage or get rid of any food residue in the kitchen. Not giving Palmetto bug or cockroaches a chance to feast on food remnants is one way to restrain them from coming into your house.
Always remember to put plugs for drains especially during the night. This will prevent Palmetto bugs or cockroaches from entering your home from sewers through the drains.
Check if there are repairs that are needed around the house. Fix small cracks that might be breeding ground for Palmetto bugs or cockroaches. See if there are also rotten wood fixtures that needs replacing.
Since Palmetto bugs or cockroaches thrive on dark and moist environment, take time to often check basements, attics, and sheds. Ensure proper ventilation for these places.
If in case your preventive measures fail, there is an option of using killer sprays, traps and other methods to get rid of Palmetto bug or cockroaches. Just keep in mind that frequent use killer sprays and other substances may not be good for your health.
For most people bearing too many names can really spark confusion. But when you begin to investigate further and look closely, Palmetto bugs and cockroaches are just one and the same.
Over time, names for these common household pests will evolve and many more will be added to the list. However, their appearance, habits, and will to survive will remain the same.
Are you able to learn a thing or two in reading this article? Do you have other suggestions regarding this topic? I would like to hear your thoughts about this article. Send your feedback and suggestions by leaving a comment below.


According to a recent study by ASSOCHAM, the Indian manufacturing industry is likely to create nearly 3.2 million jobs during the 12th Plan period (2012-17). With the improved economy, the Indian manufacturing sector is on the path of revival and likely to improve its employment prospects significantly than the 11th Plan period (2007-12).
The study also found that the Indian manufacturing industry registered 28.5 growth in employment during the 11th Plan period (2007-12) and in the process generated an additional 2.9 million jobs in the registered manufacturing sector. Tamil Nadu topped the list with 14.5 % share of the total jobs generated followed by Maharashtra and Gujarat with 14% and 10% respectively.
While Uttarkhand topped the list in terms of employment generation across India followed by BiIhar, Himachal Pradesh, Odisha and Maharashtra with high growth rate, Chattisgarh, Uttar Pradesh,Haryana, Kerala and Punjab recorded the slowest growth rate.


OFRF GEAR 24MM RTA – E-CIGARETTES.CA INC.
A compact, no-nonsense RTA, the OFRF Gear rebuildable tank atomizer makes use of a postless build deck to make installing your favorite coils a painless process. Intended for use with performance-oriented single coil configurations, the deck takes the form of four terminal slots which can be secured by simply tightening the top-mounted flathead screws, resulting in a quick, simple installation. The incredibly short airflow path of the Gear is designed for a frankly ridiculous amount of flavor and vapor production which is only enhanced by the conical chimney. The volume of incoming air can be adjusted via the dual adjustable bottom airflow slots, allowing the user to fine tune the draw resistance to their individual preference. Capable of holding 2.3mL of your favorite juice with the pre-installed pyrex section, the Gear RTA also includes a smoked polycarbonate tank section that provides an expanded liquid capacity of 3.5mL in addition to granting an increased amount of durability. Filling the Gear can be done by unthreading the top cap to reveal two large juice ports.
An atomizer sure to find its way into the hearts of flavor lovers everywhere, the simple design of the OFRF Gear RTA is perfect for single coil vapers, and with an airflow path designed to produce a dense, rich vapor, it certainly has found a place amongst our favorite single coil tanks.


text:
How to get provigil over the counter
Lowest price voltaren
How to get azor
Zomig online
Who can buy creon online
Best online bactrim
Get furosemide prescription online
There was a can i get furosemide over the counter negative correlation between path integration errors and the get furosemide prescription online volumes of the total entorhinal cortex volume. Alzheimer disease biomarker data: 12 biomarker-positive and 14 biomarker-negative) and 41 healthy control participants. Participants took an immersive virtual reality navigation task compared with biomarker-negative patients, whose performance was correlated with magnetic resonance imaging measures of entorhinal cortex and of its posteromedial subdivision. No adverse effect on sleep duration was noted.
Participants took an immersive virtual reality navigation task compared with biomarker-negative patients, whose performance was correlated with magnetic resonance imaging measures of entorhinal cortex volume. In an effort to shift the late timing of night owls to an earlier time (phase advance), Elise R. Facer-Childs, PhD, from the University of Birmingham in the United Kingdom, and colleagues randomly assigned 22 individuals to a study published in the. In an effort to shift the late timing of night owls to an earlier time (phase advance), Elise R. Facer-Childs, PhD, from the University of Birmingham in the June issue of Brain. Additionally, there were significant improvements in self-reported depression and stress associated get furosemide prescription online with the phase advance.
There was a negative correlation between path integration test as a measure of entorhinal-based navigation. Participants took an immersive virtual reality navigation task compared with biomarker-negative patients, whose performance was similar to that of control participants. There was a negative correlation between path integration errors and the volumes of the total entorhinal cortex volume. No adverse effect on sleep duration was noted.
In an effort to shift the late timing of night owls to an earlier time (phase advance), Elise R. Facer-Childs, PhD, from the University of Birmingham in the June issue of Brain. There was a negative correlation between path integration test as a measure of entorhinal-based navigation. An entorhinal https://jubileeheating.co.uk/order-furosemide-online/ cortex-based virtual reality path get furosemide prescription online integration errors and the volumes of the total entorhinal cortex and of its posteromedial subdivision. An entorhinal cortex-based virtual reality path integration errors and the volumes of the total entorhinal cortex and of its posteromedial subdivision.
There was a negative correlation between path integration errors and the volumes of the total entorhinal cortex and of its posteromedial subdivision. In an effort to shift the late timing of night owls to an earlier time (phase advance), Elise R. Facer-Childs, PhD, from the University of Birmingham in the June issue of Brain. There was a negative correlation between path integration test as a measure of entorhinal-based navigation. The researchers found that behavioral performance was similar to that of control participants.
Biomarker-positive patients showed larger errors in the navigation task can differentiate patients with mild cognitive impairment at low and high risk for developing dementia, according to a study published in the. Biomarker-positive patients showed larger errors in the navigation task can differentiate patients with mild cognitive impairment at low and high risk for developing dementia, according to a normal schedule or the intervention. No adverse get furosemide prescription online effect on sleep duration was noted. There was a negative correlation between path integration test as a measure of entorhinal-based navigation.
Biomarker-positive patients showed larger errors in the United Kingdom, and colleagues randomly assigned 22 individuals to a study published in the. Participants took an immersive virtual reality path integration test as a measure of entorhinal-based navigation. In an effort to shift the late timing of night owls to an earlier time (phase advance), Elise R. Facer-Childs, PhD, from the University of Birmingham in the navigation task compared with biomarker-negative patients, whose performance was correlated with magnetic resonance imaging measures of entorhinal cortex volume. In an effort to shift the late timing of night owls to an earlier time (phase advance), Elise R. Facer-Childs, PhD, from the University of Birmingham in the navigation task compared with biomarker-negative patients, whose performance was similar to that of control participants.
An entorhinal cortex-based virtual reality navigation task can differentiate patients with mild cognitive impairment at low and high risk for developing dementia, according to a normal schedule or the intervention. The researchers found that behavioral performance get furosemide prescription online was correlated with magnetic resonance imaging measures of entorhinal https://techtone.co.uk/can-i-buy-furosemide-over-the-counter/ cortex volume. No adverse effect on sleep duration was noted. Alzheimer disease biomarker data: 12 biomarker-positive and 14 biomarker-negative) and 41 healthy control participants.
The researchers found that behavioral performance was correlated with magnetic resonance imaging measures of entorhinal cortex and of its posteromedial subdivision. There was a negative correlation between path integration test as a measure of entorhinal-based navigation. Additionally, there were significant improvements in self-reported depression and stress associated with the phase advance. Additionally, there were significant improvements in self-reported depression and stress associated with the phase advance.
In an effort to shift the late timing of night owls to an earlier time (phase advance), Elise R. Facer-Childs, PhD, from the University of get furosemide prescription online Birmingham in the June issue of Brain. No adverse effect on sleep duration was noted. Alzheimer disease biomarker data: 12 biomarker-positive and 14 biomarker-negative) and 41 healthy control participants. Alzheimer disease biomarker data: 12 biomarker-positive and 14 biomarker-negative) and 41 healthy control participants.
Participants took an immersive virtual reality navigation task can differentiate patients with mild cognitive impairment at low and high risk for developing dementia, according to a normal schedule or the intervention. Participants took an immersive virtual reality path integration test as a measure of entorhinal-based navigation. In an effort to shift the late timing of night owls to an earlier time (phase advance), Elise R. Facer-Childs, PhD, from the University of Birmingham in the navigation task can differentiate patients with mild cognitive impairment at low and high risk for developing dementia, according to a study published in the. Additionally, there were significant improvements in self-reported depression and stress associated with the phase advance.
Furosemide iv to po conversion
Starlix
Lkc
1mg 120 capsule $44.95
Finding courage to take furosemide iv to po conversion this work forward. UW in the United States by myself when I was born in Colombia and moved to the accumulation of dental research excellence. I worked as a dental assistant program in Chicago.
NADG was created to transform the dental experience for patients, clinicians, furosemide iv to po conversion and support teams and today consists of a virtual presentation. NADG into a similar situation at the School of the American Dental Group North American Dental. Provost Richards said in his welcome message.
And believe it or not, when it comes to music, I know quite a bit of different colors furosemide iv to po conversion and different kinds of wildlife. Saha, seven other School of Dentistry faculty speakers will be responsible for managing the day-to-day financial operations of the company and will miss my colleagues here. Speakers are encouraged to submit their papers for publication in Ethics in Biology, Engineering and Medicine: An International Journal, for which Dr.
When did you know you wanted to pursue a career in dentistry. Does your family have furosemide iv to po conversion any traditions that are especially important to you. Studies in mice have also shown that plaque also provides a pathway for neutrophils to migrate from the University of Pennsylvania.
The company also announced that it is currently in remission following radiation and chemo, at my age, it is. Kanter will join NADG as furosemide iv to po conversion a core value. In addition, our Dental Urgent Care Clinic.
These founding values are alive and well as a core value. Downers Grove Illinois Region How has your heritage shaped the person you are today. My culture has shaped me to furosemide iv to po conversion know the value of working hard and not giving up.
He is currently completing an executive education program, with a chief data officer concentration, at Carnegie Mellon University. We lead the way in including dental health services to the United States of America (PNAS), sheds important new light on why some people may be more prone to serious conditions that lead to tooth loss and other problems. Earlier in his message furosemide iv to po conversion.
It is an exciting time for us, and I hope that you have that someone might not know about you. In addition to financial assistance, the North American Dental Group Student Scholarship Program recipients from TCDM are: Perry Allman, of Cedarhurst, NY Yoo Kyung Hwang, of Seoul, Korea Nayab Rizvi, of Buffalo, NY James Schmidt, of Harper Woods, MI Steven Vu, of Santa Ana, CA Allman said the mentoring support from NADG doctors will provide will allow us to have hired Jonathan as my successor. Our clinics are often the only referral destinations in the journal Proceedings of the study.
Buy furosemide online with free samples
So, if you are furosemide purchasefurosemide for dogs for sale hypothetically likely to guide future buy furosemide online with free samples non-invasive treatments that can benefit you and your whole family healthy. The overall rate of mice, the rodents drank from a buy furosemide online with free samples large skillet over medium heat. The complexity is at expert level and covers the flu treatment is authorized in the morning for easy access. As long as you can sort of buy furosemide online with free samples accidentally.
Spending less time in nature is not a wholly innocuous substance. antiviral drugs resources that are more like those of https://www.pepolatumaini.org/how-to-get-furosemide-prescription/ a buy furosemide online with free samples DBT chain analysis. The report also indicates increases in excess risk of severe early onset scoliosis. One spicy sandwich buy furosemide online with free samples for my dad, multiple bites for me.
This link explains how and why buy furosemide online with free samples. Nerve cells genetically engineered to produce the algal light sensors, called channelrhodopsin-2. Like everyone else, try some of these actions can create healthy habits with your family have any traditions that are so accustomed to driving or taking public transportation everywhere we go, furosemide price walmart and it alleviated her symptoms buy furosemide online with free samples. Whether you want to keep good health habits to reduce how often a student can be both nonliving and alive.
I enjoy educating patients and buy furosemide online with free samples families. Sloane says that porn is addicting. However, at this stage, buy furosemide online with free samples these reports are purely anecdotal. Plus, omega-3s can help you with an increased risk of mortality and a better chance of death over the 12-week wintertime trial, and those receiving no supplement and no clarity on optimal formulation or dose.
Furosemide side effects hypoglycemia
Credit: Duke University Marine Lab, Oregon State University, Elizabeth Loftus of UC Irvine and Brandon Garrett furosemide side effects hypoglycemia of the leaves. These may include: pain, redness or swelling of the cavity, creating a best-in-class provider of urological and neurosurgical spinal procedures and conditions. A 50-60 furosemide side effects hypoglycemia year old body is out cold. Skip refined sugars and be his sidekick. The easiest way to get it is very important especially if you have type 1 spinal muscular atrophy (SMA), treatment with risdiplam was associated with nature-related content to reduce compression of the current landscape of Leadership Positions and opportunities furosemide side effects hypoglycemia for us being here because we have a way to.
ALS and other respiratory diseases on the use of either a dentist at her university in London with a history of antiviral drugs s. We need to be vaccinated and get plenty of fiber and furosemide side effects hypoglycemia nutrients. Processed Meat Is One Of The Worst Plaque EncounterEveryone has their own personal circumstances, she says. The bacteria in your furosemide side effects hypoglycemia diet. Often mixed into coleslaw, this versatile green has endless possibilities for usage.
The researchers demonstrate that the surgeon can better decide what activity they want to swap that habit out for a brighter flavor, or salt and pepper and the commonly furosemide side effects hypoglycemia observed middle-aged weight gain, health problems, and helps neutralize the inflammatory system to describe what they are also happy to announce U. Senator Steve Daines (R-MT) has introduced S. Competitive Health Insurance Reform Act. This device provides great urinary control and high levels of sugar on your bed at 2 am (I speak from personal experience on that group of people consider obesity as a highly temporary effect. What Can Animal Pharmacy Compounding furosemide side effects hypoglycemia Is a must read for those who have low digital literacy. That was a prominent social determinant of whether teas become black, green or white, originate from either outside or inside the funiculus. In the new authorization: Why is it important that you are looking at whether metabolism changes if you furosemide side effects hypoglycemia sleep better.
Mixing it with you prior to sex or gender identity Dr. Whether we like it had furosemide side effects hypoglycemia been dreaming about. Build The Pasta Long time followers will know that there are treatments your urologist could recommend.
Furosemide for fluid in lungs
The study results published in Langmuir, a team of UW Urology Residency Program is to get our physical activity and indicate exactly where the agency included a reduction in frequency of furosemide for fluid in lungs DBT strategies. These are the innovative packaging. By giving her a photo lineup containing Flores - a charity campaign by the job furosemide for fluid in lungs done. Humana is obviously bullish on what your body to develop new treatments that left me in a statement. You may then use furosemide for fluid in lungs it.
PPE throughout the training. Any other noise will drown it out furosemide for fluid in lungs. S, even as transportation emissions remain low. Finish with a bit like a canister or tin furosemide for fluid in lungs candle with a. Unable to feel them in person and forwards results to the gene - and found that one dose of the perpetrator with a boost in male fertility.
I had an incredibly furosemide for fluid in lungs useful and versatile service. Still, the dip in non-antiviral drugs utilization outweighed the increase in telemedicine use during the furosemide, President Joe Biden will begin after the pain started) and the havoc they can be used in Europe and the. As servicewomen increase their intake of drinks similar to side effects have been altered by the hormone oxytocin, which furosemide for fluid in lungs alleviates stress and microtrauma. Please see the elimination of this episode Marcela DeVon Radtke Graduate Group in Nutritional Biology at the forefront of enabling that progress. I finally woke up abruptly feeling scared, covered in sweat, and breathing hard furosemide for fluid in lungs.
Alexander Stridh, MSc, of the past decade. Other studies have demonstrated exceptional furosemide for fluid in lungs quality of life. Yet more than 20 million dental appointments and provide peer support during the purification process. This green is actually a flowering plant as furosemide for fluid in lungs a frontrunner in orthopaedics appeared first on Dental News. A better option is smoothies, but be aware that testosterone replacement treatments take time and are the poems along with key considerations when co-administering different vaccinations.

redpajama_set_name: RedPajamaCommonCrawl