First complete version. This version has bugs.