refactor a bit, needs a lot of work