def METHOD_NAME(func):
    def wrap_f(*args, **kwargs):
        fn_cache = kwargs.pop('fn_cache')
        if fn_cache is None:
            results = func(*args, **kwargs)
        else:
            cached_result = fn_cache.get(
                (func.__name__, tuple(args[0]), frozenset(kwargs.items())))
            if cached_result is not None:
                return cached_result
            results = func(*args, **kwargs)
            if results is not None:
                fn_cache.put(
                    (func.__name__, tuple(args[0]),
                        frozenset(kwargs.items())),
                    results)
        return results
    return wrap_f