private static IWfTransitionDescriptor CreateMainStreamActivities(IWfActivity activityToAppend, IWfActivity startActivity, IWfActivity endActivity, IWfTransitionDescriptor entryTransition, WfControlOperationType operationType)
        {
            bool useOriginal = true;
            IWfTransitionDescriptor resultTransition = null;

            if (activityToAppend.Process.MainStream != null)
            {
                IWfActivityDescriptor startActDesp = startActivity.GetMainStreamActivityDescriptor();
                IWfActivityDescriptor endActDesp   = endActivity.GetMainStreamActivityDescriptor();

                if (startActDesp != null && endActDesp != null)
                {
                    WfCopyMainStreamContext context = new WfCopyMainStreamContext(startActDesp, endActivity.Descriptor, entryTransition, true);

                    FillCopyContext(context.StartActivityDescriptor, endActDesp, context, operationType);

                    resultTransition = context.StartActivityDescriptor.GenerateCopiedActivitiesDescriptors(activityToAppend.Process, activityToAppend.Descriptor, context, operationType);
                    useOriginal      = false;
                }
            }

            if (useOriginal)
            {
                OriginalCreateMainStreamActivities(activityToAppend, startActivity, endActivity, entryTransition, operationType);
            }

            return(resultTransition);
        }
        /// <summary>
        /// 历史实现规则。当流程不存在MainStream属性时,采用从当前流程活动中爬出来
        /// </summary>
        /// <param name="activityToAppend"></param>
        /// <param name="startActivity"></param>
        /// <param name="endActivity"></param>
        /// <param name="operationType"></param>
        private static void OriginalCreateMainStreamActivities(IWfActivity activityToAppend, IWfActivity startActivity, IWfActivity endActivity, IWfTransitionDescriptor entryTransition, WfControlOperationType operationType)
        {
            WfCopyMainStreamContext context = new WfCopyMainStreamContext(startActivity.Descriptor, endActivity.Descriptor, entryTransition, false);

            FillCopyContext(context.StartActivityDescriptor, endActivity.Descriptor, context, operationType);

            context.StartActivityDescriptor.GenerateCopiedActivitiesDescriptors(activityToAppend.Process, activityToAppend.Descriptor, context, operationType);
        }
        /// <summary>
        /// 复制所有的后续活动(没有连线)
        /// </summary>
        /// <param name="context"></param>
        /// <param name="operationType"></param>
        internal void CloneRelativeActivities(IWfProcess processInstance, WfCopyMainStreamContext context, WfControlOperationType operationType)
        {
            if (this.NeedCopy)
            {
                if (context.ClonedActivities.ContainsKey(this.TemplateActivityDescriptor.Key) == false)
                {
                    IWfActivityDescriptor clonedActDesp = CreateClonedActivityDescriptor(processInstance, context, operationType);

                    context.ClonedActivities.Add(this.TemplateActivityDescriptor.Key, clonedActDesp);

                    this.ToActivities.ForEach(sub => sub.ActivityNode.CloneRelativeActivities(processInstance, context, operationType));
                }
            }
        }
        private IWfActivityDescriptor CreateClonedActivityDescriptor(IWfProcess processInstance, WfCopyMainStreamContext context, WfControlOperationType operationType)
        {
            WfActivityDescriptor result = this.TemplateActivityDescriptor.Clone() as WfActivityDescriptor;

            result.Key = processInstance.Descriptor.FindNotUsedActivityKey();

            //2012/12/03 修改克隆时向开始环节转换时需要设置的属性
            if (this.TemplateActivityDescriptor.ActivityType == WfActivityType.InitialActivity && operationType == WfControlOperationType.Return)
            {
                ResetPropertiesByDefinedName(result, "DefaultReturnToInitialActivityTemplate");
            }

            //如果模板活动不是主线活动,则使用该活动的关联Key,否则去实例上查找主线活动对应活动的关联Key。
            if (this.TemplateActivityDescriptor.IsMainStreamActivity == false)
            {
                result.AssociatedActivityKey = this.TemplateActivityDescriptor.GetAssociatedActivity().Key;

                result.ClonedKey = this.TemplateActivityDescriptor.Key;
            }
            else
            {
                IWfActivityDescriptor matchActDesp = FindActivityDescriptorByMainStreamKey(processInstance, this.TemplateActivityDescriptor.Key);

                if (matchActDesp != null)
                {
                    result.AssociatedActivityKey = matchActDesp.Key;

                    result.ClonedKey = matchActDesp.Key;
                }
            }

            //如果原来活动上没有配置资源,则使用原来活动实例的指派人作为资源
            if (result.Resources.Count == 0)
            {
                result.Resources.CopyFrom(this.TemplateActivityDescriptor.Instance.Assignees.ToResources());
            }

            WfActivityBase newActivity = WfActivityBase.CreateActivityInstance(result, processInstance);

            if (context.IsMainStream)
            {
                newActivity.MainStreamActivityKey = this.TemplateActivityDescriptor.Key;
            }

            //沈峥调整,生成资源
            if (result.Resources.Count == 0)
            {
                newActivity.Candidates.CopyFrom(this.TemplateActivityDescriptor.Instance.Candidates);

                if (newActivity.Candidates.Count == 0)
                {
                    IWfActivityDescriptor matchActDesp = FindActivityDescriptorByMainStreamKey(processInstance, this.TemplateActivityDescriptor.Key);

                    if (matchActDesp != null && OguBase.IsNotNullOrEmpty(matchActDesp.Instance.Operator))
                    {
                        newActivity.Candidates.Add(matchActDesp.Instance.Operator);
                    }
                }

                newActivity.Assignees.CopyFrom(newActivity.Candidates);
            }
            else
            {
                if (newActivity.Descriptor.Properties.GetValue("AutoGenerateCadidates", true))
                {
                    newActivity.GenerateCandidatesFromResources();
                    newActivity.Assignees.Clear();
                    newActivity.Assignees.CopyFrom(newActivity.Candidates);
                }
                else
                {
                    newActivity.Candidates.Clear();
                    newActivity.Assignees.Clear();

                    //仅复制能够和直接转换为用户的角色
                    foreach (IUser user in result.Resources.ToUsers())
                    {
                        newActivity.Candidates.Add(user);
                        newActivity.Assignees.Add(user);
                    }
                }
            }

            processInstance.Descriptor.Activities.Add(result);

            return(result);
        }
        /// <summary>
        /// 克隆后续的活动并且连线
        /// </summary>
        /// <param name="endActivity"></param>
        /// <param name="context"></param>
        /// <param name="operationType"></param>
        private void GenerateSubActivitiesDescriptors(IWfProcess processInstance, IWfActivityDescriptor endActivity, IWfActivityDescriptor lastActDesp, WfCopyMainStreamContext context, WfControlOperationType operationType)
        {
            foreach (WfCopyMainStreamSubActivityNode subNode in this.ToActivities)
            {
                IWfActivityDescriptor targetActDesp = null;

                if (subNode.ActivityNode.NeedCopy)
                {
                    if (context.ClonedActivities.TryGetValue(subNode.ActivityNode.TemplateActivityDescriptor.Key, out targetActDesp) == false)
                    {
                        targetActDesp = subNode.ActivityNode.CreateClonedActivityDescriptor(processInstance, context, operationType);
                        context.ClonedActivities.Add(subNode.ActivityNode.TemplateActivityDescriptor.Key, targetActDesp);
                    }
                }
                else
                {
                    targetActDesp = subNode.ActivityNode.OriginalActivityDescriptor;
                    //targetActDesp = subNode.ActivityNode.TemplateActivityDescriptor;
                }

                //本身是复制点,则必须复制线
                if (this.NeedCopy)
                {
                    WfTransitionDescriptor clonedTransition = (WfTransitionDescriptor)((WfTransitionDescriptor)subNode.FromTransition).Clone();

                    //沈峥注释,2015-6-25,FindNotUsedTransitionKey应该从实例流程查找
                    //if (clonedTransition.Key.IsNullOrEmpty())
                    //    clonedTransition.Key = subNode.ActivityNode.TemplateActivityDescriptor.Process.FindNotUsedTransitionKey();
                    if (clonedTransition.Key.IsNullOrEmpty())
                    {
                        clonedTransition.Key = endActivity.Process.FindNotUsedTransitionKey();
                    }

                    if (this.IsEndActivity)
                    {
                        string targetAssociatedKey = null;

                        //沈峥调整,2015-1-24,目标点非Clone点且是加签点
                        if (targetActDesp.ClonedKey.IsNullOrEmpty() && targetActDesp.GetAssociatedActivity() != null)
                        {
                            targetAssociatedKey = targetActDesp.GetAssociatedActivity().Key;
                        }

                        if (lastActDesp != null && targetAssociatedKey != null && lastActDesp.GetAssociatedActivity().Key == targetAssociatedKey)
                        {
                            targetActDesp = lastActDesp;
                        }
                    }

                    endActivity.ToTransitions.AddTransition(targetActDesp, clonedTransition);
                }

                subNode.ActivityNode.GenerateSubActivitiesDescriptors(processInstance, targetActDesp, lastActDesp, context, operationType);
            }
        }
        /// <summary>
        /// 将MainStreamContext中的活动,复制到某个活动后
        /// </summary>
        /// <param name="processInstance"></param>
        /// <param name="activityToAppend"></param>
        /// <param name="context"></param>
        /// <param name="operationType"></param>
        /// <returns>返回的第一个Clone活动的出线</returns>
        public IWfTransitionDescriptor GenerateCopiedActivitiesDescriptors(IWfProcess processInstance, IWfActivityDescriptor activityToAppend, WfCopyMainStreamContext context, WfControlOperationType operationType)
        {
            IWfTransitionDescriptor resultTransition = null;

            CloneRelativeActivities(activityToAppend.ProcessInstance, context, operationType);

            IWfActivityDescriptor clonedActDesp = null;

            if (context.ClonedActivities.TryGetValue(this._TemplateActivityDescriptor.Key, out clonedActDesp))
            {
                //如果本活动是模板生成的动态活动,且退件的目标不是模板,则删除后续的动态活动
                if (activityToAppend.GeneratedByTemplate && clonedActDesp.GeneratedByTemplate == false)
                {
                    IWfTransitionDescriptor templateTransition = activityToAppend.ToTransitions.Find(t => t.GeneratedByTemplate);

                    while (templateTransition != null)
                    {
                        IWfActivityDescriptor actDesp = templateTransition.ToActivity;

                        //如果线的目标活动是动态活动,则删除,否则忽略
                        if (actDesp.GeneratedByTemplate)
                        {
                            actDesp.Instance.Delete();
                        }

                        templateTransition = templateTransition.ToActivity.ToTransitions.Find(t => t.GeneratedByTemplate);
                    }
                }

                IWfTransitionDescriptor lastTransition = context.EntryTransition;

                if (lastTransition == null)
                {
                    lastTransition = activityToAppend.ToTransitions.GetAllCanTransitForwardTransitions().FindDefaultSelectTransition();
                }

                IWfActivityDescriptor lastActDesp = null;

                if (lastTransition != null)
                {
                    lastActDesp = lastTransition.ToActivity;
                }

                string entryTransitionKey = (lastTransition != null) ? lastTransition.Key : string.Empty;

                //将第一个克隆的活动与原流程的某一个活动关联。
                //保留退回线
                IList <IWfTransitionDescriptor> originalBackwardTransitions = activityToAppend.ToTransitions.FindAll(t => t.IsBackward);

                activityToAppend.ToTransitions.Clear();

                foreach (WfTransitionDescriptor t in originalBackwardTransitions)
                {
                    WfTransitionDescriptor newBackwardTransition = (WfTransitionDescriptor)t.Clone();

                    newBackwardTransition.Key = activityToAppend.Process.FindNotUsedTransitionKey();
                    activityToAppend.ToTransitions.AddTransition(t.ToActivity, newBackwardTransition);
                }

                //activityToAppend.ToTransitions.CopyFrom(originalBackwardTransitions);

                IWfTransitionDescriptor newTransition = JoinOriginalActivityToClonedActivity(activityToAppend, clonedActDesp, lastTransition);

                resultTransition = newTransition;

                //将自动流转设置为False
                if (clonedActDesp.Properties.GetValue("AutoMoveTo", false))
                {
                    clonedActDesp.Properties.TrySetValue("AutoMoveTo", false);
                }

                GenerateSubActivitiesDescriptors(processInstance, clonedActDesp, lastActDesp, context, operationType);
            }

            return(resultTransition);
        }
        private static void FillCopyContext(WfCopyMainStreamActivityNode currentActivity, IWfActivityDescriptor endActivity, WfCopyMainStreamContext context, WfControlOperationType operationType)
        {
            foreach (IWfTransitionDescriptor transition in currentActivity.TemplateActivityDescriptor.ToTransitions.GetNotDynamicActivityTransitions())
            {
                if (context.IsElapsedTransition(transition) == false)
                {
                    IWfActivityDescriptor nextActivityDesp = transition.ToActivity;

                    if (operationType == WfControlOperationType.Return)
                    {
                        nextActivityDesp = FindNotReturnSkippedActivity(transition.ToActivity);
                    }

                    bool nextIsEndActivity = nextActivityDesp.Key == endActivity.Key;

                    IWfActivityDescriptor originalActDesp = nextActivityDesp;

                    if (context.IsMainStream)
                    {
                        originalActDesp = context.EndActivityDescriptor.FindSubsequentActivity((t, actDesp) =>
                                                                                               t.IsBackward == false && actDesp.Instance.MainStreamActivityKey == nextActivityDesp.Key);
                    }

                    WfCopyMainStreamActivityNode toActivity = new WfCopyMainStreamActivityNode(
                        nextActivityDesp,
                        originalActDesp,
                        IsSubsequentActivity(nextActivityDesp, endActivity) == false,
                        nextIsEndActivity);

                    currentActivity.ToActivities.Add(new WfCopyMainStreamSubActivityNode(transition, toActivity));

                    context.AddElapsedTransition(transition);

                    if (currentActivity.TemplateActivityDescriptor.Key != endActivity.Key)
                    {
                        FillCopyContext(toActivity, endActivity, context, operationType);
                    }
                }
            }
        }