def method_cache(by='value',method='run'):
    def decorate_(func):
        def decorate(*args, **kwargs):
            model = args[0]
            assert hasattr(model,method), "Model must have a '%s' method."%method
            if func.__name__ == method:
                method_args = kwargs
            else:
                method_args = kwargs[method] if method in kwargs else {}
            if not hasattr(model.__class__,'cached_runs'):
                model.__class__.cached_runs = {}
            cache = model.__class__.cached_runs
            if by == 'value':
                model_dict = {key:value for key,value in list(model.__dict__.items()) \
                              if key[0]!='_'}
                method_signature = SciUnit.dict_hash({'attrs':model_dict,'args':method_args})
            elif by == 'instance':
                method_signature = SciUnit.dict_hash({'id':id(model),'args':method_args})
            else:
                raise ValueError("Cache type must be 'value' or 'instance'")
            if method_signature not in cache:
                print("Method with this signature not found in the cache. Running...")
                f = getattr(model,method)
                f(**method_args)
                cache[method_signature] = (datetime.now(),model.__dict__.copy())
            else:
                print("Method with this signature found in the cache. Restoring...")
                _,attrs = cache[method_signature]
                model.__dict__.update(attrs)
            return func(*args, **kwargs)
        return decorate
    return decorate_