public static TypeRef<?> getElementType(TypeRef<?> typeRef) {
    Type type = typeRef.getType();
    if (type instanceof ParameterizedType) {
      ParameterizedType parameterizedType = (ParameterizedType) type;
      if (parameterizedType.getRawType() == List.class) { // fastpath
        Type[] actualTypeArguments = (parameterizedType).getActualTypeArguments();
        Preconditions.checkState(actualTypeArguments.length == 1);
        Type t = actualTypeArguments[0];
        if (t.getClass() == Class.class) { // if t is wild type, upper should be parsed.
          return TypeRef.of(t);
        }
      }
    }
    if (typeRef.getType().getTypeName().startsWith("scala.collection")) {
      return ScalaTypes.getElementType(typeRef);
    }
    TypeRef<?> supertype = ((TypeRef<? extends Iterable<?>>) typeRef).getSupertype(Iterable.class);
    return supertype.resolveType(ITERATOR_RETURN_TYPE).resolveType(NEXT_RETURN_TYPE);
  }
@Test
  public void getSubclassElementTypeTest() {
    abstract class A implements Collection<List<String>> {}
    Assert.assertEquals(
        TypeUtils.getElementType(TypeRef.of(A.class)), new TypeRef<List<String>>() {});
  }