refactor for cleaner abstraction