first implementation
Refactored to ease testing
Added proper unit & integration tests. Fixed small bugs here and there