def wait_until_page_loaded(page_obj_class,
                               webdriver=None,
                               timeout=WTF_TIMEOUT_MANAGER.NORMAL,
                               sleep=0.5,
                               bad_page_classes=[],
                               message=None,
                               **kwargs):
        """
        Waits until the page is loaded.

        Args:
            page_obj_class (Class) : PageObject class

        Kwargs:
            webdriver (Webdriver) : Selenium Webdriver.  Default uses WTF_WEBDRIVER_MANAGER's instance.
            timeout (number) : Number of seconds to wait to allow the page to load.
            sleep (number) : Number of seconds to wait between polling.
            bad_page_classes (list) : List of PageObject classes to fail if matched.  For example, ServerError page.
            message (string) : Use your own message with PageLoadTimeoutError raised.

        Returns:
            PageObject

        Raises:
            PageUtilOperationTimeoutError : Timeout occurred before the desired PageObject was matched.
            BadPageEncounteredError : One or more of the PageObject in the specified 'bad_page_classes' list 
            was matched.


        Usage Example:: 
            webdriver.get("http://www.mysite.com/login")
            # Wait up to 60 seconds for the page to load.
            login_page = wait_until_page_loaded(LoginPage, timeout=60, [ServerErrorPage])

        This will wait for the login_page to load, then return a LoginPage() PageObject.

        """
        if not webdriver:
            webdriver = WTF_WEBDRIVER_MANAGER.get_driver()

        # convert this param to list if not already.
        if type(bad_page_classes) != list:
            bad_page_classes = [bad_page_classes]

        end_time = datetime.now() + timedelta(seconds=timeout)
        last_exception = None
        while datetime.now() < end_time:
            # Check to see if we're at our target page.
            try:
                page = PageFactory.create_page(
                    page_obj_class, webdriver=webdriver, **kwargs)
                return page
            except Exception as e:
                _wtflog.debug("Encountered exception: %s ", e)
                last_exception = e

            # Check to see if we're at one of those labled 'Bad' pages.
            for bad_page_class in bad_page_classes:
                try:
                    PageFactory.create_page(
                        bad_page_class, webdriver=webdriver, **kwargs)
                    # if the if/else statement succeeds, than we have an error.
                    raise BadPageEncounteredError(
                        u("Encountered a bad page. ") + bad_page_class.__name__)
                except BadPageEncounteredError as e:
                    raise e
                except:
                    pass  # We didn't hit a bad page class yet.
            # sleep till the next iteration.
            time.sleep(sleep)

        print "Unable to construct page, last exception", last_exception

        # Attempt to get current URL to assist in debugging
        try:
            current_url = webdriver.current_url
        except:
            # unable to get current URL, could be a webdriver for a non-webpage like mobile app.
            current_url = None

        if message:
            err_msg = u(message) + u("{page}:{url}")\
                .format(page=PageUtils.__get_name_for_class__(page_obj_class),
                        url=current_url)
        else:
            err_msg = u("Timed out while waiting for {page} to load. Url:{url}")\
                .format(page=PageUtils.__get_name_for_class__(page_obj_class),
                        url=current_url)
        raise PageLoadTimeoutError(err_msg)
Waits until the page is loaded.

        Args:
            page_obj_class (Class) : PageObject class

        Kwargs:
            webdriver (Webdriver) : Selenium Webdriver.  Default uses WTF_WEBDRIVER_MANAGER's instance.
            timeout (number) : Number of seconds to wait to allow the page to load.
            sleep (number) : Number of seconds to wait between polling.
            bad_page_classes (list) : List of PageObject classes to fail if matched.  For example, ServerError page.
            message (string) : Use your own message with PageLoadTimeoutError raised.

        Returns:
            PageObject

        Raises:
            PageUtilOperationTimeoutError : Timeout occurred before the desired PageObject was matched.
            BadPageEncounteredError : One or more of the PageObject in the specified 'bad_page_classes' list 
            was matched.


        Usage Example:: 
            webdriver.get("http://www.mysite.com/login")
            # Wait up to 60 seconds for the page to load.
            login_page = wait_until_page_loaded(LoginPage, timeout=60, [ServerErrorPage])

        This will wait for the login_page to load, then return a LoginPage() PageObject.