Complete rewrite with more options and fixes.