whole plugin is now wrapped in a closure to avoid implicit global scope