private Vector3?aimImpl()
    {
        //Alteration from Kain for testing...
        m_targetSpeedAtTimeOfCalculation     = targetVelocity.magnitude;
        m_projectileSpeedAtTimeOfCalculation = shotForce;
        //...Alteration from Kain for testing

        switch (whichPredictiveCodeToUse)
        {
        case PredictiveCodeToUse.Rupert: {
            var aimVector = ProjectileAimingUtils.getLaunchVector(targetPos, targetVelocity, bulletStartPos, shotForce, ownVelocity, shotObeysGravity ? Physics.gravity : (Vector3?)null);
            return(aimVector.isNaN() ? (Vector3?)null : aimVector);
        }

        case PredictiveCodeToUse.Kain: {
            Debug.LogFormat(this, "{0} shooting with Kain's code", this);
            //Alteration from Kain for testing...
            //ORIGINAL var aimVector = GameUtilities.PredictiveAim(bulletStartPos, shotForce, targetPos, targetVelocity, shotObeysGravity ? -Physics.gravity.y : 0f); // negate gravity since multiplied by Vector3.down
            Vector3 aimVector;
            m_lastPredictionFoundValidSolution = GameUtilities.PredictiveAim(bulletStartPos, shotForce, targetPos, targetVelocity, shotObeysGravity ? -Physics.gravity.y : 0f, out aimVector);                             // negate gravity since multiplied by Vector3.down
            //...Alteration from Kain for testing
            return(aimVector.isNaN() ? (Vector3?)null : aimVector);
        }

        case PredictiveCodeToUse.JavaScript:
            return(PredictiveAimJSConverted.intercept(bulletStartPos, targetPos, targetVelocity, shotForce));

        default:
            throw new System.NotSupportedException(string.Format("Implement {0} support", whichPredictiveCodeToUse));
        }
    }