needs much refactoring