public PsiType substitute(final PsiType ext) {
                          final PsiClassType.ClassResolveResult result = Util.resolveType(ext);
                          final PsiClass aClass = result.getElement();

                          if (aClass != null) {
                            if (aClass instanceof PsiTypeParameter) {
                              final PsiType type = mapping.get(aClass);

                              if (type != null) {
                                return type;
                              }

                              return ext;
                            }

                            final PsiSubstitutor aSubst = result.getSubstitutor();
                            PsiSubstitutor theSubst = PsiSubstitutor.EMPTY;

                            for (final PsiTypeParameter param : aSubst.getSubstitutionMap().keySet()) {
                              PsiType type = aSubst.substitute(param);

                              if (type != null) {
                                if (type instanceof PsiWildcardType wildcard) {
                                  final PsiType bound = wildcard.getBound();
                                  if (bound != null) {
                                    final PsiManager manager = param.getManager();
                                    type = wildcard.isExtends()
                                           ? PsiWildcardType.createExtends(manager, substitute(bound))
                                           : PsiWildcardType.createSuper(manager, substitute(bound));
                                  }
                                }
                                else {
                                  type = substitute(type);
                                }
                              }

                              theSubst = theSubst.put(param, type);
                            }

                            return JavaPsiFacade.getElementFactory(aClass.getProject())
                              .createType(aClass, theSubst);
                          }

                          return ext;
                        }
public PsiType substitute(final PsiType ext)