public static TResult Start <T1, T2, TResult>(
            Func <T1, T2, Bounce <T1, T2, TResult> > action, T1 arg1, T2 arg2)
        {
            var result = default(TResult);
            var bounce = Bounce <T1, T2, TResult> .Continue(arg1, arg2);

            while (true)
            {
                if (bounce.HasResult)
                {
                    result = bounce.Result;
                    break;
                }

                bounce = action(bounce.Arg1, bounce.Arg2);
            }

            return(result);
        }
 private Bounce <BigInteger, BigInteger, BigInteger> Iteration(BigInteger current, BigInteger n)
 {
     return(n == 0
         ? Bounce <BigInteger, BigInteger, BigInteger> .End(current)
         : Bounce <BigInteger, BigInteger, BigInteger> .Continue(current *n, n - 1));
 }