major refactoring + new tests