some heavy refactoring