refactor & tests