static ConnectionPoint ConnectionPointHitTest(UIElement element, Point hitPoint)
        {
            FreeFormPanel          panel            = VisualTreeUtils.FindVisualAncestor <FreeFormPanel>(element);
            List <ConnectionPoint> connectionPoints = StateContainerEditor.GetConnectionPoints(element);

            return(FreeFormPanel.ConnectionPointHitTest(hitPoint, connectionPoints, panel));
        }
        internal static List <ConnectionPoint> GetEmptyConnectionPoints(UIElement designer)
        {
            List <ConnectionPoint> connectionPoints = StateContainerEditor.GetConnectionPoints(designer);

            if (connectionPoints != null)
            {
                return(new List <ConnectionPoint>(connectionPoints.Where <ConnectionPoint>(
                                                      (p) => { return p.AttachedConnectors == null || p.AttachedConnectors.Count == 0; })));
            }
            return(new List <ConnectionPoint>());
        }
        static ConnectionPoint GetConnectionPoint(UIElement element, Point location)
        {
            List <ConnectionPoint> connectionPoints = StateContainerEditor.GetConnectionPoints(element);

            foreach (ConnectionPoint connectionPoint in connectionPoints)
            {
                if (DesignerGeometryHelper.ManhattanDistanceBetweenPoints(location, connectionPoint.Location) <= ConnectorRouter.EndPointTolerance)
                {
                    return(connectionPoint);
                }
            }
            return(null);
        }
        // referenceTransitionModelItem is used when a connector is re-linked.
        void CreateTransition(ConnectionPoint sourceConnPoint, ConnectionPoint destConnPoint, ModelItem referenceTransitionModelItem, bool isSourceMoved)
        {
            VirtualizedContainerService.VirtualizingContainer srcDesigner = sourceConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer;
            Fx.Assert(srcDesigner != null, "srcDesigner should not be null.");
            VirtualizedContainerService.VirtualizingContainer destDesigner = destConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer;
            Fx.Assert(destDesigner != null, "destDesigner should not be null.");

            ModelItem srcModelItem        = srcDesigner.ModelItem;
            ModelItem destModelItem       = destDesigner.ModelItem;
            ModelItem transitionModelItem = null;

            // We are moving the connector.
            if (referenceTransitionModelItem != null && referenceTransitionModelItem.ItemType == typeof(Transition))
            {
                transitionModelItem = referenceTransitionModelItem;
                // We are moving the start of the connector. We only preserve the trigger if it is not shared.
                if (isSourceMoved)
                {
                    Transition referenceTransition = referenceTransitionModelItem.GetCurrentValue() as Transition;
                    ModelItem  stateModelItem      = GetParentStateModelItemForTransition(referenceTransitionModelItem);
                    State      state           = stateModelItem.GetCurrentValue() as State;
                    bool       isTriggerShared = false;
                    foreach (Transition transition in state.Transitions)
                    {
                        if (transition != referenceTransition && transition.Trigger == referenceTransition.Trigger)
                        {
                            isTriggerShared = true;
                            break;
                        }
                    }
                    if (isTriggerShared)
                    {
                        transitionModelItem.Properties[TransitionDesigner.TriggerPropertyName].SetValue(null);
                    }
                }
                transitionModelItem.Properties[TransitionDesigner.ToPropertyName].SetValue(destModelItem);
                srcModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(transitionModelItem);
            }
            // We are creating a new connector.
            else
            {
                ModelItem  stateMachineModelItem = GetStateMachineModelItem(srcModelItem);
                Transition newTransition         = new Transition()
                {
                    DisplayName = StateContainerEditor.GenerateTransitionName(stateMachineModelItem)
                };
                newTransition.To = destModelItem.GetCurrentValue() as State;
                // Assign the shared trigger.
                if (sourceConnPoint.AttachedConnectors.Count > 0)
                {
                    Connector  connector          = sourceConnPoint.AttachedConnectors[0];
                    Transition existingTransition = StateContainerEditor.GetConnectorModelItem(connector).GetCurrentValue() as Transition;
                    newTransition.Trigger = existingTransition.Trigger;
                }
                transitionModelItem = srcModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(newTransition);
            }
            if (transitionModelItem != null)
            {
                // if the transition connection is re-routed, the SrcConnPointIndex needs to be updated.
                PointCollection connectorViewState       = new PointCollection(ConnectorRouter.Route(this.panel, sourceConnPoint, destConnPoint));
                int             srcConnectionPointIndex  = StateContainerEditor.GetConnectionPoints(sourceConnPoint.ParentDesigner).IndexOf(sourceConnPoint);
                int             destConnectionPointIndex = StateContainerEditor.GetConnectionPoints(destConnPoint.ParentDesigner).IndexOf(destConnPoint);
                this.StoreConnectorLocationViewState(transitionModelItem, connectorViewState, true);
                this.ViewStateService.StoreViewStateWithUndo(transitionModelItem, SrcConnectionPointIndexStateKey, srcConnectionPointIndex);
                this.ViewStateService.StoreViewStateWithUndo(transitionModelItem, DestConnectionPointIndexStateKey, destConnectionPointIndex);
            }
        }
        //This returns the closest non-outgoing connectionPoint on dest. Return value will be different than sourceConnectionPoint.
        static ConnectionPoint GetClosestDestConnectionPoint(ConnectionPoint sourceConnectionPoint, UIElement dest)
        {
            ConnectionPoint destConnectionPoint = null;

            if (sourceConnectionPoint.PointType != ConnectionPointKind.Incoming)
            {
                destConnectionPoint = GetClosestConnectionPointNotOfType(sourceConnectionPoint, StateContainerEditor.GetConnectionPoints(dest), ConnectionPointKind.Outgoing);
            }
            return(destConnectionPoint);
        }
        //This returns the closest non-incoming connectionPoint on source. Return value will be different than destConnectionPoint.
        static ConnectionPoint GetClosestSrcConnectionPoint(UIElement src, ConnectionPoint destConnectionPoint)
        {
            ConnectionPoint srcConnectionPoint = null;

            if (destConnectionPoint.PointType != ConnectionPointKind.Outgoing)
            {
                srcConnectionPoint = GetClosestConnectionPointNotOfType(destConnectionPoint, StateContainerEditor.GetConnectionPoints(src), ConnectionPointKind.Incoming);
            }
            return(srcConnectionPoint);
        }