docs: @NonNull @UiThread
    public static Unbinder bind(@NonNull Object target, @NonNull View source) {
      List<Unbinder> unbinders = new ArrayList<>();
      Class<?> targetClass = target.getClass();
      if ((targetClass.getModifiers() & PRIVATE) != 0) {
        throw new IllegalArgumentException(targetClass.getName() + " must not be private.");
      }
  
      while (true) {
        String clsName = targetClass.getName();
        if (clsName.startsWith("android.") || clsName.startsWith("java.")
            || clsName.startsWith("androidx.")) {
          break;
        }
  
        for (Field field : targetClass.getDeclaredFields()) {
          int unbinderStartingSize = unbinders.size();
          Unbinder unbinder;
  
          unbinder = parseBindView(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseBindViews(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseBindAnim(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseBindArray(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseBindBitmap(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseBindBool(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseBindColor(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseBindDimen(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseBindDrawable(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseBindFloat(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseBindFont(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseBindInt(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseBindString(target, field, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          if (unbinders.size() - unbinderStartingSize > 1) {
            throw new IllegalStateException(
                "More than one bind annotation on " + targetClass.getName() + "." + field.getName());
          }
        }
  
        for (Method method : targetClass.getDeclaredMethods()) {
          Unbinder unbinder;
  
          unbinder = parseOnCheckedChanged(target, method, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseOnClick(target, method, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseOnEditorAction(target, method, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseOnFocusChange(target, method, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseOnItemClick(target, method, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseOnItemLongClick(target, method, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseOnLongClick(target, method, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseOnPageChange(target, method, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseOnTextChanged(target, method, source);
          if (unbinder != null) unbinders.add(unbinder);
  
          unbinder = parseOnTouch(target, method, source);
          if (unbinder != null) unbinders.add(unbinder);
        }
  
        targetClass = targetClass.getSuperclass();
      }
  
      if (unbinders.isEmpty()) {
        if (debug) Log.d(TAG, "MISS: Reached framework class. Abandoning search.");
        return Unbinder.EMPTY;
      }
  
      if (debug) Log.d(TAG, "HIT: Reflectively found " + unbinders.size() + " bindings.");
      return new CompositeUnbinder(unbinders);
    }