docs: public ResultFunction<M, G, R> resultFunction() throws
                                                    MethodAmbiguouslyDefinedException {
      final MasterClass masterClass = new MasterClass(this.master.getClass());
      final GuestClass guestClass = new GuestClass(this.guest.getClass());
      final GenericsContext context = GenericsResolver.resolve(this.getClass())
                                                      .type(Dispatch.class);
      // final Class<?> masterClassRestriction = context.generics().get(0); // Class M for right method searching
      // final Class<?> guestClassRestriction = context.generics().get(1); // Class G for right method searching
      final ReturnClass returnClass = new ReturnClass(context.generics()
                                                             .get(2)); // Class R for right method searching
      ResultFunction<M, G, R> method;
      final Set<Method> methods = new ByParameterClass(masterClass,
                                                       guestClass,
                                                       this.methodName,
                                                       returnClass,
                                                       new ByParameterInterfaces(masterClass,
                                                                                 guestClass,
                                                                                 this.methodName,
                                                                                 returnClass,
                                                                                 new ByParameterSuperClass(masterClass,
                                                                                                           guestClass,
                                                                                                           this.methodName,
                                                                                                           returnClass,
                                                                                                           new EmptyMethods()))).findMethods();
      if (methods.isEmpty()) {
        method = new ResultFunction<M, G, R>() {
          @Override
          public String toString() {
            return "default method";
          }
  
          @Override
          public R apply(final M m,
                         final G g) {
            return Dispatch.this.defaultMethod.apply(m,
                                                     g);
          }
        };
      } else {
        final Iterator<Method> iterator = methods.iterator();
        MethodRepresentation currentMethod = new OneMethod(iterator.next());
        while (iterator.hasNext()) {
          final MethodRepresentation nextMethod = new OneMethod(iterator.next());
          currentMethod = new OneOfTwoMethods(currentMethod,
                                              nextMethod);
        }
        final Method finalMethod = currentMethod.toMethod();
        method = new MethodFunction<>(finalMethod);
      }
      return method;
    }