refactor to use timeout parameter. add groovy/js support