private static @NotNull PsiTypeParameter substituteTypeParameter(@NotNull JVMElementFactory factory,
                                                                   @NotNull PsiTypeParameter typeParameter,
                                                                   @NotNull PsiSubstitutor substitutor,
                                                                   @NotNull PsiMethod sourceMethod) {
    if (typeParameter instanceof LightElement) {
      List<PsiClassType> substitutedSupers = ContainerUtil.map(typeParameter.getSuperTypes(), t -> ObjectUtils.notNull(toClassType(substitutor.substitute(t)), t));
      return factory.createTypeParameter(Objects.requireNonNull(typeParameter.getName()), substitutedSupers.toArray(PsiClassType.EMPTY_ARRAY));
    }
    final PsiElement copy = ObjectUtils.notNull(typeParameter instanceof PsiCompiledElement ? ((PsiCompiledElement)typeParameter).getMirror() : typeParameter, typeParameter).copy();
    LOG.assertTrue(copy != null, typeParameter);
    final Map<PsiElement, PsiElement> replacementMap = new HashMap<>();
    copy.accept(new JavaRecursiveElementVisitor() {
      @Override
      public void visitReferenceElement(@NotNull PsiJavaCodeReferenceElement reference) {
        super.visitReferenceElement(reference);
        final PsiElement resolve = reference.resolve();
        if (resolve instanceof PsiTypeParameter) {
          final PsiType type = factory.createType((PsiTypeParameter)resolve);
          replacementMap.put(reference, factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, type, sourceMethod, null)));
        }
      }
    });
    return (PsiTypeParameter)CommonJavaRefactoringUtil.replaceElementsWithMap(copy, replacementMap);
  }
private static @NotNull PsiTypeParameter substituteTypeParameter(@NotNull JVMElementFactory factory,
                                                                   @NotNull PsiTypeParameter typeParameter,
                                                                   @NotNull PsiSubstitutor substitutor,
                                                                   @NotNull PsiMethod sourceMethod)