internal refactor for better extensibility