refactored for better abstraction or something