@Override
    public PsiType visitClassType(@NotNull PsiClassType classType) {
      PsiClassType.ClassResolveResult result = classType.resolveGenerics();
      PsiClass aClass = result.getElement();
      if (aClass != null) {
        PsiSubstitutor substitutor = result.getSubstitutor();
        PsiSubstitutor targetSubstitutor = PsiSubstitutor.EMPTY;
        for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(aClass)) {
          PsiType ai = substitutor.substitute(parameter);
          if (ai == null) return PsiTypes.nullType();
          if (!mentionsRestrictedTypeVariables(ai)) {
            targetSubstitutor = targetSubstitutor.put(parameter, ai);
          }
          else if (ai instanceof PsiWildcardType) {
            if (((PsiWildcardType)ai).isExtends()) {
              PsiType extendsBound = ((PsiWildcardType)ai).getExtendsBound();
              PsiType projection = extendsBound.accept(this);
              if (projection == PsiTypes.nullType()) return PsiTypes.nullType();
              targetSubstitutor = targetSubstitutor.put(parameter, PsiWildcardType.createExtends(parameter.getManager(), projection));
            }
            else if (((PsiWildcardType)ai).isSuper()) {
              PsiType superBound = ((PsiWildcardType)ai).getSuperBound();
              targetSubstitutor = targetSubstitutor.put(parameter, getUpwardProjection(superBound));
            }
            else {
              return PsiTypes.nullType();
            }
          }
          else {
            return PsiTypes.nullType();
          }
        }
        return JavaPsiFacade.getElementFactory(aClass.getProject()).createType(aClass, targetSubstitutor);
      }
      return PsiTypes.nullType();
    }
@Override
    public PsiType visitClassType(@NotNull PsiClassType classType)