Add documentation, refactor the code and add more tests