complete refactoring for a more generic design