refactor some code, add lots of docs