PsiType introduceAdditionalTypeVariables(final PsiType type, final PsiSubstitutor qualifier, final PsiSubstitutor supertype) {
                final int level = type.getArrayDimensions();
                final PsiClassType.ClassResolveResult result = Util.resolveType(type);
                final PsiClass aClass = result.getElement();

                if (aClass != null) {
                  if (aClass instanceof PsiTypeParameter tp) {
                    final PsiClassType[] exTypes = tp.getExtendsListTypes();

                    PsiType pv = mapping.get(tp);

                    if (pv == null) {
                      pv = myTypeVariableFactory.create();
                      mapping.put(tp, pv);
                    }

                    for (final PsiClassType ext : exTypes) {
                      final PsiType exType = qualifier.substitute(new Object() {
                        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;
                        }
                      }.substitute(ext));
                      system.addSubtypeConstraint(pv, exType);
                    }

                    return PsiTypesUtil.createArrayType(pv, level);
                  }

                  final Map<PsiTypeParameter, PsiType> substitutionMap = result.getSubstitutor().getSubstitutionMap();

                  PsiSubstitutor theSubst = PsiSubstitutor.EMPTY;

                  for (final PsiTypeParameter p : substitutionMap.keySet()) {
                    final PsiType pType = substitutionMap.get(p);

                    if (pType instanceof PsiWildcardType wildcard) {
                      final PsiType theBound = wildcard.getBound();

                      if (theBound != null) {
                        final PsiType bound = qualifier.substitute(supertype.substitute(theBound));

                        if (Util.bindsTypeVariables(bound)) {
                          final PsiType var = myTypeVariableFactory.create();

                          if (wildcard.isExtends()) {
                            system.addSubtypeConstraint(var, bound);
                          }
                          else {
                            system.addSubtypeConstraint(bound, var);
                          }

                          theSubst = theSubst.put(p, var);
                        }
                        else if (Util.bindsTypeParameters(bound, typeParameters)) {
                          final PsiType var = myTypeVariableFactory.create();
                          PsiSubstitutor subst = PsiSubstitutor.EMPTY;

                          for (final PsiTypeParameter typeParam : methodTypeParameters) {
                            PsiType paramVar = mapping.get(typeParam);

                            if (paramVar == null) {
                              paramVar = myTypeVariableFactory.create();
                              mapping.put(typeParam, paramVar);
                            }

                            subst = subst.put(typeParam, paramVar);
                          }

                          final PsiType bnd = subst.substitute(bound);

                          if (wildcard.isExtends()) {
                            system.addSubtypeConstraint(bnd, var);
                          }
                          else {
                            system.addSubtypeConstraint(var, bnd);
                          }

                          theSubst = theSubst.put(p, var);
                        }
                        else {
                          theSubst = theSubst.put(p, pType);
                        }
                      }
                      else {
                        theSubst = theSubst.put(p, pType);
                      }
                    }
                    else if (pType != null) {
                      theSubst = theSubst.put(p, introduceAdditionalTypeVariables(pType, qualifier, supertype));
                    }
                  }

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

                return PsiTypesUtil.createArrayType(type, level);
              }
PsiType introduceAdditionalTypeVariables(final PsiType type, final PsiSubstitutor qualifier, final PsiSubstitutor supertype)