protected function spin($lambda, $args = false, $timeout = false, $exception = false, $microsleep = false) {

        // Using default timeout which is pretty high.
        if (!$timeout) {
            $timeout = self::get_timeout();
        }
        if ($microsleep) {
            // Will sleep 1/10th of a second by default for self::get_timeout() seconds.
            $loops = $timeout * 10;
        } else {
            // Will sleep for self::get_timeout() seconds.
            $loops = $timeout;
        }

        // DOM will never change on non-javascript case; do not wait or try again.
        if (!$this->running_javascript()) {
            $loops = 1;
        }

        for ($i = 0; $i < $loops; $i++) {
            // We catch the exception thrown by the step definition to execute it again.
            try {
                // We don't check with !== because most of the time closures will return
                // direct Behat methods returns and we are not sure it will be always (bool)false
                // if it just runs the behat method without returning anything $return == null.
                if ($return = call_user_func($lambda, $this, $args)) {
                    return $return;
                }
            } catch (Exception $e) {
                // We would use the first closure exception if no exception has been provided.
                if (!$exception) {
                    $exception = $e;
                }
            }

            if ($this->running_javascript()) {
                if ($microsleep) {
                    usleep(100000);
                } else {
                    sleep(1);
                }
            }
        }

        // Using coding_exception as is a development issue if no exception has been provided.
        if (!$exception) {
            $exception = new coding_exception('spin method requires an exception if the callback does not throw an exception');
        }

        // Throwing exception to the user.
        throw $exception;
    }