public static void replaceMovedMemberTypeParameters(final PsiElement member,
                                                      final Iterable<? extends PsiTypeParameter> parametersIterable,
                                                      final PsiSubstitutor substitutor,
                                                      final PsiElementFactory factory) {
    final Map<PsiElement, PsiElement> replacement = new LinkedHashMap<>();
    for (PsiTypeParameter parameter : parametersIterable) {
      final PsiType substitutedType = substitutor.substitute(parameter);
      final PsiType erasedType = substitutedType == null ? TypeConversionUtil.erasure(factory.createType(parameter))
                                                         : substitutedType;
      for (PsiReference reference : ReferencesSearch.search(parameter, new LocalSearchScope(member))) {
        final PsiElement element = reference.getElement();
        final PsiElement parent = element.getParent();
        if (parent instanceof PsiTypeElement) {
          if (substitutedType == null) {
            //extends/implements list of type parameters: S extends List<T>
            final PsiJavaCodeReferenceElement codeReferenceElement =
              PsiTreeUtil.getTopmostParentOfType(parent, PsiJavaCodeReferenceElement.class);
            if (codeReferenceElement != null) {
              final PsiJavaCodeReferenceElement copy = (PsiJavaCodeReferenceElement)codeReferenceElement.copy();
              final PsiReferenceParameterList parameterList = copy.getParameterList();
              if (parameterList != null) {
                parameterList.delete();
              }
              replacement.put(codeReferenceElement, copy);
            }
            else {
              //nested types List<List<T> listOfLists;
              PsiTypeElement topPsiTypeElement = PsiTreeUtil.getTopmostParentOfType(parent, PsiTypeElement.class);
              if (topPsiTypeElement == null) {
                topPsiTypeElement = (PsiTypeElement)parent;
              }
              replacement.put(topPsiTypeElement, factory.createTypeElement(TypeConversionUtil.erasure(topPsiTypeElement.getType())));
            }
          }
          else {
            replacement.put(parent, factory.createTypeElement(substitutedType));
          }
        }
        else if (element instanceof PsiJavaCodeReferenceElement && erasedType instanceof PsiClassType) {
          replacement.put(element, factory.createReferenceElementByType((PsiClassType)erasedType));
        }
      }
    }
    for (PsiElement element : replacement.keySet()) {
      if (element.isValid()) {
        element.replace(replacement.get(element));
      }
    }
  }
public static void replaceMovedMemberTypeParameters(final PsiElement member,
                                                      final Iterable<? extends PsiTypeParameter> parametersIterable,
                                                      final PsiSubstitutor substitutor,
                                                      final PsiElementFactory factory)