protected virtual void OnMouseDown(MouseDownEvent e)
        {
            if (m_Active)
            {
                e.StopImmediatePropagation();
                return;
            }

            if (!CanStartManipulation(e))
            {
                return;
            }

            var port = target.GetFirstAncestorOfType <Port>();

            if (port == null)
            {
                return;
            }

            m_MouseDownPosition = e.localMousePosition;

            m_EdgeDragHelper.CreateEdgeCandidate(port.PortModel.GraphModel);
            m_EdgeDragHelper.draggedPort = port.PortModel;

            if (m_EdgeDragHelper.HandleMouseDown(e))
            {
                m_Active = true;
                target.CaptureMouse();
                e.StopPropagation();
            }
            else
            {
                m_EdgeDragHelper.Reset();
            }
        }
        protected void OnMouseMove(MouseMoveEvent evt)
        {
            // If the left mouse button is not down then return
            if (m_Edge == null)
            {
                return;
            }

            evt.StopPropagation();

            bool alreadyDetached = (m_DetachedPort != null);

            // If one end of the edge is not already detached then
            if (!alreadyDetached)
            {
                float delta = (evt.mousePosition - m_PressPos).sqrMagnitude;

                if (delta < (s_StartDragDistance * s_StartDragDistance))
                {
                    return;
                }

                var graphView    = m_Edge.GetFirstAncestorOfType <GraphView>();
                var outputPortUI = m_Edge.Output.GetUI <Port>(graphView);
                var inputPortUI  = m_Edge.Input.GetUI <Port>(graphView);

                if (outputPortUI == null || inputPortUI == null)
                {
                    return;
                }

                // Determine which end is the nearest to the mouse position then detach it.
                Vector2 outputPos = new Vector2(outputPortUI.GetGlobalCenter().x, outputPortUI.GetGlobalCenter().y);
                Vector2 inputPos  = new Vector2(inputPortUI.GetGlobalCenter().x, inputPortUI.GetGlobalCenter().y);

                float distanceFromOutput = (m_PressPos - outputPos).sqrMagnitude;
                float distanceFromInput  = (m_PressPos - inputPos).sqrMagnitude;

                if (distanceFromInput > 50 * 50 && distanceFromOutput > 50 * 50)
                {
                    return;
                }

                m_DetachedFromInputPort = distanceFromInput < distanceFromOutput;

                IGTFPortModel connectedPort;
                Port          connectedPortUI;

                if (m_DetachedFromInputPort)
                {
                    connectedPort   = m_Edge.Output;
                    connectedPortUI = outputPortUI;

                    m_DetachedPort = m_Edge.Input;
                }
                else
                {
                    connectedPort   = m_Edge.Input;
                    connectedPortUI = inputPortUI;

                    m_DetachedPort = m_Edge.Output;
                }

                // Use the edge drag helper of the still connected port
                m_ConnectedEdgeDragHelper = connectedPortUI.EdgeConnector.edgeDragHelper;
                m_ConnectedEdgeDragHelper.originalEdge = m_Edge;
                m_ConnectedEdgeDragHelper.draggedPort  = connectedPort;
                m_ConnectedEdgeDragHelper.CreateEdgeCandidate(connectedPort.GraphModel);
                m_ConnectedEdgeDragHelper.edgeCandidateModel.EndPoint = evt.mousePosition;

                // Redirect the last mouse down event to active the drag helper

                if (m_ConnectedEdgeDragHelper.HandleMouseDown(m_LastMouseDownEvent))
                {
                    m_Active = true;
                }
                else
                {
                    Reset();
                }

                m_LastMouseDownEvent = null;
            }

            if (m_Active)
            {
                m_ConnectedEdgeDragHelper.HandleMouseMove(evt);
            }
        }