Complete rewrite. Needs documenting.