Added a lot of modifications. Please see the diff file.