/// <summary>
        /// Set this mouse action as the active action on the
        /// diagram of the given shape.
        /// </summary>
        /// <param name="attachToShape">The shape the constraint is being attached to.</param>
        /// <param name="constraint">The constraint being connected.</param>
        /// <param name="clientView">The active DiagramClientView</param>
        public void ChainMouseAction(FactTypeShape attachToShape, UniquenessConstraint constraint, DiagramClientView clientView)
        {
            DiagramView activeView = Diagram.ActiveDiagramView;

            if (activeView != null)
            {
                // Move on to the selection action
                clientView.ActiveMouseAction = this;

                // Now emulate a mouse click in the middle of the added constraint. The click
                // actions provide a starting point for the connect action, so a mouse move
                // provides a drag line.
                Point emulateClickPoint = clientView.WorldToDevice(attachToShape.GetAbsoluteConstraintAttachPoint(constraint, FactSetConstraint.GetLink(constraint, attachToShape.AssociatedFactType)));
                DiagramMouseEventArgs mouseEventArgs = new DiagramMouseEventArgs(new MouseEventArgs(MouseButtons.Left, 1, emulateClickPoint.X, emulateClickPoint.Y, 0), clientView);
                MouseDown(mouseEventArgs);
                Click(new DiagramPointEventArgs(emulateClickPoint.X, emulateClickPoint.Y, PointRelativeTo.Client, clientView));
                MouseUp(mouseEventArgs);
                attachToShape.Invalidate(true);

                // An extra move lets us chain when the mouse is not on the design surface,
                // such as when we are being activated via the task list.
                MouseMove(mouseEventArgs);

                ORMDiagram.SelectToolboxItem(activeView, ResourceStrings.ToolboxInternalUniquenessConstraintItemId);
                FactTypeShape.ActiveInternalUniquenessConstraintConnectAction = this;
            }
        }
        /// <summary>
        /// Add a source shape or commit/cancel the action by forwarding the
        /// click to the base class, or modify the current role sequence by handling
        /// the click locally.
        /// </summary>
        /// <param name="e">MouseActionEventArgs</param>
        protected override void OnClicked(MouseActionEventArgs e)
        {
            switch (myPendingOnClickedAction)
            {
            case OnClickedAction.Commit:
                myPendingOnClickedAction = OnClickedAction.Normal;
                // Letting the click through to the base ConnectAction
                // at this point (a constraint is selected and a role has been
                // double-clicked) will force the connect action to finish.
                base.OnClicked(e);
                return;

            case OnClickedAction.CheckForCommit:
                myPendingOnClickedAction = OnClickedAction.Normal;
                break;
            }
            DiagramMouseEventArgs args = CurrentDiagramArgs as DiagramMouseEventArgs;

            if (args != null)
            {
                DiagramItem  item           = args.DiagramHitTestInfo.HitDiagramItem;
                ModelElement currentElement = null;
                foreach (ModelElement elem in item.RepresentedElements)
                {
                    currentElement = elem;
                    break;
                }
                UniquenessConstraint internalUniquenessConstraint;
                RoleBase             roleBase;
                if (null != (internalUniquenessConstraint = currentElement as UniquenessConstraint) &&
                    internalUniquenessConstraint.IsInternal)
                {
                    if (mySourceShape == null)
                    {
                        // Let the click through to the base to officially begin the drag action
                        base.OnClicked(e);
                        mySourceShape = item.Shape as FactTypeShape;
                        myIUC         = internalUniquenessConstraint;
                    }
                }
                else if (mySourceShape != null)
                {
                    if (null != (roleBase = currentElement as RoleBase))
                    {
                        Role role = roleBase.Role;
                        if (role.FactType == mySourceShape.AssociatedFactType)
                        {
                            // Add or remove the role
                            IList <Role> roles       = SelectedRoleCollection;
                            int          roleIndex   = roles.IndexOf(role);
                            bool         forceRedraw = false;
                            if (roleIndex >= 0)
                            {
                                // Only remove a role when the control key is down. Otherwise,
                                // there is no way to double-click on a previously selected
                                // role without turning it off, and this is a natural gesture.
                                // Add shift key as well for discoverability.
                                if (0 != (0xff00 & GetKeyState(Keys.ControlKey)) ||
                                    0 != (0xff00 & GetKeyState(Keys.ShiftKey)))
                                {
                                    forceRedraw = true;
                                    roles.RemoveAt(roleIndex);
                                }
                            }
                            else
                            {
                                forceRedraw = true;
                                roles.Add(role);
                            }
                            if (mySourceShape != null)
                            {
                                myPendingOnClickedAction = OnClickedAction.CheckForCommit;
                            }

                            if (forceRedraw)
                            {
                                // Force the shape to redraw
                                Debug.Assert(mySourceShape != null);                                 //source shape should have been set
                                mySourceShape.Invalidate(true);
                            }
                        }
                    }
                    else if (currentElement is ORMDiagram)
                    {
                        base.OnClicked(e);                         // Let through to allow a cancel
                    }
                }
            }
        }