refactored a bit, still need to write functional test