docs: public void visitMethod(Object declaringType,
                              Object returnType,
                              Object genericReturnType,
                              Map<String, Object> returnTypeGenericTypes,
                              String methodName,
                              Map<String, Object> argumentTypes,
                              Map<String, AnnotationMetadata> argumentAnnotationMetadata,
                              Map<String, Map<String, Object>> genericTypes) {
          Type declaringTypeObject = getTypeReference(declaringType);
          boolean hasArgs = !argumentTypes.isEmpty();
          Collection<Object> argumentTypeClasses = hasArgs ? argumentTypes.values() : Collections.emptyList();
  
          int modifiers = isStatic ? ACC_SYNTHETIC | ACC_STATIC : ACC_SYNTHETIC;
          classWriter.visit(V1_8, modifiers,
              internalName,
              null,
              Type.getInternalName(AbstractExecutableMethod.class),
              null);
  
          // initialize and write the annotation metadata
          if (!(annotationMetadata instanceof AnnotationMetadataReference)) {
              writeAnnotationMetadataStaticInitializer(classWriter);
          }
          writeGetAnnotationMetadataMethod(classWriter);
  
          MethodVisitor executorMethodConstructor;
          GeneratorAdapter constructorWriter;
  
          boolean hasOuter = outerClassName != null && !isStatic;
          String constructorDescriptor;
          if (hasOuter) {
              executorMethodConstructor = startConstructor(classWriter, outerClassName);
              constructorDescriptor = getConstructorDescriptor(outerClassName);
          } else {
              executorMethodConstructor = startConstructor(classWriter);
              constructorDescriptor = DESCRIPTOR_DEFAULT_CONSTRUCTOR;
          }
          constructorWriter = new GeneratorAdapter(executorMethodConstructor,
              Opcodes.ACC_PUBLIC,
              CONSTRUCTOR_NAME,
              constructorDescriptor);
  
          if (hasOuter) {
              constructorWriter.loadThis();
              constructorWriter.loadArg(0);
              constructorWriter.putField(methodType, FIELD_PARENT, getObjectType(outerClassName));
          }
  
          // ALOAD 0
          constructorWriter.loadThis();
  
          // load 'this'
          constructorWriter.loadThis();
  
          // 1st argument: the declaring class
          constructorWriter.push(declaringTypeObject);
  
          // 2nd argument: the method name
          constructorWriter.push(methodName);
  
          // 3rd argument the generic return type
          if (genericReturnType instanceof Class && ((Class) genericReturnType).isPrimitive()) {
              Class javaType = (Class) genericReturnType;
              String constantName = javaType.getName().toUpperCase(Locale.ENGLISH);
  
              // refer to constant for primitives
              Type type = Type.getType(Argument.class);
              constructorWriter.getStatic(type, constantName, type);
  
          } else {
              // Argument.of(genericReturnType, returnTypeGenericTypes)
              buildArgumentWithGenerics(
                  constructorWriter,
                  methodName,
                  Collections.singletonMap(genericReturnType, returnTypeGenericTypes)
              );
          }
  
          if (hasArgs) {
              // 4th argument: the generic types
              pushBuildArgumentsForMethod(
                  getTypeReferenceForName(getClassName()),
                  classWriter,
                  constructorWriter,
                  argumentTypes,
                  argumentAnnotationMetadata,
                  genericTypes,
                  loadTypeMethods);
  
              for (AnnotationMetadata value : argumentAnnotationMetadata.values()) {
                  DefaultAnnotationMetadata.contributeDefaults(this.annotationMetadata, value);
              }
              // now invoke super(..) if no arg constructor
              invokeConstructor(
                  executorMethodConstructor,
                  AbstractExecutableMethod.class,
                  Class.class,
                  String.class,
                  Argument.class,
                  Argument[].class);
          } else {
              invokeConstructor(
                  executorMethodConstructor,
                  AbstractExecutableMethod.class,
                  Class.class,
                  String.class,
                  Argument.class);
          }
          constructorWriter.visitInsn(RETURN);
          constructorWriter.visitMaxs(DEFAULT_MAX_STACK, 1);
  
          // invoke the methods with the passed arguments
          String invokeDescriptor = METHOD_INVOKE_INTERNAL.getDescriptor();
          String invokeInternalName = METHOD_INVOKE_INTERNAL.getName();
          GeneratorAdapter invokeMethod = new GeneratorAdapter(classWriter.visitMethod(
              Opcodes.ACC_PUBLIC,
              invokeInternalName,
              invokeDescriptor,
              null,
              null),
              ACC_PUBLIC,
              invokeInternalName,
              invokeDescriptor
          );
  
          buildInvokeMethod(declaringTypeObject, methodName, returnType, argumentTypeClasses, invokeMethod);
  
          for (GeneratorAdapter method : loadTypeMethods.values()) {
              method.visitMaxs(3, 1);
              method.visitEnd();
          }
      }