private static PsiType handleBoundComposition(
     PsiWildcardType wildcardType, PsiWildcardType bound) {
   if (bound.isExtends() == wildcardType.isExtends()) {
     final PsiType newBoundBound = bound.getBound();
     if (newBoundBound != null) {
       return PsiWildcardType.changeBound(wildcardType, newBoundBound);
     }
   }
   return PsiWildcardType.createUnbounded(wildcardType.getManager());
 }
    @Override
    public PsiType visitWildcardType(PsiWildcardType wildcardType) {
      final PsiType bound = wildcardType.getBound();
      if (bound == null) {
        return wildcardType;
      } else {
        final PsiType newBound = bound.accept(this);
        if (newBound == null) {
          return null;
        }
        if (newBound instanceof PsiWildcardType) {
          return handleBoundComposition(wildcardType, (PsiWildcardType) newBound);
        }
        if (newBound instanceof PsiCapturedWildcardType
            && wildcardType.isExtends()
                != ((PsiCapturedWildcardType) newBound).getWildcard().isExtends()) {
          return handleBoundComposition(
              wildcardType, ((PsiCapturedWildcardType) newBound).getWildcard());
        }

        return PsiWildcardType.changeBound(wildcardType, newBound);
      }
    }