refactor the whole, pass two tests and add two tests