File: Task.cs
Project: ndp\cdf\src\WF\Activities\System.Workflow.Activities.csproj (System.Workflow.Activities)
#pragma warning disable 1634, 1691
namespace System.Workflow.Activities
{
    #region Using directives
 
    using System;
    using System.Xml.Serialization;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.CodeDom;
    using System.Diagnostics;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Drawing.Design;
    using System.Transactions;
    using System.ComponentModel.Design.Serialization;
    using System.Workflow.ComponentModel;
    using System.Workflow.ComponentModel.Design;
    using System.Workflow.ComponentModel.Compiler;
    using System.Reflection;
    using System.Workflow.Runtime.DebugEngine;
    using System.Workflow.Activities.Common;
 
    #endregion
 
    [SRDescription(SR.ReplicatorActivityDescription)]
    [ToolboxItem(typeof(ActivityToolboxItem))]
    [ToolboxBitmap(typeof(ReplicatorActivity), "Resources.Replicator.png")]
    [Designer(typeof(ReplicatorDesigner), typeof(IDesigner))]
    [ActivityValidator(typeof(ReplicatorValidator))]
    [DefaultEvent("Initialized")]
    [WorkflowDebuggerSteppingAttribute(WorkflowDebuggerSteppingOption.Concurrent)]
    [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
    public sealed class ReplicatorActivity : CompositeActivity
    {
        #region Dependency Properties
        public static readonly DependencyProperty UntilConditionProperty = DependencyProperty.Register("UntilCondition", typeof(ActivityCondition), typeof(ReplicatorActivity), new PropertyMetadata(DependencyPropertyOptions.Metadata));
        public static readonly DependencyProperty ExecutionTypeProperty = DependencyProperty.Register("ExecutionType", typeof(ExecutionType), typeof(ReplicatorActivity), new PropertyMetadata(ExecutionType.Sequence));
 
        //events
        public static readonly DependencyProperty InitializedEvent = DependencyProperty.Register("Initialized", typeof(EventHandler), typeof(ReplicatorActivity));
        public static readonly DependencyProperty CompletedEvent = DependencyProperty.Register("Completed", typeof(EventHandler), typeof(ReplicatorActivity));
        public static readonly DependencyProperty ChildInitializedEvent = DependencyProperty.Register("ChildInitialized", typeof(EventHandler<ReplicatorChildEventArgs>), typeof(ReplicatorActivity));
        public static readonly DependencyProperty ChildCompletedEvent = DependencyProperty.Register("ChildCompleted", typeof(EventHandler<ReplicatorChildEventArgs>), typeof(ReplicatorActivity));
        public static readonly DependencyProperty InitialChildDataProperty = DependencyProperty.Register("InitialChildData", typeof(IList), typeof(ReplicatorActivity));
 
        #endregion
 
        #region Constructors
 
        public ReplicatorActivity()
        {
        }
 
        public ReplicatorActivity(string name)
            : base(name)
        {
        }
 
        #endregion
 
        #region Public Properties
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public ICollection<Activity> DynamicActivities
        {
            get
            {
                if (this.EnabledActivities.Count > 0)
                    return this.GetDynamicActivities(this.EnabledActivities[0]);
                else
                    return new Activity[0];
            }
        }
 
        [Browsable(true)]
        [SRCategory(SR.Properties)]
        [SRDescription(SR.ExecutionTypeDescr)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public ExecutionType ExecutionType
        {
            get
            {
                return (ExecutionType)base.GetValue(ReplicatorActivity.ExecutionTypeProperty);
            }
            set
            {
                if (value != ExecutionType.Sequence && value != ExecutionType.Parallel)
                    throw new ArgumentOutOfRangeException("value");
                if (this.ActivityState != null && this.ActivityState.IsChildActive)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorChildRunning));
 
                base.SetValue(ReplicatorActivity.ExecutionTypeProperty, value);
            }
        }
 
        [Editor(typeof(BindUITypeEditor), typeof(UITypeEditor))]
        [Browsable(true)]
        [SRCategory(SR.Properties)]
        [SRDescription(SR.InitialChildDataDescr)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [DefaultValue(null)]
        public IList InitialChildData
        {
            get
            {
                return base.GetValue(InitialChildDataProperty) as IList;
            }
            set
            {
                base.SetValue(InitialChildDataProperty, value);
            }
        }
 
        ReplicatorChildInstanceList childDataList;
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public IList CurrentChildData
        {
            get
            {
                if (childDataList == null)
                    childDataList = new ReplicatorChildInstanceList(this);
 
                return childDataList;
            }
        }
 
 
        [SRCategory(SR.Conditions)]
        [SRDescription(SR.ReplicatorUntilConditionDescr)]
        [DefaultValue(null)]
        public ActivityCondition UntilCondition
        {
            get
            {
                return base.GetValue(UntilConditionProperty) as ActivityCondition;
            }
            set
            {
                base.SetValue(UntilConditionProperty, value);
            }
        }
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool AllChildrenComplete
        {
            get
            {
                if (this.ActivityState != null)
                    return !this.ActivityState.IsChildActive;
                else
                    return true;
            }
        }
 
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int CurrentIndex
        {
            get
            {
                if (this.ActivityState != null)
                {
                    if (this.ExecutionType == ExecutionType.Sequence)
                        return this.ActivityState.CurrentIndex;
                    else
                        return this.ActivityState.AbsoluteCount - 1;
                }
                else
                    return -1;
 
            }
        }
 
        public bool IsExecuting(int index)
        {
            if (this.ActivityState != null)
            {
                if (index < 0 || index >= this.ActivityState.AbsoluteCount)
                    throw new ArgumentOutOfRangeException("index");
 
                ChildExecutionStateInfo childStateInfo = this.ActivityState[index, false];
                return (childStateInfo.Status == ChildRunStatus.PendingExecute || childStateInfo.Status == ChildRunStatus.Running);
            }
            return false;
        }
 
        #endregion
 
        #region Public Events
        [SRDescription(SR.OnGeneratorChildInitializedDescr)]
        [SRCategory(SR.Handlers)]
        [MergableProperty(false)]
        public event EventHandler<ReplicatorChildEventArgs> ChildInitialized
        {
            add
            {
                base.AddHandler(ChildInitializedEvent, value);
            }
            remove
            {
                base.RemoveHandler(ChildInitializedEvent, value);
            }
        }
 
        [SRDescription(SR.OnGeneratorChildCompletedDescr)]
        [SRCategory(SR.Handlers)]
        [MergableProperty(false)]
        public event EventHandler<ReplicatorChildEventArgs> ChildCompleted
        {
            add
            {
                base.AddHandler(ChildCompletedEvent, value);
            }
            remove
            {
                base.RemoveHandler(ChildCompletedEvent, value);
            }
        }
 
        [SRDescription(SR.OnCompletedDescr)]
        [SRCategory(SR.Handlers)]
        [MergableProperty(false)]
        public event EventHandler Completed
        {
            add
            {
                base.AddHandler(CompletedEvent, value);
            }
            remove
            {
                base.RemoveHandler(CompletedEvent, value);
            }
        }
 
        [SRDescription(SR.OnInitializedDescr)]
        [SRCategory(SR.Handlers)]
        [MergableProperty(false)]
        public event EventHandler Initialized
        {
            add
            {
                base.AddHandler(InitializedEvent, value);
            }
            remove
            {
                base.RemoveHandler(InitializedEvent, value);
            }
        }
 
        #endregion
 
        #region ChildList Manipulation API
        private int Add(object value)
        {
            if (this.ExecutionStatus != ActivityExecutionStatus.Executing)
                throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting));
 
            if (this.ActivityState == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized));
 
