submitted version; minorly bugged