Rewrote a few bits. Needs further work.