code: private static List<Type> resolveUpperGenerics(final GenericsContext genericsContext,
                                                     final Type type,
                                                     final boolean objectDeclared,
                                                     final Class upperType) {
          final List<Type> res;
          if (objectDeclared) {
              // no generics declared in class - use raw generics (from type declaration)
              res = genericsContext.resolveTypeGenerics(upperType);
          } else {
              // computing from actual generic type because it may contain generics, not required for lower type
              // e.g. declaration is ExtraList<String, Integer>  lower type will be List<String>
              // but we need to preserve full generics info for upper type
              res = genericsContext.inlyingTypeAs(type, upperType).genericTypes();
          }
          return res;
      }
docs: Cases:
  <ul>
  <li>Object declared in class: nowere to get generics, resolving from type definition</li>
  <li>Track type generics from declared generics (may not recover all, in this case generics declaration
  would be used)</li>
  </ul>.
  Note that lowerType == upperType case checked outside.
  
  @param genericsContext generics context
  @param type            declared property type
  @param objectDeclared  declared type is not Object
  @param upperType       value type (if value available) or declaration type (from class; may be upper then
  lowerType in case of collection)
  @return upper type generics or empty list