/// <summary>
        ///     Processes the machine update for controls which weren't seen with the current (latest) point.
        /// </summary>
        /// <param name="control">The control (which was not seen).</param>
        /// <param name="data">The view-model for the control.</param>
        /// <param name="window">The window where the control is located.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     Thrown if the control is in an unexpected state (e.g. infrastructure created a new state and a module considers it,
        ///     but this module has not been updated).
        /// </exception>
        private void StateMachineUpdateForOtherControls(
            SelectableControl control,
            ISelectableControlViewModel data,
            Window window)
        {
            switch (data.State)
            {
            case SelectableState.Idle:
                break;

            case SelectableState.SeenButWaiting:
                if (data.CurrentGazeTimeSpan == TimeSpan.Zero)
                {
                    data.State = SelectableState.Idle;
                }

                break;

            case SelectableState.AnimationRunning:
                if (data.CurrentGazeTimeSpan == TimeSpan.Zero)
                {
                    data.State = SelectableState.Idle;
                    window.Dispatcher.Invoke(control.StopAnimation);
                }
                else
                {
                    data.State = SelectableState.AnimationOnHold;
                    window.Dispatcher.Invoke(control.PauseAnimation);
                }

                break;

            case SelectableState.AnimationOnHold:
                if (data.CurrentGazeTimeSpan == TimeSpan.Zero)
                {
                    data.State = SelectableState.Idle;
                    window.Dispatcher.Invoke(control.StopAnimation);
                }

                break;

            case SelectableState.RecentlySelected:
                if (data.CurrentGazeTimeSpan >= data.GazeTimeSpanBeforeCooldown)
                {
                    data.CurrentGazeTimeSpan = TimeSpan.Zero;
                }

                if (data.CurrentGazeTimeSpan == TimeSpan.Zero)
                {
                    data.State = SelectableState.Idle;
                }

                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        /// <summary>
        ///     Processes the machine update for the control which was seen with the current (latest) point.
        /// </summary>
        /// <param name="seenControl">The control which was seen.</param>
        /// <param name="data">The view-model for the control.</param>
        /// <param name="window">The window where the control is located.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     Thrown if the control is in an unexpected state (e.g. infrastructure created a new state and a module considers it,
        ///     but this module has not been updated).
        /// </exception>
        private void StateMachineUpdateForSeenControl(
            SelectableControl seenControl,
            ISelectableControlViewModel data,
            Window window)
        {
            bool isAlwaysSelectable = false;

            window.Dispatcher.Invoke(() => isAlwaysSelectable = seenControl.IsAlwaysSelectable);
            if (!data.IsSelectable &&
                !isAlwaysSelectable)
            {
                return;
            }

            switch (data.State)
            {
            case SelectableState.Idle:
                data.State = SelectableState.SeenButWaiting;
                break;

            case SelectableState.SeenButWaiting:
                if (data.CurrentGazeTimeSpan == TimeSpan.Zero)
                {
                    data.State = SelectableState.Idle;
                }

                if (data.CurrentGazeTimeSpan >= data.GazeTimeSpanBeforeAnimationBegins)
                {
                    window.Dispatcher.Invoke(seenControl.PlayAnimation);
                    data.State = SelectableState.AnimationRunning;
                }

                break;

            case SelectableState.AnimationRunning:
                if (data.CurrentGazeTimeSpan >= data.GazeTimeSpanBeforeSelectionOccurs)
                {
                    window.Dispatcher.Invoke(seenControl.Select);
                    data.State = SelectableState.RecentlySelected;
                }

                if (data.CurrentGazeTimeSpan == TimeSpan.Zero)
                {
                    data.State = SelectableState.Idle;
                    window.Dispatcher.Invoke(seenControl.StopAnimation);
                }

                break;

            case SelectableState.AnimationOnHold:
                window.Dispatcher.Invoke(seenControl.ResumeAnimation);
                data.State = SelectableState.AnimationRunning;
                if (data.CurrentGazeTimeSpan == TimeSpan.Zero)
                {
                    data.State = SelectableState.Idle;
                    window.Dispatcher.Invoke(seenControl.StopAnimation);
                }

                break;

            case SelectableState.RecentlySelected:
                if (data.CurrentGazeTimeSpan >= data.GazeTimeSpanBeforeCooldown)
                {
                    data.CurrentGazeTimeSpan = TimeSpan.Zero;
                }

                if (data.CurrentGazeTimeSpan == TimeSpan.Zero)
                {
                    data.State = SelectableState.Idle;
                }

                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }