private <T extends PageObject> void checkVisibilityOfAnnotatedFields(
     T pageInstance, Class<T> pageClazz) {
   Deque<Class<?>> classStack = ReflectionUtils.getClassAncestry(pageClazz);
   while (!classStack.isEmpty()) {
     checkVisibilityOfAnnotatedFieldsOfClass(pageInstance, classStack.pop());
   }
 }
 private <T extends PageObject> PageObject getPageObjectFromOf(Field field, T pageInstance) {
   try {
     return (PageObject) ReflectionUtils.forceGetFieldValue(field, pageInstance);
   } catch (Exception e) {
     throw exception(pageInstance, e).whenGettingPageObjectField(field);
   }
 }
 private <T extends PageObject> void invokePostConstructMethods(
     T pageInstance, Class<T> pageClazz) {
   Deque<Class<?>> classStack = ReflectionUtils.getClassAncestry(pageClazz);
   while (!classStack.isEmpty()) {
     invokePostConstructMethodsOfClass(pageInstance, classStack.pop());
   }
 }
 private <T extends PageObject> T createInstance(Class<T> pageClazz) {
   try {
     Constructor<T> classConstructor = pageClazz.getDeclaredConstructor();
     return ReflectionUtils.forceCreateInstance(classConstructor);
   } catch (Exception e) {
     throw exception(pageClazz, e).inConstructor();
   }
 }
 private <T extends PageObject> void tryToInvokePostConstructMethod(
     T pageInstance, Method method) {
   try {
     ReflectionUtils.forceInvokeMethod(method, pageInstance);
   } catch (Exception e) {
     throw exception(pageInstance, e).whenExecutingPostConstructMethod(method);
   }
 }
 private <T extends PageObject> void initializeOtherPageObjectTypeFields(
     T pageInstance, Class<T> pageClazz) {
   Browser browser = pageInstance.getBrowser();
   Deque<Class<?>> classAncestry = ReflectionUtils.getClassAncestry(pageClazz);
   while (!classAncestry.isEmpty()) {
     initializeFieldsOfClass(classAncestry.pop(), pageInstance, browser);
   }
 }
 private <T extends PageObject> void initializeWebElement(T pageInstance, WebElement webElement) {
   try {
     Field field = PageObject.class.getDeclaredField(FIELD_NAME_WEB_ELEMENT);
     ReflectionUtils.forceSetField(field, pageInstance, webElement);
   } catch (Exception e) {
     throw exception(pageInstance, e).inWebElementFieldInjection();
   }
 }
 private <T extends PageObject> void initializeModel(T pageInstance, PageObjectModel model) {
   try {
     Field field = PageObject.class.getDeclaredField(FIELD_NAME_MODEL);
     ReflectionUtils.forceSetField(field, pageInstance, model);
   } catch (Exception e) {
     throw exception(pageInstance, e).inModelFieldInjection();
   }
 }
  private <T extends PageObject> void initializeFieldAsPageObject(
      Field field, T pageInstance, Browser browser) {

    Identification identification = getIdentificationForField(field);

    PageObjectModel metaData =
        PageObjectModel.forPageFragment(browser, identification, pageInstance);
    metaData.setCaching(getCachingForField(field));
    metaData.setName(getNameForField(field));

    try {
      PageObject pageObject = create((Class<? extends PageObject>) field.getType(), metaData);
      ReflectionUtils.forceSetField(field, pageInstance, pageObject);
    } catch (Exception e) {
      throw exception(pageInstance, e).inPageObjectFieldInjection(field);
    }
  }
  @SuppressWarnings("rawtypes")
  private <T extends PageObject> void initializeFieldAsPageObjectList(
      Field field, T pageInstance, Browser browser) {

    Identification identification = getIdentificationForField(field);
    Class<? extends PageObject> listType = getPageObjectClassFromListField(pageInstance, field);

    PageObjectModel listMetaData =
        PageObjectModel.forPageFragment(browser, identification, pageInstance);
    listMetaData.setCaching(getCachingForField(field));
    listMetaData.setName(getNameForField(field));

    try {
      PageObjectList<? extends PageObject> pageObjectList =
          new LazyLoadingPageObjectList(listType, listMetaData);
      ReflectionUtils.forceSetField(field, pageInstance, pageObjectList);
    } catch (Exception e) {
      throw exception(pageInstance, e).inPageObjectFieldInjection(field);
    }
  }