            ChildExecutionStateInfo childStateInfo = new ChildExecutionStateInfo(value);
            this.ActivityState.Add(childStateInfo);
 
            int indexOfAdd = this.ActivityState.AbsoluteCount - 1;
            ScheduleExecutionIfNeeded(childStateInfo, indexOfAdd);
            return indexOfAdd;
        }
 
        private int IndexOf(object value)
        {
            if (this.ExecutionStatus != ActivityExecutionStatus.Executing)
                throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting));
 
            if (this.ActivityState == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized));
 
            int absoluteIndex = 0;
 
            for (int i = 0; i < this.ActivityState.Count; ++i)
            {
                ChildExecutionStateInfo childStateInfo = this.ActivityState[i];
 
                if (!childStateInfo.MarkedForRemoval)
                {
                    if (Object.Equals(childStateInfo.InstanceData, value))
                        return absoluteIndex;
                    else
                        ++absoluteIndex;
                }
            }
 
            return -1;
        }
        private void Insert(int index, object value)
        {
            if (value == null)
                throw new ArgumentNullException("value");
 
            if (this.ExecutionStatus != ActivityExecutionStatus.Executing)
                throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting));
 
            if (this.ActivityState == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized));
 
            if (index < 0 || index > this.ActivityState.AbsoluteCount)
                throw new ArgumentOutOfRangeException("index");
 
            ChildExecutionStateInfo childStateInfo = new ChildExecutionStateInfo(value);
            this.ActivityState.Insert(index, childStateInfo, false);
 
            ScheduleExecutionIfNeeded(childStateInfo, index);
        }
        private void Remove(object obj)
        {
            int index = this.IndexOf(obj);
 
            if (index < 0)
                return;
 
            RemoveAt(index);
            return;
        }
        private void RemoveAt(int index)
        {
            if (this.ExecutionStatus != ActivityExecutionStatus.Executing)
                throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting));
 
            if (this.ActivityState == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized));
 
            if (index < 0 || index >= this.ActivityState.AbsoluteCount)
                throw new ArgumentOutOfRangeException("index");
 
            ChildExecutionStateInfo childStateInfo = this.ActivityState[index, false];
 
            if (childStateInfo.Status == ChildRunStatus.Completed || childStateInfo.Status == ChildRunStatus.Created)
                this.ActivityState.Remove(childStateInfo);
            else
            {
                childStateInfo.MarkedForRemoval = true;
                base.Invoke(this.HandleChildUpdateOperation, new ReplicatorInterActivityEventArgs(childStateInfo, false));
            }
        }
 
        private void Clear()
        {
            if (this.ExecutionStatus != ActivityExecutionStatus.Executing)
                throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting));
 
            if (this.ActivityState == null)
                throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized));
 
            while (this.ActivityState.AbsoluteCount != 0)
                this.RemoveAt(0);
        }
        #endregion
 
        #region Protected Methods
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");
 
            this.ActivityState = new ReplicatorStateInfo();
            base.RaiseEvent(ReplicatorActivity.InitializedEvent, this, EventArgs.Empty);
 
            if (this.InitialChildData != null)
            {
                //Add the ChildData to the execution info.
                for (int i = 0; i < this.InitialChildData.Count; ++i)
                {
                    this.Add(this.InitialChildData[i]);
                }
            }
 
            bool bCompleteNow = (this.UntilCondition == null);
 
            if (this.UntilCondition != null && this.UntilCondition.Evaluate(this, executionContext))
                bCompleteNow = true;
            else if (this.ActivityState.Count != 0)
                bCompleteNow = false;
 
            if (bCompleteNow)
            {
                //This is needed to make sure we dont reevaluate this again.
                this.ActivityState.CompletionConditionTrueAlready = true;
 
                //Try cool down child. It is ok to close here immediatley
                //since we are sure we havent executed child yet.
                if (!TryCancelChildren(executionContext))
                {
                    base.RaiseEvent(ReplicatorActivity.CompletedEvent, this, EventArgs.Empty);
                    return ActivityExecutionStatus.Closed;
                }
            }
            return ActivityExecutionStatus.Executing;
        }
 
        protected override ActivityExecutionStatus Cancel(ActivityExecutionContext executionContext)
        {
            if (executionContext == null)
                throw new ArgumentNullException("executionContext");
 
            this.TryCancelChildren(executionContext);
 
            if (!this.ActivityState.IsChildActive)
            {
                //Check to make sure only once we call ReplciatorCompleted when we fault.
                if (this.ExecutionStatus == ActivityExecutionStatus.Faulting)
                {
                    if (this.ActivityState.AttemptedCloseWhileFaulting)
                        return ActivityExecutionStatus.Closed;
 
                    this.ActivityState.AttemptedCloseWhileFaulting = true;
                }
                base.RaiseEvent(ReplicatorActivity.CompletedEvent, this, EventArgs.Empty);
                return ActivityExecutionStatus.Closed;
            }
            return this.ExecutionStatus;
        }
        protected override void OnClosed(IServiceProvider provider)
        {
            //
 
        }
        #endregion
 
        #region Private Implementation
        #region Data
        //Runtime State Properties
        static DependencyProperty ActivityStateProperty = DependencyProperty.Register("ActivityState", typeof(ReplicatorStateInfo), typeof(ReplicatorActivity));
        ReplicatorStateInfo ActivityState
        {
            get
            {
                return (ReplicatorStateInfo)base.GetValue(ActivityStateProperty);
            }
            set
            {
                base.SetValue(ActivityStateProperty, value);
            }
        }
        #endregion
 
        #region Replicator Interactivity Event
        private sealed class ReplicatorInterActivityEventArgs : EventArgs
        {
            #region Data
            private bool isAdd = false;
            private ChildExecutionStateInfo childStateInfo;
            #endregion
 
            #region Properties
            internal bool IsAdd
            {
                get
                {
                    return this.isAdd;
                }
            }
            internal ChildExecutionStateInfo ChildStateInfo
            {
                get
                {
                    return this.childStateInfo;
                }
            }
            #endregion
 
            internal ReplicatorInterActivityEventArgs(ChildExecutionStateInfo childStateInfo, bool isAdd)
            {
                this.childStateInfo = childStateInfo;
                this.isAdd = isAdd;
            }
        }
        void HandleChildUpdateOperation(Object sender, ReplicatorInterActivityEventArgs e)
        {
            if (sender == null)
                throw new ArgumentNullException("sender");
 
            ActivityExecutionContext executionContext = sender as ActivityExecutionContext;
 
            if (executionContext == null)
                throw new ArgumentException(SR.Error_SenderMustBeActivityExecutionContext, "sender");
 
            if (this.ExecutionStatus != ActivityExecutionStatus.Executing)
                return;
 
            if (!e.IsAdd)
            {
                CancelChildExecution(executionContext, e.ChildStateInfo);
            }
            else
            {
                Debug.Assert(this.ActivityState.Contains(e.ChildStateInfo));
                Debug.Assert(e.ChildStateInfo.Status == ChildRunStatus.PendingExecute);
                ExecuteTemplate(executionContext, e.ChildStateInfo);
            }
        }
 
        private void CancelChildExecution(ActivityExecutionContext executionContext, ChildExecutionStateInfo childStateInfo)
        {
            // Mark the Instance For Removal
            System.Diagnostics.Debug.Assert(childStateInfo.MarkedForRemoval);
 
            // check if the instance is currently executing
            if (childStateInfo.Status != ChildRunStatus.Running) //It is passive, then we can safely remove the State.
            {
                this.ActivityState.Remove(childStateInfo);
                return;
            }
 
            // schedule the child cancellation
            // once this run is cancelled, the handleEvent should remove this from execution state.
            TryCancelChild(executionContext, childStateInfo);
        }
        #endregion
 
        #region Execution related helpers
        private void ExecuteTemplate(ActivityExecutionContext executionContext, ChildExecutionStateInfo childStateInfo)
        {
            System.Diagnostics.Debug.Assert(childStateInfo.Status != ChildRunStatus.Running);
 
            ActivityExecutionContextManager contextManager = executionContext.ExecutionContextManager;
            ActivityExecutionContext templateExecutionContext = contextManager.CreateExecutionContext(this.EnabledActivities[0]);
            childStateInfo.RunId = templateExecutionContext.ContextGuid;
            childStateInfo.Status = ChildRunStatus.Running;
            try
            {
                base.RaiseGenericEvent(ReplicatorActivity.ChildInitializedEvent, this, new ReplicatorChildEventArgs(childStateInfo.InstanceData, templateExecutionContext.Activity));
            }
            catch
            {
                childStateInfo.RunId = Guid.Empty;
                childStateInfo.Status = ChildRunStatus.Completed;
                contextManager.CompleteExecutionContext(templateExecutionContext);
                throw;
            }
 
            templateExecutionContext.ExecuteActivity(templateExecutionContext.Activity);
            templateExecutionContext.Activity.RegisterForStatusChange(Activity.ClosedEvent, new ReplicatorSubscriber(this, templateExecutionContext.ContextGuid));
        }
        private void HandleStatusChange(ActivityExecutionContext executionContext, ActivityExecutionStatusChangedEventArgs e, ReplicatorSubscriber subscriber)
        {
            //System.Diagnostics.Debug.Assert(this.ExecutionStatus != ActivityExecutionStatus.Closed, "Stale notification should not have reache here");
            //System.Diagnostics.Debug.Assert(e.Activity.QualifiedName.Equals(this.EnabledActivities[0].QualifiedName), "Got status change notification of non existing child");
            //System.Diagnostics.Debug.Assert(subscriber.RunIdentifier != Guid.Empty, "Got notification from non-running template instance");
 
            //Perform cleanup on completed run.
            int runIndex = this.ActivityState.FindIndexOfChildStateInfo(subscriber.RunIdentifier);
 
            if (runIndex == -1)
            {
                //This will happen when CancelChild is issued after Child Closed 
                //but before StatusChange Event raised on parent.                
                return;
            }
 
            ChildExecutionStateInfo childStateInfo = this.ActivityState[runIndex];
            bool isMarkedForRemoval = childStateInfo.MarkedForRemoval;
 
            try
            {
                try
                {
                    base.RaiseGenericEvent(ReplicatorActivity.ChildCompletedEvent, this, new ReplicatorChildEventArgs(childStateInfo.InstanceData, e.Activity));
                    e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, subscriber);
                }
                finally
                {
                    ActivityExecutionContextManager contextManager = executionContext.ExecutionContextManager;
                    ActivityExecutionContext templateExecutionContext = contextManager.GetExecutionContext(e.Activity);
                    contextManager.CompleteExecutionContext(templateExecutionContext);
                }
 
                //Reevaluate CompletionCondition
                if (!this.ActivityState.CompletionConditionTrueAlready)
                    this.ActivityState.CompletionConditionTrueAlready = (this.UntilCondition != null && this.UntilCondition.Evaluate(this, executionContext));
            }
            finally //Always perform cleanup of just completed child.
            {
                //This will mark child as passive.
                childStateInfo.RunId = Guid.Empty;
                childStateInfo.Status = ChildRunStatus.Completed;
 
                if (isMarkedForRemoval)
                {
                    //This is the case, when user issued CancelChild request on running template instance.
                    //We flush out execution state of that run when it becomes passive.
                    this.ActivityState.Remove(childStateInfo);
                    runIndex = runIndex - 1; //Needed for sequence execution type.
                }
            }
 
            //Next Step.
            if (!this.ActivityState.IsChildActive) //Everything is passive now.
            {
                if (this.ExecutionStatus == ActivityExecutionStatus.Canceling || this.ExecutionStatus == ActivityExecutionStatus.Faulting || this.ActivityState.CompletionConditionTrueAlready)
                {
                    base.RaiseEvent(ReplicatorActivity.CompletedEvent, this, EventArgs.Empty);
                    executionContext.CloseActivity();
                    return;
                }
            }
            else //Template is active; Valid only for parallel
            {
                System.Diagnostics.Debug.Assert(this.ExecutionType == ExecutionType.Parallel);
 
                if (this.ExecutionStatus != ActivityExecutionStatus.Canceling && this.ExecutionStatus != ActivityExecutionStatus.Faulting)
                {
                    if (this.ActivityState.CompletionConditionTrueAlready)
                    {
                        //Try cool down child.
                        TryCancelChildren(executionContext);
                        return;
                    }
                }
            }
 
            switch (this.ExecutionType)
            {
                case ExecutionType.Sequence:
                    if (runIndex < this.ActivityState.Count - 1)
                    {
                        ExecuteTemplate(executionContext, this.ActivityState[runIndex + 1]);
                        return;
                    }
                    else if (this.UntilCondition == null || this.UntilCondition.Evaluate(this, executionContext))
                    {
                        base.RaiseEvent(ReplicatorActivity.CompletedEvent, this, EventArgs.Empty);
                        executionContext.CloseActivity();
                        return;
                    }
                    break;
 
                case ExecutionType.Parallel:
                    if (!this.ActivityState.IsChildActive && (this.UntilCondition == null || (this.UntilCondition.Evaluate(this, executionContext))))
                    {
                        base.RaiseEvent(ReplicatorActivity.CompletedEvent, this, EventArgs.Empty);
                        executionContext.CloseActivity();
                        return;
                    }
                    break;
                default:
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorInvalidExecutionType));
 
            }
        }
        bool TryCancelChildren(ActivityExecutionContext executionContext)
        {
            // returns true iff scheduled cancel on one or more executions of the template
            // false if all executions are already closed
            if (this.ActivityState == null)
                return false;
 
            ReplicatorStateInfo stateInfo = this.ActivityState;
 
            bool fScheduledCancel = false;
            for (int i = 0; i < stateInfo.Count; ++i)
            {
                if (this.TryCancelChild(executionContext, stateInfo[i]))
                {
                    fScheduledCancel = true;
                }
            }
 
            return fScheduledCancel;
        }
        bool TryCancelChild(ActivityExecutionContext outerProvider, ChildExecutionStateInfo childStateInfo)
        {
            // schedule cancellation of the child in the inner execution context
            bool fScheduledCancel = false;
 
            // returns true iff scheduled cancel on one execution of the template
            // false if execution already closed
 
            // get the execution context for this run
            ActivityExecutionContextManager contextManager = outerProvider.ExecutionContextManager;
            ActivityExecutionContext innerProvider = GetExecutionContext(contextManager, childStateInfo.RunId);
            if (innerProvider != null)
            {
                switch (innerProvider.Activity.ExecutionStatus)
                {
                    case ActivityExecutionStatus.Executing:
                        // schedule cancellation on child
                        innerProvider.CancelActivity(innerProvider.Activity);
                        fScheduledCancel = true;
                        break;
 
                    case ActivityExecutionStatus.Canceling:
                    case ActivityExecutionStatus.Faulting:
                        fScheduledCancel = true;
                        break;
 
                    default:
                        // do nothing
                        break;
                }
            }
            else
            {
                //Finish the run if it is pending for execution.
                if (this.ExecutionStatus != ActivityExecutionStatus.Executing && childStateInfo.Status == ChildRunStatus.PendingExecute)
                    childStateInfo.Status = ChildRunStatus.Completed;
            }
            return fScheduledCancel;
        }
 
        private ActivityExecutionContext GetExecutionContext(ActivityExecutionContextManager contextManager, Guid contextIdGuid)
        {
            foreach (ActivityExecutionContext context in contextManager.ExecutionContexts)
                if (context.ContextGuid == contextIdGuid)
                    return context;
 
            return null;
        }
 
        //Schedules execution if mode is parallel or if the insert is at head of empty list
        //or tail of all completed list in sequence case.
        void ScheduleExecutionIfNeeded(ChildExecutionStateInfo childStateInfo, int index)
        {
            bool bShouldExecute = (this.ExecutionType == ExecutionType.Parallel);
 
            if (!bShouldExecute) //Sequence Case.
            {
                //Execute if its head and only node or tail and previous tail already completed.
                int totalListSize = this.ActivityState.AbsoluteCount;
 
                if ((index == 0 && totalListSize == 1) || ((index == totalListSize - 1) && this.ActivityState[totalListSize - 2, false].Status == ChildRunStatus.Completed))
                    bShouldExecute = true;
            }
 
            if (bShouldExecute)
            {
                childStateInfo.Status = ChildRunStatus.PendingExecute;
                base.Invoke(this.HandleChildUpdateOperation, new ReplicatorInterActivityEventArgs(childStateInfo, true));
            }
        }
        #endregion
 
        #region Execution related Data structures
        [Serializable]
        class ReplicatorSubscriber : IActivityEventListener<ActivityExecutionStatusChangedEventArgs>
        {
            #region Data
            private Guid runId;
            internal Guid RunIdentifier
            {
                get { return this.runId; }
            }
            #endregion
 
            internal ReplicatorSubscriber(Activity ownerActivity, Guid runIdentifier)
                : base()
            {
                this.runId = runIdentifier;
            }
 
            #region IActivityEventListener<ActivityExecutionStatusChangedEventArgs> Members
            void IActivityEventListener<ActivityExecutionStatusChangedEventArgs>.OnEvent(object sender, ActivityExecutionStatusChangedEventArgs e)
            {
                if (sender == null)
                    throw new ArgumentNullException("sender");
 
                ActivityExecutionContext context = sender as ActivityExecutionContext;
 
                if (context == null)
                    throw new ArgumentException(SR.Error_SenderMustBeActivityExecutionContext, "sender");
 
                //
 
 
 
                ((ReplicatorActivity)context.Activity).HandleStatusChange(context, e, this);
            }
            #endregion
 
            #region Object Overrides
            public override bool Equals(object obj)
            {
                ReplicatorSubscriber subscriber = obj as ReplicatorSubscriber;
                return (subscriber != null && base.Equals(obj) && (this.runId.Equals(subscriber.runId)));
            }
            public override int GetHashCode()
            {
                return base.GetHashCode() ^ this.runId.GetHashCode();
            }
            #endregion
        }
 
        [Serializable]
        class ReplicatorStateInfo : List<ChildExecutionStateInfo>
        {
            //Fields / Properties
            internal bool CompletionConditionTrueAlready = false;
            internal bool AttemptedCloseWhileFaulting = false;
            internal bool IsChildActive
            {
                get
                {
                    for (int i = 0; i < this.Count; ++i)
                    {
                        ChildExecutionStateInfo childStateInfo = this[i];
                        if (childStateInfo.Status == ChildRunStatus.Running || childStateInfo.Status == ChildRunStatus.PendingExecute)
                            return true;
                    }
 
                    return false;
                }
            }
 
            internal int CurrentIndex
            {
                get
                {
                    for (int i = 0; i < this.AbsoluteCount; ++i)
                    {
                        if (this[i, false].RunId != Guid.Empty)
                            return i;
                    }
 
                    return this.AbsoluteCount - 1;
                }
            }
 
            //Helper Methods
            internal int FindIndexOfChildStateInfo(Guid runId)
            {
                for (int i = 0; i < this.Count; ++i)
                {
                    ChildExecutionStateInfo childStateInfo = this[i];
 
                    if (childStateInfo.RunId == runId)
                        return i;
                }
 
                Debug.Assert(false, "Child State Info not Found for the RunID");
                throw new IndexOutOfRangeException();
            }
            internal ChildExecutionStateInfo this[int index, bool includeStaleEntries]
            {
                get
                {
                    if (includeStaleEntries)
                        return this[index];
 
                    for (int i = 0; i < this.Count; ++i)
                    {
                        if (!this[i].MarkedForRemoval && index-- == 0)
                            return this[i];
                    }
 
                    throw new IndexOutOfRangeException();
                }
            }
 
            internal void Insert(int index, ChildExecutionStateInfo value, bool includeStaleEntries)
            {
                if (includeStaleEntries)
                {
                    Insert(index, value);
                    return;
                }
 
                int indexOfInsert = 0;
                for (indexOfInsert = 0; (indexOfInsert < this.Count) && index > 0; ++indexOfInsert)
                {
                    if (!this[indexOfInsert].MarkedForRemoval)
                        --index;
                }
 
                if (index == 0)
                    Insert(indexOfInsert, value);
                else
                    throw new IndexOutOfRangeException();
            }
 
            internal int Add(ChildExecutionStateInfo value, bool includeStaleEntries)
            {
                base.Add(value);
 
                if (includeStaleEntries)
                    return base.Count - 1;
                else
                    return this.AbsoluteCount - 1;
            }
 
            internal int AbsoluteCount
            {
                get
                {
                    int absoluteCount = 0;
                    int counter = 0;
 
                    while (counter < this.Count)
                    {
                        if (!this[counter++].MarkedForRemoval)
                            ++absoluteCount;
                    }
                    return absoluteCount;
                }
            }
        }
 
        [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
        enum ChildRunStatus : byte
        {
            Created, PendingExecute, Running, Completed
        }
 
        [Serializable]
        class ChildExecutionStateInfo
        {
            Object data;
            Guid runId;
            bool markedForRemoval;
            ChildRunStatus status;
 
            internal ChildRunStatus Status
            {
                get
                {
                    return this.status;
                }
                set
                {
                    this.status = value;
                }
            }
 
            internal Object InstanceData
            {
                get
                {
                    return this.data;
                }
                set
                {
                    this.data = value;
                }
            }
 
            internal Guid RunId
            {
                get
                {
                    return this.runId;
                }
                set
                {
                    this.runId = value;
                }
            }
 
            internal bool MarkedForRemoval
            {
                get
                {
                    return this.markedForRemoval;
                }
                set
                {
                    this.markedForRemoval = value;
                }
            }
 
            internal ChildExecutionStateInfo(Object instanceData)
            {
                this.data = instanceData;
                this.markedForRemoval = false;
                this.status = ChildRunStatus.Created;
            }
        }
        #endregion
 
 
        #endregion
 
        #region Replicator Child List Implementation
        [Serializable]
        private sealed class ReplicatorChildInstanceList : IList
        {
            ReplicatorActivity replicatorActivity;
 
            internal ReplicatorChildInstanceList(ReplicatorActivity replicatorActivity)
            {
                this.replicatorActivity = replicatorActivity;
            }
 
            #region IList Members
 
            int IList.Add(object value)
            {
                if (replicatorActivity == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorDisconnected));
 
                return replicatorActivity.Add(value);
            }
 
            void IList.Clear()
            {
                if (replicatorActivity == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorDisconnected));
 
                replicatorActivity.Clear();
            }
 
            bool IList.Contains(object value)
            {
                if (replicatorActivity == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorDisconnected));
 
                return replicatorActivity.IndexOf(value) != -1;
            }
 
            int IList.IndexOf(object value)
            {
                if (replicatorActivity == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorDisconnected));
 
                return replicatorActivity.IndexOf(value);
            }
 
            void IList.Insert(int index, object value)
            {
                if (replicatorActivity == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorDisconnected));
 
                replicatorActivity.Insert(index, value);
            }
 
            bool IList.IsFixedSize
            {
                get
                {
                    return false;
                }
            }
 
            bool IList.IsReadOnly
            {
                get
                {
                    return false;
                }
            }
 
            void IList.Remove(object value)
            {
                if (replicatorActivity == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorDisconnected));
 
                replicatorActivity.Remove(value);
            }
 
            void IList.RemoveAt(int index)
            {
                if (replicatorActivity == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorDisconnected));
 
                replicatorActivity.RemoveAt(index);
            }
 
            object IList.this[int index]
            {
                get
                {
                    if (replicatorActivity == null)
                        throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorDisconnected));
 
                    if (replicatorActivity.ExecutionStatus != ActivityExecutionStatus.Executing)
                        throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting));
 
                    if (replicatorActivity.ActivityState == null)
                        throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized));
 
                    return replicatorActivity.ActivityState[index, false].InstanceData;
                }
                set
                {
                    if (replicatorActivity == null)
                        throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorDisconnected));
 
                    if (replicatorActivity.ExecutionStatus != ActivityExecutionStatus.Executing)
                        throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting));
 
                    if (replicatorActivity.ActivityState == null)
                        throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized));
 
                    replicatorActivity.ActivityState[index, false].InstanceData = value;
                }
            }
 
            #endregion
 
            #region ICollection Members
 
            void ICollection.CopyTo(Array array, int index)
            {
                if (replicatorActivity == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorDisconnected));
 
                if (replicatorActivity.ExecutionStatus != ActivityExecutionStatus.Executing)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting));
 
                if (replicatorActivity.ActivityState == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized));
 
                if (array == null)
                    throw new ArgumentNullException("array");
 
                if (array.Rank != 1)
                    throw new ArgumentException(SR.GetString(SR.Error_MultiDimensionalArray), "array");
 
                if (index < 0)
                    throw new ArgumentOutOfRangeException("index");
 
                if (array.Length - index < replicatorActivity.ActivityState.AbsoluteCount)
                    throw new ArgumentException(SR.GetString(SR.Error_InsufficientArrayPassedIn), "array");
 
                for (int i = 0; i < replicatorActivity.ActivityState.AbsoluteCount; ++i)
                {
                    array.SetValue(replicatorActivity.ActivityState[i, false].InstanceData, i + index);
                }
            }
 
            int ICollection.Count
            {
                get
                {
#pragma warning disable 56503
                    if (replicatorActivity == null)
                        throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorDisconnected));
 
                    if (replicatorActivity.ExecutionStatus != ActivityExecutionStatus.Executing)
                        throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting));
 
                    if (replicatorActivity.ActivityState == null)
                        throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized));
 
                    return replicatorActivity.ActivityState.AbsoluteCount;
