refactoring and add cache.