def cache_control(validator=None, storage=None):
	def default_validator(*args, **kwargs):
		return True
	if validator is None:
		validator = default_validator
	if storage is None:
		storage = WGlobalSingletonCacheStorage()
	def first_level_decorator(decorated_function):
		def second_level_decorator(original_function, *args, **kwargs):
			validator_check = validator(original_function, *args, **kwargs)
			cache_entry = storage.get_cache(original_function, *args, **kwargs)
			if validator_check is not True or cache_entry.has_value is False:
				result = original_function(*args, **kwargs)
				storage.put(result, original_function, *args, **kwargs)
				return result
			else:
				return cache_entry.cached_value
		return decorator(second_level_decorator)(decorated_function)
	return first_level_decorator