This could probably use some more tests, but it is good enough for now.