WorkflowRuntime.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / RunTime / WorkflowRuntime.cs / 1305376 / WorkflowRuntime.cs

                            #region Imports 

using System;
using System.ComponentModel;
using System.Diagnostics; 
using System.Collections;
using System.Collections.Generic; 
using System.Collections.Specialized; 
using System.Collections.ObjectModel;
using System.Configuration; 
using System.Reflection;
using System.Threading;
using System.Globalization;
using System.IO; 
using System.Workflow.Runtime.Hosting;
using System.Workflow.Runtime.Configuration; 
using System.Workflow.ComponentModel; 
using System.Workflow.Runtime.Tracking;
using System.Workflow.ComponentModel.Compiler; 
using System.Xml;
using System.Workflow.Runtime.DebugEngine;
using System.Workflow.ComponentModel.Serialization;
using System.ComponentModel.Design; 
using System.ComponentModel.Design.Serialization;
 
#endregion 

namespace System.Workflow.Runtime 
{
    #region Class WorkflowRuntimeEventArgs

    public sealed class WorkflowRuntimeEventArgs : EventArgs 
    {
        private bool _isStarted; 
 
        internal WorkflowRuntimeEventArgs(bool isStarted)
        { 
            _isStarted = isStarted;
        }

        public bool IsStarted { get { return _isStarted; } } 
    }
 
    #endregion 

    internal class FanOutOnKeyDictionary: IEnumerable> 
    {
        Dictionary> dictionaryDictionary;

        public FanOutOnKeyDictionary( int fanDegree ) 
        {
            dictionaryDictionary = new Dictionary>(fanDegree); 
            for (int i = 0; i < fanDegree; ++i) 
            {
                dictionaryDictionary.Add(i, new Dictionary()); 
            }
        }

        public Dictionary this[K key] 
        {
            get 
            { 
                return dictionaryDictionary[Math.Abs(key.GetHashCode() % dictionaryDictionary.Count)];
            } 
        }

        public bool SafeTryGetValue(K key, out V value)
        { 
            Dictionary dict = this[key];
            lock (dict) 
            { 
                return dict.TryGetValue(key, out value);
            } 
        }

        #region IEnumerable> Members
 
        public IEnumerator> GetEnumerator()
        { 
            return dictionaryDictionary.Values.GetEnumerator(); 
        }
 
        #endregion

        #region IEnumerable Members
 
        IEnumerator IEnumerable.GetEnumerator()
        { 
            return dictionaryDictionary.Values.GetEnumerator(); 
        }
 
        #endregion
    }

    public class WorkflowRuntime : IServiceProvider, IDisposable 
    {
        #region Private members 
 
        internal const string DefaultName = "WorkflowRuntime";
        // Instances aggregation 
        private FanOutOnKeyDictionary workflowExecutors;
        private WorkflowDefinitionDispenser _workflowDefinitionDispenser;

        private PerformanceCounterManager _performanceCounterManager; 

        private bool _disposed = false; 
        //This is Instance Specific Flag to mark the given instance of 
        //Instance Service is started or not.
        private bool isInstanceStarted; 
 	    private DebugController debugController;
        private object _servicesLock = new object();        // protects integrity or the services collection
        private object _startStopLock = new object();       // serializes calls to start and stop
        private Guid _uid = Guid.NewGuid(); 

		private BooleanSwitch disableWorkflowDebugging = new BooleanSwitch("DisableWorkflowDebugging", "Disables workflow debugging in host"); 
 
        private TrackingListenerFactory _trackingFactory = new TrackingListenerFactory();
        private static Dictionary _runtimes = new Dictionary(); 
        private static object _runtimesLock = new object(); // protects the collection of runtime objects

        #endregion
 
        #region Constructors and Configure methods
 
        static WorkflowRuntime() 
        {
            // listen to activity definition resolve events 
            Activity.ActivityResolve += OnActivityDefinitionResolve;
            Activity.WorkflowChangeActionsResolve += OnWorkflowChangeActionsResolve;
        }
 
        public WorkflowRuntime()
        { 
            this.PrivateInitialize(null); 
        }
 
        public WorkflowRuntime(string configSectionName)
        {
            if (configSectionName == null)
                throw new ArgumentNullException("configSectionName"); 

            WorkflowRuntimeSection settings = ConfigurationManager.GetSection(configSectionName) as WorkflowRuntimeSection; 
            if (settings == null) 
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
                    ExecutionStringManager.ConfigurationSectionNotFound, configSectionName), "configSectionName"); 

