updated with unit tests