public void OnItemsPasted(List<object> itemsToPaste, List<object> metaData, Point pastePoint, WorkflowViewElement pastePointReference)
        {
            if (this.ModelItem.ItemType == typeof(State))
            {
                WorkflowViewElement view = VisualTreeUtils.FindVisualAncestor<WorkflowViewElement>(this);
                if (view != null)
                {
                    StateContainerEditor container = (StateContainerEditor)DragDropHelper.GetCompositeView(view);
                    container.OnItemsPasted(itemsToPaste, metaData, pastePoint, pastePointReference);
                }

                return;
            }

            if (itemsToPaste.Count == 1 && itemsToPaste.First() is Transition)
            {
                if (metaData == null || metaData.Count != 1 || !(metaData.First() is string))
                {
                    ShowMessageBox(SR.PasteTransitionWithoutDestinationState);
                    return;
                }

                ModelItem destinationState = FindState(metaData.First() as string);

                if (destinationState == null)
                {
                    ShowMessageBox(SR.PasteTransitionWithoutDestinationState);
                    return;
                }

                this.PopulateVirtualizingContainer(destinationState);

                ModelItem[] selectedItems = this.Context.Items.GetValue<Selection>().SelectedObjects.ToArray();
                string errorMessage;
                if (!CanPasteTransition(destinationState, out errorMessage, selectedItems))
                {
                    ShowMessageBox(errorMessage);
                    return;
                }

                Transition pastedTransition = itemsToPaste.First() as Transition;
                Fx.Assert(pastedTransition != null, "Copied Transition should not be null.");

                using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(System.Activities.Presentation.SR.PropertyChangeEditingScopeDescription))
                {
                    string displayName = pastedTransition.DisplayName;
                    bool isFirst = true;
                    foreach (ModelItem selectedItem in selectedItems)
                    {
                        if (!isFirst)
                        {
                            StringReader reader = new StringReader(XamlServices.Save(pastedTransition));
                            pastedTransition = (Transition)XamlServices.Load(reader);
                        }

                        ModelItem transitionModelItem = this.Context.Services.GetRequiredService<ModelTreeManager>().WrapAsModelItem(pastedTransition);
                        ModelItem sourceState = selectedItem;
                        sourceState.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(transitionModelItem);
                        transitionModelItem.Properties[TransitionDesigner.ToPropertyName].SetValue(destinationState);

                        if (isFirst)
                        {
                            this.ViewStateService.RemoveViewState(transitionModelItem, ConnectorLocationViewStateKey);
                            this.ViewStateService.RemoveViewState(transitionModelItem, SrcConnectionPointIndexStateKey);
                            this.ViewStateService.RemoveViewState(transitionModelItem, DestConnectionPointIndexStateKey);
                            isFirst = false;
                        }
                    }

                    es.Complete();
                }
            }
            else
            {
                List<ModelItem> modelItemsPasted = new List<ModelItem>();
                List<State> states = new List<State>();

                foreach (object obj in itemsToPaste)
                {
                    State state;
                    if (obj is FinalState)
                    {
                        state = new State() { DisplayName = DefaultFinalStateDisplayName, IsFinal = true };
                    }
                    else
                    {
                        state = (State)obj;
                        if (state.DisplayName == null)
                        {
                            state.DisplayName = DefaultStateDisplayName;
                        }
                    }
                    states.Add(state);
                }

                RemoveDanglingTransitions(states);

                using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(
                    System.Activities.Presentation.SR.CollectionAddEditingScopeDescription))
                {
                    // Fix 157591 by storing the height and width of the container "before" the new states are added to the
                    // panel, and group the insertion inside one editing scope - such that Undo will also restore the 
                    // size of the StateMachineContainer to pre-insert size.
                    StoreShapeSizeWithUndoRecursively(this.ModelItem);

                    foreach (State state in states)
                    {
                        ModelItem stateModelItem =
                            (this.ModelItem.ItemType == typeof(StateMachine)) ?
                            this.ModelItem.Properties[StateMachineDesigner.StatesPropertyName].Collection.Add(state) :
                            GetStateMachineModelItem(this.ModelItem).Properties[StateMachineDesigner.StatesPropertyName].Collection.Add(state);
                        modelItemsPasted.Add(stateModelItem);
                    }

                    es.Complete();
                }

                if (modelItemsPasted.Count > 0)
                {
                    // translate location view states to be in the coordinate system of the pasting target
                    Fx.Assert(this.ModelItem.ItemType == typeof(StateMachine), "Only StateMachine contain the StateContainerEditor.");

                    this.UpdateLocationViewStatesByMetaData(modelItemsPasted, metaData, this);

                    if (pastePoint.X > 0 && pastePoint.Y > 0)
                    {
                        if (pastePointReference != null)
                        {
                            pastePoint = pastePointReference.TranslatePoint(pastePoint, this.panel);
                            pastePoint.X = pastePoint.X < 0 ? 0 : pastePoint.X;
                            pastePoint.Y = pastePoint.Y < 0 ? 0 : pastePoint.Y;
                        }
                        this.UpdateLocationViewStatesByPoint(modelItemsPasted, pastePoint);
                    }
                    // If paste point is not available, paste the items to the top left corner.
                    else
                    {
                        this.UpdateLocationViewStatesToAvoidOverlap(modelItemsPasted);
                    }
                }

                this.Dispatcher.BeginInvoke(() =>
                {
                    if (modelItemsPasted.Count > 0 && modelItemsPasted[0] != null)
                    {
                        Keyboard.Focus(modelItemsPasted[0].View as IInputElement);
                    }
                    this.Context.Items.SetValue(new Selection(modelItemsPasted));
                },
                DispatcherPriority.ApplicationIdle
                );
            }
        }
        public void OnItemsPasted(List<object> itemsToPaste, List<object> metaData, Point pastePoint, WorkflowViewElement pastePointReference)
        {
            List<ModelItem> modelItemsPasted = new List<ModelItem>();
            List<State> states = new List<State>();
            foreach (object obj in itemsToPaste)
            {
                State state;
                if (obj is FinalState)
                {
                    state = new State() { DisplayName = SR.DefaultFinalStateDisplayName, IsFinal = true };
                }
                else
                {
                    state = (State)obj;
                    if (state.DisplayName == null)
                    {
                        state.DisplayName = SR.DefaultStateDisplayName;
                    }
                }
                states.Add(state);
            }

            RemoveDanglingTransitions(states);
            foreach (State state in states)
            {
                ModelItem stateModelItem = this.ModelItem.Properties[ChildStatesPropertyName].Collection.Add(state);
                modelItemsPasted.Add(stateModelItem);
            }
            if (modelItemsPasted.Count > 0)
            {
                // translate location view states to be in the coordinate system of the pasting target             
                this.UpdateLocationViewStatesByMetaData(modelItemsPasted, metaData);
                if (pastePoint.X > 0 && pastePoint.Y > 0)
                {
                    if (pastePointReference != null)
                    {
                        pastePoint = pastePointReference.TranslatePoint(pastePoint, this.panel);
                        pastePoint.X = pastePoint.X < 0 ? 0 : pastePoint.X;
                        pastePoint.Y = pastePoint.Y < 0 ? 0 : pastePoint.Y;
                    }
                    this.UpdateLocationViewStatesByPoint(modelItemsPasted, pastePoint);
                }
                // If paste point is not available, paste the items to the top left corner.
                else
                {
                    this.UpdateLocationViewStatesToTopLeft(modelItemsPasted);
                }
            }

            this.Context.Items.SetValue(new Selection(modelItemsPasted));
        }
        public void OnItemsPasted(List<object> itemsToPaste, List<object> metaData, Point pastePoint, WorkflowViewElement pastePointReference)
        {
            Fx.Assert(this.panel != null, "This code shouldn't be hit if panel is null");
            HashSet<Activity> workflowElementsPasted = new HashSet<Activity>();
            List<ModelItem> modelItemsToSelect = new List<ModelItem>();
            bool shouldStoreCurrentSizeViewState = true;

            Fx.Assert(this.ModelItem is IModelTreeItem, "this.ModelItem must implement IModelTreeItem");
            using (EditingScope editingScope = ((IModelTreeItem)this.ModelItem).ModelTreeManager.CreateEditingScope(System.Activities.Presentation.SR.CollectionAddEditingScopeDescription))
            {
                if (metaData != null)
                {
                    List<ModelItem> modelItemsPerMetaData = new List<ModelItem>();
                    foreach (object designerMetaData in metaData)
                    {
                        if (designerMetaData is List<FlowNode>)
                        {
                            //This is flowchart metadata.
                            foreach (FlowNode element in designerMetaData as List<FlowNode>)
                            {
                                FlowStep step = element as FlowStep;
                                if (step != null)
                                {
                                    workflowElementsPasted.Add(step.Action);
                                }

                                if (shouldStoreCurrentSizeViewState)
                                {
                                    // Pasting may change the size of flowchart; need this to undo the size change.
                                    this.StoreCurrentSizeViewStateWithUndo();
                                    shouldStoreCurrentSizeViewState = false;
                                }

                                ModelItem item = this.ModelItem.Properties["Nodes"].Collection.Add(element);

                                // if the pasted item is a flowswitch but the default target is not in the pasted selection,
                                // reset the DefaultCaseDisplayName to "Default".
                                if (GenericFlowSwitchHelper.IsGenericFlowSwitch(item.ItemType) &&
                                    item.Properties["Default"].Value == null)
                                {
                                    item.Properties[FlowSwitchLabelFeature.DefaultCaseDisplayNamePropertyName].SetValue(FlowSwitchLabelFeature.DefaultCaseDisplayNameDefaultValue);
                                }

                                modelItemsPerMetaData.Add(item);
                                if (item != null)
                                {
                                    if (item.ItemType.Equals(typeof(FlowStep)))
                                    {
                                        modelItemsToSelect.Add(item.Properties["Action"].Value);
                                    }
                                    else
                                    {
                                        modelItemsToSelect.Add(item);
                                    }
                                }
                            }
                            if (pastePoint.X > 0 && pastePoint.Y > 0)
                            {
                                Point panelPoint = this.TranslatePoint(pastePoint, this.panel);
                                if (pastePointReference != null && !pastePointReference.Equals(this))
                                {
                                    if (pastePointReference.ModelItem != null && this.modelElement.ContainsKey(pastePointReference.ModelItem))
                                    {
                                        panelPoint = pastePointReference.TranslatePoint(pastePoint, this.panel);
                                    }
                                }
                                panelPoint.X = panelPoint.X < 0 ? 0 : panelPoint.X;
                                panelPoint.Y = panelPoint.Y < 0 ? 0 : panelPoint.Y;
                                UpdateViewStateOnPastePoint(modelItemsPerMetaData, panelPoint);
                            }
                            else
                            {
                                UpdateViewStateToAvoidOverlapOnPaste(modelItemsPerMetaData);
                            }
                            modelItemsPerMetaData.Clear();
                        }
                    }
                }

                foreach (object itemToPaste in itemsToPaste)
                {
                    Activity workflowElementToPaste = itemToPaste as Activity;
                    if (workflowElementToPaste != null && !workflowElementsPasted.Contains(workflowElementToPaste))
                    {
                        FlowStep flowStep = new FlowStep { Action = workflowElementToPaste, Next = null };
                        if (shouldStoreCurrentSizeViewState)
                        {
                            // Pasting may change the size of flowchart; need this to undo the size change.
                            this.StoreCurrentSizeViewStateWithUndo();
                            shouldStoreCurrentSizeViewState = false;
                        }
                        
                        // When paste a non-flowstep object to flowchart, the existing hintsize of the object 
                        // should be removed, and let flowchart panel to compute the right size.
                        VirtualizedContainerService.SetHintSize(workflowElementToPaste, null);
                        ModelItem flowStepItem = this.ModelItem.Properties["Nodes"].Collection.Add(flowStep);
                     
                        if (flowStepItem != null)
                        {
                            modelItemsToSelect.Add(flowStepItem.Properties["Action"].Value);
                        }
                    }
                }

                editingScope.Complete();
            }

            this.Dispatcher.BeginInvoke(() =>
            {
                if (modelItemsToSelect.Count > 0 && modelItemsToSelect[0] != null)
                {
                    Keyboard.Focus(modelItemsToSelect[0].View as IInputElement);
                }
                this.Context.Items.SetValue(new Selection(modelItemsToSelect));
            },
            DispatcherPriority.ApplicationIdle
            );
        }