heavy refactoring for better testability