/// <summary>
        /// This method can start, stop, resume or pause a group of components of the specified type.
        /// </summary>
        /// <param name="action">The action required</param>
        /// <param name="components">The components to which the action should be provided</param>
        /// <param name="componentType">The component type.</param>
        public virtual void ComponentsStatusChange(XimuraServiceStatusAction action,
            ICollection components, Type componentType,
            ComponentStatusChangeNotify NotifyAfter, ComponentStatusChangeNotify NotifyBefore)
        {
            if (components == null)
                return;

            bool donotNotifyBefore = NotifyBefore == null;
            bool doNotifyAfter = NotifyAfter != null;

            foreach (object objService in components)
            {
                IXimuraService service = objService as IXimuraService;
                if (service != null &&
                    (componentType == null || (componentType.IsInstanceOfType(service))))
                {
                    try
                    {
                        switch (action)
                        {
                            case XimuraServiceStatusAction.Start:
                                if (service.ServiceStatus == XimuraServiceStatus.Stopped ||
                                    service.ServiceStatus == XimuraServiceStatus.NotStarted)
                                {
                                    if (donotNotifyBefore || NotifyBefore(action, service))
                                    {
                                        service.Start();
                                        if (doNotifyAfter) NotifyAfter(action, service);
                                    }
                                }
                                break;
                            case XimuraServiceStatusAction.Stop:
                                if (service.ServiceStatus != XimuraServiceStatus.Stopped ||
                                    service.ServiceStatus != XimuraServiceStatus.Stopping ||
                                    service.ServiceStatus != XimuraServiceStatus.NotStarted ||
                                    service.ServiceStatus != XimuraServiceStatus.Undefined)
                                {
                                    if (donotNotifyBefore || NotifyBefore(action, service))
                                    {
                                        service.Stop();
                                        if (doNotifyAfter) NotifyAfter(action, service);
                                    }
                                }
                                break;
                            case XimuraServiceStatusAction.Pause:
                                if (service.ServiceStatus == XimuraServiceStatus.Started)
                                {
                                    if (donotNotifyBefore || NotifyBefore(action, service))
                                    {
                                        service.Pause();
                                        if (doNotifyAfter) NotifyAfter(action, service);
                                    }
                                }
                                break;
                            case XimuraServiceStatusAction.Continue:
                                if (service.ServiceStatus == XimuraServiceStatus.Paused)
                                    if (service.ServiceStatus == XimuraServiceStatus.Started)
                                    {
                                        if (donotNotifyBefore || NotifyBefore(action, service))
                                        {
                                            service.Continue();
                                            if (doNotifyAfter) NotifyAfter(action, service);
                                        }
                                    }
                                break;
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("ComponentsStatusChange -> " + action.ToString() +
                            " -> " + ex.Message, "Start error.");
                        throw ex;
                    }
                }
            }
        }
		/// <summary>
		/// This method can start, stop, resume or pause a group of components of the specified type.
		/// </summary>
		/// <param name="action">The action required</param>
		/// <param name="components">The components to which the action should be provided</param>
		/// <param name="componentType">The component type.</param>
		protected virtual void ComponentsStatusChange(XimuraServiceStatusAction action, 
			ICollection components, Type componentType)
		{
			if (components == null)
				return;

			foreach(object objService in components)
			{
				IXimuraService service = objService as IXimuraService;
				if (service != null && 
					(componentType==null || (componentType.IsInstanceOfType(service))))
				{
					try
					{
						switch (action)
						{
							case XimuraServiceStatusAction.Start:
								if (service.ServiceEnabled && 
                                    (service.ServiceStatus == XimuraServiceStatus.Stopped ||
									service.ServiceStatus == XimuraServiceStatus.NotStarted))
								{
									if (ComponentsStatusBeforeChange(action, service))
									{
                                        if (service is IXimuraServiceParentSettings)
                                            ServiceParentSettingsSet((IXimuraServiceParentSettings)service);
										service.Start();
										ComponentsStatusAfterChange(action, service);
									}
								}
								break;
							case XimuraServiceStatusAction.Stop:
								if (service.ServiceStatus != XimuraServiceStatus.Stopped ||
									service.ServiceStatus != XimuraServiceStatus.Stopping ||
									service.ServiceStatus != XimuraServiceStatus.NotStarted ||
									service.ServiceStatus != XimuraServiceStatus.Undefined)
								{
									if (ComponentsStatusBeforeChange(action, service))
									{
										service.Stop();
										ComponentsStatusAfterChange(action, service);
									}				
								}
								break;
							case XimuraServiceStatusAction.Pause:
								if (service.ServiceStatus == XimuraServiceStatus.Started)
								{
									if (ComponentsStatusBeforeChange(action, service))
									{
										service.Pause();
										ComponentsStatusAfterChange(action, service);
									}				
								}								
								break;
							case XimuraServiceStatusAction.Continue:
								if (service.ServiceStatus == XimuraServiceStatus.Paused)
									if (service.ServiceStatus == XimuraServiceStatus.Started)
									{
										if (ComponentsStatusBeforeChange(action, service))
										{
											service.Continue();
											ComponentsStatusAfterChange(action, service);
										}				
									}									
								break;
						}
					}
					catch (Exception ex)
					{
                        string message = "ComponentsStatusChange: " + objService.ToString() + " -> " 
                            + action.ToString() + " -> " + ex.Message;
#if (DEBUG)
                        Debug.WriteLine(message, action.ToString() + " error.");
#endif
                        throw new XimuraComponentServiceException(message,ex);
					}
				}
			}
		}