major refactor, compile through but not tested