Almost finished, needs more tests