private void invokeImpl(@NotNull PsiClass targetClass) {
    PsiMethodReferenceExpression expression = getMethodReference();
    if (expression == null) return;

    if (isValidElement(expression)) return;

    PsiClass parentClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
    PsiMember enclosingContext = PsiTreeUtil.getParentOfType(expression, PsiMethod.class, PsiField.class, PsiClassInitializer.class);

    String methodName = expression.getReferenceName();
    LOG.assertTrue(methodName != null);


    final Project project = targetClass.getProject();
    JVMElementFactory elementFactory = JVMElementFactories.getFactory(targetClass.getLanguage(), project);
    if (elementFactory == null) elementFactory = JavaPsiFacade.getElementFactory(project);

    PsiMethod method;
    if (expression.isConstructor()) {
      method = (PsiMethod)targetClass.add(elementFactory.createConstructor());
    }
    else {
      PsiMethod prototype = elementFactory.createMethodFromText("public <__TMP__> __TMP__ " + methodName + "(){}", null);
      method = CreateMethodFromUsageFix.addMethod(targetClass, parentClass, enclosingContext, prototype);
    }

    expression = getMethodReference();
    LOG.assertTrue(expression.isValid());

    final PsiElement context = PsiTreeUtil.getParentOfType(expression, PsiClass.class, PsiMethod.class);

    ExpectedSignature result = ExpectedSignature.from(expression);
    List<Pair<PsiExpression, PsiType>> arguments = result.arguments();
    
    boolean shouldBeAbstract = false;
    if (!expression.isConstructor()) {
      PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(expression);
      boolean secondSearchPossible = PsiMethodReferenceUtil.isSecondSearchPossible(arguments.stream().map(p -> p.second).toArray(PsiType[]::new), 
                                                                                   qualifierResolveResult, expression);
      if (secondSearchPossible) {
        arguments = arguments.subList(1, arguments.size());
      }
      if (!arguments.isEmpty()) {
        String protoText =
          "public <RET," + IntStream.range(0, arguments.size()).mapToObj(n -> "ARG" + n).collect(Collectors.joining(",")) + "> RET " + methodName +
          "(" + IntStream.range(0, arguments.size()).mapToObj(n -> "ARG" + n + " arg" + n).collect(Collectors.joining(","))+"){}";
        PsiMethod prototype = elementFactory.createMethodFromText(protoText, null);
        method = (PsiMethod)method.replace(prototype);
        result = ExpectedSignature.from(expression);
        arguments = result.arguments();
        if (secondSearchPossible) {
          arguments = arguments.subList(1, arguments.size());
        }
      }
      setupVisibility(parentClass, targetClass, method.getModifierList());
      for (PsiTypeParameter parameter : method.getTypeParameters()) {
        parameter.delete();
      }
      if (!secondSearchPossible && shouldCreateStaticMember(expression, targetClass)) {
        PsiUtil.setModifierProperty(method, PsiModifier.STATIC, true);
      }
      else if (targetClass.isInterface()) {
        shouldBeAbstract = true;
        PsiCodeBlock body = method.getBody();
        assert body != null;
        body.delete();
      }
    }

    CreateMethodFromUsageFix.doCreate(targetClass, method, shouldBeAbstract,
                                      arguments,
                                      PsiSubstitutor.EMPTY,
                                      result.expectedReturn(), context);
  }
private void invokeImpl(@NotNull PsiClass targetClass)