refactor needs more testing, but should work for experimental purposes