refactored, added some tests (still failing)