docs: private static ClassNode convertClosureTypeToSAMType(final Expression expression, final ClassNode closureType, final ClassNode samType, final Map<GenericsTypeName, GenericsType> placeholders) {
          if (!samType.isUsingGenerics()) return samType;
  
          // use the generics information from the Closure to further specify the type
          MethodNode sam = findSAM(samType);
          if (closureType.isUsingGenerics() && sam != null) {
              //correct SAM type for generics
              //sam = applyGenericsContext(placeholders, sam);
  
              // the return type of the SAM method exactly corresponds to the inferred return type
              ClassNode samReturnType = sam.getReturnType();
              ClassNode closureReturnType = expression.getNodeMetaData(INFERRED_TYPE);
              if (closureReturnType != null && closureReturnType.isUsingGenerics()) {
                  ClassNode unwrapped = closureReturnType.getGenericsTypes()[0].getType();
                  extractGenericsConnections(placeholders, unwrapped, samReturnType);
              } else if (samReturnType.isGenericsPlaceHolder()) {
                  placeholders.put(new GenericsTypeName(samReturnType.getGenericsTypes()[0].getName()), closureType.getGenericsTypes()[0]);
              }
  
              // now repeat the same for each parameter given in the ClosureExpression
              if (expression instanceof ClosureExpression && sam.getParameters().length > 0) {
                  List<ClassNode[]> genericsToConnect = new LinkedList<ClassNode[]>();
                  Parameter[] closureParams = ((ClosureExpression) expression).getParameters();
                  ClassNode[] closureParamTypes = extractTypesFromParameters(closureParams);
                  if (expression.getNodeMetaData(CLOSURE_ARGUMENTS) != null) {
                      closureParamTypes = expression.getNodeMetaData(CLOSURE_ARGUMENTS);
                  }
                  final Parameter[] parameters = sam.getParameters();
                  for (int i = 0; i < parameters.length; i++) {
                      final Parameter parameter = parameters[i];
                      if (parameter.getOriginType().isUsingGenerics() && closureParamTypes.length > i) {
                          genericsToConnect.add(new ClassNode[]{closureParamTypes[i], parameter.getOriginType()});
                      }
                  }
                  for (ClassNode[] classNodes : genericsToConnect) {
                      ClassNode found = classNodes[0];
                      ClassNode expected = classNodes[1];
                      if (!isAssignableTo(found, expected)) {
                          // probably facing a type mismatch
                          continue;
                      }
                      ClassNode generifiedType = GenericsUtils.parameterizeType(found, expected);
                      while (expected.isArray()) {
                          expected = expected.getComponentType();
                          generifiedType = generifiedType.getComponentType();
                      }
                      if (expected.isGenericsPlaceHolder()) {
                          placeholders.put(new GenericsTypeName(expected.getGenericsTypes()[0].getName()), new GenericsType(generifiedType));
                      } else {
                          GenericsType[] expectedGenericsTypes = expected.getGenericsTypes();
                          GenericsType[] foundGenericsTypes = generifiedType.getGenericsTypes();
  
                          for (int i = 0; i < expectedGenericsTypes.length; i++) {
                              final GenericsType type = expectedGenericsTypes[i];
                              if (type.isPlaceholder()) {
                                  String name = type.getName();
                                  placeholders.put(new GenericsTypeName(name), foundGenericsTypes[i]);
                              }
                          }
                      }
                  }
              }
          }
          ClassNode result = applyGenericsContext(placeholders, samType.redirect());
          return result;
      }