reworked a lot of stuff... only partially tested