public static <V1,V2,T,R> Function2<V1, V2, R> andThen(final Function2<? super V1,? super V2, ? extends T> before, final Function1<? super T, ? extends R> after) {
		if (after == null)
			throw new NullPointerException("after");
		if (before == null)
			throw new NullPointerException("before");
		return new Function2<V1, V2, R>() {
			@Override
			public R apply(V1 v1, V2 v2) {
				return after.apply(before.apply(v1, v2));
			}
		};
	}
public static < V1 , V2 , T , R > Function2 < V1 , V2 , R > andThen ( final Function2 < ? super V1 , ? super V2 , ? extends T > before , final Function1 < ? super T , ? extends R > after ) { if ( after == null ) throw new NullPointerException ( "after" ) ; if ( before == null ) throw new NullPointerException ( "before" ) ; return new Function2 < V1 , V2 , R > ( ) { @ Override public R apply ( V1 v1 , V2 v2 ) { return after . apply ( before . apply ( v1 , v2 ) ) ; } } ; }
Returns a composed function that first applies the {@code before}
function to its input, and then applies the {@code after} function to the result.
If evaluation of either function throws an exception, it is relayed to
the caller of the composed function.

@param <V1> the type of the first parameter to the {@code before} function, and to the composed function
@param <V2> the type of the second parameter to the {@code before} function, and to the composed function
@param <T> the type of output of the {@code before} function, and input to the {@code after} function
@param <R> the type of output to the {@code after} function, and to the composed function
@param before the function to apply before the {@code after} function is applied
@param after the function to apply after the {@code before} function is applied
@return a composed function that first applies the {@code before}
function and then applies the {@code after} function
@throws NullPointerException if {@code before} or {@code after} is null

@see #compose(Functions.Function1, Functions.Function1)
@since 2.9