major rewrite + refactor