Activity.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WF / Common / AuthoringOM / Activity.cs / 1305376 / Activity.cs

                            #pragma warning disable 1634, 1691 

namespace System.Workflow.ComponentModel
{
    #region Imports 

    using System; 
    using System.CodeDom; 
    using System.CodeDom.Compiler;
    using System.Xml; 
    using System.Text;
    using System.IO;
    using System.Reflection;
    using System.Collections; 
    using System.Runtime.Serialization;
    using System.Collections.Generic; 
    using System.ComponentModel; 
    using System.ComponentModel.Design;
    using System.ComponentModel.Design.Serialization; 
    using System.Drawing.Design;
    using System.Workflow.ComponentModel.Design;
    using System.Workflow.ComponentModel.Compiler;
    using System.Resources; 
    using System.Globalization;
    using System.Diagnostics; 
    using System.Collections.Specialized; 
    using System.Collections.ObjectModel;
    using System.Runtime.Serialization.Formatters.Binary; 
    using System.Workflow.ComponentModel.Serialization;

    #endregion
 
    #region Classes ActivityResolveEventArgs and WorkflowChangeActionsResolveEventArgs
 
    internal delegate Activity ActivityResolveEventHandler(object sender, ActivityResolveEventArgs e); 
    internal delegate ArrayList WorkflowChangeActionsResolveEventHandler(object sender, WorkflowChangeActionsResolveEventArgs e);
 
    internal sealed class ActivityResolveEventArgs : EventArgs
    {
        private Type activityType = null;
        private string activityDefinition = null; 
        private string rulesDefinition = null;
        private bool createNew = false; 
        private bool initForRuntime = true; 
        private IServiceProvider serviceProvider = null;
 
        internal ActivityResolveEventArgs(Type activityType, string workflowMarkup, string rulesMarkup, bool createNew, bool initForRuntime, IServiceProvider serviceProvider)
        {
            if (!(string.IsNullOrEmpty(workflowMarkup) ^ activityType == null))
                throw new ArgumentException(SR.GetString(SR.Error_WrongParamForActivityResolveEventArgs)); 

            this.activityType = activityType; 
            this.activityDefinition = workflowMarkup; 
            this.rulesDefinition = rulesMarkup;
            this.createNew = createNew; 
            this.initForRuntime = initForRuntime;
            this.serviceProvider = serviceProvider;
        }
 
        public Type Type
        { 
            get 
            {
                return this.activityType; 
            }
        }
        public string WorkflowMarkup
        { 
            get
            { 
                return this.activityDefinition; 
            }
        } 
        public string RulesMarkup
        {
            get
            { 
                return this.rulesDefinition;
            } 
        } 
        public bool CreateNewDefinition
        { 
            get
            {
                return this.createNew;
            } 
        }
        public bool InitializeForRuntime 
        { 
            get
            { 
                return this.initForRuntime;
            }
        }
        public IServiceProvider ServiceProvider 
        {
            get 
            { 
                return this.serviceProvider;
            } 
        }
    }

    internal sealed class WorkflowChangeActionsResolveEventArgs : EventArgs 
    {
        private string workflowChangesMarkup; 
 
        public WorkflowChangeActionsResolveEventArgs(string workflowChangesMarkup)
        { 
            this.workflowChangesMarkup = workflowChangesMarkup;
        }

        public string WorkflowChangesMarkup 
        {
            get 
            { 
                return this.workflowChangesMarkup;
            } 
        }
    }

    #endregion 

    #region Class Activity 
 