            this.PrivateInitialize(settings);
        }
        ///  Creates a WorkflowRuntime from settings.  
        ///  The settings for this container 
        public WorkflowRuntime(WorkflowRuntimeSection settings) 
        { 
            if (settings == null)
                throw new ArgumentNullException("settings"); 

            this.PrivateInitialize(settings);

        } 

        private void VerifyInternalState() 
        { 
            if (_disposed)
                throw new ObjectDisposedException("WorkflowRuntime"); 
        }
        /// Initializes this container with the provided settings.
        /// 
        private void PrivateInitialize(WorkflowRuntimeSection settings) 
        {
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Created WorkflowRuntime {0}", _uid); 
 
            _workflowDefinitionDispenser = new WorkflowDefinitionDispenser(this, (settings != null) ? settings.ValidateOnCreate : true, (settings != null) ? settings.WorkflowDefinitionCacheCapacity : 0);
            workflowExecutors = new FanOutOnKeyDictionary((Environment.ProcessorCount * 4)-1); 
            _name = DefaultName;

            if (settings == null || settings.EnablePerformanceCounters) // on by default
                this.PerformanceCounterManager = new PerformanceCounterManager(); 

            if (settings != null) 
            { 
                _name = settings.Name;
                _configurationParameters = settings.CommonParameters; 

                foreach (WorkflowRuntimeServiceElement service in settings.Services)
                {
					AddServiceFromSettings(service); 
                }
            } 
 
            // create controller
            if (!disableWorkflowDebugging.Enabled) 
            {
                DebugController.InitializeProcessSecurity();
                this.debugController = new DebugController(this, _name);
            } 

            lock (_runtimesLock) 
            { 
                if (!_runtimes.ContainsKey(_uid))
                    _runtimes.Add(_uid, new WeakReference(this)); 
            }
        }

        public void Dispose() 
        {
            lock (_startStopLock) 
            { 
                if (!_disposed)
                { 
                    if (this.debugController != null)
                    {
                        this.debugController.Close();
                    } 
                    _workflowDefinitionDispenser.Dispose();
                    _startedServices = false; 
                    _disposed = true; 
                }
            } 
            lock (_runtimesLock)
            {
                //
                // Clean up our weakref entries 
                if (_runtimes.ContainsKey(_uid))
                    _runtimes.Remove(_uid); 
            } 
        }
 
        internal bool IsZombie
        {
            get
            { 
                return this._disposed;
            } 
        } 

        #endregion 

        #region Workflow accessor methods

        public WorkflowInstance GetWorkflow(Guid instanceId) 
        {
            if (instanceId == Guid.Empty) 
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.CantBeEmptyGuid, "instanceId")); 
            VerifyInternalState();
            if (!IsStarted) 
                throw new InvalidOperationException(ExecutionStringManager.WorkflowRuntimeNotStarted);

            WorkflowExecutor executor = Load(instanceId, null, null);
            return executor.WorkflowInstance; 
        }
 
        public ReadOnlyCollection GetLoadedWorkflows() 
        {
            VerifyInternalState(); 
            List lSchedules = new List();
            foreach (WorkflowExecutor executor in GetWorkflowExecutors())
            {
                lSchedules.Add(executor.WorkflowInstance); 
            }
            return lSchedules.AsReadOnly(); 
        } 

        internal WorkflowDefinitionDispenser DefinitionDispenser 
        {
            get
            {
                return _workflowDefinitionDispenser; 
            }
        } 
 
        #endregion
 
        #region Service accessors

        internal List TrackingServices
        { 
            get
            { 
                List retval = new List(); 
                foreach (TrackingService trackingService in GetAllServices(typeof(TrackingService)))
                { 
                    retval.Add(trackingService);
                }
                return retval;
            } 
        }
        internal WorkflowSchedulerService SchedulerService 
        { 
            get
            { 
                return GetService();
            }
        }
 
        internal WorkflowCommitWorkBatchService TransactionService
        { 
            get 
            {
                return (WorkflowCommitWorkBatchService)GetService(typeof(WorkflowCommitWorkBatchService)); 
            }
        }

        internal WorkflowPersistenceService WorkflowPersistenceService 
        {
            get 
            { 
                return (WorkflowPersistenceService)GetService(typeof(WorkflowPersistenceService));
            } 
        }

        internal System.Workflow.Runtime.PerformanceCounterManager PerformanceCounterManager
        { 
            get
            { 
                return _performanceCounterManager; 
            }
            private set 
            {
                _performanceCounterManager = value;
            }
        } 

        internal TrackingListenerFactory TrackingListenerFactory 
        { 
            get
            { 
                return _trackingFactory;
            }
        }
 
        #endregion
 
        #region Workflow creation methods 

        internal Activity GetWorkflowDefinition(Type workflowType) 
        {
            if (workflowType == null)
                throw new ArgumentNullException("workflowType");
            VerifyInternalState(); 

            return _workflowDefinitionDispenser.GetRootActivity(workflowType, false, true); 
        } 

        public WorkflowInstance CreateWorkflow(Type workflowType) 
        {
            if (workflowType == null)
                throw new ArgumentNullException("workflowType");
            if (!typeof(Activity).IsAssignableFrom(workflowType)) 
                throw new ArgumentException(ExecutionStringManager.TypeMustImplementRootActivity, "workflowType");
            VerifyInternalState(); 
 
            return InternalCreateWorkflow(new CreationContext(workflowType, null, null, null), Guid.NewGuid());
        } 

        public WorkflowInstance CreateWorkflow(Type workflowType, Dictionary namedArgumentValues)
        {
            return CreateWorkflow(workflowType, namedArgumentValues, Guid.NewGuid()); 
        }
 
        public WorkflowInstance CreateWorkflow(XmlReader workflowDefinitionReader) 
        {
            if (workflowDefinitionReader == null) 
                throw new ArgumentNullException("workflowDefinitionReader");
            VerifyInternalState();

            return CreateWorkflow(workflowDefinitionReader, null, null); 
        }
 
        public WorkflowInstance CreateWorkflow(XmlReader workflowDefinitionReader, XmlReader rulesReader, Dictionary namedArgumentValues) 
        {
            return CreateWorkflow(workflowDefinitionReader, rulesReader, namedArgumentValues, Guid.NewGuid()); 
        }

        public WorkflowInstance CreateWorkflow(Type workflowType, Dictionary namedArgumentValues, Guid instanceId)
        { 
            if (workflowType == null)
                throw new ArgumentNullException("workflowType"); 
            if (!typeof(Activity).IsAssignableFrom(workflowType)) 
                throw new ArgumentException(ExecutionStringManager.TypeMustImplementRootActivity, "workflowType");
            VerifyInternalState(); 

            return InternalCreateWorkflow(new CreationContext(workflowType, null, null, namedArgumentValues), instanceId);
        }
 
        public WorkflowInstance CreateWorkflow(XmlReader workflowDefinitionReader, XmlReader rulesReader, Dictionary namedArgumentValues, Guid instanceId)
        { 
            if (workflowDefinitionReader == null) 
                throw new ArgumentNullException("workflowDefinitionReader");
            VerifyInternalState(); 

            CreationContext context = new CreationContext(workflowDefinitionReader, rulesReader, namedArgumentValues);
            return InternalCreateWorkflow(context, instanceId);
        } 

        internal WorkflowInstance InternalCreateWorkflow(CreationContext context, Guid instanceId) 
        { 
            using (new WorkflowTraceTransfer(instanceId))
            { 
                VerifyInternalState();

                if ( !IsStarted )
                    this.StartRuntime(); 

                WorkflowExecutor executor = GetWorkflowExecutor(instanceId, context); 
                if (!context.Created) 
                {
                    throw new InvalidOperationException(ExecutionStringManager.WorkflowWithIdAlreadyExists); 
                }


                return executor.WorkflowInstance; 
            }
        } 
 
        internal sealed class WorkflowExecutorInitializingEventArgs : EventArgs
        { 
            private bool _loading = false;

            internal WorkflowExecutorInitializingEventArgs( bool loading )
            { 
                _loading = loading;
            } 
 
            internal bool Loading
            { 
                get { return _loading; }
            }
        }
 
        // register for idle events here
        ///  
        /// Raised whenever a WorkflowExecutor is constructed.  This signals either a new instance 
        /// or a loading (args) and gives listening components a chance to set up subscriptions.
        ///  
        internal event EventHandler WorkflowExecutorInitializing;
        public event EventHandler WorkflowIdled;
        public event EventHandler WorkflowCreated;
        public event EventHandler WorkflowStarted; 
        public event EventHandler WorkflowLoaded;
        public event EventHandler WorkflowUnloaded; 
        public event EventHandler WorkflowCompleted; 
        public event EventHandler WorkflowTerminated;
        public event EventHandler WorkflowAborted; 
        public event EventHandler WorkflowSuspended;
        public event EventHandler WorkflowPersisted;
        public event EventHandler WorkflowResumed;
        internal event EventHandler WorkflowDynamicallyChanged; 
        public event EventHandler ServicesExceptionNotHandled;
        public event EventHandler Stopped; 
        public event EventHandler Started; 

        internal WorkflowExecutor Load(WorkflowInstance instance) 
        {
            return Load(instance.InstanceId, null, instance);
        }
 
        internal WorkflowExecutor Load(Guid key, CreationContext context, WorkflowInstance workflowInstance)
        { 
            WorkflowExecutor executor; 
            Dictionary executors = workflowExecutors[key];
 

            lock (executors)
            {
                if (!IsStarted) 
                    throw new InvalidOperationException(ExecutionStringManager.WorkflowRuntimeNotStarted);
 
                if (executors.TryGetValue(key, out executor)) 
                {
                    if (executor.IsInstanceValid) 
                    {
                        return executor;
                    }
                } 

                // If we get here, 'executor' is either null or unusable. 
                // Before grabbing the lock, allocate a resource as we 
                // may need to insert a new resource.
                executor = new WorkflowExecutor(key); 
                if (workflowInstance == null)
                    workflowInstance = new WorkflowInstance(key, this);

                InitializeExecutor(key, context, executor, workflowInstance); 
                try
                { 
                    // If we get here, 'executor' is either null or has not been replaced. 
                    // If it has not been replaced, we know that it is unusable
 
                    WorkflowTrace.Host.TraceInformation("WorkflowRuntime:: replacing unusable executor for key {0} with new one (hc: {1})", key, executor.GetHashCode());
                    executors[key] = executor;
                    RegisterExecutor(context != null && context.IsActivation, executor);
                } 
                catch
                { 
                    WorkflowExecutor currentRes; 
                    if (executors.TryGetValue(key, out currentRes))
                    { 
                        if (Object.Equals(executor, currentRes))
                        {
                            executors.Remove(key);
                        } 
                    }
                    throw; 
                } 
            }
            executor.Registered(context != null && context.IsActivation); 
            return executor;
        }

        // this should be called under scheduler lock 
        // todo assert this condition
        internal void ReplaceWorkflowExecutor(Guid instanceId, WorkflowExecutor oldWorkflowExecutor, WorkflowExecutor newWorkflowExecutor) 
        { 
            Dictionary executors = workflowExecutors[instanceId];
            lock (executors) 
            {
                oldWorkflowExecutor.IsInstanceValid = false;

                WorkflowTrace.Host.TraceInformation("WorkflowRuntime:: replacing old executor for key {0} with new one", instanceId); 
                executors[instanceId] = newWorkflowExecutor;
            } 
        } 

        private Activity InitializeExecutor(Guid instanceId, CreationContext context, WorkflowExecutor executor, WorkflowInstance workflowInstance) 
        {
            Activity rootActivity = null;
            if (context != null && context.IsActivation)
            { 
                Activity workflowDefinition = null;
                string xomlText = null; 
                string rulesText = null; 

                if (context.Type != null) 
                {
                    workflowDefinition = _workflowDefinitionDispenser.GetRootActivity(context.Type, false, true);
                    //spawn a new instance
                    rootActivity = _workflowDefinitionDispenser.GetRootActivity(context.Type, true, false); 
                }
                else if (context.XomlReader != null) 
                { 
                    try
                    { 
                        context.XomlReader.MoveToContent();
                        while (!context.XomlReader.EOF && !context.XomlReader.IsStartElement())
                            context.XomlReader.Read();
 
                        xomlText = context.XomlReader.ReadOuterXml();
 
                        if (context.RulesReader != null) 
                        {
                            context.RulesReader.MoveToContent(); 
                            while (!context.RulesReader.EOF && !context.RulesReader.IsStartElement())
                                context.RulesReader.Read();

                            rulesText = context.RulesReader.ReadOuterXml(); 
                        }
                    } 
                    catch (Exception e) 
                    {
                        throw new ArgumentException(ExecutionStringManager.InvalidXAML, e); 
                    }

                    if (!string.IsNullOrEmpty(xomlText))
                    { 
                        workflowDefinition = _workflowDefinitionDispenser.GetRootActivity(xomlText, rulesText, false, true);
                        //spawn a new instance 
                        rootActivity = _workflowDefinitionDispenser.GetRootActivity(xomlText, rulesText, true, false); 
                    }
                    else 
                        throw new ArgumentException(ExecutionStringManager.InvalidXAML);
                }
                rootActivity.SetValue(Activity.WorkflowDefinitionProperty, workflowDefinition);
 
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "Creating instance " + instanceId.ToString());
 
                context.Created = true; 
                executor.Initialize(rootActivity, context.InvokerExecutor, context.InvokeActivityID, instanceId, context.Args, workflowInstance);
            } 
            else
            {
                if (this.WorkflowPersistenceService == null)
                { 
                    string errMsg = String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.MissingPersistenceService, instanceId);
                    WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, errMsg); 
                    throw new InvalidOperationException(errMsg); 
                }
 
                // get the state from the persistenceService
                using (RuntimeEnvironment runtimeEnv = new RuntimeEnvironment(this))
                {
                    rootActivity = this.WorkflowPersistenceService.LoadWorkflowInstanceState(instanceId); 
                }
                if (rootActivity == null) 
                { 
                    throw new InvalidOperationException(string.Format(Thread.CurrentThread.CurrentCulture, ExecutionStringManager.InstanceNotFound, instanceId));
                } 
                executor.Reload(rootActivity, workflowInstance);
            }
            return rootActivity;
        } 

        private void RegisterExecutor(bool isActivation, WorkflowExecutor executor) 
        { 
            if (isActivation)
            { 
                executor.RegisterWithRuntime(this);
            }
            else
            { 
                executor.ReRegisterWithRuntime(this);
            } 
        } 

        ///  
        /// On receipt of this call unload the instance
        /// This will be invoked by the runtime executor
        /// 
        ///  
        internal void OnIdle(WorkflowExecutor executor)
        { 
            // raise the OnIdle event , typically handled 
            // by the hosting environment
            try 
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "Received OnIdle Event for instance, {0}", executor.InstanceId);
                WorkflowInstance scheduleInstance = executor.WorkflowInstance;
                if (WorkflowIdled != null) 
                {
                    WorkflowIdled(this, new WorkflowEventArgs(scheduleInstance)); 
                } 
            }
            catch (Exception) 
            {
                //
                WorkflowTrace.Host.TraceEvent(TraceEventType.Warning, 0, "OnIdle Event for instance, {0} threw an exception", executor.InstanceId);
                throw; 
            }
        } 
 
        private void _unRegister(WorkflowExecutor executor)
        { 
            TryRemoveWorkflowExecutor(executor.InstanceId,executor);
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime::_removeInstance, instance:{0}, hc:{1}", executor.InstanceId, executor.GetHashCode());

            // be sure to flush all traces 
            WorkflowTrace.Runtime.Flush();
            WorkflowTrace.Tracking.Flush(); 
            WorkflowTrace.Host.Flush(); 
        }
 
        private WorkflowExecutor GetWorkflowExecutor(Guid instanceId, CreationContext context)
        {
            try
            { 
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime dispensing resource, instanceId: {0}", instanceId);
 
                WorkflowExecutor executor = this.Load(instanceId, context, null); 
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime dispensing resource instanceId: {0}, hc: {1}", instanceId, executor.GetHashCode());
                return executor; 
            }
            catch (OutOfMemoryException)
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime dispensing resource, can't create service due to OOM!(1), instance, {0}", instanceId); 
                throw;
            } 
            catch (Exception e) 
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime dispensing resource, can't create service due to unexpected exception!(2), instance, {0}, exception, {1}", instanceId, e); 
                throw;
            }
        }
 
        #endregion
 
        #region Workflow event handlers 

        internal void OnScheduleCompleted(WorkflowExecutor schedule, WorkflowCompletedEventArgs args) 
        {
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleCompleted event raised for instance Id {0}", schedule.InstanceId);

            Debug.Assert(schedule != null); 
            try
            { 
                //Notify Subscribers 
                if (WorkflowCompleted != null) WorkflowCompleted(this, args);
            } 
            catch (Exception)
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime:OnScheduleCompleted Event threw an exception.");
                throw; 
            }
            finally 
            { 
                _unRegister(schedule);
            } 
        }

        internal void OnScheduleSuspended(WorkflowExecutor schedule, WorkflowSuspendedEventArgs args)
        { 
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleSuspension event raised for instance Id {0}", schedule.InstanceId);
 
            try 
            {
                if (WorkflowSuspended != null) WorkflowSuspended(this, args); 
            }
            catch (Exception)
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime:OnScheduleSuspended Event threw an exception."); 
                throw;
            } 
        } 

        internal void OnScheduleTerminated(WorkflowExecutor schedule, WorkflowTerminatedEventArgs args) 
        {
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleTermination event raised for instance Id {0}", schedule.InstanceId);

            try 
            {
                if (WorkflowTerminated != null) WorkflowTerminated(this, args); 
            } 
            catch (Exception)
            { 
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime:OnScheduleTerminated Event threw an exception.");
                throw;
            }
            finally 
            {
                _unRegister(schedule); 
            } 
        }
 
        internal void OnScheduleLoaded(WorkflowExecutor schedule)
        {
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleLoaded event raised for instance Id {0}", schedule.InstanceId);
 
            _OnServiceEvent(schedule, false, WorkflowLoaded);
        } 
 
        internal void OnScheduleAborted(WorkflowExecutor schedule)
        { 
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleAborted event raised for instance Id {0}", schedule.InstanceId);
            _OnServiceEvent(schedule, true, WorkflowAborted);
        }
 
        internal void OnScheduleUnloaded(WorkflowExecutor schedule)
        { 
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleUnloaded event raised for instance Id {0}", schedule.InstanceId); 

            _OnServiceEvent(schedule, true, WorkflowUnloaded); 
        }

        internal void OnScheduleResumed(WorkflowExecutor schedule)
        { 
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleResumed event raised for instance Id {0}", schedule.InstanceId);
            _OnServiceEvent(schedule, false, WorkflowResumed); 
        } 

        internal void OnScheduleDynamicallyChanged(WorkflowExecutor schedule) 
        {
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleDynamicallyChanged event raised for instance Id {0}", schedule.InstanceId);
            _OnServiceEvent(schedule, false, WorkflowDynamicallyChanged);
        } 

        internal void OnSchedulePersisted(WorkflowExecutor schedule) 
        { 
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:SchedulePersisted event raised for instance Id {0}", schedule.InstanceId);
 
            _OnServiceEvent(schedule, false, WorkflowPersisted);
        }

        private void _OnServiceEvent(WorkflowExecutor sched, bool unregister, EventHandler handler) 
        {
            Debug.Assert(sched != null); 
            try 
            {
                WorkflowEventArgs args = new WorkflowEventArgs(sched.WorkflowInstance); 
                //Notify Subscribers
                if (handler != null) handler(this, args);
            }
            catch (Exception) 
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime:OnService Event threw an exception."); 
                throw; 
            }
            finally 
            {
                if (unregister)
                {
                    _unRegister(sched); 
                }
            } 
        } 

        internal void RaiseServicesExceptionNotHandledEvent(Exception exception, Guid instanceId) 
        {
            VerifyInternalState();
            WorkflowTrace.Host.TraceEvent(TraceEventType.Critical, 0, "WorkflowRuntime:ServicesExceptionNotHandled event raised for instance Id {0} " + exception.ToString(), instanceId);
            EventHandler handler = ServicesExceptionNotHandled; 
            if (handler != null)
                handler(this, new ServicesExceptionNotHandledEventArgs(exception, instanceId)); 
        } 

        #endregion 

        #region More service accessors

        private Dictionary> _services = new Dictionary>(); 
        private string _name;
        private bool _startedServices; 
        private NameValueConfigurationCollection _configurationParameters; 
        private Dictionary _trackingServiceReplacement;
 

        ///  The name of this container. 
        public string Name
        { 
            get
            { 
                return _name; 
            }
            set 
            {
                lock (_startStopLock)
                {
                    if (_startedServices) 
                        throw new InvalidOperationException(ExecutionStringManager.CantChangeNameAfterStart);
                    VerifyInternalState(); 
                    _name = value; 
                }
            } 
        }

        /// 
        /// Returns the configuration parameters that can be shared by all services 
        /// 
        internal NameValueConfigurationCollection CommonParameters 
        { 
            get
            { 
                return _configurationParameters;
            }
        }
 
        // A previous tracking service whose type has the string as its AssemblyQualifiedName
        // will be replaced by the current tracking service of the Type. This dictionary is 
        // neede in order to replace the previous tracking service used by a persisted workflow 
        // because what is persisted is the one-way hashed string of that AssemblyQualifiedName.
        internal Dictionary TrackingServiceReplacement 
        {
            get
            {
                return _trackingServiceReplacement; 
            }
        } 
 

        ///  Adds a service to this container.  
        ///  The service to add 
        /// 
        public void AddService(object service)
        { 
            if (service == null)
                throw new ArgumentNullException("service"); 
            VerifyInternalState(); 

            using (new WorkflowRuntime.EventContext()) 
            {
                lock (_startStopLock)
                {
                    AddServiceImpl(service); 
                }
            } 
        } 

        private void AddServiceImpl(object service) 
        {
            //ASSERT: _startStopLock is held

            lock (_servicesLock) 
            {
                if (GetAllServices(service.GetType()).Contains(service)) 
                    throw new InvalidOperationException(ExecutionStringManager.CantAddServiceTwice); 

                if (_startedServices && IsCoreService(service)) 
                    throw new InvalidOperationException(ExecutionStringManager.CantChangeImmutableContainer);

                Type basetype = service.GetType();
                if (basetype.IsSubclassOf(typeof(TrackingService))) 
                {
                    AddTrackingServiceReplacementInfo(basetype); 
                } 

 
                foreach (Type t in basetype.GetInterfaces())
                {
                    List al;
                    if (_services.ContainsKey(t)) 
                    {
                        al = _services[t]; 
                    } 
                    else
                    { 
                        al = new List();
                        _services.Add(t, al);
                    }
                    al.Add(service); 
                }
 
                while (basetype != null) 
                {
                    List al = null; 
                    if (_services.ContainsKey(basetype))
                    {
                        al = _services[basetype];
                    } 
                    else
                    { 
                        al = new List(); 
                        _services.Add(basetype, al);
                    } 
                    al.Add(service);
                    basetype = basetype.BaseType;
                }
            } 

            WorkflowRuntimeService wrs = service as WorkflowRuntimeService; 
            if (wrs != null) 
            {
                wrs.SetRuntime(this); 
                if (_startedServices)
                    wrs.Start();
            }
        } 

 
        ///  Removes a service.  
        ///  The service to remove 
        public void RemoveService(object service) 
        {
            if (service == null)
                throw new ArgumentNullException("service");
            VerifyInternalState(); 

            using (new WorkflowRuntime.EventContext()) 
            { 
                lock (_startStopLock)
                { 
                    lock (_servicesLock)
                    {
                        if (_startedServices && IsCoreService(service))
                            throw new InvalidOperationException(ExecutionStringManager.CantChangeImmutableContainer); 

                        if (!GetAllServices(service.GetType()).Contains(service)) 
                            throw new InvalidOperationException(ExecutionStringManager.CantRemoveServiceNotContained); 

                        Type type = service.GetType(); 
                        if (type.IsSubclassOf(typeof(TrackingService)))
                        {
                            RemoveTrackingServiceReplacementInfo(type);
                        } 

                        foreach (List al in _services.Values) 
                        { 
                            if (al.Contains(service))
                            { 
                                al.Remove(service);
                            }
                        }
                    } 
                    WorkflowRuntimeService wrs = service as WorkflowRuntimeService;
                    if (wrs != null) 
                    { 
                        if (_startedServices)
                            wrs.Stop(); 

                        wrs.SetRuntime(null);
                    }
                } 
            }
        } 
 
        private void AddTrackingServiceReplacementInfo(Type type)
        { 
            Debug.Assert(type.IsSubclassOf(typeof(TrackingService)), "Argument should be a subtype of TrackingService");
            object[] attributes = type.GetCustomAttributes(typeof(PreviousTrackingServiceAttribute), true);
            if (attributes != null && attributes.Length > 0)
            { 
                foreach (object attribute in attributes)
                { 
                    if (_trackingServiceReplacement == null) 
                    {
                        _trackingServiceReplacement = new Dictionary(); 
                    }
                    _trackingServiceReplacement.Add(((PreviousTrackingServiceAttribute)attribute).AssemblyQualifiedName, type);
                }
            } 
        }
 
        private void RemoveTrackingServiceReplacementInfo(Type type) 
        {
            Debug.Assert(type.IsSubclassOf(typeof(TrackingService)), "Argument should be a subtype of TrackingService"); 
            object[] attributes = type.GetCustomAttributes(typeof(PreviousTrackingServiceAttribute), true);
            if (attributes != null && attributes.Length > 0)
            {
                foreach (object attribute in attributes) 
                {
                    string previousTrackingService = ((PreviousTrackingServiceAttribute)attribute).AssemblyQualifiedName; 
                    if (_trackingServiceReplacement.ContainsKey(previousTrackingService)) 
                    {
                        _trackingServiceReplacement.Remove(previousTrackingService); 
                    }
                }
            }
        } 

        private bool IsCoreService(object service) 
        { 
            return service is WorkflowSchedulerService
                || service is WorkflowPersistenceService 
                || service is TrackingService
                || service is WorkflowCommitWorkBatchService
                || service is WorkflowLoaderService;
        } 

 
        ///  Returns a collection of all services that implement the give type.  
        ///  The type to look for 
        ///  A collection of zero or more services  
        public ReadOnlyCollection GetAllServices(Type serviceType)
        {
            if (serviceType == null)
                throw new ArgumentNullException("serviceType"); 
            VerifyInternalState();
 
            lock(_servicesLock) 
            {
                List retval = new List(); 
                if (_services.ContainsKey(serviceType))
                    retval.AddRange(_services[serviceType]);

                return new ReadOnlyCollection(retval); 
            }
        } 
 

        public T GetService() 
        {
            VerifyInternalState();
            return (T)GetService(typeof(T));
        } 

        public ReadOnlyCollection GetAllServices() 
        { 
            VerifyInternalState();
            List l = new List(); 
            foreach(T t in GetAllServices(typeof(T)))
                l.Add(t);
            return new ReadOnlyCollection(l);
        } 

        ///  Looks for a service of the given type.  
        ///  The type of object to find  
        ///  An object of the requested type, or null
        public object GetService(Type serviceType) 
        {
            if (serviceType == null)
                throw new ArgumentNullException("serviceType");
            VerifyInternalState(); 

            lock(_servicesLock) 
            { 
                object retval = null;
 
                if (_services.ContainsKey(serviceType))
                {
                    List al = _services[serviceType];
 
                    if (al.Count > 1)
                        throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, 
                            ExecutionStringManager.MoreThanOneService, serviceType.ToString())); 

                    if (al.Count == 1) 
                        retval = al[0];
                }

                return retval; 
            }
        } 
 
        #endregion
 
        #region Other methods


        ///  Raises the Starting event  
        /// 
        ///  
        public void StartRuntime() 
        {
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Starting WorkflowRuntime {0}", _uid); 
            lock (_startStopLock)
            {
                VerifyInternalState();
 
                if (!_startedServices)
                { 
 
                    if (GetAllServices(typeof(WorkflowCommitWorkBatchService)).Count == 0)
                        AddServiceImpl(new DefaultWorkflowCommitWorkBatchService()); 

                    if (GetAllServices(typeof(WorkflowSchedulerService)).Count == 0)
                        AddServiceImpl(new DefaultWorkflowSchedulerService());
 
                    if (GetAllServices(typeof(WorkflowLoaderService)).Count == 0)
                        AddServiceImpl(new DefaultWorkflowLoaderService()); 
 
                    if (GetAllServices(typeof(WorkflowCommitWorkBatchService)).Count != 1)
                        throw new InvalidOperationException(String.Format( 
                        CultureInfo.CurrentCulture,
                        ExecutionStringManager.InvalidWorkflowRuntimeConfiguration,
                        typeof(WorkflowCommitWorkBatchService).Name));
 
                    if (GetAllServices(typeof(WorkflowSchedulerService)).Count != 1)
                        throw new InvalidOperationException(String.Format( 
                        CultureInfo.CurrentCulture, ExecutionStringManager.InvalidWorkflowRuntimeConfiguration, 
                        typeof(WorkflowSchedulerService).Name));
 
                    if (GetAllServices(typeof(WorkflowLoaderService)).Count != 1)
                        throw new InvalidOperationException(String.Format(
                        CultureInfo.CurrentCulture, ExecutionStringManager.InvalidWorkflowRuntimeConfiguration,
                        typeof(WorkflowLoaderService).Name)); 

                    if (GetAllServices(typeof(WorkflowPersistenceService)).Count > 1) 
                        throw new InvalidOperationException(String.Format( 
                        CultureInfo.CurrentCulture, ExecutionStringManager.InvalidWorkflowRuntimeConfiguration,
                        typeof(WorkflowPersistenceService).Name)); 

                    if (GetAllServices(typeof(WorkflowTimerService)).Count == 0)
                    {
                        AddServiceImpl(new WorkflowTimerService()); 
                    }
 
                    //Mark this instance has started 
                    isInstanceStarted = true;
 
                    //Set up static tracking structures
                    _trackingFactory.Initialize(this);
                    if (this.PerformanceCounterManager != null)
                    { 
                        this.PerformanceCounterManager.Initialize(this);
                        this.PerformanceCounterManager.SetInstanceName(this.Name); 
                    } 

                    foreach (WorkflowRuntimeService s in GetAllServices()) 
                    {
                        s.Start();
                    }
 
                    _startedServices = true;
                    using (new WorkflowRuntime.EventContext()) 
                    { 
                        EventHandler ss = Started;
                        if (ss != null) 
                            ss(this, new WorkflowRuntimeEventArgs(isInstanceStarted));
                    }
                }
            } 
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Started WorkflowRuntime {0}", _uid);
        } 
 
        void DynamicUpdateCommit( object sender, WorkflowExecutor.DynamicUpdateEventArgs e )
        { 
            if ( null == sender )
                throw new ArgumentNullException( "sender" );

            if ( !typeof( WorkflowExecutor ).IsInstanceOfType( sender ) ) 
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidArgumentType, "sender", typeof(WorkflowExecutor).ToString()));
 
            WorkflowExecutor exec = ( WorkflowExecutor ) sender; 

            OnScheduleDynamicallyChanged( exec ); 
        }

        internal void WorkflowExecutorCreated( WorkflowExecutor workflowExecutor, bool loaded )
        { 
            //
            // Fire the event for all other components that need to register for notification of WorkflowExecutor events 
            EventHandler localEvent = WorkflowExecutorInitializing; 
            if (null != localEvent)
                localEvent(workflowExecutor, new WorkflowExecutorInitializingEventArgs(loaded)); 

            workflowExecutor.WorkflowExecutionEvent += new EventHandler(WorkflowExecutionEvent);
        }
 
        void WorkflowExecutionEvent( object sender, WorkflowExecutor.WorkflowExecutionEventArgs e )
        { 
            if ( null == sender ) 
                throw new ArgumentNullException( "sender" );
 
            if ( !typeof( WorkflowExecutor ).IsInstanceOfType( sender ) )
                throw new ArgumentException( "sender" );

            WorkflowExecutor exec = ( WorkflowExecutor ) sender; 

            switch ( e.EventType ) 
            { 
                case WorkflowEventInternal.Idle:
                    OnIdle( exec ); 
                    break;
                case WorkflowEventInternal.Created:
                    if ( WorkflowCreated != null )
                        WorkflowCreated( this, new WorkflowEventArgs( exec.WorkflowInstance ) ); 
                    break;
                case WorkflowEventInternal.Started: 
                    if (WorkflowStarted != null) 
                        WorkflowStarted(this, new WorkflowEventArgs(exec.WorkflowInstance));
                    break; 
                case WorkflowEventInternal.Loaded:
                    OnScheduleLoaded( exec );
                    break;
                case WorkflowEventInternal.Unloaded: 
                    OnScheduleUnloaded( exec );
                    break; 
                case WorkflowEventInternal.Completed: 
                    OnScheduleCompleted( exec, CreateCompletedEventArgs( exec ) );
                    break; 
                case WorkflowEventInternal.Terminated:
                    WorkflowExecutor.WorkflowExecutionTerminatedEventArgs args = ( WorkflowExecutor.WorkflowExecutionTerminatedEventArgs ) e;

                    if (null != args.Exception) 
                        OnScheduleTerminated(exec, new WorkflowTerminatedEventArgs(exec.WorkflowInstance, args.Exception));
                    else 
                        OnScheduleTerminated(exec, new WorkflowTerminatedEventArgs(exec.WorkflowInstance, args.Error)); 

                    break; 
                case WorkflowEventInternal.Aborted:
                    OnScheduleAborted( exec );
                    break;
                case WorkflowEventInternal.Suspended: 
                    WorkflowExecutor.WorkflowExecutionSuspendedEventArgs sargs = ( WorkflowExecutor.WorkflowExecutionSuspendedEventArgs ) e;
                    OnScheduleSuspended( exec, new WorkflowSuspendedEventArgs( exec.WorkflowInstance, sargs.Error ) ); 
                    break; 
                case WorkflowEventInternal.Persisted:
                    OnSchedulePersisted( exec ); 
                    break;
                case WorkflowEventInternal.Resumed:
                    OnScheduleResumed( exec );
                    break; 
                case WorkflowEventInternal.DynamicChangeCommit:
                    DynamicUpdateCommit( exec, ( WorkflowExecutor.DynamicUpdateEventArgs ) e ); 
                    break; 
                default:
                    break; 
            }
        }

        private WorkflowCompletedEventArgs CreateCompletedEventArgs( WorkflowExecutor exec ) 
        {
            WorkflowCompletedEventArgs args = new WorkflowCompletedEventArgs(exec.WorkflowInstance, exec.WorkflowDefinition); 
            foreach (PropertyInfo property in _workflowDefinitionDispenser.GetOutputParameters(exec.RootActivity)) 
                args.OutputParameters.Add(property.Name, property.GetValue(exec.RootActivity, null));
 
            return args;
        }

        private void StopServices() 
        {
            // Stop remaining services 
            foreach (WorkflowRuntimeService s in GetAllServices()) 
            {
                s.Stop(); 
            }
        }

        ///  Fires the Stopping event  
        public void StopRuntime()
        { 
            VerifyInternalState(); 

            using (new WorkflowRuntime.EventContext()) 
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Stopping WorkflowRuntime {0}", _uid);
                lock (_startStopLock)
                { 
                    if (_startedServices)
                    { 
                        try 
                        {
                            isInstanceStarted = false; 

                            if (this.WorkflowPersistenceService != null)
                            {
                                // 
                                // GetWorkflowExecutors() takes a lock on workflowExecutors
                                // and then returns a copy of the list.  As long as GetWorkflowExecutors() 
                                // returns a non empty/null list we'll attempt to unload what's in it. 
                                IList executors = GetWorkflowExecutors();
                                while ((null != executors) && (executors.Count > 0)) 
                                {
                                    foreach (WorkflowExecutor executor in executors)
                                    {
                                        if (executor.IsInstanceValid) 
                                        {
                                            try 
                                            { 
                                                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Calling Unload on instance {0} executor hc {1}", executor.InstanceIdString, executor.GetHashCode());
                                                executor.Unload(); 
                                            }
                                            catch (ExecutorLocksHeldException)
                                            {
                                                // 
                                                // This exception means that an atomic scope is ongoing
                                                // (we cannot unload/suspend during an atomic scope) 
                                                // This instance will still be in the GetWorkflowExecutors list 
                                                // so we'll attempt to unload it on the next outer loop
                                                // Yes, we may loop indefinitely if an atomic tx is hung 
                                                // See WorkflowInstance.Unload for an example of retrying
                                                // when this exception is thrown.
                                            }
                                            catch (InvalidOperationException) 
                                            {
                                                if (executor.IsInstanceValid) 
                                                { 
                                                    //
                                                    // Failed to stop, reset the flag 
                                                    isInstanceStarted = true;
                                                    throw;
                                                }
                                            } 
                                            catch
                                            { 
                                                // 
                                                // Failed to stop, reset the flag
                                                isInstanceStarted = true; 
                                                throw;
                                            }
                                        }
                                    } 
                                    //
                                    // Check if anything was added to the main list 
                                    // while we were working on the copy. 
                                    // This happens if a executor reverts to a checkpoint.
                                    // There is the potential to loop indefinitely if 
                                    // an instance continually reverts.
                                    executors = GetWorkflowExecutors();
                                }
                            } 

                            StopServices(); 
                            _startedServices = false; 

 
                            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Stopped WorkflowRuntime {0}", _uid);

                            //
                            // Clean up tracking 
                            _trackingFactory.Uninitialize(this);
                            if (this.PerformanceCounterManager != null) 
                            { 
                                this.PerformanceCounterManager.Uninitialize(this);
                            } 

                            EventHandler handler = Stopped;
                            if (handler != null)
                                handler(this, new WorkflowRuntimeEventArgs(isInstanceStarted)); 
                        }
                        catch (Exception) 
                        { 
                            WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime::StartUnload Unexpected Exception");
                            throw; 
                        }
                        finally
                        {
                            isInstanceStarted = false; 
                        }
                    } 
                } 
            }
        } 

        ///  True if services have been started and not stopped 
        public bool IsStarted
        { 
            get
            { 
                return _startedServices; 
            }
        } 


        private static Activity OnActivityDefinitionResolve(object sender, ActivityResolveEventArgs e)
        { 
            WorkflowRuntime runtime = e.ServiceProvider as WorkflowRuntime;
            if (runtime == null) 
                runtime = RuntimeEnvironment.CurrentRuntime; 

            Debug.Assert(runtime != null); 
            if (runtime != null)
            {
                if (e.Type != null)
                    return runtime._workflowDefinitionDispenser.GetRootActivity(e.Type, e.CreateNewDefinition, e.InitializeForRuntime); 
                else
                    return runtime._workflowDefinitionDispenser.GetRootActivity(e.WorkflowMarkup, e.RulesMarkup, e.CreateNewDefinition, e.InitializeForRuntime); 
            } 
            return null;
        } 

        internal static TypeProvider CreateTypeProvider(Activity rootActivity)
        {
            TypeProvider typeProvider = new TypeProvider(null); 

            Type companionType = rootActivity.GetType(); 
            typeProvider.SetLocalAssembly(companionType.Assembly); 
            typeProvider.AddAssembly(companionType.Assembly);
 
            foreach (AssemblyName assemblyName in companionType.Assembly.GetReferencedAssemblies())
            {
                Assembly referencedAssembly = null;
                try 
                {
                    referencedAssembly = Assembly.Load(assemblyName); 
                    if (referencedAssembly != null) 
                        typeProvider.AddAssembly(referencedAssembly);
                } 
                catch
                {
                }
 
                if (referencedAssembly == null && assemblyName.CodeBase != null)
                    typeProvider.AddAssemblyReference(assemblyName.CodeBase); 
            } 

            return typeProvider; 
        }

        private static ArrayList OnWorkflowChangeActionsResolve(object sender, WorkflowChangeActionsResolveEventArgs e)
        { 
            ArrayList changes = null;
            WorkflowRuntime runtime = RuntimeEnvironment.CurrentRuntime; 
            Debug.Assert(runtime != null); 
            if (runtime != null)
            { 
                WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
                ServiceContainer serviceContainer = new ServiceContainer();
                ITypeProvider typeProvider = runtime.GetService();
                if (typeProvider != null) 
                    serviceContainer.AddService(typeof(ITypeProvider), typeProvider);
                else if (sender is Activity) 
                { 
                    serviceContainer.AddService(typeof(ITypeProvider), CreateTypeProvider(sender as Activity));
                } 

                DesignerSerializationManager manager = new DesignerSerializationManager(serviceContainer);
                using (manager.CreateSession())
                { 
                    using (StringReader reader = new StringReader(e.WorkflowChangesMarkup))
                    { 
                        using (XmlReader xmlReader = XmlReader.Create(reader)) 
                        {
                            WorkflowMarkupSerializationManager xomlSerializationManager = new WorkflowMarkupSerializationManager(manager); 
                            changes = serializer.Deserialize(xomlSerializationManager, xmlReader) as ArrayList;
                        }
                    }
                } 
            }
 
            return changes; 
        }
 
        ///  Creates and adds a service to this container. 
        ///  Description of the service to add. 
        private void AddServiceFromSettings(WorkflowRuntimeServiceElement serviceSettings)
        { 
            object service = null;
 
            Type t = Type.GetType(serviceSettings.Type, true); 

            ConstructorInfo serviceProviderAndSettingsConstructor = null; 
            ConstructorInfo serviceProviderConstructor = null;
            ConstructorInfo settingsConstructor = null;

            foreach (ConstructorInfo ci in t.GetConstructors()) 
            {
                ParameterInfo[] pi = ci.GetParameters(); 
                if (pi.Length == 1) 
                {
                    if (typeof(IServiceProvider).IsAssignableFrom(pi[0].ParameterType)) 
                    {
                        serviceProviderConstructor = ci;
                    }
                    else if (typeof(NameValueCollection).IsAssignableFrom(pi[0].ParameterType)) 
                    {
                        settingsConstructor = ci; 
                    } 
                }
                else if (pi.Length == 2) 
                {
                    if (typeof(IServiceProvider).IsAssignableFrom(pi[0].ParameterType)
                        && typeof(NameValueCollection).IsAssignableFrom(pi[1].ParameterType))
                    { 
                        serviceProviderAndSettingsConstructor = ci;
                        break; 
                    } 
                }
            } 

            if (serviceProviderAndSettingsConstructor != null)
            {
                service = serviceProviderAndSettingsConstructor.Invoke( 
                    new object[] { this, serviceSettings.Parameters });
            } 
            else if (serviceProviderConstructor != null) 
            {
                service = serviceProviderConstructor.Invoke(new object[] { this }); 
            }
            else if (settingsConstructor != null)
            {
                service = settingsConstructor.Invoke(new object[] { serviceSettings.Parameters }); 
            }
            else 
            { 
                service = Activator.CreateInstance(t);
            } 

            AddServiceImpl(service);
        }
 
        internal static void ClearTrackingProfileCache()
        { 
            lock (_runtimesLock) 
            {
                foreach (WeakReference wr in _runtimes.Values) 
                {
                    WorkflowRuntime runtime = wr.Target as WorkflowRuntime;
                    if (null != runtime)
                    { 
                        if ( ( null != runtime.TrackingListenerFactory ) && ( null != runtime.TrackingListenerFactory.TrackingProfileManager ) )
                            runtime.TrackingListenerFactory.TrackingProfileManager.ClearCacheImpl(); 
                    } 
                }
            } 
        }
        /// Utility class that prevents reentrance during event processing.
        /// 
        /// When created an EventContext it creates a static variable local to 
        /// a managed thread (similar to the old TLS slot),
        /// which can detect cases when events are invoked while handling other events. 
        /// The variable is removed on dispose. 
        /// 
        internal sealed class EventContext : IDisposable 
        {

            /// 
            /// Indicates that the value of a static field is unique for each thread 
            /// CLR Perf suggests using this attribute over the slot approach.
            ///  
            [ThreadStatic()] 
            static object threadData;
 
            public EventContext(params Object[] ignored)
            {
                if (threadData != null)
                    throw new InvalidOperationException(ExecutionStringManager.CannotCauseEventInEvent); 

                threadData = this; 
            } 

            void IDisposable.Dispose() 
            {
                Debug.Assert(threadData != null, "unexpected call to EventContext::Dispose method");
                threadData = null;
            } 
        }
 
        #endregion 

        #region WorkflowExecutor utility methods 
        private IList GetWorkflowExecutors()
        {
            //
            // This is a safety check in to avoid returning invalid executors in the following cases: 
            // 1.  We ---- between the executor going invalid and getting removed from the list.
            // 2.  We have a leak somewhere where invalid executors are not getting removed from the list. 
            List executorsList = new List(); 
            foreach (Dictionary executors in workflowExecutors)
            { 
                lock (executors)
                {
                    foreach (WorkflowExecutor executor in executors.Values)
                    { 
                        if ((null != executor) && (executor.IsInstanceValid))
                            executorsList.Add(executor); 
                    } 
                }
            } 
            return executorsList;
        }

        private bool TryRemoveWorkflowExecutor(Guid instanceId, WorkflowExecutor executor) 
        {
            Dictionary executors = workflowExecutors[instanceId]; 
            lock (executors) 
            {
                WorkflowExecutor currentRes; 
                if (executors.TryGetValue(instanceId, out currentRes) && Object.Equals(executor, currentRes))
                {
                    WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime::TryRemoveWorkflowExecutor, instance:{0}, hc:{1}", executor.InstanceIdString, executor.GetHashCode());
                    return executors.Remove(instanceId); 
                }
 
                return false; 
            }
        } 
        #endregion
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
#region Imports 

