Refactored and reorganized. Added caching.