refactoring, and added caching