using System;
using System.ComponentModel;
using System.Diagnostics; 
using System.Collections;
using System.Collections.Generic; 
using System.Collections.Specialized; 
using System.Collections.ObjectModel;
using System.Configuration; 
using System.Reflection;
using System.Threading;
using System.Globalization;
using System.IO; 
using System.Workflow.Runtime.Hosting;
using System.Workflow.Runtime.Configuration; 
using System.Workflow.ComponentModel; 
using System.Workflow.Runtime.Tracking;
using System.Workflow.ComponentModel.Compiler; 
using System.Xml;
using System.Workflow.Runtime.DebugEngine;
using System.Workflow.ComponentModel.Serialization;
using System.ComponentModel.Design; 
using System.ComponentModel.Design.Serialization;
 
#endregion 

namespace System.Workflow.Runtime 
{
    #region Class WorkflowRuntimeEventArgs

    public sealed class WorkflowRuntimeEventArgs : EventArgs 
    {
        private bool _isStarted; 
 
        internal WorkflowRuntimeEventArgs(bool isStarted)
        { 
            _isStarted = isStarted;
        }

        public bool IsStarted { get { return _isStarted; } } 
    }
 
    #endregion 

    internal class FanOutOnKeyDictionary: IEnumerable> 
    {
        Dictionary> dictionaryDictionary;

