Massive refactor, add docs