Big refactoring and some fixes

Please see my changes.