@@ -0,0 +1,1308 @@
+package org.xander.behavioral.lazyevaluation;%0A%0Aimport java.math.BigInteger;%0A%0Aimport static org.xander.behavioral.lazyevaluation.TailCalls.call;%0Aimport static org.xander.behavioral.lazyevaluation.TailCalls.done;%0A%0Apublic class BigFactorial %7B%0A    public static BigInteger decrement(final BigInteger number) %7B%0A        return number.subtract(BigInteger.ONE);%0A    %7D%0A%0A    public static BigInteger multiply(final BigInteger first, final BigInteger second) %7B%0A        return first.multiply(second);%0A    %7D%0A%0A    final static BigInteger ONE = BigInteger.ONE;%0A    final static BigInteger FIVE = new BigInteger(%225%22);%0A    final static BigInteger TWENTYK = new BigInteger(%2220000%22);%0A%0A    private static TailCall%3CBigInteger%3E factorialTailRec(final BigInteger factorial, final BigInteger number) %7B%0A        if (number.equals(BigInteger.ONE)) %7B%0A            return done(factorial);%0A        %7D else %7B%0A            return call(() -%3E factorialTailRec(multiply(factorial, number), decrement(number)));%0A        %7D%0A    %7D%0A%0A    public static BigInteger factorial(final BigInteger number) %7B%0A        return factorialTailRec(BigInteger.ONE, number).invoke();%0A    %7D%0A%0A    public static void main(final String%5B%5D args) %7B%0A        System.out.println(factorial(FIVE));%0A        System.out.println(String.format(%22%25.10s...%22, factorial(TWENTYK)));%0A    %7D%0A%7D%0A

Create BigFactorial.java