Almost done. Need some tests and a bit refactor