most of the code done, not tested