lots of changes, please use diff tool for details