complete rewrite
complete rewrite
added tests