public static function allowExcessiveArguments(callable $function)
    {
        $reflection = Reflection::fromCallable($function);
        if ($reflection->isUserDefined()) {
            return $function;
        }

        if (Reflection::isVariadic($reflection)) {
            return $function;
        }

        $numberOfArguments = $reflection->getNumberOfParameters();

        $argumentLimiter = function () use ($function, $numberOfArguments) {
            return call_user_func_array($function, array_slice(func_get_args(), 0, $numberOfArguments));
        };

        /*
         * If there are default values, just use the default closure to
         * ensure correct default values are used for unsupplied arguments.
         */
        if ($numberOfArguments !== $reflection->getNumberOfRequiredParameters()) {
            return $argumentLimiter;
        }

        /*
         * Micro-optimization: provide simple wrappers for internal functions
         * with simple signatures rather than the more costly argument array slicing.
         */
        switch ($numberOfArguments) {
            case 0:
                return function () use ($function) {
                    return $function();
                };

            case 1:
                return function ($a) use ($function) {
                    return $function($a);
                };

            case 2:
                return function ($a, $b) use ($function) {
                    return $function($a, $b);
                };

            case 3:
                return function ($a, $b, $c) use ($function) {
                    return $function($a, $b, $c);
                };

            case 4:
                return function ($a, $b, $c, $d) use ($function) {
                    return $function($a, $b, $c, $d);
                };

            default:
                return $argumentLimiter;
        }
    }