lots of refactoring, cache works