function filterArguments( fcn, predicate, thisArg ) {
	if ( !isFunction( fcn ) ) {
		throw new TypeError( format( 'invalid argument. First argument must be a function. Value: `%s`.', fcn ) );
	}
	if ( !isFunction( predicate ) ) {
		throw new TypeError( format( 'invalid argument. Second argument must be a function. Value: `%s`.', predicate ) );
	}
	return wrap;

	/**
	* Invokes a function according to a predicate function.
	*
	* @private
	* @param {...*} args - arguments
	* @returns {*} return value
	*/
	function wrap() {
		var args;
		var v;
		var i;

		args = [];
		for ( i = 0; i < arguments.length; i++ ) {
			v = arguments[ i ];
			if ( predicate( v, i ) ) {
				args.push( v );
			}
		}
		return fcn.apply( thisArg, args );
	}
}
Returns a function that applies arguments to a provided function according to a predicate function.

## Notes

-   The predicate function is provided the following arguments:

    -   **value**: argument value.
    -   **index**: argument index.

-   Only those arguments in which the predicate function returns a truthy value are applied to a provided function.

@param {Function} fcn - input function
@param {Function} predicate - predicate function
@param {*} [thisArg] - function context
@throws {TypeError} first argument must be a function
@throws {TypeError} second argument must be a function
@returns {Function} wrapped function

@example
function foo( a, b ) {
    return [ a, b ];
}

function predicate( v ) {
    return ( v !== 2 );
}

var bar = filterArguments( foo, predicate );

var out = bar( 1, 2, 3 );
// returns [ 1, 3 ]