public class Factorial_J {
  public static long iterative ( final long n ) {
    if ( n < 0 ) { throw new FactorialIllegalArgumentException ( "Parameter must be a non-negative integer." ) ; }
    long total = 1 ;
    for ( long i = 2 ; i <= n ; ++i ) { total *= i ; }
    return total ;
  }
  public static long recursive ( final long n ) {
    if ( n < 0 ) { throw new FactorialIllegalArgumentException ( "Parameter must be a non-negative integer." ) ; }
    return n < 2 ? 1 : n * recursive ( n - 1 ) ;
  }
  private static long iterate ( final long n , final long result ) {
    return n < 2 ? result : iterate ( n - 1 , result * n ) ;
  }
  public static long tailRecursive ( final long n ) {
    if ( n < 0 ) { throw new FactorialIllegalArgumentException ( "Parameter must be a non-negative integer." ) ; }
    return n < 2 ? 1 : iterate ( n  , 1 ) ;
  }
}
