Major refactoring. Still work in progress.