full code rewrite (note: syntax changed)