complete refactor; fix tests