fully refactored to simplify the API