try to do as much refactoring as possible, will try to come up with new rules after this