code: protected final String findMessage(Class<?> clazz, String key, Set<String> checked) {
      logger.debug("find message {} key {}", clazz, key);
      final String className = clazz.getName();
  
      if (checked.contains(className)) return null;
      checked.add(className);
  
      String msg = getClassMessage(className, key);
      if (null != msg) return msg;
  
      // check my package
      msg = findPackageMessage(className, key, checked);
      if (null != msg) return msg;
  
      // check all interfaces class and package
      Set<Class<?>> interfaces = new HashSet<Class<?>>();
      collectInterfaces(clazz, interfaces);
      for (Class<?> ifc : interfaces) {
        msg = getClassMessage(ifc.getName(), key);
        if (msg != null) return msg;
      }
      for (Class<?> ifc : interfaces) {
        msg = this.findPackageMessage(ifc.getName(), key, checked);
        if (null != msg) return msg;
      }
  
      // traverse up hierarchy
      if (clazz.isInterface()) {
        for (Class<?> ifc : clazz.getInterfaces()) {
          msg = findMessage(ifc, key, checked);
          if (null != msg) return msg;
        }
      } else {
        Class<?> superClass = clazz.getSuperclass();
        if (!superClass.equals(Object.class) && !clazz.isPrimitive()) {
          msg = findMessage(superClass, key, checked);
          if (null != msg) return msg;
        }
      }
      return null;
    }
docs: <li>Look for message in aClass' class hierarchy.
  <ol>
  <li>Look for the message in a resource bundle for aClass</li>
  <li>If not found, look for the message in a resource bundle for any implemented interface</li>
  <li>If not found, traverse up the Class' hierarchy and repeat from the first sub-step</li>
  </ol>
  </li>
  
  @param clazz
  @param key
  @param checked
  @return