code: public int applicability(final Class<?>[] paramTypes, boolean varArgs) {
          if (argTypes == null) {
              return MATCH_WILDCARD;
          }
          int level = MATCH;
          final int fixArgs = paramTypes.length - (varArgs ? 1 : 0);
          if (fixArgs > argTypes.length 
                  || (!varArgs && fixArgs != argTypes.length)) {
              return NO_MATCH;
          }
          // match fix args
          for (int i = 0; i < fixArgs; i++) {
              int m = applicable(argTypes[i], paramTypes[i]);
              if (m == NO_MATCH) return NO_MATCH;
              if (m < level) level = m;
          }
          if (varArgs) {
              // try if last arg matches varargs parameter directly
              Class<?> varArgType = paramTypes[fixArgs];
              if (paramTypes.length == argTypes.length) {
                  int m = applicable(argTypes[fixArgs], varArgType);
                  if (m != NO_MATCH) {
                      return Math.min(m, level);
                  }
              }
              // match remaining args against vararg component type
              level = MATCH_VARARGS;
              Class<?> comp = varArgType.getComponentType();
              for (int i = fixArgs; i < argTypes.length; i++) {
                  int m = applicable(argTypes[i], comp);
                  if (m == NO_MATCH) return NO_MATCH;
              }
          }
          return level;
      }
docs: Returns the applicabilty of a signature. A signature with higher
  applicability is always preferred, even if the other is more specific.
  @param paramTypes
  @param varArgs
  @return applicability level