File: AuthoringOM\Activity.cs
Project: ndp\cdf\src\WF\Common\System.Workflow.ComponentModel.csproj (System.Workflow.ComponentModel)
#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<Activity>))]
    [Designer(typeof(ActivityDesigner), typeof(IDesigner))]
    [Designer(typeof(ActivityDesigner), typeof(IRootDesigner))]
    [ToolboxItem(typeof(ActivityToolboxItem))]
    [RuntimeNameProperty("Name")]
    [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
    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<String>), 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<Activity>), 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;
        }
 
        /// <summary>
        /// Derived implementation may do necessary cleanup here such as removing serializable instance 
        /// dependency properties before the activity status is set to closed.
        /// </summary>
        protected virtual void OnClosed(IServiceProvider provider)
        {
        }
 
        /// <summary>
        /// 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.
        /// </summary>
        /// <param name="serviceProvider"></param>
        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<T>(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<T>[] eventHandlers = ((IDependencyObjectAccessor)this).GetInvocationList<EventHandler<T>>(dependencyEvent);
            if (eventHandlers != null)
            {
                foreach (EventHandler<T> 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<EventHandler>(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<T>(EventHandler<T> 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<T> activityExecutorDelegate = null;
            using (this.WorkflowCoreRuntime.SetCurrentActivity(this))
                activityExecutorDelegate = new ActivityExecutorDelegateInfo<T>(handler, this.ContextActivity);
 
            activityExecutorDelegate.InvokeDelegate(this.WorkflowCoreRuntime.CurrentActivity.ContextActivity, e, false);
        }
 
        protected internal void Invoke<T>(IActivityEventListener<T> 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<T> activityExecutorDelegate = null;
            using (this.WorkflowCoreRuntime.SetCurrentActivity(this))
                activityExecutorDelegate = new ActivityExecutorDelegateInfo<T>(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<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public event EventHandler<ActivityExecutionStatusChangedEventArgs> StatusChanged
        {
            add
            {
                this.AddStatusChangeHandler(StatusChangedEvent, value);
            }
            remove
            {
                this.RemoveStatusChangeHandler(StatusChangedEvent, value);
            }
        }
 
        internal static readonly DependencyProperty LockCountOnStatusChangeChangedEvent = DependencyProperty.Register("LockCountOnStatusChangeChanged", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
        internal static readonly DependencyProperty StatusChangedLockedEvent = DependencyProperty.Register("StatusChangedLocked", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
        internal void HoldLockOnStatusChange(IActivityEventListener<ActivityExecutionStatusChangedEventArgs> eventListener)
        {
            this.RegisterForStatusChange(StatusChangedLockedEvent, eventListener);
 
            // increment count
            this.SetValue(LockCountOnStatusChangeProperty, this.LockCountOnStatusChange + 1);
        }
        internal void ReleaseLockOnStatusChange(IActivityEventListener<ActivityExecutionStatusChangedEventArgs> 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<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public event EventHandler<ActivityExecutionStatusChangedEventArgs> Canceling
        {
            add
            {
                this.AddStatusChangeHandler(CancelingEvent, value);
            }
            remove
            {
                this.RemoveStatusChangeHandler(CancelingEvent, value);
            }
        }
 
        public static readonly DependencyProperty FaultingEvent = DependencyProperty.Register("Faulting", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public event EventHandler<ActivityExecutionStatusChangedEventArgs> Faulting
        {
            add
            {
                this.AddStatusChangeHandler(FaultingEvent, value);
            }
            remove
            {
                this.RemoveStatusChangeHandler(FaultingEvent, value);
            }
        }
 
 
        public static readonly DependencyProperty ClosedEvent = DependencyProperty.Register("Closed", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public event EventHandler<ActivityExecutionStatusChangedEventArgs> Closed
        {
            add
            {
                this.AddStatusChangeHandler(ClosedEvent, value);
            }
            remove
            {
                this.RemoveStatusChangeHandler(ClosedEvent, value);
            }
        }
 
        public static readonly DependencyProperty ExecutingEvent = DependencyProperty.Register("Executing", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public event EventHandler<ActivityExecutionStatusChangedEventArgs> Executing
        {
            add
            {
                this.AddStatusChangeHandler(ExecutingEvent, value);
            }
            remove
            {
                this.RemoveStatusChangeHandler(ExecutingEvent, value);
            }
        }
 
        public static readonly DependencyProperty CompensatingEvent = DependencyProperty.Register("Compensating", typeof(EventHandler<ActivityExecutionStatusChangedEventArgs>), typeof(Activity));
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public event EventHandler<ActivityExecutionStatusChangedEventArgs> Compensating
        {
            add
            {
                this.AddStatusChangeHandler(CompensatingEvent, value);
            }
            remove
            {
                this.RemoveStatusChangeHandler(CompensatingEvent, value);
            }
        }
        private void AddStatusChangeHandler(DependencyProperty dependencyProp, EventHandler<ActivityExecutionStatusChangedEventArgs> 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<ActivityExecutionStatusChangedEventArgs>(true, delegateValue, this.ContextActivity ?? this.RootActivity));
        }
        private void RemoveStatusChangeHandler(DependencyProperty dependencyProp, EventHandler<ActivityExecutionStatusChangedEventArgs> delegateValue)
        {
            if (this.DependencyPropertyValues.ContainsKey(dependencyProp))
            {
                IList handlers = this.DependencyPropertyValues[dependencyProp] as IList;
                if (handlers != null)
                {
                    handlers.Remove(new ActivityExecutorDelegateInfo<ActivityExecutionStatusChangedEventArgs>(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<ActivityExecutionStatusChangedEventArgs> 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<ActivityExecutionStatusChangedEventArgs>(true, activityStatusChangeListener, this.ContextActivity));
        }
        public void UnregisterForStatusChange(DependencyProperty dependencyProp, IActivityEventListener<ActivityExecutionStatusChangedEventArgs> 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<ActivityExecutionStatusChangedEventArgs>(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<Activity> 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<Activity> deserializedActivityRootsQueue = new Queue<Activity>();
                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<Activity> deserializedNestedActivityRoots = (IList<Activity>)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<Activity> nestedActivities = (IList<Activity>)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<Activity> activityRootsQueue = new Queue<Activity>();
            activityRootsQueue.Enqueue(seedActivity);
            while (activityRootsQueue.Count > 0)
            {
                Activity activityRoot = activityRootsQueue.Dequeue();
                if (activityRoot.IsContextActivity)
                {
                    ContextIdToActivityMap[activityRoot.ContextId] = activityRoot;
                    IList<Activity> activeActivityRoots = (IList<Activity>)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<String> handles = (ICollection<String>)GetValue(SynchronizationHandlesProperty);
                if (this.SupportsTransaction)
                {
                    if (handles == null)
                        handles = new List<string>();
                    handles.Add(TransactionScopeActivity.TransactionScopeActivityIsolationHandle);
                }
                if (handles != null)
                    this.SetValue(SynchronizationHandlesProperty, new ReadOnlyCollection<string>(new List<string>(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<Activity> 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<ActivityExecutionStatusChangedEventArgs> 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<ActivityExecutionContextInfo> childsCompletedContexts = contextActivity.GetValue(Activity.CompletedExecutionContextsProperty) as IList<ActivityExecutionContextInfo>;
 
                    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<ActivityExecutionContextInfo> childsCompletedContexts = activity.GetValue(Activity.CompletedExecutionContextsProperty) as IList<ActivityExecutionContextInfo>;
 
            if (childsCompletedContexts != null && childsCompletedContexts.Count > 0)
            {
                IList<ActivityExecutionContextInfo> childsCompletedContextsClone = new List<ActivityExecutionContextInfo>(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<ActivityExecutionContextInfo> childsCompletedContexts = this.GetValue(Activity.CompletedExecutionContextsProperty) as IList<ActivityExecutionContextInfo>;
                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<Activity> completedActivities = new Queue<Activity>();
                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<CompositeActivity>))]
    [TypeDescriptionProvider(typeof(CompositeActivityTypeDescriptorProvider))]
    [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
    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<ActivityCollectionChangeEventArgs>(OnListChangingEventHandler);
            this.activities.ListChanged += new EventHandler<ActivityCollectionChangeEventArgs>(OnListChangedEventHandler);
 
            SetValue(CanModifyActivitiesProperty, false);
        }
 
        public CompositeActivity(IEnumerable<Activity> 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<ActivityCollectionChangeEventArgs>(OnListChangingEventHandler);
            this.activities.ListChanged += new EventHandler<ActivityCollectionChangeEventArgs>(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<Activity> dynamicActivities = new List<Activity>();
            if (contextActivity != null)
            {
                IList<Activity> activeContextActivities = (IList<Activity>)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<Activity> EnabledActivities
        {
            get
            {
                List<Activity> executableActivities = new List<Activity>();
                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<Activity> ISupportAlternateFlow.AlternateFlowActivities
        {
            get
            {
                List<Activity> secondaryFlowActivities = new List<Activity>();
                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<ActivityCollectionChangeEventArgs>(OnListChangingEventHandler);
            this.activities.ListChanged += new EventHandler<ActivityCollectionChangeEventArgs>(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<Activity> CollectNestedActivities()
        {
            List<Activity> nestedActivities = new List<Activity>();
            Queue<Activity> activityQueue = new Queue<Activity>(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<Activity> queue = new Queue<Activity>(e.AddedItems as IEnumerable<Activity>);
                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
}