        public FanOutOnKeyDictionary( int fanDegree ) 
        {
            dictionaryDictionary = new Dictionary>(fanDegree); 
            for (int i = 0; i < fanDegree; ++i) 
            {
                dictionaryDictionary.Add(i, new Dictionary()); 
            }
        }

        public Dictionary this[K key] 
        {
            get 
            { 
                return dictionaryDictionary[Math.Abs(key.GetHashCode() % dictionaryDictionary.Count)];
            } 
        }

        public bool SafeTryGetValue(K key, out V value)
        { 
            Dictionary dict = this[key];
            lock (dict) 
            { 
                return dict.TryGetValue(key, out value);
            } 
        }

        #region IEnumerable> Members
 
        public IEnumerator> GetEnumerator()
        { 
            return dictionaryDictionary.Values.GetEnumerator(); 
        }
 
        #endregion

        #region IEnumerable Members
 
        IEnumerator IEnumerable.GetEnumerator()
        { 
            return dictionaryDictionary.Values.GetEnumerator(); 
        }
 
        #endregion
    }

    public class WorkflowRuntime : IServiceProvider, IDisposable 
    {
        #region Private members 
 
        internal const string DefaultName = "WorkflowRuntime";
        // Instances aggregation 
        private FanOutOnKeyDictionary workflowExecutors;
        private WorkflowDefinitionDispenser _workflowDefinitionDispenser;

