docs: def cache_control(validator=None, storage=None):
  	""" Decorator that is used for caching result.
  
  	:param validator: function, that has following signature (decorated_function, \*args, \*\*kwargs), where \
  	decorated_function - original function, args - function arguments, kwargs - function keyword arguments. \
  	This function must return True if cache is valid (old result must be use if it there is one), or False - to \
  	generate and to store new result. So function that always return True can be used as singleton. And function \
  	that always return False won't cache anything at all. By default (if no validator is specified), it presumes \
  	that cache is always valid.
  	:param storage: storage that is used for caching results. see :class:`.WCacheStorage` class.
  
  	:return: decorated function
  	"""
  
  	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