docs: private static int preferSignature(Object[] args,
                                         Class<?>[] sig1,
                                         boolean vararg1,
                                         Class<?>[] sig2,
                                         boolean vararg2 )
      {
          int totalPreference = 0;
          for (int j = 0; j < args.length; j++) {
              Class<?> type1 = vararg1 && j >= sig1.length ? sig1[sig1.length-1] : sig1[j];
              Class<?> type2 = vararg2 && j >= sig2.length ? sig2[sig2.length-1] : sig2[j];
              if (type1 == type2) {
                  continue;
              }
              Object arg = args[j];
  
              // Determine which of type1, type2 is easier to convert from arg.
  
              int rank1 = NativeJavaObject.getConversionWeight(arg, type1);
              int rank2 = NativeJavaObject.getConversionWeight(arg, type2);
  
              int preference;
              if (rank1 < rank2) {
                  preference = PREFERENCE_FIRST_ARG;
              } else if (rank1 > rank2) {
                  preference = PREFERENCE_SECOND_ARG;
              } else {
                  // Equal ranks
                  if (rank1 == NativeJavaObject.CONVERSION_NONTRIVIAL) {
                      if (type1.isAssignableFrom(type2)) {
                          preference = PREFERENCE_SECOND_ARG;
                      } else if (type2.isAssignableFrom(type1)) {
                          preference = PREFERENCE_FIRST_ARG;
                      } else {
                          preference = PREFERENCE_AMBIGUOUS;
                      }
                  } else {
                      preference = PREFERENCE_AMBIGUOUS;
                  }
              }
  
              totalPreference |= preference;
  
              if (totalPreference == PREFERENCE_AMBIGUOUS) {
                  break;
              }
          }
          return totalPreference;
      }