This is a version of code submitted by Daisuke Aoyama <aoyama at peach.ne.jp> with some architectural changes.