docs: static boolean isAssignableTo(ClassNode type, ClassNode toBeAssignedTo) {
          if (UNKNOWN_PARAMETER_TYPE == type) return true;
          if (type == toBeAssignedTo) return true;
          if (toBeAssignedTo.redirect() == STRING_TYPE && type.redirect() == GSTRING_TYPE) {
              return true;
          }
          if (isPrimitiveType(toBeAssignedTo)) toBeAssignedTo = getWrapper(toBeAssignedTo);
          if (isPrimitiveType(type)) type = getWrapper(type);
          if (NUMBER_TYPES.containsKey(type.redirect()) && NUMBER_TYPES.containsKey(toBeAssignedTo.redirect())) {
              return NUMBER_TYPES.get(type.redirect()) <= NUMBER_TYPES.get(toBeAssignedTo.redirect());
          }
          if (type.isArray() && toBeAssignedTo.isArray()) {
              return isAssignableTo(type.getComponentType(), toBeAssignedTo.getComponentType());
          }
          if (type.isDerivedFrom(GSTRING_TYPE) && STRING_TYPE.equals(toBeAssignedTo)) {
              return true;
          }
          if (toBeAssignedTo.isDerivedFrom(GSTRING_TYPE) && STRING_TYPE.equals(type)) {
              return true;
          }
          if (implementsInterfaceOrIsSubclassOf(type, toBeAssignedTo)) {
              if (OBJECT_TYPE.equals(toBeAssignedTo)) return true;
              if (toBeAssignedTo.isUsingGenerics()) {
                  // perform additional check on generics
                  // ? extends toBeAssignedTo
                  GenericsType gt = GenericsUtils.buildWildcardType(toBeAssignedTo);
                  return gt.isCompatibleWith(type);
              }
              return true;
          }
  
          //SAM check
          if (type.isDerivedFrom(CLOSURE_TYPE) && isSAMType(toBeAssignedTo)) {
              return true;
          }
  
          return false;
      }