#pragma warning restore 56503
                }
            }
 
            bool ICollection.IsSynchronized
            {
                get
                {
                    return false;
                }
            }
 
            object ICollection.SyncRoot
            {
                get
                {
#pragma warning disable 56503
                    throw new NotImplementedException();
#pragma warning restore 56503
                }
            }
 
            #endregion
 
            #region IEnumerable Members
 
            IEnumerator IEnumerable.GetEnumerator()
            {
                if (replicatorActivity == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorDisconnected));
 
                if (replicatorActivity.ExecutionStatus != ActivityExecutionStatus.Executing)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotExecuting));
 
                if (replicatorActivity.ActivityState == null)
                    throw new InvalidOperationException(SR.GetString(SR.Error_ReplicatorNotInitialized));
 
                for (int i = 0; i < replicatorActivity.ActivityState.AbsoluteCount; ++i)
                    yield return replicatorActivity.ActivityState[i, false].InstanceData;
 
            }
 
            #endregion
        }
        #endregion
    }
 
    #region ReplicatorEventArgs
    [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
    public sealed class ReplicatorChildEventArgs : EventArgs
    {
        private object instanceData = null;
        private Activity activity = null;
 
        public ReplicatorChildEventArgs(object instanceData, Activity activity)
        {
            this.instanceData = instanceData;
            this.activity = activity;
        }
 
        public object InstanceData
        {
            get
            {
                return this.instanceData;
            }
        }
 
        public Activity Activity
        {
            get
            {
                return this.activity;
            }
        }
    }
    #endregion
 
    #region Execution Type Enum
    [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
    public enum ExecutionType
    {
        Sequence = 0,
        Parallel = 1
    }
    #endregion
 
    #region Validator
    internal sealed class ReplicatorValidator : CompositeActivityValidator
    {
        public override ValidationErrorCollection Validate(ValidationManager manager, object obj)
        {
            ValidationErrorCollection validationErrors = base.Validate(manager, obj);
 
            ReplicatorActivity replicator = obj as ReplicatorActivity;
            if (replicator == null)
                throw new ArgumentException(SR.GetString(SR.Error_UnexpectedArgumentType, typeof(ReplicatorActivity).FullName), "obj");
 
            if ((replicator.EnabledActivities.Count != 1))
                validationErrors.Add(new ValidationError(SR.GetString(SR.Error_GeneratorShouldContainSingleActivity), ErrorNumbers.Error_GeneratorShouldContainSingleActivity));
 
            return validationErrors;
        }
    }
    #endregion
}