Refactored for cleaner client API