add docs and test, refactor