void IEventPortal.PortalMouseLeaveFromViewport()
        {
            //mouse out from viewport

            if (_latestMouseActive != null)
            {
                _mouseLeaveEventArgs.IsDragging = false;
                UIMouseLeaveEventArgs.SetDiff(_mouseLeaveEventArgs, 0, 0);
                _mouseLeaveEventArgs.SetCurrentContextElement(null);

                _latestMouseActive.ListenMouseLeave(_mouseLeaveEventArgs);
                _latestMouseActive = null;
            }
        }
        void IEventPortal.PortalMouseMove(UIMouseMoveEventArgs e)
        {
            HitChain hitPointChain = GetFreeHitChain();

#if DEBUG
            _dbugHitChainPhase = dbugHitChainPhase.MouseMove;
#endif
            HitTestCoreWithPrevChainHint(hitPointChain, _previousChain, e.X, e.Y);
            _previousChain.Reset();
            SetEventOrigin(e, hitPointChain);
            //-------------------------------------------------------
            ForEachOnlyEventPortalBubbleUp(e, hitPointChain, (e1, portal) =>
            {
                //please ensure=> no local var/pararmeter capture inside lambda
                portal.PortalMouseMove(e1);
                return(true);
            });
            //-------------------------------------------------------
            if (!e.CancelBubbling)
            {
                _mouseMoveFoundSomeHit         = false;
                _mouseMoveFoundLastMouseActive = false;
                ForEachEventListenerBubbleUp(e, hitPointChain, (e1, listener) =>
                {
                    //please ensure=> no local var/pararmeter capture inside lambda
                    _mouseMoveFoundSomeHit = true;

#if DEBUG
                    if (_dbugEnableDebugMark && e.Ctrl && e1.X <= 10 && e1.Y <= 10)
                    {
                        //show dbug info
                        listener.dbugDevWriteInfo();
                    }
#endif



                    bool _bubble = true; //temp fix
                    if (_latestMouseActive != listener && !_mouseMoveFoundLastMouseActive)
                    {
                        //----------
                        e1.CancelBubbling = _bubble; //temp fix
                        listener.ListenMouseEnter(e1);
                        _bubble = e1.CancelBubbling;
                        //----------

                        if (_latestMouseActive != null)
                        {
                            _mouseLeaveEventArgs.SetCurrentContextElement(_latestMouseActive);
                            UIMouseLeaveEventArgs.SetDiff(_mouseLeaveEventArgs, e1.XDiff, e1.YDiff);
                            _latestMouseActive.ListenMouseLeave(_mouseLeaveEventArgs);
                        }

                        _latestMouseActive = listener;
                    }


                    if (!e1.IsCanceled)
                    {
                        //TODO: review here
                        e1.CancelBubbling = _bubble; //temp fix
                        listener.ListenMouseMove(e1);

                        if (!_mouseMoveFoundLastMouseActive)
                        {
                            _latestMouseActive = e1.CurrentContextElement;
                        }
                    }

                    if (!e1.CancelBubbling)
                    {
                        _mouseMoveFoundLastMouseActive = true;
                    }
                    return(e1.CancelBubbling);
                });

                if (!_mouseMoveFoundSomeHit)
                {
                    if (_latestMouseActive != null)
                    {
                        _mouseLeaveEventArgs.IsDragging = e.IsDragging;
                        UIMouseLeaveEventArgs.SetDiff(_mouseLeaveEventArgs, e.XDiff, e.YDiff);
                        _mouseLeaveEventArgs.SetCurrentContextElement(_latestMouseActive);

                        _latestMouseActive.ListenMouseLeave(_mouseLeaveEventArgs);
                        _latestMouseActive = null;
                    }
                }
            }
            SwapHitChain(hitPointChain);
            e.StopPropagation();
        }