pretty large refactoring for better structure