private AnnotatedElement getAnnotatedElement(Class<?> cl, String propertyName)
     throws NoSuchMethodException {
   try {
     return cl.getDeclaredField(propertyName);
   } catch (NoSuchFieldException e) {
     String getter = "get" + BeanUtils.capitalize(propertyName);
     String bgetter = "is" + BeanUtils.capitalize(propertyName);
     for (Method method : cl.getDeclaredMethods()) {
       if ((method.getName().equals(getter) || method.getName().equals(bgetter))
           && method.getParameterTypes().length == 0) {
         return method;
       }
     }
     if (cl.getSuperclass().equals(Object.class)) {
       throw new IllegalArgumentException(
           "No property found for " + cl.getName() + "." + propertyName);
     } else {
       return getAnnotatedElement(cl.getSuperclass(), propertyName);
     }
   }
 }
 private Type getType(Class<?> cl, String propertyName) throws NoSuchMethodException {
   try {
     Field field = cl.getDeclaredField(propertyName);
     return typeFactory.create(field.getType(), field.getGenericType());
   } catch (NoSuchFieldException e) {
     String getter = "get" + BeanUtils.capitalize(propertyName);
     String bgetter = "is" + BeanUtils.capitalize(propertyName);
     for (Method method : cl.getDeclaredMethods()) {
       if ((method.getName().equals(getter) || method.getName().equals(bgetter))
           && method.getParameterTypes().length == 0) {
         return typeFactory.create(method.getReturnType(), method.getGenericReturnType());
       }
     }
     if (cl.getSuperclass().equals(Object.class)) {
       throw new IllegalArgumentException(
           "No property found for " + cl.getName() + "." + propertyName);
     } else {
       return getType(cl.getSuperclass(), propertyName);
     }
   }
 }