Extensive changes. Untested and may not compile.