First version - needs more tests + 2b squashed