need a major refactor IMO