there are probably bugs left, but most of the code is coherent