complete refactor (not done yet)