public MissileAccelerationData CalculateMissileAcceleration(int targetRange, int burnDuration, int acceleration, AimAdjustment aimAdjustment, float roc)
        {
            int   tableColumn;
            float totalPositionAdjustment = _missilePositionAdjustmentTable.GetTotalMissileAdjustment(burnDuration, acceleration, aimAdjustment, out tableColumn);

            var result = new MissileAccelerationData
            {
                TotalAcceleration       = roc * burnDuration,
                TotalPositionAdjustment = totalPositionAdjustment,
                TableColumn             = tableColumn,
                TargetRange             = targetRange,
                BurnDuration            = burnDuration,
                ValidLaunch             = true
            };

            result.BurnDistance = result.TotalAcceleration - result.TotalPositionAdjustment;
            float nextRange = targetRange - result.BurnDistance;

            if (nextRange <= 0)
            {
                result.ValidLaunch = false;
                return(result);
            }

            // Filling acceleration data per impulse.
            for (int i = 0; i < burnDuration; i++)
            {
                var currentImpulse = new MissileAccelerationImpulse
                {
                    PositionAdjustment = _missilePositionAdjustmentTable.GetSegmentMissileAdjustment(i + 1, acceleration, aimAdjustment),
                    Range = nextRange
                };

                result.ImpulseData.Add(currentImpulse);

                nextRange = nextRange + roc - currentImpulse.PositionAdjustment;
            }

            if (Math.Abs(nextRange - targetRange) > 0.3f)
            {
                throw new ArithmeticException(string.Format("After computing missile acceleration info, couldn't reach target range at launch ({0}). Final range = {1}",
                                                            targetRange, nextRange));
            }

            return(result);
        }