A lot of changes

Please see code comments for details.