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);
    }
  }
  @Override
  public <T extends PageObject> T create(
      Class<T> pageClazz, PageObjectModel model, WebElement webElement) {

    try {

      T pageInstance = createInstance(pageClazz);
      initializeModel(pageInstance, model);
      initializeWebElement(pageInstance, webElement);

      initializeOtherPageObjectTypeFields(pageInstance, pageClazz);

      invokePostConstructMethods(pageInstance, pageClazz);
      checkVisibilityOfAnnotatedFields(pageInstance, pageClazz);

      return pageInstance;

    } catch (RuntimeException e) {
      EventSystem.fireEvent(new ExceptionEvent(model.getBrowser(), e));
      throw e;
    }
  }