more refactoring, added some tests