        private PerformanceCounterManager _performanceCounterManager; 

        private bool _disposed = false; 
        //This is Instance Specific Flag to mark the given instance of 
        //Instance Service is started or not.
        private bool isInstanceStarted; 
 	    private DebugController debugController;
        private object _servicesLock = new object();        // protects integrity or the services collection
        private object _startStopLock = new object();       // serializes calls to start and stop
        private Guid _uid = Guid.NewGuid(); 

		private BooleanSwitch disableWorkflowDebugging = new BooleanSwitch("DisableWorkflowDebugging", "Disables workflow debugging in host"); 
 
        private TrackingListenerFactory _trackingFactory = new TrackingListenerFactory();
        private static Dictionary _runtimes = new Dictionary(); 
        private static object _runtimesLock = new object(); // protects the collection of runtime objects

        #endregion
 
        #region Constructors and Configure methods
 
        static WorkflowRuntime() 
        {
            // listen to activity definition resolve events 
            Activity.ActivityResolve += OnActivityDefinitionResolve;
            Activity.WorkflowChangeActionsResolve += OnWorkflowChangeActionsResolve;
        }
 
        public WorkflowRuntime()
        { 
            this.PrivateInitialize(null); 
        }
 
        public WorkflowRuntime(string configSectionName)
        {
            if (configSectionName == null)
                throw new ArgumentNullException("configSectionName"); 

            WorkflowRuntimeSection settings = ConfigurationManager.GetSection(configSectionName) as WorkflowRuntimeSection; 
            if (settings == null) 
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
                    ExecutionStringManager.ConfigurationSectionNotFound, configSectionName), "configSectionName"); 