    [ActivityCodeGenerator(typeof(ActivityCodeGenerator))] 
    [ActivityValidator(typeof(ActivityValidator))]
    [System.Drawing.ToolboxBitmap(typeof(Activity), "Design.Resources.Activity.png")]
    [ToolboxItemFilter("Microsoft.Workflow.VSDesigner", ToolboxItemFilterType.Require)]
    [ToolboxItemFilter("System.Workflow.ComponentModel.Design.ActivitySet", ToolboxItemFilterType.Allow)] 
    [DesignerSerializer(typeof(ActivityMarkupSerializer), typeof(WorkflowMarkupSerializer))]
    [DesignerSerializer(typeof(ActivityCodeDomSerializer), typeof(CodeDomSerializer))] 
    [DesignerSerializer(typeof(ActivityTypeCodeDomSerializer), typeof(TypeCodeDomSerializer))] 
    [DesignerCategory("Component")]
    [ActivityExecutor(typeof(ActivityExecutor))] 
    [Designer(typeof(ActivityDesigner), typeof(IDesigner))]
    [Designer(typeof(ActivityDesigner), typeof(IRootDesigner))]
    [ToolboxItem(typeof(ActivityToolboxItem))]
    [RuntimeNameProperty("Name")] 
    public class Activity : DependencyObject
    { 
        private static DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Activity), new PropertyMetadata("", DependencyPropertyOptions.Metadata, new ValidationOptionAttribute(ValidationOption.Required))); 
        private static DependencyProperty DescriptionProperty = DependencyProperty.Register("Description", typeof(string), typeof(Activity), new PropertyMetadata("",DependencyPropertyOptions.Metadata));
        private static DependencyProperty EnabledProperty = DependencyProperty.Register("Enabled", typeof(bool), typeof(Activity), new PropertyMetadata(true,DependencyPropertyOptions.Metadata)); 
        private static DependencyProperty QualifiedNameProperty = DependencyProperty.Register("QualifiedName", typeof(string), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.Metadata | DependencyPropertyOptions.ReadOnly));
        private static DependencyProperty DottedPathProperty = DependencyProperty.Register("DottedPath", typeof(string), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.Metadata | DependencyPropertyOptions.ReadOnly));
        internal static readonly DependencyProperty WorkflowXamlMarkupProperty = DependencyProperty.Register("WorkflowXamlMarkup", typeof(string), typeof(Activity));
        internal static readonly DependencyProperty WorkflowRulesMarkupProperty = DependencyProperty.Register("WorkflowRulesMarkup", typeof(string), typeof(Activity)); 

        internal static readonly DependencyProperty SynchronizationHandlesProperty = DependencyProperty.Register("SynchronizationHandles", typeof(ICollection), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.Metadata)); 
 
        internal static readonly DependencyProperty ActivityExecutionContextInfoProperty = DependencyProperty.RegisterAttached("ActivityExecutionContextInfo", typeof(ActivityExecutionContextInfo), typeof(Activity));
        public static readonly DependencyProperty ActivityContextGuidProperty = DependencyProperty.RegisterAttached("ActivityContextGuid", typeof(Guid), typeof(Activity),new PropertyMetadata(Guid.Empty)); 
        internal static readonly DependencyProperty CompletedExecutionContextsProperty = DependencyProperty.RegisterAttached("CompletedExecutionContexts", typeof(IList), typeof(Activity));
        internal static readonly DependencyProperty ActiveExecutionContextsProperty = DependencyProperty.RegisterAttached("ActiveExecutionContexts", typeof(IList), typeof(Activity));
        internal static readonly DependencyProperty CompletedOrderIdProperty = DependencyProperty.Register("CompletedOrderId", typeof(int), typeof(Activity),new PropertyMetadata(new Int32()));
        private static readonly DependencyProperty SerializedStreamLengthProperty = DependencyProperty.RegisterAttached("SerializedStreamLength", typeof(long), typeof(Activity),new PropertyMetadata(DependencyPropertyOptions.NonSerialized)); 

        // activity runtime state 
        internal static readonly DependencyProperty ExecutionStatusProperty = DependencyProperty.RegisterAttached("ExecutionStatus", typeof(ActivityExecutionStatus), typeof(Activity), new PropertyMetadata(ActivityExecutionStatus.Initialized, new Attribute[] { new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) })); 
        internal static readonly DependencyProperty ExecutionResultProperty = DependencyProperty.RegisterAttached("ExecutionResult", typeof(ActivityExecutionResult), typeof(Activity), new PropertyMetadata(ActivityExecutionResult.None, new Attribute[] { new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) }));
        internal static readonly DependencyProperty WasExecutingProperty = DependencyProperty.RegisterAttached("WasExecuting", typeof(bool), typeof(Activity), new PropertyMetadata(false, new Attribute[] { new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) })); 

        // lock count on status change property
        private static readonly DependencyProperty LockCountOnStatusChangeProperty = DependencyProperty.RegisterAttached("LockCountOnStatusChange", typeof(int), typeof(Activity), new PropertyMetadata(new Int32()));
        internal static readonly DependencyProperty HasPrimaryClosedProperty = DependencyProperty.RegisterAttached("HasPrimaryClosed", typeof(bool), typeof(Activity), new PropertyMetadata(false)); 

        // nested activity collection used at serialization time 
        private static readonly DependencyProperty NestedActivitiesProperty = DependencyProperty.RegisterAttached("NestedActivities", typeof(IList), typeof(Activity)); 

        // Workflow Definition property, should only be visible to runtime 
        internal static readonly DependencyProperty WorkflowDefinitionProperty = DependencyProperty.RegisterAttached("WorkflowDefinition", typeof(Activity), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.NonSerialized));

        // Workflow Runtime property, should only be visible to runtime
        internal static readonly DependencyProperty WorkflowRuntimeProperty = DependencyProperty.RegisterAttached("WorkflowRuntime", typeof(IServiceProvider), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.NonSerialized)); 

        [ThreadStatic] 
        internal static Hashtable ContextIdToActivityMap = null; 
        [ThreadStatic]
        internal static Activity DefinitionActivity = null; 
        [ThreadStatic]
        internal static ArrayList ActivityRoots = null;

        private static readonly BinaryFormatter binaryFormatter = null; 
        private static ActivityResolveEventHandler activityDefinitionResolve = null;
        private static WorkflowChangeActionsResolveEventHandler workflowChangeActionsResolve = null; 
 
        [NonSerialized]
        private string cachedDottedPath = null; 

 		[NonSerialized]
		private IWorkflowCoreRuntime workflowCoreRuntime = null;
 
        [NonSerialized]
        internal CompositeActivity parent = null; 
 
        private static object staticSyncRoot = new object();
 
        internal static readonly DependencyProperty CustomActivityProperty = DependencyProperty.Register("CustomActivity", typeof(bool), typeof(Activity), new PropertyMetadata(DependencyPropertyOptions.Metadata));
        internal static Type ActivityType = null;

        static Activity() 
        {
            binaryFormatter = new BinaryFormatter(); 
            binaryFormatter.SurrogateSelector = ActivitySurrogateSelector.Default; 

            // register known properties 
            DependencyProperty.RegisterAsKnown(ActivityExecutionContextInfoProperty, (byte)1, DependencyProperty.PropertyValidity.Reexecute);
            DependencyProperty.RegisterAsKnown(CompletedExecutionContextsProperty, (byte)2, DependencyProperty.PropertyValidity.Reexecute);
            DependencyProperty.RegisterAsKnown(ActiveExecutionContextsProperty, (byte)3, DependencyProperty.PropertyValidity.Uninitialize);
            DependencyProperty.RegisterAsKnown(CompletedOrderIdProperty, (byte)4, DependencyProperty.PropertyValidity.Uninitialize); 
            DependencyProperty.RegisterAsKnown(ExecutionStatusProperty, (byte)5, DependencyProperty.PropertyValidity.Reexecute);
            DependencyProperty.RegisterAsKnown(ExecutionResultProperty, (byte)6, DependencyProperty.PropertyValidity.Reexecute); 
            DependencyProperty.RegisterAsKnown(WasExecutingProperty, (byte)7, DependencyProperty.PropertyValidity.Uninitialize); 
            DependencyProperty.RegisterAsKnown(LockCountOnStatusChangeProperty, (byte)8, DependencyProperty.PropertyValidity.Uninitialize);
            DependencyProperty.RegisterAsKnown(HasPrimaryClosedProperty, (byte)9, DependencyProperty.PropertyValidity.Uninitialize); 
            DependencyProperty.RegisterAsKnown(NestedActivitiesProperty, (byte)10, DependencyProperty.PropertyValidity.Uninitialize);
            DependencyProperty.RegisterAsKnown(ActivityContextGuidProperty, (byte)11, DependencyProperty.PropertyValidity.Reexecute);
            DependencyProperty.RegisterAsKnown(WorkflowXamlMarkupProperty, (byte)12, DependencyProperty.PropertyValidity.Uninitialize);
            DependencyProperty.RegisterAsKnown(WorkflowRulesMarkupProperty, (byte)13, DependencyProperty.PropertyValidity.Uninitialize); 

            // other classes 
            DependencyProperty.RegisterAsKnown(ActivityExecutionContext.CurrentExceptionProperty, (byte)23, DependencyProperty.PropertyValidity.Reexecute); 
            DependencyProperty.RegisterAsKnown(ActivityExecutionContext.GrantedLocksProperty, (byte)24, DependencyProperty.PropertyValidity.Uninitialize);
            DependencyProperty.RegisterAsKnown(ActivityExecutionContext.LockAcquiredCallbackProperty, (byte)25, DependencyProperty.PropertyValidity.Uninitialize); 


            // events
            DependencyProperty.RegisterAsKnown(ExecutingEvent, (byte)31, DependencyProperty.PropertyValidity.Uninitialize); 
            DependencyProperty.RegisterAsKnown(CancelingEvent, (byte)32, DependencyProperty.PropertyValidity.Uninitialize);
            DependencyProperty.RegisterAsKnown(ClosedEvent, (byte)33, DependencyProperty.PropertyValidity.Uninitialize); 
            DependencyProperty.RegisterAsKnown(CompensatingEvent, (byte)34, DependencyProperty.PropertyValidity.Uninitialize); 
            DependencyProperty.RegisterAsKnown(StatusChangedEvent, (byte)35, DependencyProperty.PropertyValidity.Uninitialize);
            DependencyProperty.RegisterAsKnown(StatusChangedLockedEvent, (byte)36, DependencyProperty.PropertyValidity.Uninitialize); 
            DependencyProperty.RegisterAsKnown(LockCountOnStatusChangeChangedEvent, (byte)37, DependencyProperty.PropertyValidity.Uninitialize);
            DependencyProperty.RegisterAsKnown(FaultingEvent, (byte)38, DependencyProperty.PropertyValidity.Uninitialize);

            // misc. others 
            DependencyProperty.RegisterAsKnown(FaultAndCancellationHandlingFilter.FaultProcessedProperty, (byte)41, DependencyProperty.PropertyValidity.Uninitialize);
            DependencyProperty.RegisterAsKnown(CompensationHandlingFilter.CompensateProcessedProperty, (byte)43, DependencyProperty.PropertyValidity.Uninitialize); 
            DependencyProperty.RegisterAsKnown(CompensationHandlingFilter.LastCompensatedOrderIdProperty, (byte)44, DependencyProperty.PropertyValidity.Uninitialize); 
        }
 
        public Activity()
        {
            SetValue(CustomActivityProperty, false);
            SetValue(NameProperty, GetType().Name); 
        }
 
        public Activity(string name) 
        {
            if (name == null) 
                throw new ArgumentNullException("name");

            SetValue(CustomActivityProperty, false);
            SetValue(NameProperty, name); 
        }
 
        #region Execution Signals 

        protected internal virtual void Initialize(IServiceProvider provider) 
        {
            if (provider == null)
                throw new ArgumentNullException("provider");
 
        }
        protected internal virtual ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) 
        { 
            if (executionContext == null)
                throw new ArgumentNullException("executionContext"); 

            return ActivityExecutionStatus.Closed;
        }
        protected internal virtual ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext) 
        {
            if (executionContext == null) 
                throw new ArgumentNullException("executionContext"); 

            return ActivityExecutionStatus.Closed; 
        }
        protected internal virtual ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext, Exception exception)
        {
            if (executionContext == null) 
                throw new ArgumentNullException("executionContext");
 
            return ActivityExecutionStatus.Closed; 
        }
 
        /// 
        /// Derived implementation may do necessary cleanup here such as removing serializable instance
        /// dependency properties before the activity status is set to closed.		
        ///  
        protected virtual void OnClosed(IServiceProvider provider)
        { 
        } 

        ///  
        /// Called Immediatly once activity is done with it life time
        /// i.e Simple Activity when they transition to close.
        ///     CompensatableActivity & any activity which is in compensation chain
        ///     when root activity close. 
        /// 
        ///  
        protected internal virtual void Uninitialize(IServiceProvider provider) 
        {
            if (provider == null) 
                throw new ArgumentNullException("provider");

            ResetKnownDependencyProperties(false);
        } 

        protected internal virtual void OnActivityExecutionContextLoad(IServiceProvider provider) 
        { 
            if (provider == null)
                throw new ArgumentNullException("provider"); 
        }

        protected internal virtual void OnActivityExecutionContextUnload(IServiceProvider provider)
        { 
            if (provider == null)
                throw new ArgumentNullException("provider"); 
        } 
        #endregion
 
        #region Activity Execution Helper Methods

		protected internal void RaiseGenericEvent(DependencyProperty dependencyEvent, object sender, T e) where T : EventArgs
		{ 
 			if (dependencyEvent == null)
				throw new ArgumentNullException("dependencyEvent"); 
 
 			if (e == null)
 				throw new ArgumentNullException("e"); 

			if (this.WorkflowCoreRuntime == null)
 				throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
 
			EventHandler[] eventHandlers = ((IDependencyObjectAccessor)this).GetInvocationList>(dependencyEvent);
			if (eventHandlers != null) 
			{ 
 				foreach (EventHandler eventHandler in eventHandlers)
				{ 
 					this.WorkflowCoreRuntime.RaiseHandlerInvoking(eventHandler);
                    try
                    {
                        eventHandler(sender, e); 
                    }
                    finally 
                    { 
                        this.WorkflowCoreRuntime.RaiseHandlerInvoked();
                    } 
 				}
			}
 		}
 
		protected internal void RaiseEvent(DependencyProperty dependencyEvent, object sender, EventArgs e)
		{ 
			if (sender == null) 
 				throw new ArgumentNullException("sender");
 
			if (dependencyEvent == null)
 				throw new ArgumentNullException("dependencyEvent");

 			if (e == null) 
				throw new ArgumentNullException("e");
 
 			if (this.WorkflowCoreRuntime == null) 
				throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
 
			EventHandler[] eventHandlers = ((IDependencyObjectAccessor)this).GetInvocationList(dependencyEvent);
			if (eventHandlers != null)
 			{
				foreach (EventHandler eventHandler in eventHandlers) 
 				{
 					this.WorkflowCoreRuntime.RaiseHandlerInvoking(eventHandler); 
                    try 
                    {
                        eventHandler(sender, e); 
                    }
                    finally
                    {
                        this.WorkflowCoreRuntime.RaiseHandlerInvoked(); 
                    }
				} 
 			} 
		}
 
        protected void TrackData(object userData)
        {
            if (userData == null)
                throw new ArgumentNullException("userData"); 
            if (this.WorkflowCoreRuntime == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable)); 
 
            this.WorkflowCoreRuntime.Track(null, userData);
        } 
        protected void TrackData(string userDataKey, object userData)
        {
            if (userData == null)
                throw new ArgumentNullException("userData"); 
            if (this.WorkflowCoreRuntime == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable)); 
 
            this.WorkflowCoreRuntime.Track(userDataKey, userData);
        } 
        protected Guid WorkflowInstanceId
        {
            get
            { 
                if (this.WorkflowCoreRuntime == null)
#pragma warning suppress 56503 
                    throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable)); 
                return this.WorkflowCoreRuntime.InstanceID;
            } 
        }
        protected internal void Invoke(EventHandler handler, T e) where T : EventArgs
        {
 
            if (handler == null)
                throw new ArgumentNullException("handler"); 
 
            if (e == null)
                throw new ArgumentNullException("e"); 

            if (this.WorkflowCoreRuntime == null)
                throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_NoRuntimeAvailable));
 
            if (this.ExecutionStatus == ActivityExecutionStatus.Initialized || this.ExecutionStatus == ActivityExecutionStatus.Closed)
                throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_InvalidInvokingState)); 
 
            // create subscriber
            ActivityExecutorDelegateInfo activityExecutorDelegate = null; 
            using (this.WorkflowCoreRuntime.SetCurrentActivity(this))
                activityExecutorDelegate = new ActivityExecutorDelegateInfo(handler, this.ContextActivity);

            activityExecutorDelegate.InvokeDelegate(this.WorkflowCoreRuntime.CurrentActivity.ContextActivity, e, false); 
        }
 
        protected internal void Invoke(IActivityEventListener eventListener, T e) where T : EventArgs 
        {
            if (eventListener == null) 
                throw new ArgumentNullException("eventListener");

            if (e == null)
                throw new ArgumentNullException("e"); 

            if (this.WorkflowCoreRuntime == null) 
                throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_NoRuntimeAvailable)); 

            if (this.ExecutionStatus == ActivityExecutionStatus.Initialized || this.ExecutionStatus == ActivityExecutionStatus.Closed) 
                throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_InvalidInvokingState));

            // create subscriber
            ActivityExecutorDelegateInfo activityExecutorDelegate = null; 
            using (this.WorkflowCoreRuntime.SetCurrentActivity(this))
                activityExecutorDelegate = new ActivityExecutorDelegateInfo(eventListener, this.ContextActivity); 
 
            activityExecutorDelegate.InvokeDelegate(this.WorkflowCoreRuntime.CurrentActivity.ContextActivity, e, false);
        } 
        #endregion

        #region Activity Meta Properties
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public CompositeActivity Parent 
        {
            get 
            {
                return this.parent;
            }
        } 

        internal void SetParent(CompositeActivity compositeActivity) 
        { 
            this.parent = compositeActivity;
        } 

        [Browsable(true)]
        [SRCategory(SR.Activity)]
        [ParenthesizePropertyName(true)] 
        [SRDescription(SR.NameDescr)]
        [MergableProperty(false)] 
        [DefaultValue("")] 
        public string Name
        { 
            get
            {
                return (string)GetValue(NameProperty);
            } 
            set
            { 
                SetValue(NameProperty, value); 
            }
        } 

        [Browsable(true)]
        [SRCategory(SR.Activity)]
        [SRDescription(SR.EnabledDescr)] 
        [DefaultValue(true)]
        public bool Enabled 
        { 
            get
            { 
                return (bool)GetValue(EnabledProperty);
            }
            set
            { 
                SetValue(EnabledProperty, value);
            } 
        } 

        [Browsable(false)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public string QualifiedName
        {
            get 
            {
                if (!this.DesignMode && !this.DynamicUpdateMode) 
                { 
                    string cachedQualifiedName = (string)GetValue(QualifiedNameProperty);
                    if (cachedQualifiedName != null) 
                        return cachedQualifiedName;
                }

                string sbQId = null; 
                if (Helpers.IsActivityLocked(this))
                    sbQId = InternalHelpers.GenerateQualifiedNameForLockedActivity(this, null); 
                else 
                    sbQId = (string)GetValue(NameProperty);
                return sbQId; 
            }
        }

        [Browsable(true)] 
        [SRCategory(SR.Activity)]
        [SRDescription(SR.DescriptionDescr)] 
        [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))] 
        [DefaultValue("")]
        public string Description 
        {
            get
            {
                return (string)GetValue(DescriptionProperty); 
            }
            set 
            { 
                SetValue(DescriptionProperty, value);
            } 
        }
        #endregion

        #region Activity Instance Properties 

        public static readonly DependencyProperty StatusChangedEvent = DependencyProperty.Register("StatusChanged", typeof(EventHandler), typeof(Activity)); 
        [Browsable(false)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public event EventHandler StatusChanged 
        {
            add
            {
                this.AddStatusChangeHandler(StatusChangedEvent, value); 
            }
            remove 
            { 
                this.RemoveStatusChangeHandler(StatusChangedEvent, value);
            } 
        }

        internal static readonly DependencyProperty LockCountOnStatusChangeChangedEvent = DependencyProperty.Register("LockCountOnStatusChangeChanged", typeof(EventHandler), typeof(Activity));
        internal static readonly DependencyProperty StatusChangedLockedEvent = DependencyProperty.Register("StatusChangedLocked", typeof(EventHandler), typeof(Activity)); 
        internal void HoldLockOnStatusChange(IActivityEventListener eventListener)
        { 
            this.RegisterForStatusChange(StatusChangedLockedEvent, eventListener); 

            // increment count 
            this.SetValue(LockCountOnStatusChangeProperty, this.LockCountOnStatusChange + 1);
        }
        internal void ReleaseLockOnStatusChange(IActivityEventListener eventListener)
        { 
            // remove it
            this.UnregisterForStatusChange(StatusChangedLockedEvent, eventListener); 
 
            // decrement count and fire event
            int lockCountOnStatusChange = this.LockCountOnStatusChange; 
            Debug.Assert(lockCountOnStatusChange > 0, "lock count on status change should be > 0");
            this.SetValue(LockCountOnStatusChangeProperty, --lockCountOnStatusChange);
            if (lockCountOnStatusChange == 0)
            { 
                // Work around: if primary activity was never closed, then we set it to Canceled outcome
                if (!this.HasPrimaryClosed) 
                    this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Canceled); 

                try 
                {
                    this.MarkClosed();
                }
                catch 
                {
                    // roll back the lock count changes which we did 
                    this.SetValue(LockCountOnStatusChangeProperty, ++lockCountOnStatusChange); 
                    this.RegisterForStatusChange(StatusChangedLockedEvent, eventListener);
                    throw; 
                }
            }
            else
            { 
                FireStatusChangedEvents(Activity.LockCountOnStatusChangeChangedEvent, false);
            } 
        } 

        [Browsable(false)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal int LockCountOnStatusChange
        {
            get 
            {
                return (int)this.GetValue(LockCountOnStatusChangeProperty); 
            } 
        }
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal bool HasPrimaryClosed
        { 
            get
            { 
                return (bool)this.GetValue(HasPrimaryClosedProperty); 
            }
        } 

        public static readonly DependencyProperty CancelingEvent = DependencyProperty.Register("Canceling", typeof(EventHandler), typeof(Activity));

        [Browsable(false)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public event EventHandler Canceling 
        { 
            add
            { 
                this.AddStatusChangeHandler(CancelingEvent, value);
            }
            remove
            { 
                this.RemoveStatusChangeHandler(CancelingEvent, value);
            } 
        } 

        public static readonly DependencyProperty FaultingEvent = DependencyProperty.Register("Faulting", typeof(EventHandler), typeof(Activity)); 

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public event EventHandler Faulting 
        {
            add 
            { 
                this.AddStatusChangeHandler(FaultingEvent, value);
            } 
            remove
            {
                this.RemoveStatusChangeHandler(FaultingEvent, value);
            } 
        }
 
 
        public static readonly DependencyProperty ClosedEvent = DependencyProperty.Register("Closed", typeof(EventHandler), typeof(Activity));
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public event EventHandler Closed
        { 
            add
            { 
                this.AddStatusChangeHandler(ClosedEvent, value); 
            }
            remove 
            {
                this.RemoveStatusChangeHandler(ClosedEvent, value);
            }
        } 

        public static readonly DependencyProperty ExecutingEvent = DependencyProperty.Register("Executing", typeof(EventHandler), typeof(Activity)); 
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public event EventHandler Executing
        {
            add
            { 
                this.AddStatusChangeHandler(ExecutingEvent, value);
            } 
            remove 
            {
                this.RemoveStatusChangeHandler(ExecutingEvent, value); 
            }
        }

        public static readonly DependencyProperty CompensatingEvent = DependencyProperty.Register("Compensating", typeof(EventHandler), typeof(Activity)); 

        [Browsable(false)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public event EventHandler Compensating
        { 
            add
            {
                this.AddStatusChangeHandler(CompensatingEvent, value);
            } 
            remove
            { 
                this.RemoveStatusChangeHandler(CompensatingEvent, value); 
            }
        } 
        private void AddStatusChangeHandler(DependencyProperty dependencyProp, EventHandler delegateValue)
        {
            IList handlers = null;
            if (this.DependencyPropertyValues.ContainsKey(dependencyProp)) 
            {
                handlers = this.DependencyPropertyValues[dependencyProp] as IList; 
            } 
            else
            { 
                handlers = new ArrayList();
                this.DependencyPropertyValues[dependencyProp] = handlers;
            }
            handlers.Add(new ActivityExecutorDelegateInfo(true, delegateValue, this.ContextActivity ?? this.RootActivity)); 
        }
        private void RemoveStatusChangeHandler(DependencyProperty dependencyProp, EventHandler delegateValue) 
        { 
            if (this.DependencyPropertyValues.ContainsKey(dependencyProp))
            { 
                IList handlers = this.DependencyPropertyValues[dependencyProp] as IList;
                if (handlers != null)
                {
                    handlers.Remove(new ActivityExecutorDelegateInfo(true, delegateValue, this.ContextActivity)); 
                    if (handlers.Count == 0)
                        this.DependencyPropertyValues.Remove(dependencyProp); 
                } 
            }
        } 
        private IList GetStatusChangeHandlers(DependencyProperty dependencyProp)
        {
            IList handlers = null;
            if (this.DependencyPropertyValues.ContainsKey(dependencyProp)) 
                handlers = this.DependencyPropertyValues[dependencyProp] as IList;
            return handlers; 
        } 

        public void RegisterForStatusChange(DependencyProperty dependencyProp, IActivityEventListener activityStatusChangeListener) 
        {
            if (dependencyProp == null)
                throw new ArgumentNullException("dependencyProp");
            if (activityStatusChangeListener == null) 
                throw new ArgumentNullException("activityStatusChangeListener");
 
            if (dependencyProp != Activity.ExecutingEvent && 
                dependencyProp != Activity.CancelingEvent &&
                dependencyProp != Activity.ClosedEvent && 
                dependencyProp != Activity.CompensatingEvent &&
                dependencyProp != Activity.FaultingEvent &&
                dependencyProp != Activity.StatusChangedEvent &&
                dependencyProp != Activity.StatusChangedLockedEvent && 
                dependencyProp != Activity.LockCountOnStatusChangeChangedEvent)
                throw new ArgumentException(); 
 
            IList handlers = null;
            if (this.DependencyPropertyValues.ContainsKey(dependencyProp)) 
            {
                handlers = this.DependencyPropertyValues[dependencyProp] as IList;
            }
            else 
            {
                handlers = new ArrayList(); 
                this.DependencyPropertyValues[dependencyProp] = handlers; 
            }
            handlers.Add(new ActivityExecutorDelegateInfo(true, activityStatusChangeListener, this.ContextActivity)); 
        }
        public void UnregisterForStatusChange(DependencyProperty dependencyProp, IActivityEventListener activityStatusChangeListener)
        {
            if (dependencyProp == null) 
                throw new ArgumentNullException("dependencyProp");
            if (activityStatusChangeListener == null) 
                throw new ArgumentNullException("activityStatusChangeListener"); 

            if (dependencyProp != Activity.ExecutingEvent && 
                dependencyProp != Activity.CancelingEvent &&
                dependencyProp != Activity.ClosedEvent &&
                dependencyProp != Activity.CompensatingEvent &&
                dependencyProp != Activity.FaultingEvent && 
                dependencyProp != Activity.StatusChangedEvent &&
                dependencyProp != Activity.StatusChangedLockedEvent && 
                dependencyProp != Activity.LockCountOnStatusChangeChangedEvent) 
                throw new ArgumentException();
 
            if (this.DependencyPropertyValues.ContainsKey(dependencyProp))
            {
                IList handlers = this.DependencyPropertyValues[dependencyProp] as IList;
                if (handlers != null) 
                {
                    handlers.Remove(new ActivityExecutorDelegateInfo(true, activityStatusChangeListener, this.ContextActivity)); 
                    if (handlers.Count == 0) 
                        this.DependencyPropertyValues.Remove(dependencyProp);
                } 
            }
        }

        [Browsable(false)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public ActivityExecutionStatus ExecutionStatus 
        { 
            get
            { 
                return (ActivityExecutionStatus)this.GetValue(ExecutionStatusProperty);
            }
        }
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public ActivityExecutionResult ExecutionResult 
        {
            get 
            {
                return (ActivityExecutionResult)this.GetValue(ExecutionResultProperty);
            }
        } 

        [Browsable(false)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public bool IsDynamicActivity
        { 
            get
            {
                if (this.DesignMode)
                    return false; 
                else
                    return (this.ContextActivity != this.RootActivity); 
            } 
        }
 

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        internal bool WasExecuting 
        {
            get 
            { 
                return (bool)this.GetValue(WasExecutingProperty);
            } 
        }
        public Activity GetActivityByName(string activityQualifiedName)
        {
            return GetActivityByName(activityQualifiedName, false); 
        }
        public Activity GetActivityByName(string activityQualifiedName, bool withinThisActivityOnly) 
        { 
            if (activityQualifiedName == null)
                throw new ArgumentNullException("activityQualifiedName"); 

            if (this.QualifiedName == activityQualifiedName)
                return this;
 
            Activity resolvedActivity = null;
 
            // try with just the passed qualified id 
            resolvedActivity = ResolveActivityByName(activityQualifiedName, withinThisActivityOnly);
 
            if (resolvedActivity == null)
            {
                // if custom then append its qualified id and then try it
                if (this is CompositeActivity && Helpers.IsCustomActivity(this as CompositeActivity)) 
                    resolvedActivity = ResolveActivityByName(this.QualifiedName + "." + activityQualifiedName, withinThisActivityOnly);
            } 
 
            return resolvedActivity;
        } 

        private Activity ResolveActivityByName(string activityQualifiedName, bool withinThisActivityOnly)
        {
            Activity resolvedActivity = null; 
            if (!this.DesignMode && !this.DynamicUpdateMode)
            { 
                Activity rootActivity = this.RootActivity; 

                Hashtable lookupPaths = (Hashtable)rootActivity.UserData[UserDataKeys.LookupPaths]; 
                if (lookupPaths != null)
                {
                    string path = (string)lookupPaths[activityQualifiedName];
                    if (path != null) 
                    {
                        if (path.Length != 0) 
                        { 
                            string thisPath = (string)lookupPaths[this.QualifiedName];
                            if (path.StartsWith(thisPath, StringComparison.Ordinal)) 
                            {
                                if (path.Length == thisPath.Length)
                                    resolvedActivity = this;
                                else if (thisPath.Length == 0 || path[thisPath.Length] == '.') 
                                    resolvedActivity = this.TraverseDottedPath(path.Substring(thisPath.Length > 0 ? thisPath.Length + 1 : 0));
                            } 
                            else if (!withinThisActivityOnly) 
                            {
                                resolvedActivity = rootActivity.TraverseDottedPath(path); 
                            }
                        }
                        else if (!withinThisActivityOnly)
                        { 
                            resolvedActivity = rootActivity;
                        } 
                    } 
                }
            } 
            else if (!this.DesignMode)
            {
                // WinOE Bug 20584: Fix this for dynamic updates only.  See bug description for details.
                CompositeActivity parent = (withinThisActivityOnly ? this : this.RootActivity) as CompositeActivity; 
                if (parent != null)
                { 
                    foreach (Activity childActivity in Helpers.GetNestedActivities(parent)) 
                    {
                        if (childActivity.QualifiedName == activityQualifiedName) 
                        {
                            resolvedActivity = childActivity;
                            break;
                        } 
                    }
                } 
            } 
            else
            { 
                //
                resolvedActivity = Helpers.ParseActivity(this, activityQualifiedName);

                if (resolvedActivity == null && !withinThisActivityOnly) 
                    resolvedActivity = Helpers.ParseActivity(this.RootActivity, activityQualifiedName);
            } 
 
            return resolvedActivity;
        } 

        internal void ResetAllKnownDependencyProperties()
        {
            ResetKnownDependencyProperties(true); 
        }
 
        private void ResetKnownDependencyProperties(bool forReexecute) 
        {
            DependencyProperty[] propertyClone = new DependencyProperty[this.DependencyPropertyValues.Keys.Count]; 
            this.DependencyPropertyValues.Keys.CopyTo(propertyClone, 0);

            foreach (DependencyProperty property in propertyClone)
            { 
                if (property.IsKnown && (property.Validity == DependencyProperty.PropertyValidity.Uninitialize || (forReexecute && property.Validity == DependencyProperty.PropertyValidity.Reexecute)))
                    this.RemoveProperty(property); 
            } 
        }
 
        internal virtual Activity TraverseDottedPath(string dottedPath)
        {
            return null;
        } 
        internal Activity TraverseDottedPathFromRoot(string dottedPathFromRoot)
        { 
            string thisActivityDottedPath = this.DottedPath; 
            if (dottedPathFromRoot == thisActivityDottedPath)
                return this; 

            // if it start with the smae dotted path then it's ok, otherwise return
            if (!dottedPathFromRoot.StartsWith(thisActivityDottedPath, StringComparison.Ordinal))
                return null; 

            // calculate relative path 
            string relativeDottedPath = dottedPathFromRoot; 
            if (thisActivityDottedPath.Length > 0)
                relativeDottedPath = dottedPathFromRoot.Substring(thisActivityDottedPath.Length + 1); 

            return this.TraverseDottedPath(relativeDottedPath);
        }
        internal string DottedPath 
        {
            get 
            { 
                if (!this.DesignMode && !this.DynamicUpdateMode)
                { 
                    string cachedDottedPath = (string)GetValue(DottedPathProperty);
                    if (cachedDottedPath != null)
                        return cachedDottedPath;
                } 

                StringBuilder dottedPathBuilder = new StringBuilder(); 
                Activity thisActivity = this; 
                while (thisActivity.parent != null)
                { 
                    int thisActivityIndex = thisActivity.parent.Activities.IndexOf(thisActivity);
                    dottedPathBuilder.Insert(0, thisActivityIndex.ToString(CultureInfo.InvariantCulture));	//15
                    dottedPathBuilder.Insert(0, '.');							//.15	
                    thisActivity = thisActivity.parent; 
                }
                if (dottedPathBuilder.Length > 0) 
                    dottedPathBuilder.Remove(0, 1); // remove the first dot 
                return dottedPathBuilder.ToString();
            } 
        }

        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        internal IWorkflowCoreRuntime WorkflowCoreRuntime
        { 
            get 
            {
                return this.workflowCoreRuntime; 
            }
        }
        internal bool DynamicUpdateMode
        { 
            get
            { 
                return (this.cachedDottedPath != null); 
            }
            set 
            {
                if (value)
                    this.cachedDottedPath = this.DottedPath;
                else 
                    this.cachedDottedPath = null;
            } 
        } 
        internal string CachedDottedPath
        { 
            get
            {
                return this.cachedDottedPath;
            } 
        }
 
        #endregion 

        #region Load/Save Static Methods 

        public Activity Clone()
        {
            if (this.DesignMode) 
                throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
 
            long max = (long)this.GetValue(SerializedStreamLengthProperty); 
            if ( max == 0 )
                max = 10240; 
            MemoryStream memoryStream = new MemoryStream((int)max);
            Save(memoryStream);
            memoryStream.Position = 0;
            this.SetValue(SerializedStreamLengthProperty,memoryStream.Length > max ? memoryStream.Length : max); 
            return Activity.Load(memoryStream, this);
        } 
 
        public void Save(Stream stream)
        { 
            this.Save(stream, binaryFormatter);
        }
        public void Save(Stream stream, IFormatter formatter)
        { 
            if (stream == null)
                throw new ArgumentNullException("stream"); 
            if (formatter == null) 
                throw new ArgumentNullException("formatter");
 
            if (this.DesignMode)
                throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));

            // cache the old values so that this fucntion can be re-entrant 
            Hashtable oldContextIdToActivityMap = ContextIdToActivityMap;
 
            ContextIdToActivityMap = new Hashtable(); 
            try
            { 
                // fill context id to Activity map
                FillContextIdToActivityMap(this);

                // walk through all nested activity roots and set nested activities 
                foreach (Activity activityRoot in ContextIdToActivityMap.Values)
                { 
                    IList nestedActivities = activityRoot.CollectNestedActivities(); 
                    if (nestedActivities != null && nestedActivities.Count > 0)
                        activityRoot.SetValue(Activity.NestedActivitiesProperty, nestedActivities); 
                }

                // serialize the graph
                formatter.Serialize(stream, this); 
            }
            finally 
            { 
                foreach (Activity activityRoot in ContextIdToActivityMap.Values)
                    activityRoot.RemoveProperty(Activity.NestedActivitiesProperty); 
                ContextIdToActivityMap = oldContextIdToActivityMap;
                ActivityRoots = null;
            }
        } 
        public static Activity Load(Stream stream, Activity outerActivity)
        { 
            return Load(stream, outerActivity, binaryFormatter); 
        }
        public static Activity Load(Stream stream, Activity outerActivity, IFormatter formatter) 
        {
            if (stream == null)
                throw new ArgumentNullException("stream");
            if (formatter == null) 
                throw new ArgumentNullException("formatter");
 
            if (outerActivity != null && outerActivity.DesignMode) 
                throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));
 
            Activity returnActivity = null;

            // cache the old values, so that this fucntion can be re-entrant
            Hashtable oldContextIdToActivityMap = ContextIdToActivityMap; 
            Activity oldDefinitionActivity = DefinitionActivity;
 
            // initialize the thread static guys 
            ContextIdToActivityMap = new Hashtable();
            DefinitionActivity = outerActivity; 

            try
            {
                // fill in the context id to activity map for surrounding contexts 
                if (outerActivity != null)
                    FillContextIdToActivityMap(outerActivity.RootActivity); 
 
                // deserialize the stream
                returnActivity = (Activity)formatter.Deserialize(stream); 

                // fix up parent child relation ships for root activity and al nested context activities
                Queue deserializedActivityRootsQueue = new Queue();
                deserializedActivityRootsQueue.Enqueue(returnActivity); 
                while (deserializedActivityRootsQueue.Count > 0)
                { 
                    Activity deserializedActivityRoot = deserializedActivityRootsQueue.Dequeue(); 

                    // determine the parent activity and definition activity 
                    Activity definitionActivity = DefinitionActivity;
                    Activity parentActivity = outerActivity != null ? outerActivity.parent : null;

                    if (deserializedActivityRoot.IsContextActivity) 
                    {
                        // get the corresponding definition activity 
                        ActivityExecutionContextInfo contextInfo = (ActivityExecutionContextInfo)deserializedActivityRoot.GetValue(Activity.ActivityExecutionContextInfoProperty); 
                        definitionActivity = definitionActivity.GetActivityByName(contextInfo.ActivityQualifiedName);
 
                        // get the corresponding parent activity
                        Activity parentContextActivity = (Activity)ContextIdToActivityMap[contextInfo.ParentContextId];
                        if (parentContextActivity != null)
                            parentActivity = parentContextActivity.GetActivityByName(contextInfo.ActivityQualifiedName).parent; 

                        // fill up the cached context activities 
                        ContextIdToActivityMap[deserializedActivityRoot.ContextId] = deserializedActivityRoot; 

                        // get nested context activities and queue them for processing 
                        IList deserializedNestedActivityRoots = (IList)deserializedActivityRoot.GetValue(Activity.ActiveExecutionContextsProperty);
                        if (deserializedNestedActivityRoots != null)
                        {
                            foreach (Activity deserializedNestedActivityRoot in deserializedNestedActivityRoots) 
                                deserializedActivityRootsQueue.Enqueue(deserializedNestedActivityRoot);
                        } 
                    } 

                    // prepare hash of id to activity 
                    Hashtable idToActivityMap = new Hashtable();
                    IList nestedActivities = (IList)deserializedActivityRoot.GetValue(Activity.NestedActivitiesProperty);
                    if (nestedActivities != null)
                    { 
                        foreach (Activity nestedActivity in nestedActivities)
                            idToActivityMap.Add(nestedActivity.DottedPath, nestedActivity); 
                    } 

                    // fix up parent child relation ship for this activity 
                    deserializedActivityRoot.FixUpParentChildRelationship(definitionActivity, parentActivity, idToActivityMap);
                    deserializedActivityRoot.FixUpMetaProperties(definitionActivity);
                    deserializedActivityRoot.RemoveProperty(Activity.NestedActivitiesProperty);
                } 

                // set the Workflow Definition in case of root activity 
                if (returnActivity.Parent == null) 
                    returnActivity.SetValue(Activity.WorkflowDefinitionProperty, DefinitionActivity);
            } 
            finally
            {
                ContextIdToActivityMap = oldContextIdToActivityMap;
                DefinitionActivity = oldDefinitionActivity; 
                ActivityRoots = null;
            } 
            return returnActivity; 
        }
        private static void FillContextIdToActivityMap(Activity seedActivity) 
        {
            Queue activityRootsQueue = new Queue();
            activityRootsQueue.Enqueue(seedActivity);
            while (activityRootsQueue.Count > 0) 
            {
                Activity activityRoot = activityRootsQueue.Dequeue(); 
                if (activityRoot.IsContextActivity) 
                {
                    ContextIdToActivityMap[activityRoot.ContextId] = activityRoot; 
                    IList activeActivityRoots = (IList)activityRoot.GetValue(Activity.ActiveExecutionContextsProperty);
                    if (activeActivityRoots != null)
                    {
                        foreach (Activity activeActivityRoot in activeActivityRoots) 
                            activityRootsQueue.Enqueue(activeActivityRoot);
                    } 
                } 
                else
                { 
                    ContextIdToActivityMap[0] = activityRoot;
                }
            }
            ActivityRoots = new ArrayList(ContextIdToActivityMap.Values); 
        }
 
        internal static event ActivityResolveEventHandler ActivityResolve 
        {
            add 
            {
                lock (staticSyncRoot)
                {
                    activityDefinitionResolve += value; 
                }
            } 
            remove 
            {
                lock (staticSyncRoot) 
                {
                    activityDefinitionResolve -= value;
                }
            } 
        }
 
        internal static event WorkflowChangeActionsResolveEventHandler WorkflowChangeActionsResolve 
        {
            add 
            {
                lock (staticSyncRoot)
                {
                    workflowChangeActionsResolve += value; 
                }
            } 
 
            remove
            { 
                lock (staticSyncRoot)
                {
                    workflowChangeActionsResolve -= value;
                } 
            }
        } 
 
        internal static Activity OnResolveActivityDefinition(Type type, string workflowMarkup, string rulesMarkup, bool createNew, bool initForRuntime, IServiceProvider serviceProvider)
        { 
            // get invocation list
            Delegate[] invocationList = null;
            lock (staticSyncRoot)
            { 
                if (activityDefinitionResolve != null)
                    invocationList = activityDefinitionResolve.GetInvocationList(); 
            } 

            // call resovlers one by one 
            Activity activityDefinition = null;
            if (invocationList != null)
            {
                foreach (ActivityResolveEventHandler activityDefinitionResolver in invocationList) 
                {
                    activityDefinition = activityDefinitionResolver(null, new ActivityResolveEventArgs(type, workflowMarkup, rulesMarkup, createNew, initForRuntime, serviceProvider)); 
                    if (activityDefinition != null) 
                        return activityDefinition;
                } 
            }
            return null;
        }
 
        internal static ArrayList OnResolveWorkflowChangeActions(string workflowChangesMarkup, Activity root)
        { 
            // get invocation list 
            Delegate[] invocationList = null;
            lock (staticSyncRoot) 
            {
                if (workflowChangeActionsResolve != null)
                    invocationList = workflowChangeActionsResolve.GetInvocationList();
            } 

            // call resovlers one by one 
            ArrayList changeActions = null; 
            if (invocationList != null)
            { 
                foreach (WorkflowChangeActionsResolveEventHandler workflowChangeActionsResolver in invocationList)
                {
                    changeActions = workflowChangeActionsResolver(root, new WorkflowChangeActionsResolveEventArgs(workflowChangesMarkup));
                    if (changeActions != null) 
                        return changeActions;
                } 
            } 
            return null;
        } 

        #endregion

        #region Context Activity properties 

        internal bool IsContextActivity 
        { 
            get
            { 
                return this.GetValue(Activity.ActivityExecutionContextInfoProperty) != null;
            }
        }
        internal int ContextId 
        {
            get 
            { 
                return ((ActivityExecutionContextInfo)this.ContextActivity.GetValue(Activity.ActivityExecutionContextInfoProperty)).ContextId;
            } 
        }
        internal Guid ContextGuid
        {
            get 
            {
                return ((ActivityExecutionContextInfo)this.ContextActivity.GetValue(Activity.ActivityExecutionContextInfoProperty)).ContextGuid; 
            } 
        }
        internal Activity ContextActivity 
        {
            get
            {
                Activity contextActivity = this; 
                while (contextActivity != null && contextActivity.GetValue(Activity.ActivityExecutionContextInfoProperty) == null)
                    contextActivity = contextActivity.parent; 
                return contextActivity; 
            }
        } 
        internal Activity ParentContextActivity
        {
            get
            { 
                Activity contextActivity = this.ContextActivity;
                ActivityExecutionContextInfo executionContextInfo = (ActivityExecutionContextInfo)contextActivity.GetValue(Activity.ActivityExecutionContextInfoProperty); 
                if (executionContextInfo.ParentContextId == -1) 
                    return null;
                return this.WorkflowCoreRuntime.GetContextActivityForId(executionContextInfo.ParentContextId); 
            }
        }
        internal Activity RootContextActivity
        { 
            get
            { 
                return this.WorkflowCoreRuntime.RootActivity; 
            }
        } 
        internal Activity RootActivity
        {
            get
            { 
                Activity parent = this;
                while (parent.parent != null) 
                    parent = parent.parent; 
                return parent;
            } 
        }

        #endregion
 
        #region Runtime Initialization
 
        internal override void OnInitializeDefinitionForRuntime() 
        {
            // only if we are in design mode, execute this code, other wise ignore this call 
            if (this.DesignMode)
            {
                // call base
                base.OnInitializeDefinitionForRuntime(); 

                this.UserData[UserDataKeys.CustomActivity] = this.GetValue(CustomActivityProperty); 
 
                // Work around !! Supports Synchronization and atomic transaction isolation
                ICollection handles = (ICollection)GetValue(SynchronizationHandlesProperty); 
                if (this.SupportsTransaction)
                {
                    if (handles == null)
                        handles = new List(); 
                    handles.Add(TransactionScopeActivity.TransactionScopeActivityIsolationHandle);
                } 
                if (handles != null) 
                    this.SetValue(SynchronizationHandlesProperty, new ReadOnlyCollection(new List(handles)));
 
                // lookup paths for root activity
                if (this.Parent == null)
                {
                    Hashtable lookupPaths = new Hashtable(); 
                    this.UserData[UserDataKeys.LookupPaths] = lookupPaths;
                    lookupPaths.Add(this.QualifiedName, string.Empty); 
                } 

                // Initialize the cache at runtime 
                SetReadOnlyPropertyValue(QualifiedNameProperty, this.QualifiedName);
                SetReadOnlyPropertyValue(DottedPathProperty, this.DottedPath);

                // cache attributes 
                this.UserData[typeof(PersistOnCloseAttribute)] = (this.GetType().GetCustomAttributes(typeof(PersistOnCloseAttribute), true).Length > 0);
            } 
        } 
        internal override void OnInitializeInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)
        { 
            base.OnInitializeInstanceForRuntime(workflowCoreRuntime);
			this.workflowCoreRuntime = workflowCoreRuntime;

        } 

        internal override void OnInitializeActivatingInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime) 
        { 
            //doing this will call OnRuntimeInitialized() which is a hook for the activity writers
            //to initialize/wire up their DPs correctly for the activating instance 
            base.OnInitializeActivatingInstanceForRuntime(workflowCoreRuntime);
			this.workflowCoreRuntime = workflowCoreRuntime;
        }
 
        internal override void FixUpMetaProperties(DependencyObject originalObject)
        { 
            if (originalObject == null) 
                throw new ArgumentNullException();
 
            // call base class
            base.FixUpMetaProperties(originalObject);
        }
        internal virtual void FixUpParentChildRelationship(Activity definitionActivity, Activity parentActivity, Hashtable deserializedActivities) 
        {
            // set parent for myself, root activity will have null parent 
            if (parentActivity != null) 
                this.SetParent((CompositeActivity)parentActivity);
        } 
        internal virtual IList CollectNestedActivities()
        {
            return null;
        } 
        #endregion
 
        #region Activity Status Change Signals 

        internal void SetStatus(ActivityExecutionStatus newStatus, bool transacted) 
        {
            System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Activity Status Change - Activity: {0} Old:{1}; New:{2}", this.QualifiedName, ActivityExecutionStatusEnumToString(this.ExecutionStatus), ActivityExecutionStatusEnumToString(newStatus));

            // Set Was Executing 
            if (newStatus == ActivityExecutionStatus.Faulting &&
                    this.ExecutionStatus == ActivityExecutionStatus.Executing) 
            { 
                this.SetValue(WasExecutingProperty, true);
            } 
            this.SetValue(ExecutionStatusProperty, newStatus);

            // fire status change events
            FireStatusChangedEvents(Activity.StatusChangedEvent, transacted); 
            switch (newStatus)
            { 
                case ActivityExecutionStatus.Closed: 
                    FireStatusChangedEvents(Activity.ClosedEvent, transacted);
                    break; 
                case ActivityExecutionStatus.Executing:
                    FireStatusChangedEvents(Activity.ExecutingEvent, transacted);
                    break;
                case ActivityExecutionStatus.Canceling: 
                    FireStatusChangedEvents(Activity.CancelingEvent, transacted);
                    break; 
                case ActivityExecutionStatus.Faulting: 
                    FireStatusChangedEvents(Activity.FaultingEvent, transacted);
                    break; 
                case ActivityExecutionStatus.Compensating:
                    FireStatusChangedEvents(Activity.CompensatingEvent, transacted);
                    break;
                default: 
                    return;
            } 
 
            // inform the workflow synchronously about this
            this.WorkflowCoreRuntime.ActivityStatusChanged(this, transacted, false); 
            if (newStatus == ActivityExecutionStatus.Closed)
            {
                // remove these
                this.RemoveProperty(Activity.LockCountOnStatusChangeProperty); 
                this.RemoveProperty(Activity.HasPrimaryClosedProperty);
                this.RemoveProperty(Activity.WasExecutingProperty); 
            } 
        }
        private void FireStatusChangedEvents(DependencyProperty dependencyProperty, bool transacted) 
        {
            IList eventListeners = this.GetStatusChangeHandlers(dependencyProperty);
            if (eventListeners != null)
            { 
                ActivityExecutionStatusChangedEventArgs statusChangeEventArgs = new ActivityExecutionStatusChangedEventArgs(this.ExecutionStatus, this.ExecutionResult, this);
                foreach (ActivityExecutorDelegateInfo delegateInfo in eventListeners) 
                    delegateInfo.InvokeDelegate(this.ContextActivity, statusChangeEventArgs, delegateInfo.ActivityQualifiedName == null, transacted); 
            }
        } 
        internal void MarkCanceled()
        {
            if (this.ExecutionStatus != ActivityExecutionStatus.Closed)
            { 
                if (this.ExecutionStatus != ActivityExecutionStatus.Canceling)
                    throw new InvalidOperationException(SR.GetString(SR.Error_InvalidCancelActivityState)); //DCR01 
                this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Canceled); 
                this.MarkClosed();
            } 
        }
        internal void MarkCompleted()
        {
            this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Succeeded); 
            this.MarkClosed();
        } 
        internal void MarkCompensated() 
        {
            if (this.ExecutionStatus != ActivityExecutionStatus.Compensating) 
                throw new InvalidOperationException(SR.GetString(SR.Error_InvalidCompensateActivityState)); //DCR01

            this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Compensated);
            this.MarkClosed(); 
        }
        internal void MarkFaulted() 
        { 
            this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Faulted);
            this.MarkClosed(); 
        }
        private void MarkClosed()
        {
            switch (this.ExecutionStatus) 
            {
                case ActivityExecutionStatus.Executing: 
                case ActivityExecutionStatus.Faulting: 
                case ActivityExecutionStatus.Compensating:
                case ActivityExecutionStatus.Canceling: 
                    break;
                default:
                    throw new InvalidOperationException(SR.GetString(SR.Error_InvalidCloseActivityState)); //DCR01
            } 

            if (this is CompositeActivity) 
            { 
                foreach (Activity childActivity in ((CompositeActivity)this).Activities)
                    if (childActivity.Enabled && !(childActivity.ExecutionStatus == ActivityExecutionStatus.Initialized || childActivity.ExecutionStatus == ActivityExecutionStatus.Closed)) 
                        throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_ActiveChildExist));

                ActivityExecutionContext currentContext = new ActivityExecutionContext(this);
 
                foreach (ActivityExecutionContext childContext in currentContext.ExecutionContextManager.ExecutionContexts)
                { 
                    if (this.GetActivityByName(childContext.Activity.QualifiedName, true) != null) 
                        throw new InvalidOperationException(SR.GetString(System.Globalization.CultureInfo.CurrentCulture, SR.Error_ActiveChildContextExist));
                } 
            }

            if (this.LockCountOnStatusChange > 0)
            { 
                this.SetValue(HasPrimaryClosedProperty, true);
                this.FireStatusChangedEvents(Activity.StatusChangedLockedEvent, false); 
            } 
            else if (this.parent == null ||
                        (this.ExecutionResult == ActivityExecutionResult.Succeeded && (this is ICompensatableActivity || this.PersistOnClose)) 
                    )
            {
                ActivityExecutionStatus oldStatus = this.ExecutionStatus;
                ActivityExecutionResult oldOutcome = this.ExecutionResult; 

                this.SetStatus(ActivityExecutionStatus.Closed, true); 
                try 
                {
                    // The activity may remove any instance specific dependency properties to reduce serialization size 
                    this.OnClosed(this.RootActivity.WorkflowCoreRuntime);
                }
                catch (Exception e)
                { 
                    this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Faulted);
                    this.SetValueCommon(ActivityExecutionContext.CurrentExceptionProperty, e, ActivityExecutionContext.CurrentExceptionProperty.DefaultMetadata, false); 
                } 

 
                if (this.parent != null && (this is ICompensatableActivity))
                {
                    this.SetValue(CompletedOrderIdProperty, this.IncrementCompletedOrderId());
                } 
                if(CanUninitializeNow)
                { 
                    // 

                    this.Uninitialize(this.RootActivity.WorkflowCoreRuntime); 
                    this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Uninitialized);
                }
                else if(this.parent == null) //Root Activity Closure
                { 
                    UninitializeCompletedContext(this, new ActivityExecutionContext(this));
                } 
 
                try
                { 
                    Exception exception = (Exception)this.GetValue(ActivityExecutionContext.CurrentExceptionProperty);
                    if (exception != null && this.parent == null)
                    {
                        this.WorkflowCoreRuntime.ActivityStatusChanged(this, false, true); 
                        // terminate the workflow instance
                        string errorString = "Uncaught exception escaped to the root of the workflow.\n" 
                            + string.Format(CultureInfo.CurrentCulture, "    In instance {0} in activity {1}\n", new object[] { this.WorkflowInstanceId, string.Empty }) 
                            + string.Format(CultureInfo.CurrentCulture, "Inner exception: {0}", new object[] { exception });
                        System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Critical, 0, errorString); 
                        this.WorkflowCoreRuntime.TerminateInstance(exception);
                    }
                    else if (exception != null && this.parent != null)
                    { 
                        this.WorkflowCoreRuntime.RaiseException(exception, this.Parent, string.Empty);
                        this.RemoveProperty(ActivityExecutionContext.CurrentExceptionProperty); 
                    } 
                    else if (this.parent == null || this.PersistOnClose)
                    { 
                        this.WorkflowCoreRuntime.PersistInstanceState(this);
                        this.WorkflowCoreRuntime.ActivityStatusChanged(this, false, true);

                        // throw exception to outer 
                        if (exception != null)
                        { 
                            this.WorkflowCoreRuntime.RaiseException(exception, this.Parent, string.Empty); 
                            this.RemoveProperty(ActivityExecutionContext.CurrentExceptionProperty);
                        } 
                    }

                    // remove the cached lock values
                    Activity parent = this.parent; 
                    while (parent != null)
                    { 
                        if (parent.SupportsSynchronization || parent.Parent == null) 
                            parent.RemoveProperty(ActivityExecutionContext.CachedGrantedLocksProperty);
 
                        parent = parent.parent;
                    }

                } 
                catch
                { 
                    if (this.parent != null && (this is ICompensatableActivity)) 
                    {
                        this.RemoveProperty(CompletedOrderIdProperty); 
                        this.DecrementCompletedOrderId();
                    }
                    this.SetValue(ExecutionResultProperty, oldOutcome);
                    this.SetStatus(oldStatus, true); 

                    // copy back the old locks values 
                    Activity parent = this.parent; 
                    while(parent != null)
                    { 
                        if (parent.SupportsSynchronization || parent.Parent == null)
                        {
                            object cachedGrantedLocks = parent.GetValue(ActivityExecutionContext.CachedGrantedLocksProperty);
                            if(cachedGrantedLocks != null) 
                                parent.SetValue(ActivityExecutionContext.GrantedLocksProperty, cachedGrantedLocks);
                            parent.RemoveProperty(ActivityExecutionContext.CachedGrantedLocksProperty); 
                        } 
                        parent = parent.parent;
                    } 
                    throw;
                }
            }
            else 
            {
                // The activity may remove any instance specific dependency properties to reduce serialization size 
                this.SetStatus(ActivityExecutionStatus.Closed, false); 
                try
                { 
                    this.OnClosed(this.RootActivity.WorkflowCoreRuntime);
                }
                catch (Exception e)
                { 
                    this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Faulted);
                    this.SetValueCommon(ActivityExecutionContext.CurrentExceptionProperty, e, ActivityExecutionContext.CurrentExceptionProperty.DefaultMetadata, false); 
                } 
                if(CanUninitializeNow)
                { 
                    //

                    this.Uninitialize(this.RootActivity.WorkflowCoreRuntime);
                    this.SetValue(ExecutionResultProperty, ActivityExecutionResult.Uninitialized); 
                }
 
                Exception exception = (Exception)this.GetValue(ActivityExecutionContext.CurrentExceptionProperty); 
                if (exception != null)
                { 
                    this.WorkflowCoreRuntime.RaiseException(exception, this.Parent, string.Empty);
                    this.RemoveProperty(ActivityExecutionContext.CurrentExceptionProperty);
                }
            } 
        }
 
        internal bool CanUninitializeNow 
        {
            get 
            {
                //This check finds
                //1) Existence of Succeeded ISC in same context.
                //2) If activity is ContextActivity? Checks existence of completed child 
                //context which needs compensation
                if (this.NeedsCompensation) 
                    return false; 

                //3) If this activity is not a context activity, check for completed child context 
                //which needs compensation.
                Activity contextActivity = this.ContextActivity;

                if (contextActivity != this) 
                {
                    IList childsCompletedContexts = contextActivity.GetValue(Activity.CompletedExecutionContextsProperty) as IList; 
 
                    if (childsCompletedContexts != null && childsCompletedContexts.Count > 0)
                    { 
                        foreach (ActivityExecutionContextInfo contextInfo in childsCompletedContexts)
                        {
                            if ((contextInfo.Flags & PersistFlags.NeedsCompensation) != 0 && this.GetActivityByName(contextInfo.ActivityQualifiedName, true) != null)
                            { 
                                return false;
                            } 
                        } 
                    }
                } 

                //Safe to Uninitialize this activity now.
                return true;
            } 
        }
 
        static void UninitializeCompletedContext(Activity activity, ActivityExecutionContext executionContext) 
        {
            //Uninitialize Compensatable Children which ran in Sub Contextee. 
            IList childsCompletedContexts = activity.GetValue(Activity.CompletedExecutionContextsProperty) as IList;

            if (childsCompletedContexts != null && childsCompletedContexts.Count > 0)
            { 
                IList childsCompletedContextsClone = new List(childsCompletedContexts);
                foreach (ActivityExecutionContextInfo contextInfo in childsCompletedContextsClone) 
                { 
                    if ((contextInfo.Flags & PersistFlags.NeedsCompensation) != 0 && activity.GetActivityByName(contextInfo.ActivityQualifiedName, true) != null)
                    { 
                        ActivityExecutionContext resurrectedContext = executionContext.ExecutionContextManager.DiscardPersistedExecutionContext(contextInfo);
                        UninitializeCompletedContext(resurrectedContext.Activity, resurrectedContext);
                        executionContext.ExecutionContextManager.CompleteExecutionContext(resurrectedContext);
                    } 
                }
            } 
 
            //UnInitialize any compensatable children which ran in same context.
            CompositeActivity compositeActivity = activity as CompositeActivity; 
            if(compositeActivity != null)
            {
                Activity[] compensatableChildren = CompensationUtils.GetCompensatableChildren(compositeActivity);
 
                for (int i = compensatableChildren.Length - 1; i >= 0; --i)
                { 
                    Activity compensatableChild =(Activity)compensatableChildren.GetValue(i); 
                    compensatableChild.Uninitialize(activity.RootActivity.WorkflowCoreRuntime);
                    compensatableChild.SetValue(ExecutionResultProperty, ActivityExecutionResult.Uninitialized); 
                }
            }

            //UnInitialize Self 
            activity.Uninitialize(activity.RootActivity.WorkflowCoreRuntime);
            activity.SetValue(ExecutionResultProperty, ActivityExecutionResult.Uninitialized); 
        } 

        internal bool NeedsCompensation 
        {
            get
            {
                IList childsCompletedContexts = this.GetValue(Activity.CompletedExecutionContextsProperty) as IList; 
                if (childsCompletedContexts != null && childsCompletedContexts.Count > 0)
                { 
                    foreach(ActivityExecutionContextInfo completedActivityInfo in childsCompletedContexts) 
                    {
                        if ((completedActivityInfo.Flags & PersistFlags.NeedsCompensation) != 0 && this.GetActivityByName(completedActivityInfo.ActivityQualifiedName, true) != null) 
                            return true;
                    }
                }
 
                // walk through all compensatable children and compensate them
                Queue completedActivities = new Queue(); 
                completedActivities.Enqueue(this); 
                while (completedActivities.Count > 0)
                { 
                    Activity completedChild = completedActivities.Dequeue();
                    if (completedChild is ICompensatableActivity &&
                         completedChild.ExecutionStatus == ActivityExecutionStatus.Closed &&
                         completedChild.ExecutionResult == ActivityExecutionResult.Succeeded) 
                        return true;
 
                    if (completedChild is CompositeActivity) 
                    {
                        foreach (Activity completedChild2 in ((CompositeActivity)completedChild).Activities) 
                        {
                            if (completedChild2.Enabled)
                                completedActivities.Enqueue(completedChild2);
                        } 
                    }
                } 
                return false; 
            }
        } 

        #endregion

        #region Behaviors Supports 

        internal bool SupportsTransaction 
        { 
            get
            { 
                return this is CompensatableTransactionScopeActivity || this is TransactionScopeActivity;
            }
        }
        internal bool SupportsSynchronization 
        {
            get 
            { 
                return this is SynchronizationScopeActivity;
            } 
        }
        internal bool PersistOnClose
        {
            get 
            {
                if (this.UserData.Contains(typeof(PersistOnCloseAttribute))) 
                    return (bool)this.UserData[typeof(PersistOnCloseAttribute)]; 

                object[] attributes = this.GetType().GetCustomAttributes(typeof(PersistOnCloseAttribute), true); 
                return (attributes != null && attributes.Length > 0);
            }
        }
 
        internal int IncrementCompletedOrderId()
        { 
            int completedOrderId = (int)this.RootActivity.GetValue(Activity.CompletedOrderIdProperty); 
            this.RootActivity.SetValue(Activity.CompletedOrderIdProperty, completedOrderId + 1);
            return (completedOrderId + 1); 
        }
        internal void DecrementCompletedOrderId()
        {
            int completedOrderId = (int)this.RootActivity.GetValue(Activity.CompletedOrderIdProperty); 
            this.RootActivity.SetValue(Activity.CompletedOrderIdProperty, completedOrderId - 1);
        } 
 
        #endregion
 
        #region EnumToString Converters

        internal static string ActivityExecutionStatusEnumToString(ActivityExecutionStatus status)
        { 
            string retVal = string.Empty;
            switch (status) 
            { 
                case ActivityExecutionStatus.Initialized:
                    retVal = "Initialized"; 
                    break;
                case ActivityExecutionStatus.Executing:
                    retVal = "Executing";
                    break; 
                case ActivityExecutionStatus.Canceling:
                    retVal = "Canceling"; 
                    break; 
                case ActivityExecutionStatus.Faulting:
                    retVal = "Faulting"; 
                    break;
                case ActivityExecutionStatus.Compensating:
                    retVal = "Compensating";
                    break; 
                case ActivityExecutionStatus.Closed:
                    retVal = "Closed"; 
                    break; 
            }
            return retVal; 
        }
        internal static string ActivityExecutionResultEnumToString(ActivityExecutionResult activityExecutionResult)
        {
            string retVal = string.Empty; 
            switch (activityExecutionResult)
            { 
                case ActivityExecutionResult.None: 
                    retVal = "None";
                    break; 
                case ActivityExecutionResult.Succeeded:
                    retVal = "Succeeded";
                    break;
                case ActivityExecutionResult.Canceled: 
                    retVal = "Canceled";
                    break; 
                case ActivityExecutionResult.Faulted: 
                    retVal = "Faulted";
                    break; 
                case ActivityExecutionResult.Compensated:
                    retVal = "Compensated";
                    break;
            } 
            return retVal;
        } 
 
        #endregion
 
        public override String ToString()
        {
            return this.QualifiedName + " [" + GetType().FullName + "]";
        } 
    }
    #endregion 
 
    #region Class CompositeActivity
 
    [ContentProperty("Activities")]
    [DesignerSerializer(typeof(CompositeActivityMarkupSerializer), typeof(WorkflowMarkupSerializer))]
    [ActivityCodeGenerator(typeof(CompositeActivityCodeGenerator))]
    [ActivityValidator(typeof(CompositeActivityValidator))] 
    [ActivityExecutor(typeof(CompositeActivityExecutor))]
    [TypeDescriptionProvider(typeof(CompositeActivityTypeDescriptorProvider))] 
    public class CompositeActivity : Activity, ISupportAlternateFlow 
    {
        private static DependencyProperty CanModifyActivitiesProperty = DependencyProperty.Register("CanModifyActivities", typeof(bool), typeof(CompositeActivity), new PropertyMetadata(DependencyPropertyOptions.Metadata, new Attribute[] { new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) })); 

        [NonSerialized]
        private ActivityCollection activities = null;
 
        public CompositeActivity()
        { 
            this.activities = new ActivityCollection(this); 
            this.activities.ListChanging += new EventHandler(OnListChangingEventHandler);
            this.activities.ListChanged += new EventHandler(OnListChangedEventHandler); 

            SetValue(CanModifyActivitiesProperty, false);
        }
 
        public CompositeActivity(IEnumerable children)
            : this() 
        { 
            if (children == null)
                throw new ArgumentNullException("children"); 

            foreach (Activity child in children)
                this.activities.Add(child);
        } 

        public CompositeActivity(string name) 
            : base(name) 
        {
            this.activities = new ActivityCollection(this); 
            this.activities.ListChanging += new EventHandler(OnListChangingEventHandler);
            this.activities.ListChanged += new EventHandler(OnListChangedEventHandler);

            SetValue(CanModifyActivitiesProperty, false); 
        }
 
        protected Activity[] GetDynamicActivities(Activity activity) 
        {
            if (activity == null) 
                throw new ArgumentNullException("activity");

            // Work around - make sure that we return the parent property value
            // otherwise .Parent property would have set the workflowCoreRuntime for parent 
            if (activity.parent != this)
                throw new ArgumentException(SR.GetString(SR.GetDynamicActivities_InvalidActivity), "activity"); 
 
            // get context activity
            Activity contextActivity = this.ContextActivity; 
            List dynamicActivities = new List();
            if (contextActivity != null)
            {
                IList activeContextActivities = (IList)contextActivity.GetValue(Activity.ActiveExecutionContextsProperty); 
                if (activeContextActivities != null)
                { 
                    foreach (Activity activeContextActivity in activeContextActivities) 
                    {
                        if (activeContextActivity.MetaEquals(activity)) 
                            dynamicActivities.Add(activeContextActivity);
                    }
                }
            } 
            return dynamicActivities.ToArray();
        } 
 
        protected internal override void Initialize(IServiceProvider provider)
        { 
            if (provider == null)
                throw new ArgumentNullException("provider");

            if (!(provider is ActivityExecutionContext)) 
                throw new ArgumentException(SR.GetString(SR.Error_InvalidServiceProvider, "provider"));
 
            foreach (Activity childActivity in Helpers.GetAllEnabledActivities(this)) 
            {
                ActivityExecutionContext executionContext = provider as ActivityExecutionContext; 
                executionContext.InitializeActivity(childActivity);
            }
        }
 
        protected internal override void Uninitialize(IServiceProvider provider)
        { 
            if (provider == null) 
                throw new ArgumentNullException("provider");
 
            foreach (Activity childActivity in Helpers.GetAllEnabledActivities(this))
            {
                //Case for Template/Conditional Branch/Non Context based Composite which
                //exists in path between compensatable context. 
                if (childActivity.ExecutionResult != ActivityExecutionResult.Uninitialized)
                { 
                    childActivity.Uninitialize(provider); 
                    childActivity.SetValue(ExecutionResultProperty, ActivityExecutionResult.Uninitialized);
                } 
            }
            base.Uninitialize(provider);
        }
        protected internal override void OnActivityExecutionContextLoad(IServiceProvider provider) 
        {
            if(provider == null) 
               throw new ArgumentNullException("provider"); 

            base.OnActivityExecutionContextLoad(provider); 

            foreach (Activity childActivity in Helpers.GetAllEnabledActivities(this))
            {
                childActivity.OnActivityExecutionContextLoad(provider); 
            }
        } 
        protected internal override void OnActivityExecutionContextUnload(IServiceProvider provider) 
        {
            if (provider == null) 
                throw new ArgumentNullException("provider");

            base.OnActivityExecutionContextUnload(provider);
 
            foreach (Activity childActivity in Helpers.GetAllEnabledActivities(this))
            { 
                childActivity.OnActivityExecutionContextUnload(provider); 
            }
        } 

        protected internal override ActivityExecutionStatus HandleFault(ActivityExecutionContext executionContext, Exception exception)
        {
            if (executionContext == null) 
                throw new ArgumentNullException("executionContext");
 
            if (exception == null) 
                throw new ArgumentNullException("exception");
 
            ActivityExecutionStatus newStatus = this.Cancel(executionContext);
            if (newStatus == ActivityExecutionStatus.Canceling)
                return ActivityExecutionStatus.Faulting;
 
            return newStatus;
        } 
 
        protected void ApplyWorkflowChanges(WorkflowChanges workflowChanges)
        { 
            if (workflowChanges == null)
                throw new ArgumentNullException("workflowChanges");

            if (this.Parent != null) 
                throw new InvalidOperationException(SR.GetString(SR.Error_InvalidActivityForWorkflowChanges));
 
            if (this.RootActivity == null) 
                throw new InvalidOperationException(SR.GetString(SR.Error_MissingRootActivity));
 
            if (this.WorkflowCoreRuntime == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_NoRuntimeAvailable));

            workflowChanges.ApplyTo(this); 
        }
 
 
        #region Workflow Change Notification Methods
        protected internal virtual void OnActivityChangeAdd(ActivityExecutionContext executionContext, Activity addedActivity) 
        {
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");
 
            if (addedActivity == null)
                throw new ArgumentNullException("addedActivity"); 
 

        } 

        protected internal virtual void OnActivityChangeRemove(ActivityExecutionContext executionContext, Activity removedActivity)
        {
 
        }
 
        protected internal virtual void OnWorkflowChangesCompleted(ActivityExecutionContext rootContext) 
        {
 
        }
        #endregion

        #region CompositeActivity Meta Properties 

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
        [Browsable(false)] 
        public ActivityCollection Activities
        { 
            get
            {
                return this.activities;
            } 
        }
 
        protected internal bool CanModifyActivities 
        {
            get 
            {
                return (bool)GetValue(CanModifyActivitiesProperty);
            }
            set 
            {
                SetValue(CanModifyActivitiesProperty, value); 
                if (this.Activities.Count > 0) 
                    SetValue(CustomActivityProperty, true);
            } 
        }

        #endregion
 
        #region CompositeActivity Instance Properties
 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        [Browsable(false)]
        public ReadOnlyCollection EnabledActivities 
        {
            get
            {
                List executableActivities = new List(); 
                foreach (Activity activity in this.activities)
                { 
                    // This check makes sure that only Enabled activities are returned 
                    // and the framwork provided activities are skipped.
                    if (activity.Enabled && !Helpers.IsFrameworkActivity(activity)) 
                        executableActivities.Add(activity);
                }
                return executableActivities.AsReadOnly();
            } 
        }
 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        [Browsable(false)]
        IList ISupportAlternateFlow.AlternateFlowActivities 
        {
            get
            {
                List secondaryFlowActivities = new List(); 
                foreach (Activity activity in this.activities)
                { 
                    if (activity.Enabled && Helpers.IsFrameworkActivity(activity)) 
                        secondaryFlowActivities.Add(activity);
                } 
                return secondaryFlowActivities.AsReadOnly();
            }
        }
 
        internal override Activity TraverseDottedPath(string dottedPath)
        { 
            string subPath = dottedPath; 
            string remainingPath = string.Empty;
            int indexOfDot = dottedPath.IndexOf('.'); 
            if (indexOfDot != -1)
            {
                subPath = dottedPath.Substring(0, indexOfDot);
                remainingPath = dottedPath.Substring(indexOfDot + 1); 
            }
 
            int index = Convert.ToInt32(subPath, CultureInfo.InvariantCulture); 
            if (index >= this.activities.Count)
                return null; 

            Activity nextActivity = this.activities[index];
            if (!string.IsNullOrEmpty(remainingPath))
                return nextActivity.TraverseDottedPath(remainingPath); 
            return nextActivity;
        } 
 
        #endregion
 
        #region Runtime Initialize

        internal override void OnInitializeDefinitionForRuntime()
        { 
            // only if we are in design mode, execute this code, other wise ignore this call
            if (this.DesignMode) 
            { 
                // call base
                base.OnInitializeDefinitionForRuntime(); 

                // get the lookup path
                Activity rootActivity = this.RootActivity;
                Hashtable lookupPaths = (Hashtable)rootActivity.UserData[UserDataKeys.LookupPaths]; 
                string thisLookupPath = (string)lookupPaths[this.QualifiedName];
 
                // call initializeForRuntime for every activity 
                foreach (Activity childActivity in (IList)this.activities)
                { 
                    if (childActivity.Enabled)
                    {
                        // setup lookup path
                        string lookupPath = thisLookupPath; 
                        if (!string.IsNullOrEmpty(thisLookupPath))
                            lookupPath += "."; 
                        lookupPath += this.activities.IndexOf(childActivity).ToString(CultureInfo.InvariantCulture); 
                        lookupPaths.Add(childActivity.QualifiedName, lookupPath);
 
                        // initialize for runtime
                        ((IDependencyObjectAccessor)childActivity).InitializeDefinitionForRuntime(null);
                    }
                    else 
                    {
                        // There are sevrel properties that are required even for disabled activities.  They include 
                        // DottedPath, QualifiedName and Readonly.  To initialize these properties, we call 
                        // OnInitializeDefinitionForRuntime directly and skip the InitializeProperties call inside
                        // IDependencyObjectAccessor.InitializeDefinitionForRuntime because other properties are not 
                        // validated and they may not initialize properly, which the runtime really doesn't care.
                        childActivity.OnInitializeDefinitionForRuntime();
                        childActivity.Readonly = true;
                    } 
                }
            } 
        } 

        internal override void OnInitializeInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime) 
        {
            base.OnInitializeInstanceForRuntime(workflowCoreRuntime);

            // call children to do initialize runtime instance 
            foreach (Activity childActivity in this.activities)
            { 
                if (childActivity.Enabled) 
                    ((IDependencyObjectAccessor)childActivity).InitializeInstanceForRuntime(workflowCoreRuntime);
            } 
        }

        internal override void OnInitializeActivatingInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)
        { 
            // call base: this will call activity
            base.OnInitializeActivatingInstanceForRuntime(workflowCoreRuntime); 
 
            // call children to do initialize runtime instance
            foreach (Activity childActivity in this.activities) 
            {
                if (childActivity.Enabled)
                    ((IDependencyObjectAccessor)childActivity).InitializeActivatingInstanceForRuntime(null, workflowCoreRuntime);
                else 
                    this.Readonly = true;
            } 
        } 

        internal override void FixUpMetaProperties(DependencyObject originalObject) 
        {
            if (originalObject == null)
                throw new ArgumentNullException();
            if (!(originalObject is CompositeActivity)) 
                throw new ArgumentException();
 
            // call base 
            base.FixUpMetaProperties(originalObject);
 
            // ask each child to fixup
            if (this.activities != null)
            {
                CompositeActivity originalCompositeActivity = originalObject as CompositeActivity; 
                if (originalCompositeActivity != null)
                { 
                    int index = 0; 
                    foreach (Activity childActivity in this.activities)
                        childActivity.FixUpMetaProperties(originalCompositeActivity.activities[index++]); 
                }
            }
        }
        internal override void FixUpParentChildRelationship(Activity definitionActivity, Activity parentActivity, Hashtable deserializedActivities) 
        {
            CompositeActivity definitionCompositeActivity = definitionActivity as CompositeActivity; 
            if (definitionCompositeActivity == null) 
                throw new ArgumentException("definitionActivity");
 
            // call base
            base.FixUpParentChildRelationship(definitionActivity, parentActivity, deserializedActivities);

            // fix up the children collection 
            this.activities = new ActivityCollection(this);
            this.activities.ListChanging += new EventHandler(OnListChangingEventHandler); 
            this.activities.ListChanged += new EventHandler(OnListChangedEventHandler); 

            // detect if there was a context 
            string prefix = this.DottedPath;

            // fixup all the children, and then call them to fixup their relation ships
            int index = 0; 
            foreach (Activity definitionChildActivity in definitionCompositeActivity.activities)
            { 
                Activity childActivity = (Activity)deserializedActivities[prefix.Length == 0 ? index.ToString(CultureInfo.InvariantCulture) : prefix + "." + index.ToString(CultureInfo.InvariantCulture)]; 
                this.activities.InnerAdd(childActivity);
 
                // ask child to fix up its parent child relation ship
                childActivity.FixUpParentChildRelationship(definitionChildActivity, this, deserializedActivities);
                index++;
            } 
        }
        internal override IList CollectNestedActivities() 
        { 
            List nestedActivities = new List();
            Queue activityQueue = new Queue(this.activities); 
            while (activityQueue.Count > 0)
            {
                Activity nestedActivity = activityQueue.Dequeue();
                nestedActivities.Add(nestedActivity); 
                if (nestedActivity is CompositeActivity)
                { 
                    foreach (Activity nestedChildActivity in ((CompositeActivity)nestedActivity).activities) 
                        activityQueue.Enqueue(nestedChildActivity);
                } 
            }
            return nestedActivities;
        }
 
        #endregion
 
        #region Collection's Event Handlers 
        private void OnListChangingEventHandler(object sender, ActivityCollectionChangeEventArgs e)
        { 
            if (!this.DesignMode && !this.DynamicUpdateMode)
                throw new InvalidOperationException(SR.GetString(SR.Error_CanNotChangeAtRuntime));

            if (!this.CanModifyActivities) 
            {
                // Check the ActivityType only during design mode 
                if (this.DesignMode && Activity.ActivityType != null && this.GetType() == Activity.ActivityType) 
                    throw new InvalidOperationException(SR.GetString(SR.Error_Missing_CanModifyProperties_True, this.GetType().FullName));
 
                if (!IsDynamicMode(this) && CannotModifyChildren(this, false))
                    throw new InvalidOperationException(SR.GetString(SR.Error_CannotAddRemoveChildActivities));

                if (IsDynamicMode(this) && CannotModifyChildren(this, true)) 
                    throw new InvalidOperationException(SR.GetString(SR.Error_CannotAddRemoveChildActivities));
            } 
 
            if (e.Action == ActivityCollectionChangeAction.Add && e.AddedItems != null)
            { 
                Activity parent = this;
                while (parent != null)
                {
                    if (e.AddedItems.Contains(parent)) 
                        throw new InvalidOperationException(SR.GetString(SR.Error_ActivityCircularReference));
 
                    parent = parent.Parent; 
                }
            } 

            OnListChanging(e);
        }
 
        protected virtual void OnListChanging(ActivityCollectionChangeEventArgs e)
        { 
            if (e == null) 
                throw new ArgumentNullException("e");
            if (e.Action == ActivityCollectionChangeAction.Add && e.AddedItems != null) 
            {
                foreach (Activity activity in e.AddedItems)
                {
                    if (activity.Parent != null) 
                        throw new InvalidOperationException(SR.GetString(SR.Error_ActivityHasParent, activity.QualifiedName, activity.Parent.QualifiedName));
                    if (activity == this) 
                        throw new InvalidOperationException(SR.GetString(SR.Error_Recursion, activity.QualifiedName)); 
                }
            } 
            if (((IComponent)this).Site != null)
            {
                IComponentChangeService changeService = ((IComponent)this).Site.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
                if (changeService != null) 
                    changeService.OnComponentChanging(this, null);
            } 
        } 

        private void OnListChangedEventHandler(object sender, ActivityCollectionChangeEventArgs e) 
        {
            OnListChanged(e);
        }
 
        protected virtual void OnListChanged(ActivityCollectionChangeEventArgs e)
        { 
            if (e == null) 
                throw new ArgumentNullException("e");
            // remove the parent 
            if ((e.Action == ActivityCollectionChangeAction.Replace || e.Action == ActivityCollectionChangeAction.Remove) &&
                    e.RemovedItems != null)
            {
                foreach (Activity activity in e.RemovedItems) 
                    activity.SetParent(null);
            } 
 
            // set the parent on the activity
            if ((e.Action == ActivityCollectionChangeAction.Replace || e.Action == ActivityCollectionChangeAction.Add) && 
                    e.AddedItems != null)
            {
                foreach (Activity activity in e.AddedItems)
                    activity.SetParent(this); 

                Queue queue = new Queue(e.AddedItems as IEnumerable); 
                while (queue.Count > 0) 
                {
                    Activity activity = queue.Dequeue() as Activity; 
                    if (activity != null && (activity.Name == null || activity.Name.Length == 0 || activity.Name == activity.GetType().Name))
                    {
                        Activity rootActivity = Helpers.GetRootActivity(activity);
                        string className = rootActivity.GetValue(WorkflowMarkupSerializer.XClassProperty) as string; 
                        if (rootActivity.Parent == null || !string.IsNullOrEmpty(className))
                        { 
                            ArrayList identifiers = new ArrayList(); 
                            identifiers.AddRange(Helpers.GetIdentifiersInCompositeActivity(rootActivity as CompositeActivity));
                            activity.Name = DesignerHelpers.GenerateUniqueIdentifier(((IComponent)this).Site, Helpers.GetBaseIdentifier(activity), (string[])identifiers.ToArray(typeof(string))); 
                        }
                    }
                    if (activity is CompositeActivity)
                    { 
                        foreach (Activity activity2 in ((CompositeActivity)activity).Activities)
                            queue.Enqueue(activity2); 
                    } 
                }
            } 

            //
            if (((IComponent)this).Site != null)
            { 
                IComponentChangeService changeService = ((IComponent)this).Site.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
                if (changeService != null) 
                    changeService.OnComponentChanged(this, null, e, null); 
            }
        } 

        private static bool IsDynamicMode(CompositeActivity compositeActivity)
        {
            if (compositeActivity == null) 
                throw new ArgumentNullException("compositeActivity");
 
            while (compositeActivity.Parent != null) 
            {
                if (compositeActivity.DynamicUpdateMode) 
                    return true;
                compositeActivity = compositeActivity.Parent;
            }
            return compositeActivity.DynamicUpdateMode; 
        }
 
        private static bool CannotModifyChildren(CompositeActivity compositeActivity, bool parent) 
        {
            if (compositeActivity == null) 
                throw new ArgumentNullException("compositeActivity");

            if (parent && compositeActivity.Parent == null)
                return false; 

            if ((bool)compositeActivity.GetValue(CustomActivityProperty) == true) 
                return true; 

            if (compositeActivity.Parent != null) 
                return CannotModifyChildren(compositeActivity.Parent, parent);

            return false;
        } 

        #endregion 
 
        #region IDisposable
        protected override void Dispose(bool disposing) 
        {
            if (disposing)
            {
                foreach (Activity activity in this.Activities) 
                    activity.Dispose();
            } 
            base.Dispose(disposing); 
        }
        #endregion 
    }
    #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