further refactoring (maybe final)