rewritten some parts of code to be more loose coupled