            this.PrivateInitialize(settings);
        }
        ///  Creates a WorkflowRuntime from settings.  
        ///  The settings for this container 
        public WorkflowRuntime(WorkflowRuntimeSection settings) 
        { 
            if (settings == null)
                throw new ArgumentNullException("settings"); 

            this.PrivateInitialize(settings);

        } 

        private void VerifyInternalState() 
        { 
            if (_disposed)
                throw new ObjectDisposedException("WorkflowRuntime"); 
        }
        /// Initializes this container with the provided settings.
        /// 
        private void PrivateInitialize(WorkflowRuntimeSection settings) 
        {
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Created WorkflowRuntime {0}", _uid); 
 
            _workflowDefinitionDispenser = new WorkflowDefinitionDispenser(this, (settings != null) ? settings.ValidateOnCreate : true, (settings != null) ? settings.WorkflowDefinitionCacheCapacity : 0);
            workflowExecutors = new FanOutOnKeyDictionary((Environment.ProcessorCount * 4)-1); 
            _name = DefaultName;

            if (settings == null || settings.EnablePerformanceCounters) // on by default
                this.PerformanceCounterManager = new PerformanceCounterManager(); 

            if (settings != null) 
            { 
                _name = settings.Name;
                _configurationParameters = settings.CommonParameters; 

                foreach (WorkflowRuntimeServiceElement service in settings.Services)
                {
					AddServiceFromSettings(service); 
                }
            } 
 
            // create controller
            if (!disableWorkflowDebugging.Enabled) 
            {
                DebugController.InitializeProcessSecurity();
                this.debugController = new DebugController(this, _name);
            } 

            lock (_runtimesLock) 
            { 
                if (!_runtimes.ContainsKey(_uid))
                    _runtimes.Add(_uid, new WeakReference(this)); 
            }
        }

        public void Dispose() 
        {
            lock (_startStopLock) 
            { 
                if (!_disposed)
                { 
                    if (this.debugController != null)
                    {
                        this.debugController.Close();
                    } 
                    _workflowDefinitionDispenser.Dispose();
                    _startedServices = false; 
                    _disposed = true; 
                }
            } 
            lock (_runtimesLock)
            {
                //
                // Clean up our weakref entries 
                if (_runtimes.ContainsKey(_uid))
                    _runtimes.Remove(_uid); 
            } 
        }
 
        internal bool IsZombie
        {
            get
            { 
                return this._disposed;
            } 
        } 

        #endregion 

        #region Workflow accessor methods

        public WorkflowInstance GetWorkflow(Guid instanceId) 
        {
            if (instanceId == Guid.Empty) 
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.CantBeEmptyGuid, "instanceId")); 
            VerifyInternalState();
            if (!IsStarted) 
                throw new InvalidOperationException(ExecutionStringManager.WorkflowRuntimeNotStarted);

            WorkflowExecutor executor = Load(instanceId, null, null);
            return executor.WorkflowInstance; 
        }
 
        public ReadOnlyCollection GetLoadedWorkflows() 
        {
            VerifyInternalState(); 
            List lSchedules = new List();
            foreach (WorkflowExecutor executor in GetWorkflowExecutors())
            {
                lSchedules.Add(executor.WorkflowInstance); 
            }
            return lSchedules.AsReadOnly(); 
        } 

        internal WorkflowDefinitionDispenser DefinitionDispenser 
        {
            get
            {
                return _workflowDefinitionDispenser; 
            }
        } 
 
        #endregion
 
        #region Service accessors

        internal List TrackingServices
        { 
            get
            { 
                List retval = new List(); 
                foreach (TrackingService trackingService in GetAllServices(typeof(TrackingService)))
                { 
                    retval.Add(trackingService);
                }
                return retval;
            } 
        }
        internal WorkflowSchedulerService SchedulerService 
        { 
            get
            { 
                return GetService();
            }
        }
 
        internal WorkflowCommitWorkBatchService TransactionService
        { 
            get 
            {
                return (WorkflowCommitWorkBatchService)GetService(typeof(WorkflowCommitWorkBatchService)); 
            }
        }

        internal WorkflowPersistenceService WorkflowPersistenceService 
        {
            get 
            { 
                return (WorkflowPersistenceService)GetService(typeof(WorkflowPersistenceService));
            } 
        }

        internal System.Workflow.Runtime.PerformanceCounterManager PerformanceCounterManager
        { 
            get
            { 
                return _performanceCounterManager; 
            }
            private set 
            {
                _performanceCounterManager = value;
            }
        } 

        internal TrackingListenerFactory TrackingListenerFactory 
        { 
            get
            { 
                return _trackingFactory;
            }
        }
 
        #endregion
 
        #region Workflow creation methods 

        internal Activity GetWorkflowDefinition(Type workflowType) 
        {
            if (workflowType == null)
                throw new ArgumentNullException("workflowType");
            VerifyInternalState(); 

            return _workflowDefinitionDispenser.GetRootActivity(workflowType, false, true); 
        } 

        public WorkflowInstance CreateWorkflow(Type workflowType) 
        {
            if (workflowType == null)
                throw new ArgumentNullException("workflowType");
            if (!typeof(Activity).IsAssignableFrom(workflowType)) 
                throw new ArgumentException(ExecutionStringManager.TypeMustImplementRootActivity, "workflowType");
            VerifyInternalState(); 
 
            return InternalCreateWorkflow(new CreationContext(workflowType, null, null, null), Guid.NewGuid());
        } 

        public WorkflowInstance CreateWorkflow(Type workflowType, Dictionary namedArgumentValues)
        {
            return CreateWorkflow(workflowType, namedArgumentValues, Guid.NewGuid()); 
        }
 
        public WorkflowInstance CreateWorkflow(XmlReader workflowDefinitionReader) 
        {
            if (workflowDefinitionReader == null) 
                throw new ArgumentNullException("workflowDefinitionReader");
            VerifyInternalState();

            return CreateWorkflow(workflowDefinitionReader, null, null); 
        }
 
        public WorkflowInstance CreateWorkflow(XmlReader workflowDefinitionReader, XmlReader rulesReader, Dictionary namedArgumentValues) 
        {
            return CreateWorkflow(workflowDefinitionReader, rulesReader, namedArgumentValues, Guid.NewGuid()); 
        }

        public WorkflowInstance CreateWorkflow(Type workflowType, Dictionary namedArgumentValues, Guid instanceId)
        { 
            if (workflowType == null)
                throw new ArgumentNullException("workflowType"); 
            if (!typeof(Activity).IsAssignableFrom(workflowType)) 
                throw new ArgumentException(ExecutionStringManager.TypeMustImplementRootActivity, "workflowType");
            VerifyInternalState(); 

            return InternalCreateWorkflow(new CreationContext(workflowType, null, null, namedArgumentValues), instanceId);
        }
 
        public WorkflowInstance CreateWorkflow(XmlReader workflowDefinitionReader, XmlReader rulesReader, Dictionary namedArgumentValues, Guid instanceId)
        { 
            if (workflowDefinitionReader == null) 
                throw new ArgumentNullException("workflowDefinitionReader");
            VerifyInternalState(); 

            CreationContext context = new CreationContext(workflowDefinitionReader, rulesReader, namedArgumentValues);
            return InternalCreateWorkflow(context, instanceId);
        } 

        internal WorkflowInstance InternalCreateWorkflow(CreationContext context, Guid instanceId) 
        { 
            using (new WorkflowTraceTransfer(instanceId))
            { 
                VerifyInternalState();

                if ( !IsStarted )
                    this.StartRuntime(); 

                WorkflowExecutor executor = GetWorkflowExecutor(instanceId, context); 
                if (!context.Created) 
                {
                    throw new InvalidOperationException(ExecutionStringManager.WorkflowWithIdAlreadyExists); 
                }


                return executor.WorkflowInstance; 
            }
        } 
 
        internal sealed class WorkflowExecutorInitializingEventArgs : EventArgs
        { 
            private bool _loading = false;

            internal WorkflowExecutorInitializingEventArgs( bool loading )
            { 
                _loading = loading;
            } 
 
            internal bool Loading
            { 
                get { return _loading; }
            }
        }
 
        // register for idle events here
        ///  
        /// Raised whenever a WorkflowExecutor is constructed.  This signals either a new instance 
        /// or a loading (args) and gives listening components a chance to set up subscriptions.
        ///  
        internal event EventHandler WorkflowExecutorInitializing;
        public event EventHandler WorkflowIdled;
        public event EventHandler WorkflowCreated;
        public event EventHandler WorkflowStarted; 
        public event EventHandler WorkflowLoaded;
        public event EventHandler WorkflowUnloaded; 
        public event EventHandler WorkflowCompleted; 
        public event EventHandler WorkflowTerminated;
        public event EventHandler WorkflowAborted; 
        public event EventHandler WorkflowSuspended;
        public event EventHandler WorkflowPersisted;
        public event EventHandler WorkflowResumed;
        internal event EventHandler WorkflowDynamicallyChanged; 
        public event EventHandler ServicesExceptionNotHandled;
        public event EventHandler Stopped; 
        public event EventHandler Started; 

        internal WorkflowExecutor Load(WorkflowInstance instance) 
        {
            return Load(instance.InstanceId, null, instance);
        }
 
        internal WorkflowExecutor Load(Guid key, CreationContext context, WorkflowInstance workflowInstance)
        { 
            WorkflowExecutor executor; 
            Dictionary executors = workflowExecutors[key];
 

            lock (executors)
            {
                if (!IsStarted) 
                    throw new InvalidOperationException(ExecutionStringManager.WorkflowRuntimeNotStarted);
 
                if (executors.TryGetValue(key, out executor)) 
                {
                    if (executor.IsInstanceValid) 
                    {
                        return executor;
                    }
                } 

                // If we get here, 'executor' is either null or unusable. 
                // Before grabbing the lock, allocate a resource as we 
                // may need to insert a new resource.
                executor = new WorkflowExecutor(key); 
                if (workflowInstance == null)
                    workflowInstance = new WorkflowInstance(key, this);

                InitializeExecutor(key, context, executor, workflowInstance); 
                try
                { 
                    // If we get here, 'executor' is either null or has not been replaced. 
                    // If it has not been replaced, we know that it is unusable
 
                    WorkflowTrace.Host.TraceInformation("WorkflowRuntime:: replacing unusable executor for key {0} with new one (hc: {1})", key, executor.GetHashCode());
                    executors[key] = executor;
                    RegisterExecutor(context != null && context.IsActivation, executor);
                } 
                catch
                { 
                    WorkflowExecutor currentRes; 
                    if (executors.TryGetValue(key, out currentRes))
                    { 
                        if (Object.Equals(executor, currentRes))
                        {
                            executors.Remove(key);
                        } 
                    }
                    throw; 
                } 
            }
            executor.Registered(context != null && context.IsActivation); 
            return executor;
        }

        // this should be called under scheduler lock 
        // todo assert this condition
        internal void ReplaceWorkflowExecutor(Guid instanceId, WorkflowExecutor oldWorkflowExecutor, WorkflowExecutor newWorkflowExecutor) 
        { 
            Dictionary executors = workflowExecutors[instanceId];
            lock (executors) 
            {
                oldWorkflowExecutor.IsInstanceValid = false;

                WorkflowTrace.Host.TraceInformation("WorkflowRuntime:: replacing old executor for key {0} with new one", instanceId); 
                executors[instanceId] = newWorkflowExecutor;
            } 
        } 

        private Activity InitializeExecutor(Guid instanceId, CreationContext context, WorkflowExecutor executor, WorkflowInstance workflowInstance) 
        {
            Activity rootActivity = null;
            if (context != null && context.IsActivation)
            { 
                Activity workflowDefinition = null;
                string xomlText = null; 
                string rulesText = null; 

                if (context.Type != null) 
                {
                    workflowDefinition = _workflowDefinitionDispenser.GetRootActivity(context.Type, false, true);
                    //spawn a new instance
                    rootActivity = _workflowDefinitionDispenser.GetRootActivity(context.Type, true, false); 
                }
                else if (context.XomlReader != null) 
                { 
                    try
                    { 
                        context.XomlReader.MoveToContent();
                        while (!context.XomlReader.EOF && !context.XomlReader.IsStartElement())
                            context.XomlReader.Read();
 
                        xomlText = context.XomlReader.ReadOuterXml();
 
                        if (context.RulesReader != null) 
                        {
                            context.RulesReader.MoveToContent(); 
                            while (!context.RulesReader.EOF && !context.RulesReader.IsStartElement())
                                context.RulesReader.Read();

                            rulesText = context.RulesReader.ReadOuterXml(); 
                        }
                    } 
                    catch (Exception e) 
                    {
                        throw new ArgumentException(ExecutionStringManager.InvalidXAML, e); 
                    }

                    if (!string.IsNullOrEmpty(xomlText))
                    { 
                        workflowDefinition = _workflowDefinitionDispenser.GetRootActivity(xomlText, rulesText, false, true);
                        //spawn a new instance 
                        rootActivity = _workflowDefinitionDispenser.GetRootActivity(xomlText, rulesText, true, false); 
                    }
                    else 
                        throw new ArgumentException(ExecutionStringManager.InvalidXAML);
                }
                rootActivity.SetValue(Activity.WorkflowDefinitionProperty, workflowDefinition);
 
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "Creating instance " + instanceId.ToString());
 
                context.Created = true; 
                executor.Initialize(rootActivity, context.InvokerExecutor, context.InvokeActivityID, instanceId, context.Args, workflowInstance);
            } 
            else
            {
                if (this.WorkflowPersistenceService == null)
                { 
                    string errMsg = String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.MissingPersistenceService, instanceId);
                    WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, errMsg); 
                    throw new InvalidOperationException(errMsg); 
                }
 
                // get the state from the persistenceService
                using (RuntimeEnvironment runtimeEnv = new RuntimeEnvironment(this))
                {
                    rootActivity = this.WorkflowPersistenceService.LoadWorkflowInstanceState(instanceId); 
                }
                if (rootActivity == null) 
                { 
                    throw new InvalidOperationException(string.Format(Thread.CurrentThread.CurrentCulture, ExecutionStringManager.InstanceNotFound, instanceId));
                } 
                executor.Reload(rootActivity, workflowInstance);
            }
            return rootActivity;
        } 

        private void RegisterExecutor(bool isActivation, WorkflowExecutor executor) 
        { 
            if (isActivation)
            { 
                executor.RegisterWithRuntime(this);
            }
            else
            { 
                executor.ReRegisterWithRuntime(this);
            } 
        } 

        ///  
        /// On receipt of this call unload the instance
        /// This will be invoked by the runtime executor
        /// 
        ///  
        internal void OnIdle(WorkflowExecutor executor)
        { 
            // raise the OnIdle event , typically handled 
            // by the hosting environment
            try 
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "Received OnIdle Event for instance, {0}", executor.InstanceId);
                WorkflowInstance scheduleInstance = executor.WorkflowInstance;
                if (WorkflowIdled != null) 
                {
                    WorkflowIdled(this, new WorkflowEventArgs(scheduleInstance)); 
                } 
            }
            catch (Exception) 
            {
                //
                WorkflowTrace.Host.TraceEvent(TraceEventType.Warning, 0, "OnIdle Event for instance, {0} threw an exception", executor.InstanceId);
                throw; 
            }
        } 
 
        private void _unRegister(WorkflowExecutor executor)
        { 
            TryRemoveWorkflowExecutor(executor.InstanceId,executor);
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime::_removeInstance, instance:{0}, hc:{1}", executor.InstanceId, executor.GetHashCode());

            // be sure to flush all traces 
            WorkflowTrace.Runtime.Flush();
            WorkflowTrace.Tracking.Flush(); 
            WorkflowTrace.Host.Flush(); 
        }
 
        private WorkflowExecutor GetWorkflowExecutor(Guid instanceId, CreationContext context)
        {
            try
            { 
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime dispensing resource, instanceId: {0}", instanceId);
 
                WorkflowExecutor executor = this.Load(instanceId, context, null); 
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime dispensing resource instanceId: {0}, hc: {1}", instanceId, executor.GetHashCode());
                return executor; 
            }
            catch (OutOfMemoryException)
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime dispensing resource, can't create service due to OOM!(1), instance, {0}", instanceId); 
                throw;
            } 
            catch (Exception e) 
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime dispensing resource, can't create service due to unexpected exception!(2), instance, {0}, exception, {1}", instanceId, e); 
                throw;
            }
        }
 
        #endregion
 
        #region Workflow event handlers 

        internal void OnScheduleCompleted(WorkflowExecutor schedule, WorkflowCompletedEventArgs args) 
        {
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleCompleted event raised for instance Id {0}", schedule.InstanceId);

            Debug.Assert(schedule != null); 
            try
            { 
                //Notify Subscribers 
                if (WorkflowCompleted != null) WorkflowCompleted(this, args);
            } 
            catch (Exception)
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime:OnScheduleCompleted Event threw an exception.");
                throw; 
            }
            finally 
            { 
                _unRegister(schedule);
            } 
        }

        internal void OnScheduleSuspended(WorkflowExecutor schedule, WorkflowSuspendedEventArgs args)
        { 
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleSuspension event raised for instance Id {0}", schedule.InstanceId);
 
            try 
            {
                if (WorkflowSuspended != null) WorkflowSuspended(this, args); 
            }
            catch (Exception)
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime:OnScheduleSuspended Event threw an exception."); 
                throw;
            } 
        } 

        internal void OnScheduleTerminated(WorkflowExecutor schedule, WorkflowTerminatedEventArgs args) 
        {
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleTermination event raised for instance Id {0}", schedule.InstanceId);

            try 
            {
                if (WorkflowTerminated != null) WorkflowTerminated(this, args); 
            } 
            catch (Exception)
            { 
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime:OnScheduleTerminated Event threw an exception.");
                throw;
            }
            finally 
            {
                _unRegister(schedule); 
            } 
        }
 
        internal void OnScheduleLoaded(WorkflowExecutor schedule)
        {
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleLoaded event raised for instance Id {0}", schedule.InstanceId);
 
            _OnServiceEvent(schedule, false, WorkflowLoaded);
        } 
 
        internal void OnScheduleAborted(WorkflowExecutor schedule)
        { 
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleAborted event raised for instance Id {0}", schedule.InstanceId);
            _OnServiceEvent(schedule, true, WorkflowAborted);
        }
 
        internal void OnScheduleUnloaded(WorkflowExecutor schedule)
        { 
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleUnloaded event raised for instance Id {0}", schedule.InstanceId); 

            _OnServiceEvent(schedule, true, WorkflowUnloaded); 
        }

        internal void OnScheduleResumed(WorkflowExecutor schedule)
        { 
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleResumed event raised for instance Id {0}", schedule.InstanceId);
            _OnServiceEvent(schedule, false, WorkflowResumed); 
        } 

        internal void OnScheduleDynamicallyChanged(WorkflowExecutor schedule) 
        {
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleDynamicallyChanged event raised for instance Id {0}", schedule.InstanceId);
            _OnServiceEvent(schedule, false, WorkflowDynamicallyChanged);
        } 

        internal void OnSchedulePersisted(WorkflowExecutor schedule) 
        { 
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:SchedulePersisted event raised for instance Id {0}", schedule.InstanceId);
 
            _OnServiceEvent(schedule, false, WorkflowPersisted);
        }

        private void _OnServiceEvent(WorkflowExecutor sched, bool unregister, EventHandler handler) 
        {
            Debug.Assert(sched != null); 
            try 
            {
                WorkflowEventArgs args = new WorkflowEventArgs(sched.WorkflowInstance); 
                //Notify Subscribers
                if (handler != null) handler(this, args);
            }
            catch (Exception) 
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime:OnService Event threw an exception."); 
                throw; 
            }
            finally 
            {
                if (unregister)
                {
                    _unRegister(sched); 
                }
            } 
        } 

        internal void RaiseServicesExceptionNotHandledEvent(Exception exception, Guid instanceId) 
        {
            VerifyInternalState();
            WorkflowTrace.Host.TraceEvent(TraceEventType.Critical, 0, "WorkflowRuntime:ServicesExceptionNotHandled event raised for instance Id {0} " + exception.ToString(), instanceId);
            EventHandler handler = ServicesExceptionNotHandled; 
            if (handler != null)
                handler(this, new ServicesExceptionNotHandledEventArgs(exception, instanceId)); 
        } 

        #endregion 

        #region More service accessors

        private Dictionary> _services = new Dictionary>(); 
        private string _name;
        private bool _startedServices; 
        private NameValueConfigurationCollection _configurationParameters; 
        private Dictionary _trackingServiceReplacement;
 

        ///  The name of this container. 
        public string Name
        { 
            get
            { 
                return _name; 
            }
            set 
            {
                lock (_startStopLock)
                {
                    if (_startedServices) 
                        throw new InvalidOperationException(ExecutionStringManager.CantChangeNameAfterStart);
                    VerifyInternalState(); 
                    _name = value; 
                }
            } 
        }

        /// 
        /// Returns the configuration parameters that can be shared by all services 
        /// 
        internal NameValueConfigurationCollection CommonParameters 
        { 
            get
            { 
                return _configurationParameters;
            }
        }
 
        // A previous tracking service whose type has the string as its AssemblyQualifiedName
        // will be replaced by the current tracking service of the Type. This dictionary is 
        // neede in order to replace the previous tracking service used by a persisted workflow 
        // because what is persisted is the one-way hashed string of that AssemblyQualifiedName.
        internal Dictionary TrackingServiceReplacement 
        {
            get
            {
                return _trackingServiceReplacement; 
            }
        } 
 

        ///  Adds a service to this container.  
        ///  The service to add 
        /// 
        public void AddService(object service)
        { 
            if (service == null)
                throw new ArgumentNullException("service"); 
            VerifyInternalState(); 

            using (new WorkflowRuntime.EventContext()) 
            {
                lock (_startStopLock)
                {
                    AddServiceImpl(service); 
                }
            } 
        } 

        private void AddServiceImpl(object service) 
        {
            //ASSERT: _startStopLock is held

            lock (_servicesLock) 
            {
                if (GetAllServices(service.GetType()).Contains(service)) 
                    throw new InvalidOperationException(ExecutionStringManager.CantAddServiceTwice); 

                if (_startedServices && IsCoreService(service)) 
                    throw new InvalidOperationException(ExecutionStringManager.CantChangeImmutableContainer);

                Type basetype = service.GetType();
                if (basetype.IsSubclassOf(typeof(TrackingService))) 
                {
                    AddTrackingServiceReplacementInfo(basetype); 
                } 

 
                foreach (Type t in basetype.GetInterfaces())
                {
                    List al;
                    if (_services.ContainsKey(t)) 
                    {
                        al = _services[t]; 
                    } 
                    else
                    { 
                        al = new List();
                        _services.Add(t, al);
                    }
                    al.Add(service); 
                }
 
                while (basetype != null) 
                {
                    List al = null; 
                    if (_services.ContainsKey(basetype))
                    {
                        al = _services[basetype];
                    } 
                    else
                    { 
                        al = new List(); 
                        _services.Add(basetype, al);
                    } 
                    al.Add(service);
                    basetype = basetype.BaseType;
                }
            } 

            WorkflowRuntimeService wrs = service as WorkflowRuntimeService; 
            if (wrs != null) 
            {
                wrs.SetRuntime(this); 
                if (_startedServices)
                    wrs.Start();
            }
        } 

 
        ///  Removes a service.  
        ///  The service to remove 
        public void RemoveService(object service) 
        {
            if (service == null)
                throw new ArgumentNullException("service");
            VerifyInternalState(); 

            using (new WorkflowRuntime.EventContext()) 
            { 
                lock (_startStopLock)
                { 
                    lock (_servicesLock)
                    {
                        if (_startedServices && IsCoreService(service))
                            throw new InvalidOperationException(ExecutionStringManager.CantChangeImmutableContainer); 

                        if (!GetAllServices(service.GetType()).Contains(service)) 
                            throw new InvalidOperationException(ExecutionStringManager.CantRemoveServiceNotContained); 

                        Type type = service.GetType(); 
                        if (type.IsSubclassOf(typeof(TrackingService)))
                        {
                            RemoveTrackingServiceReplacementInfo(type);
                        } 

                        foreach (List al in _services.Values) 
                        { 
                            if (al.Contains(service))
                            { 
                                al.Remove(service);
                            }
                        }
                    } 
                    WorkflowRuntimeService wrs = service as WorkflowRuntimeService;
                    if (wrs != null) 
                    { 
                        if (_startedServices)
                            wrs.Stop(); 

                        wrs.SetRuntime(null);
                    }
                } 
            }
        } 
 
        private void AddTrackingServiceReplacementInfo(Type type)
        { 
            Debug.Assert(type.IsSubclassOf(typeof(TrackingService)), "Argument should be a subtype of TrackingService");
            object[] attributes = type.GetCustomAttributes(typeof(PreviousTrackingServiceAttribute), true);
            if (attributes != null && attributes.Length > 0)
            { 
                foreach (object attribute in attributes)
                { 
                    if (_trackingServiceReplacement == null) 
                    {
                        _trackingServiceReplacement = new Dictionary(); 
                    }
                    _trackingServiceReplacement.Add(((PreviousTrackingServiceAttribute)attribute).AssemblyQualifiedName, type);
                }
            } 
        }
 
        private void RemoveTrackingServiceReplacementInfo(Type type) 
        {
            Debug.Assert(type.IsSubclassOf(typeof(TrackingService)), "Argument should be a subtype of TrackingService"); 
            object[] attributes = type.GetCustomAttributes(typeof(PreviousTrackingServiceAttribute), true);
            if (attributes != null && attributes.Length > 0)
            {
                foreach (object attribute in attributes) 
                {
                    string previousTrackingService = ((PreviousTrackingServiceAttribute)attribute).AssemblyQualifiedName; 
                    if (_trackingServiceReplacement.ContainsKey(previousTrackingService)) 
                    {
                        _trackingServiceReplacement.Remove(previousTrackingService); 
                    }
                }
            }
        } 

        private bool IsCoreService(object service) 
        { 
            return service is WorkflowSchedulerService
                || service is WorkflowPersistenceService 
                || service is TrackingService
                || service is WorkflowCommitWorkBatchService
                || service is WorkflowLoaderService;
        } 

 
        ///  Returns a collection of all services that implement the give type.  
        ///  The type to look for 
        ///  A collection of zero or more services  
        public ReadOnlyCollection GetAllServices(Type serviceType)
        {
            if (serviceType == null)
                throw new ArgumentNullException("serviceType"); 
            VerifyInternalState();
 
            lock(_servicesLock) 
            {
                List retval = new List(); 
                if (_services.ContainsKey(serviceType))
                    retval.AddRange(_services[serviceType]);

                return new ReadOnlyCollection(retval); 
            }
        } 
 

        public T GetService() 
        {
            VerifyInternalState();
            return (T)GetService(typeof(T));
        } 

        public ReadOnlyCollection GetAllServices() 
        { 
            VerifyInternalState();
            List l = new List(); 
            foreach(T t in GetAllServices(typeof(T)))
                l.Add(t);
            return new ReadOnlyCollection(l);
        } 

        ///  Looks for a service of the given type.  
        ///  The type of object to find  
        ///  An object of the requested type, or null
        public object GetService(Type serviceType) 
        {
            if (serviceType == null)
                throw new ArgumentNullException("serviceType");
            VerifyInternalState(); 

            lock(_servicesLock) 
            { 
                object retval = null;
 
                if (_services.ContainsKey(serviceType))
                {
                    List al = _services[serviceType];
 
                    if (al.Count > 1)
                        throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, 
                            ExecutionStringManager.MoreThanOneService, serviceType.ToString())); 

                    if (al.Count == 1) 
                        retval = al[0];
                }

                return retval; 
            }
        } 
 
        #endregion
 
        #region Other methods


        ///  Raises the Starting event  
        /// 
        ///  
        public void StartRuntime() 
        {
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Starting WorkflowRuntime {0}", _uid); 
            lock (_startStopLock)
            {
                VerifyInternalState();
 
                if (!_startedServices)
                { 
 
                    if (GetAllServices(typeof(WorkflowCommitWorkBatchService)).Count == 0)
                        AddServiceImpl(new DefaultWorkflowCommitWorkBatchService()); 

                    if (GetAllServices(typeof(WorkflowSchedulerService)).Count == 0)
                        AddServiceImpl(new DefaultWorkflowSchedulerService());
 
                    if (GetAllServices(typeof(WorkflowLoaderService)).Count == 0)
                        AddServiceImpl(new DefaultWorkflowLoaderService()); 
 
                    if (GetAllServices(typeof(WorkflowCommitWorkBatchService)).Count != 1)
                        throw new InvalidOperationException(String.Format( 
                        CultureInfo.CurrentCulture,
                        ExecutionStringManager.InvalidWorkflowRuntimeConfiguration,
                        typeof(WorkflowCommitWorkBatchService).Name));
 
                    if (GetAllServices(typeof(WorkflowSchedulerService)).Count != 1)
                        throw new InvalidOperationException(String.Format( 
                        CultureInfo.CurrentCulture, ExecutionStringManager.InvalidWorkflowRuntimeConfiguration, 
                        typeof(WorkflowSchedulerService).Name));
 
                    if (GetAllServices(typeof(WorkflowLoaderService)).Count != 1)
                        throw new InvalidOperationException(String.Format(
                        CultureInfo.CurrentCulture, ExecutionStringManager.InvalidWorkflowRuntimeConfiguration,
                        typeof(WorkflowLoaderService).Name)); 

                    if (GetAllServices(typeof(WorkflowPersistenceService)).Count > 1) 
                        throw new InvalidOperationException(String.Format( 
                        CultureInfo.CurrentCulture, ExecutionStringManager.InvalidWorkflowRuntimeConfiguration,
                        typeof(WorkflowPersistenceService).Name)); 

                    if (GetAllServices(typeof(WorkflowTimerService)).Count == 0)
                    {
                        AddServiceImpl(new WorkflowTimerService()); 
                    }
 
                    //Mark this instance has started 
                    isInstanceStarted = true;
 
                    //Set up static tracking structures
                    _trackingFactory.Initialize(this);
                    if (this.PerformanceCounterManager != null)
                    { 
                        this.PerformanceCounterManager.Initialize(this);
                        this.PerformanceCounterManager.SetInstanceName(this.Name); 
                    } 

                    foreach (WorkflowRuntimeService s in GetAllServices()) 
                    {
                        s.Start();
                    }
 
                    _startedServices = true;
                    using (new WorkflowRuntime.EventContext()) 
                    { 
                        EventHandler ss = Started;
                        if (ss != null) 
                            ss(this, new WorkflowRuntimeEventArgs(isInstanceStarted));
                    }
                }
            } 
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Started WorkflowRuntime {0}", _uid);
        } 
 
        void DynamicUpdateCommit( object sender, WorkflowExecutor.DynamicUpdateEventArgs e )
        { 
            if ( null == sender )
                throw new ArgumentNullException( "sender" );

            if ( !typeof( WorkflowExecutor ).IsInstanceOfType( sender ) ) 
                throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidArgumentType, "sender", typeof(WorkflowExecutor).ToString()));
 
            WorkflowExecutor exec = ( WorkflowExecutor ) sender; 

            OnScheduleDynamicallyChanged( exec ); 
        }

        internal void WorkflowExecutorCreated( WorkflowExecutor workflowExecutor, bool loaded )
        { 
            //
            // Fire the event for all other components that need to register for notification of WorkflowExecutor events 
            EventHandler localEvent = WorkflowExecutorInitializing; 
            if (null != localEvent)
                localEvent(workflowExecutor, new WorkflowExecutorInitializingEventArgs(loaded)); 

            workflowExecutor.WorkflowExecutionEvent += new EventHandler(WorkflowExecutionEvent);
        }
 
        void WorkflowExecutionEvent( object sender, WorkflowExecutor.WorkflowExecutionEventArgs e )
        { 
            if ( null == sender ) 
                throw new ArgumentNullException( "sender" );
 
            if ( !typeof( WorkflowExecutor ).IsInstanceOfType( sender ) )
                throw new ArgumentException( "sender" );

            WorkflowExecutor exec = ( WorkflowExecutor ) sender; 

            switch ( e.EventType ) 
            { 
                case WorkflowEventInternal.Idle:
                    OnIdle( exec ); 
                    break;
                case WorkflowEventInternal.Created:
                    if ( WorkflowCreated != null )
                        WorkflowCreated( this, new WorkflowEventArgs( exec.WorkflowInstance ) ); 
                    break;
                case WorkflowEventInternal.Started: 
                    if (WorkflowStarted != null) 
                        WorkflowStarted(this, new WorkflowEventArgs(exec.WorkflowInstance));
                    break; 
                case WorkflowEventInternal.Loaded:
                    OnScheduleLoaded( exec );
                    break;
                case WorkflowEventInternal.Unloaded: 
                    OnScheduleUnloaded( exec );
                    break; 
                case WorkflowEventInternal.Completed: 
                    OnScheduleCompleted( exec, CreateCompletedEventArgs( exec ) );
                    break; 
                case WorkflowEventInternal.Terminated:
                    WorkflowExecutor.WorkflowExecutionTerminatedEventArgs args = ( WorkflowExecutor.WorkflowExecutionTerminatedEventArgs ) e;

                    if (null != args.Exception) 
                        OnScheduleTerminated(exec, new WorkflowTerminatedEventArgs(exec.WorkflowInstance, args.Exception));
                    else 
                        OnScheduleTerminated(exec, new WorkflowTerminatedEventArgs(exec.WorkflowInstance, args.Error)); 

                    break; 
                case WorkflowEventInternal.Aborted:
                    OnScheduleAborted( exec );
                    break;
                case WorkflowEventInternal.Suspended: 
                    WorkflowExecutor.WorkflowExecutionSuspendedEventArgs sargs = ( WorkflowExecutor.WorkflowExecutionSuspendedEventArgs ) e;
                    OnScheduleSuspended( exec, new WorkflowSuspendedEventArgs( exec.WorkflowInstance, sargs.Error ) ); 
                    break; 
                case WorkflowEventInternal.Persisted:
                    OnSchedulePersisted( exec ); 
                    break;
                case WorkflowEventInternal.Resumed:
                    OnScheduleResumed( exec );
                    break; 
                case WorkflowEventInternal.DynamicChangeCommit:
                    DynamicUpdateCommit( exec, ( WorkflowExecutor.DynamicUpdateEventArgs ) e ); 
                    break; 
                default:
                    break; 
            }
        }

        private WorkflowCompletedEventArgs CreateCompletedEventArgs( WorkflowExecutor exec ) 
        {
            WorkflowCompletedEventArgs args = new WorkflowCompletedEventArgs(exec.WorkflowInstance, exec.WorkflowDefinition); 
            foreach (PropertyInfo property in _workflowDefinitionDispenser.GetOutputParameters(exec.RootActivity)) 
                args.OutputParameters.Add(property.Name, property.GetValue(exec.RootActivity, null));
 
            return args;
        }

        private void StopServices() 
        {
            // Stop remaining services 
            foreach (WorkflowRuntimeService s in GetAllServices()) 
            {
                s.Stop(); 
            }
        }

        ///  Fires the Stopping event  
        public void StopRuntime()
        { 
            VerifyInternalState(); 

            using (new WorkflowRuntime.EventContext()) 
            {
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Stopping WorkflowRuntime {0}", _uid);
                lock (_startStopLock)
                { 
                    if (_startedServices)
                    { 
                        try 
                        {
                            isInstanceStarted = false; 

                            if (this.WorkflowPersistenceService != null)
                            {
                                // 
                                // GetWorkflowExecutors() takes a lock on workflowExecutors
                                // and then returns a copy of the list.  As long as GetWorkflowExecutors() 
                                // returns a non empty/null list we'll attempt to unload what's in it. 
                                IList executors = GetWorkflowExecutors();
                                while ((null != executors) && (executors.Count > 0)) 
                                {
                                    foreach (WorkflowExecutor executor in executors)
                                    {
                                        if (executor.IsInstanceValid) 
                                        {
                                            try 
                                            { 
                                                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Calling Unload on instance {0} executor hc {1}", executor.InstanceIdString, executor.GetHashCode());
                                                executor.Unload(); 
                                            }
                                            catch (ExecutorLocksHeldException)
                                            {
                                                // 
                                                // This exception means that an atomic scope is ongoing
                                                // (we cannot unload/suspend during an atomic scope) 
                                                // This instance will still be in the GetWorkflowExecutors list 
                                                // so we'll attempt to unload it on the next outer loop
                                                // Yes, we may loop indefinitely if an atomic tx is hung 
                                                // See WorkflowInstance.Unload for an example of retrying
                                                // when this exception is thrown.
                                            }
                                            catch (InvalidOperationException) 
                                            {
                                                if (executor.IsInstanceValid) 
                                                { 
                                                    //
                                                    // Failed to stop, reset the flag 
                                                    isInstanceStarted = true;
                                                    throw;
                                                }
                                            } 
                                            catch
                                            { 
                                                // 
                                                // Failed to stop, reset the flag
                                                isInstanceStarted = true; 
                                                throw;
                                            }
                                        }
                                    } 
                                    //
                                    // Check if anything was added to the main list 
                                    // while we were working on the copy. 
                                    // This happens if a executor reverts to a checkpoint.
                                    // There is the potential to loop indefinitely if 
                                    // an instance continually reverts.
                                    executors = GetWorkflowExecutors();
                                }
                            } 

                            StopServices(); 
                            _startedServices = false; 

 
                            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Stopped WorkflowRuntime {0}", _uid);

                            //
                            // Clean up tracking 
                            _trackingFactory.Uninitialize(this);
                            if (this.PerformanceCounterManager != null) 
                            { 
                                this.PerformanceCounterManager.Uninitialize(this);
                            } 

                            EventHandler handler = Stopped;
                            if (handler != null)
                                handler(this, new WorkflowRuntimeEventArgs(isInstanceStarted)); 
                        }
                        catch (Exception) 
                        { 
                            WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime::StartUnload Unexpected Exception");
                            throw; 
                        }
                        finally
                        {
                            isInstanceStarted = false; 
                        }
                    } 
                } 
            }
        } 

        ///  True if services have been started and not stopped 
        public bool IsStarted
        { 
            get
            { 
                return _startedServices; 
            }
        } 


        private static Activity OnActivityDefinitionResolve(object sender, ActivityResolveEventArgs e)
        { 
            WorkflowRuntime runtime = e.ServiceProvider as WorkflowRuntime;
            if (runtime == null) 
                runtime = RuntimeEnvironment.CurrentRuntime; 

            Debug.Assert(runtime != null); 
            if (runtime != null)
            {
                if (e.Type != null)
                    return runtime._workflowDefinitionDispenser.GetRootActivity(e.Type, e.CreateNewDefinition, e.InitializeForRuntime); 
                else
                    return runtime._workflowDefinitionDispenser.GetRootActivity(e.WorkflowMarkup, e.RulesMarkup, e.CreateNewDefinition, e.InitializeForRuntime); 
            } 
            return null;
        } 

        internal static TypeProvider CreateTypeProvider(Activity rootActivity)
        {
            TypeProvider typeProvider = new TypeProvider(null); 

            Type companionType = rootActivity.GetType(); 
            typeProvider.SetLocalAssembly(companionType.Assembly); 
            typeProvider.AddAssembly(companionType.Assembly);
 
            foreach (AssemblyName assemblyName in companionType.Assembly.GetReferencedAssemblies())
            {
                Assembly referencedAssembly = null;
                try 
                {
                    referencedAssembly = Assembly.Load(assemblyName); 
                    if (referencedAssembly != null) 
                        typeProvider.AddAssembly(referencedAssembly);
                } 
                catch
                {
                }
 
                if (referencedAssembly == null && assemblyName.CodeBase != null)
                    typeProvider.AddAssemblyReference(assemblyName.CodeBase); 
            } 

            return typeProvider; 
        }

        private static ArrayList OnWorkflowChangeActionsResolve(object sender, WorkflowChangeActionsResolveEventArgs e)
        { 
            ArrayList changes = null;
            WorkflowRuntime runtime = RuntimeEnvironment.CurrentRuntime; 
            Debug.Assert(runtime != null); 
            if (runtime != null)
            { 
                WorkflowMarkupSerializer serializer = new WorkflowMarkupSerializer();
                ServiceContainer serviceContainer = new ServiceContainer();
                ITypeProvider typeProvider = runtime.GetService();
                if (typeProvider != null) 
                    serviceContainer.AddService(typeof(ITypeProvider), typeProvider);
                else if (sender is Activity) 
                { 
                    serviceContainer.AddService(typeof(ITypeProvider), CreateTypeProvider(sender as Activity));
                } 

                DesignerSerializationManager manager = new DesignerSerializationManager(serviceContainer);
                using (manager.CreateSession())
                { 
                    using (StringReader reader = new StringReader(e.WorkflowChangesMarkup))
                    { 
                        using (XmlReader xmlReader = XmlReader.Create(reader)) 
                        {
                            WorkflowMarkupSerializationManager xomlSerializationManager = new WorkflowMarkupSerializationManager(manager); 
                            changes = serializer.Deserialize(xomlSerializationManager, xmlReader) as ArrayList;
                        }
                    }
                } 
            }
 
            return changes; 
        }
 
        ///  Creates and adds a service to this container. 
        ///  Description of the service to add. 
        private void AddServiceFromSettings(WorkflowRuntimeServiceElement serviceSettings)
        { 
            object service = null;
 
            Type t = Type.GetType(serviceSettings.Type, true); 

            ConstructorInfo serviceProviderAndSettingsConstructor = null; 
            ConstructorInfo serviceProviderConstructor = null;
            ConstructorInfo settingsConstructor = null;

            foreach (ConstructorInfo ci in t.GetConstructors()) 
            {
                ParameterInfo[] pi = ci.GetParameters(); 
                if (pi.Length == 1) 
                {
                    if (typeof(IServiceProvider).IsAssignableFrom(pi[0].ParameterType)) 
                    {
                        serviceProviderConstructor = ci;
                    }
                    else if (typeof(NameValueCollection).IsAssignableFrom(pi[0].ParameterType)) 
                    {
                        settingsConstructor = ci; 
                    } 
                }
                else if (pi.Length == 2) 
                {
                    if (typeof(IServiceProvider).IsAssignableFrom(pi[0].ParameterType)
                        && typeof(NameValueCollection).IsAssignableFrom(pi[1].ParameterType))
                    { 
                        serviceProviderAndSettingsConstructor = ci;
                        break; 
                    } 
                }
            } 

            if (serviceProviderAndSettingsConstructor != null)
            {
                service = serviceProviderAndSettingsConstructor.Invoke( 
                    new object[] { this, serviceSettings.Parameters });
            } 
            else if (serviceProviderConstructor != null) 
            {
                service = serviceProviderConstructor.Invoke(new object[] { this }); 
            }
            else if (settingsConstructor != null)
            {
                service = settingsConstructor.Invoke(new object[] { serviceSettings.Parameters }); 
            }
            else 
            { 
                service = Activator.CreateInstance(t);
            } 

            AddServiceImpl(service);
        }
 
        internal static void ClearTrackingProfileCache()
        { 
            lock (_runtimesLock) 
            {
                foreach (WeakReference wr in _runtimes.Values) 
                {
                    WorkflowRuntime runtime = wr.Target as WorkflowRuntime;
                    if (null != runtime)
                    { 
                        if ( ( null != runtime.TrackingListenerFactory ) && ( null != runtime.TrackingListenerFactory.TrackingProfileManager ) )
                            runtime.TrackingListenerFactory.TrackingProfileManager.ClearCacheImpl(); 
                    } 
                }
            } 
        }
        /// Utility class that prevents reentrance during event processing.
        /// 
        /// When created an EventContext it creates a static variable local to 
        /// a managed thread (similar to the old TLS slot),
        /// which can detect cases when events are invoked while handling other events. 
        /// The variable is removed on dispose. 
        /// 
        internal sealed class EventContext : IDisposable 
        {

            /// 
            /// Indicates that the value of a static field is unique for each thread 
            /// CLR Perf suggests using this attribute over the slot approach.
            ///  
            [ThreadStatic()] 
            static object threadData;
 
            public EventContext(params Object[] ignored)
            {
                if (threadData != null)
                    throw new InvalidOperationException(ExecutionStringManager.CannotCauseEventInEvent); 

                threadData = this; 
            } 

            void IDisposable.Dispose() 
            {
                Debug.Assert(threadData != null, "unexpected call to EventContext::Dispose method");
                threadData = null;
            } 
        }
 
        #endregion 

        #region WorkflowExecutor utility methods 
        private IList GetWorkflowExecutors()
        {
            //
            // This is a safety check in to avoid returning invalid executors in the following cases: 
            // 1.  We ---- between the executor going invalid and getting removed from the list.
            // 2.  We have a leak somewhere where invalid executors are not getting removed from the list. 
            List executorsList = new List(); 
            foreach (Dictionary executors in workflowExecutors)
            { 
                lock (executors)
                {
                    foreach (WorkflowExecutor executor in executors.Values)
                    { 
                        if ((null != executor) && (executor.IsInstanceValid))
                            executorsList.Add(executor); 
                    } 
                }
            } 
            return executorsList;
        }

        private bool TryRemoveWorkflowExecutor(Guid instanceId, WorkflowExecutor executor) 
        {
            Dictionary executors = workflowExecutors[instanceId]; 
            lock (executors) 
            {
                WorkflowExecutor currentRes; 
                if (executors.TryGetValue(instanceId, out currentRes) && Object.Equals(executor, currentRes))
                {
                    WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime::TryRemoveWorkflowExecutor, instance:{0}, hc:{1}", executor.InstanceIdString, executor.GetHashCode());
                    return executors.Remove(instanceId); 
                }
 
                return false; 
            }
        } 
        #endregion
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK