public static PsiType eliminateWildcards(PsiType type,
                                           final boolean eliminateInTypeArguments,
                                           boolean eliminateCapturedWildcards) {
    if (eliminateInTypeArguments && type instanceof PsiClassType) {
      PsiClassType classType = (PsiClassType)type;
      JavaResolveResult resolveResult = classType.resolveGenerics();
      PsiClass aClass = (PsiClass)resolveResult.getElement();
      if (aClass != null) {
        PsiManager manager = aClass.getManager();
        PsiTypeParameter[] typeParams = aClass.getTypeParameters();
        Map<PsiTypeParameter, PsiType> map = new HashMap<>();
        for (PsiTypeParameter typeParam : typeParams) {
          PsiType substituted = resolveResult.getSubstitutor().substitute(typeParam);
          if (substituted instanceof PsiWildcardType) {
            substituted = ((PsiWildcardType)substituted).getBound();
            if (substituted instanceof PsiCapturedWildcardType) {
              substituted = ((PsiCapturedWildcardType)substituted).getWildcard().getBound();
            }
            if (substituted == null) substituted = TypeConversionUtil.typeParameterErasure(typeParam);
          }
          map.put(typeParam, substituted);
        }

        PsiElementFactory factory = JavaPsiFacade.getElementFactory(manager.getProject());
        PsiSubstitutor substitutor = factory.createSubstitutor(map);
        type = factory.createType(aClass, substitutor).annotate(classType.getAnnotationProvider());
      }
    }
    else if (type instanceof PsiArrayType) {
      PsiType component = eliminateWildcards(((PsiArrayType)type).getComponentType(), false);
      PsiType newArray = type instanceof PsiEllipsisType ? new PsiEllipsisType(component) : new PsiArrayType(component);
      return newArray.annotate(type.getAnnotationProvider());
    }
    else if (type instanceof PsiWildcardType) {
      final PsiType bound = ((PsiWildcardType)type).getBound();
      return eliminateWildcards(bound != null ? bound : ((PsiWildcardType)type).getExtendsBound(), false);//object
    }
    else if (type instanceof PsiCapturedWildcardType && eliminateCapturedWildcards) {
      return eliminateWildcards(((PsiCapturedWildcardType)type).getUpperBound(), false);
    }
    return type;
  }
public static PsiType eliminateWildcards(PsiType type,
                                           final boolean eliminateInTypeArguments,
                                           boolean eliminateCapturedWildcards)