private bool CanInitiateDragDrop()
        {
            //Go thru all the selected components and make sure that they can participate in drag drop
            ISelectionService selectionService = (ISelectionService)GetService(typeof(ISelectionService));
            IDesignerHost designerHost = (IDesignerHost)GetService(typeof(IDesignerHost));
            if (selectionService == null || designerHost == null)
                return false;

            // check if we are cutting root component
            ICollection components = selectionService.GetSelectedComponents();
            if (components == null || components.Count < 1 || selectionService.GetComponentSelected(designerHost.RootComponent) || !Helpers.AreAllActivities(components))
                return false;

            return true;
        }
        private void InitiateDragDrop()
        {
            WorkflowView parentView = ParentView;
            ISelectionService selectionService = (ISelectionService)GetService(typeof(ISelectionService));
            IDesignerHost designerHost = (IDesignerHost)GetService(typeof(IDesignerHost));
            if (selectionService == null || designerHost == null)
                return;

            // check if we are cutting root component
            ICollection components = selectionService.GetSelectedComponents();
            if (components == null || components.Count < 1 || selectionService.GetComponentSelected(designerHost.RootComponent) || !Helpers.AreAllActivities(components))
                return;

            DragDropEffects effects = DragDropEffects.None;
            try
            {
                // get component serialization service
                this.existingDraggedActivities.AddRange(Helpers.GetTopLevelActivities(components));

                //IMPORTANT: FOR WITHIN DESIGNER COMPONENT MOVE WE REMOVE THE ACTIVITIES BEFORE WE ADD THEM WHICH IS IN 
                //ONDRAGDROP FUNCTION. ALTHOUGH THIS VIOLATES THE DODRAGDROP FUNCTION SIMANTICS, WE NEED TO DO THIS
                //SO THAT WE CAN USE THE SAME IDS FOR THE ACTIVITIES
                DragDropEffects allowedEffects = (DesignerHelpers.AreAssociatedDesignersMovable(this.existingDraggedActivities)) ? DragDropEffects.Move | DragDropEffects.Copy : DragDropEffects.Copy;
                IDataObject dataObject = CompositeActivityDesigner.SerializeActivitiesToDataObject(ParentView, this.existingDraggedActivities.ToArray());
                effects = parentView.DoDragDrop(dataObject, allowedEffects);

                // 
            }
            catch (Exception e)
            {
                DesignerHelpers.ShowError(ParentView, e.Message);
            }
            finally
            {
                //This means drag drop occurred across designer
                if (effects == DragDropEffects.Move && this.existingDraggedActivities.Count > 0)
                {
                    string transactionDescription = String.Empty;
                    if (this.existingDraggedActivities.Count > 1)
                        transactionDescription = SR.GetString(SR.MoveMultipleActivities, this.existingDraggedActivities.Count);
                    else
                        transactionDescription = SR.GetString(SR.MoveSingleActivity, this.existingDraggedActivities[0].GetType());

                    CompositeActivityDesigner.RemoveActivities(ParentView, this.existingDraggedActivities.AsReadOnly(), transactionDescription);
                }

                this.existingDraggedActivities.Clear();
            }
        }
        protected override bool OnDragDrop(DragEventArgs eventArgs)
        {
            //Invalidate the entire rectangle so that we draw active placement glyphs on connectors
            WorkflowView parentView = ParentView;
            parentView.InvalidateClientRectangle(Rectangle.Empty);

            //By default we do not allow any drag drop operation
            eventArgs.Effect = DragDropEffects.None;

            DestroyDragFeedbackImages();

            //Get the coordinates
            Point clientPoint = parentView.PointToClient(new Point(eventArgs.X, eventArgs.Y));
            Point logicalPoint = parentView.ScreenPointToLogical(new Point(eventArgs.X, eventArgs.Y));

            //Now we check if the drag drop was in any valid area, if not then do not proceed further
            if (!parentView.IsClientPointInActiveLayout(clientPoint))
            {
                if (this.dropTargetDesigner != null)
                    ((IWorkflowDesignerMessageSink)this.dropTargetDesigner).OnDragLeave();
                this.wasCtrlKeyPressed = false;
                this.dropTargetDesigner = null;
                this.draggedActivities.Clear();
                return false;
            }

            //Now we have a potential for successful drag drop, so construct drag event arguments with logical coordinates
            this.wasCtrlKeyPressed = ((eventArgs.KeyState & 8) == 8);
            ActivityDragEventArgs dragdropEventArgs = new ActivityDragEventArgs(eventArgs, this.dragInitiationPoint, logicalPoint, this.draggedActivities);

            //Now check which designer is under the cursor, if we have the same designer as the old one
            //If not then we set the new one as drop target and pump in messages
            HitTestInfo hitTestInfo = MessageHitTestContext;
            if (this.dropTargetDesigner != hitTestInfo.AssociatedDesigner)
            {
                if (this.dropTargetDesigner != null)
                {
                    ((IWorkflowDesignerMessageSink)this.dropTargetDesigner).OnDragLeave();
                    this.dropTargetDesigner = null;
                }

                if (hitTestInfo.AssociatedDesigner != null)
                {
                    this.dropTargetDesigner = hitTestInfo.AssociatedDesigner;
                    if (this.dropTargetDesigner != null)
                        ((IWorkflowDesignerMessageSink)this.dropTargetDesigner).OnDragEnter(dragdropEventArgs);
                }
            }

            //We now have appropriate droptarget designer
            try
            {
                if (this.dropTargetDesigner != null)
                {
                    //We do not allow recursive drag and drop
                    if (!this.wasCtrlKeyPressed && IsRecursiveDropOperation(this.dropTargetDesigner) ||
                        (this.dropTargetDesigner is CompositeActivityDesigner && !((CompositeActivityDesigner)this.dropTargetDesigner).IsEditable))
                    {
                        ((IWorkflowDesignerMessageSink)this.dropTargetDesigner).OnDragLeave();
                        dragdropEventArgs.Effect = DragDropEffects.None;
                    }
                    else
                    {
                        // IMPORTANT: Don't use draggedActivities variable, because components which are
                        // there may not be created using the assembly references  added to ITypeResultionService
                        // this.workflowView.time the components will be created using the assembly references got added to the project
                        List<Activity> droppedActivities = new List<Activity>();
                        string transactionDescription = SR.GetString(SR.DragDropActivities);

                        //This means that we are trying to move activities so we use the same activities for drop
                        if (!this.wasCtrlKeyPressed && this.existingDraggedActivities.Count > 0)
                        {
                            droppedActivities.AddRange(this.existingDraggedActivities);
                            if (droppedActivities.Count > 1)
                                transactionDescription = SR.GetString(SR.MoveMultipleActivities, droppedActivities.Count);
                            else if (droppedActivities.Count == 1)
                                transactionDescription = SR.GetString(SR.MoveSingleActivity, droppedActivities[0].GetType());
                        }
                        else
                        {
                            droppedActivities.AddRange(CompositeActivityDesigner.DeserializeActivitiesFromDataObject(ParentView, eventArgs.Data, true));
                            if (droppedActivities.Count > 0)
                                transactionDescription = SR.GetString(SR.CreateActivityFromToolbox, droppedActivities[0].GetType());
                        }

                        //Now that we have what needs to be dropped, we start the actual drag and drop
                        IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
                        DesignerTransaction transaction = null;
                        if (droppedActivities.Count > 0)
                            transaction = designerHost.CreateTransaction(transactionDescription);

                        dragdropEventArgs = new ActivityDragEventArgs(eventArgs, this.dragInitiationPoint, logicalPoint, droppedActivities);

                        try
                        {
                            ((IWorkflowDesignerMessageSink)this.dropTargetDesigner).OnDragDrop(dragdropEventArgs);

                            if (dragdropEventArgs.Effect == DragDropEffects.Move)
                                this.existingDraggedActivities.Clear();

                            if (transaction != null)
                                transaction.Commit();
                        }
                        catch (Exception e)
                        {
                            if (transaction != null)
                                transaction.Cancel();
                            throw e;
                        }

                        //We deserialize the designers and try to store the designer states
                        if (droppedActivities.Count > 0)
                        {
                            Stream componentStateStream = eventArgs.Data.GetData(DragDropManager.CF_DESIGNERSTATE) as Stream;
                            if (componentStateStream != null)
                                Helpers.DeserializeDesignersFromStream(droppedActivities, componentStateStream);

                            //Set the current selection
                            ISelectionService selectionService = (ISelectionService)GetService(typeof(ISelectionService));
                            if (selectionService != null)
                                selectionService.SetSelectedComponents(droppedActivities, SelectionTypes.Replace);
                        }

                        //Active the design surface
                        if (designerHost != null)
                            designerHost.Activate();
                    }
                }
            }
            catch (Exception ex)
            {
                //We purposely consume application thrown exception which are result of user cancelling the action
                //during dragdrop where we popup UI Wizards during drag drop. Ref: InvokeWebService
                ((IWorkflowDesignerMessageSink)this.dropTargetDesigner).OnDragLeave();
                dragdropEventArgs.Effect = DragDropEffects.None;

                string dragDropException = ex.Message;
                if (ex.InnerException != null && !String.IsNullOrEmpty(ex.InnerException.Message))
                    dragDropException = ex.InnerException.Message;

                string errorMessage = DR.GetString(DR.Error_FailedToDeserializeComponents);
                errorMessage += "\r\n" + DR.GetString(DR.Error_Reason, dragDropException);
                DesignerHelpers.ShowError(ParentView, errorMessage);

                if (ex != CheckoutException.Canceled)
                    throw new Exception(errorMessage, ex);
            }
            finally
            {
                //Make sure that mouse over designer is set to null
                this.wasCtrlKeyPressed = false;
                this.draggedActivities.Clear();
                this.dropTargetDesigner = null;
                this.exceptionInDragDrop = false;
                eventArgs.Effect = dragdropEventArgs.Effect;
            }

            return true;
        }