code: public static boolean isAssignable(final Type what, final Type toType) {
          final AssignabilityTypesVisitor visitor = new AssignabilityTypesVisitor();
          TypesWalker.walk(what, toType, visitor);
  
          return visitor.isAssignable();
      }
docs: Checks if type could be casted to type. Generally, method is supposed to answer: if this type could be tried
  to set on that place (defined by second type). Not resolved type variables are resolved to Object. Object is
  considered as unknown type: everything is assignable to Object and Object is assignable to everything.
  Note that {@code T<String, Object>} is assignable to {@code T<String, String>} as Object considered as unknown
  type and so could be compatible (in opposite way is also assignable as anything is assignable to Object).
  <p>
  Of course, actual value used instead of Object may be incompatible, but method intended only to
  check all available types information (if nothing stops me yet). Use exact types to get more correct
  result. Example usage scenario: check field type before trying to assign something with reflection.
  <p>
  Java wildcard rules are generally not honored because at runtime they are meaningless.
  {@code List == List<Object> == List<? super Object> == List<? extends Object>}. All upper bounds are used for
  comparison (multiple upper bounds in wildcard could be from repackaging of generic declaration
  {@code T<extends A&B>}. Lower bounds are taken into account as: if both have lower bound then
  right's type bound must be higher ({@code ? extends Number and ? extends Integer}). If only left
  type is lower bounded wildcard then it is not assignable (except Object).
  <p>
  Primitive types are checked as wrappers (for example, int is more specific then Number).
  
  @param what   type to check
  @param toType type to check assignability for
  @return true if types are equal or type is more specific, false if can't be casted or types incompatible
  @see AssignabilityTypesVisitor for implementation details