private void UpdateInteractionSourceState(InteractionSourceState sourceState)
    {
        uint            id    = sourceState.source.id;
        ControllerState state = InputState.Current.GetController(sourceState);

        if (imDevices.ContainsKey(id))
        {
            var        sourcePose      = sourceState.sourcePose;
            Vector3    position        = Vector3.zero;
            Quaternion rotation        = Quaternion.identity;
            Vector3    pointerPosition = Vector3.zero;
            Quaternion pointerRotation = Quaternion.identity;

#if UNITY_5
            bool hasRotation = sourcePose.TryGetRotation(out rotation);
            bool hasPosition = sourcePose.TryGetPosition(out position);
#else
            bool hasRotation = sourcePose.TryGetRotation(out rotation, InteractionSourceNode.Grip);
            bool hasPosition = sourcePose.TryGetPosition(out position, InteractionSourceNode.Grip);
#endif

#if UNITY_5
            bool hasPointerPosition = sourcePose.TryGetPointerPosition(out pointerPosition);
            bool hasPointerRotation = sourcePose.TryGetPointerRotation(out pointerRotation);
#else
            bool hasPointerPosition = sourcePose.TryGetPosition(out pointerPosition, InteractionSourceNode.Pointer);
            bool hasPointerRotation = sourcePose.TryGetRotation(out pointerRotation, InteractionSourceNode.Pointer);
#endif

            if (hasPosition || hasRotation || hasPointerPosition || hasPointerRotation)
            {
#if VALIDATE_INPUT
                if (pointerPosition.IsDebugValid() && position.IsDebugValid() &&
                    pointerRotation.IsDebugValid() && rotation.IsDebugValid()
                    )
#endif
                {
                    state.Position = position;
                    state.Rotation = rotation;

                    if ((hasPosition && hasRotation) && ((FilterInput & PoseSource.Grip) != PoseSource.None))
                    {
                        SetTransform(imDevices[id], position, rotation);
                    }

                    else if ((hasPointerPosition && hasPointerRotation) && ((FilterInput & PoseSource.Pointer) != PoseSource.None))
                    {
                        SetTransform(imDevices[id], pointerPosition, pointerRotation);
                    }


                    if (hasPointerPosition)
                    {
                        Vector3 forward;
#if UNITY_5
                        Ray ray;
                        if (sourcePose.TryGetPointerRay(out ray))
                        {
                            forward         = ray.direction;
                            pointerPosition = ray.origin;
#else
                        if (sourcePose.TryGetForward(out forward, InteractionSourceNode.Pointer))
                        {
#endif
#if VERBOSE_POSITION
                            TraceHelper.LogDiff(string.Format("Pos:{0}, Fwd:{1}",
                                                              pointerPosition, forward), Cache.ForwardPosition);
#endif
                            if (cursor != null)
                            {
                                cursor.transform.position = pointerPosition + forward;
                            }
                        }
                        else
                        {
                            TraceHelper.Log("Failed get forward");
                        }
                    }
                }
#if VALIDATE_INPUT
                else
                {
                    invalidCoordsCount++;
                    TraceHelper.LogModulus(string.Format("Invalid: Pointer: {0}, Grip: {1}, count: {2}",
                                                         pointerPosition, position, invalidCoordsCount), TraceVariables.InteractionManagerLoop);
                }
#endif
            }
            else
            {
                TraceHelper.LogModulus(string.Format("No readings:{0}-- Grip: Pos-{1}, Rot-{2}, PointerPos-{3}, Rot-{4}",
#if UNITY_5
                                                     sourceState.source.sourceKind.ToString(),
#else
                                                     sourceState.source.kind.ToString(),
#endif
                                                     hasPosition, hasRotation,
                                                     hasPointerPosition, hasPointerRotation
                                                     ), TraceVariables.InteractionManagerLoop);
            }
            var rootproperties = sourceState;
#if UNITY_5
            state.SelectValue       = (float)rootproperties.selectPressedValue;
            state.TouchPadXValue    = (float)rootproperties.controllerProperties.touchpadX;
            state.TouchPadYValue    = (float)rootproperties.controllerProperties.touchpadY;
            state.ThumbstickXValue  = (float)rootproperties.controllerProperties.thumbstickX;
            state.ThumbstickYValue  = (float)rootproperties.controllerProperties.thumbstickY;
            state.TouchPadPressed   = rootproperties.controllerProperties.touchpadPressed;
            state.TouchPadTouched   = rootproperties.controllerProperties.touchpadTouched;
            state.ThumbstickPressed = rootproperties.controllerProperties.thumbstickPressed;
#else
            state.SelectValue       = rootproperties.selectPressedAmount;
            state.TouchPadXValue    = rootproperties.touchpadPosition.x;
            state.TouchPadYValue    = rootproperties.touchpadPosition.y;
            state.ThumbstickXValue  = rootproperties.thumbstickPosition.x;
            state.ThumbstickYValue  = rootproperties.thumbstickPosition.y;
            state.TouchPadPressed   = rootproperties.touchpadPressed;
            state.TouchPadTouched   = rootproperties.touchpadTouched;
            state.ThumbstickPressed = rootproperties.thumbstickPressed;
#endif

            state.SelectPressed   = rootproperties.selectPressed;
            state.MenuPressed     = rootproperties.menuPressed;
            state.GraspPressed    = rootproperties.grasped;
            state.Position        = position;
            state.PointerPosition = pointerPosition;
            state.Rotation        = rotation;
            state.PointerRotation = pointerRotation;
            state.IsLeftHand      = sourceState.source.handedness == InteractionSourceHandedness.Left;
            state.IsRightHand     = sourceState.source.handedness == InteractionSourceHandedness.Right;

#if VERBOSE_STATE
            state.TraceState(FilterInput);
#endif

            Vector3 pointerForward = Vector3.zero, gripForward = Vector3.zero;
            bool    hasPointerForward = false, hasGripForward = false;
#if !UNITY_5
            if ((hasPointerForward = sourcePose.TryGetForward(out pointerForward, InteractionSourceNode.Pointer)) &&
                (hasGripForward = sourcePose.TryGetForward(out gripForward, InteractionSourceNode.Grip)))
            {
#else
            Ray rayAxis;
            if ((hasPointerForward = hasPointerPosition = sourcePose.TryGetPointerRay(out rayAxis)))
            {
                pointerForward  = rayAxis.direction;
                pointerPosition = rayAxis.origin;
                hasGripForward  = true; //it is a zero vector.
#endif
                if (ShowDebugAxis)
                {
                    AxisRenderer axis = (state.IsLeftHand ? axisRendererLeft : axisRendererRight);
                    if (axis != null)
                    {
                        if (hasPointerForward && hasPointerPosition)
                        {
                            axis.SetValues(state.PointerPosition, pointerForward * 2, state.PointerRotation, AxisRenderer.ControllerElement.Pointer);
                        }
                        if (hasGripForward && hasPosition)
                        {
                            axis.SetValues(state.Position, gripForward * 2, state.Rotation, AxisRenderer.ControllerElement.Grip);
                        }
                    }
                }
            }
#if VERBOSE_STATE
            else
            {
                TraceHelper.LogModulus(string.Format("No Forward vectors. Grip: {0}, pointer:{1}",
                                                     hasPointerForward, hasGripForward), TraceVariables.InteractionManagerLoop);
            }
#endif


            if (AnimateControllerModel)
            {
                MotionControllerInfo currentController;
                if (controllerInfoForAnimation.TryGetValue(sourceState.source.id, out currentController))
                {
#if !UNITY_5
                    currentController.AnimateSelect(sourceState.selectPressedAmount);
                    if (sourceState.source.supportsGrasp)
                    {
                        currentController.AnimateGrasp(sourceState.grasped);
                    }

                    if (sourceState.source.supportsMenu)
                    {
                        currentController.AnimateMenu(sourceState.menuPressed);
                    }
                    if (sourceState.source.supportsThumbstick)
                    {
                        currentController.AnimateThumbstick(sourceState.thumbstickPressed, sourceState.thumbstickPosition);
                    }

                    if (sourceState.source.supportsTouchpad)
                    {
                        currentController.AnimateTouchpad(sourceState.touchpadPressed, sourceState.touchpadTouched, sourceState.touchpadPosition);
                    }
#else
                    currentController.AnimateSelect((float)sourceState.selectPressedValue);
                    if (sourceState.source.supportsGrasp)
                    {
                        currentController.AnimateGrasp(sourceState.grasped);
                    }

                    if (sourceState.source.supportsMenu)
                    {
                        currentController.AnimateMenu(sourceState.menuPressed);
                    }

                    InteractionController controller;
                    if (sourceState.source.TryGetController(out controller))
                    {
                        if (controller.hasThumbstick)
                        {
                            currentController.AnimateThumbstick(sourceState.controllerProperties.thumbstickPressed,
                                                                new Vector2((float)sourceState.controllerProperties.thumbstickX,
                                                                            (float)sourceState.controllerProperties.thumbstickY));
                        }

                        if (controller.hasTouchpad)
                        {
                            currentController.AnimateTouchpad(sourceState.controllerProperties.touchpadPressed,
                                                              sourceState.controllerProperties.touchpadTouched,
                                                              new Vector2((float)sourceState.controllerProperties.touchpadX,
                                                                          (float)sourceState.controllerProperties.touchpadX));
                        }
                    }
#endif
                }
                else
                {
                    TraceHelper.Log("Could not animate " + sourceState.source.id);
                }
            }

            if (state.ThumbstickPressed &&
                (Time.unscaledTime > (debounceThumbstickTime + 3f))
                )
            {
                ShowDebugAxis = !ShowDebugAxis;
                UpdateDebugAxis(ShowDebugAxis);
                debounceThumbstickTime = Time.unscaledTime;
            }
        }
    }

    float debounceThumbstickTime = 0f;