code: protected static Map<String, Method> getPropertyGetters(Class<?> clazz) { //todo: clazz.getDeclaredMethods() + hierarchy up OR clazz.getMethods()?
          Map<String, Method> result = new HashMap<String, Method>();
  
          if (clazz != Object.class) {
              Method[] methodArr = clazz.getMethods();
              for (Method method : methodArr) {
                  if (isNameSuitableForGetter(method)) {
                      if (method.getDeclaringClass() != Object.class && !method.isBridge()) { //remove Object.getClass()
                          final Annotation[] annArr = method.getDeclaredAnnotations();
                          boolean find = false;
                          for (Annotation ann : annArr) {
                              if (ann.annotationType() == Transient.class) { 
                                  find = true;
                                  break;
                              }
                          }
                          if (!find) {
                              String fieldName;
                              if (method.getReturnType() == Boolean.TYPE && method.getName().startsWith("is"))
                                  fieldName = method.getName().substring(2, 3).toLowerCase() + method.getName().substring(3);
                              else
                                  fieldName = method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4);
                              result.put(fieldName, method);
                          }
                      }
                  }
              }
              clazz = clazz.getSuperclass();
          }
  
          return result;
      }
docs: 1) move hierarchy up
  2) look for method with name
  3) check @TransientGetter
  
  @param clazz
  @return