quite some refactoring