@Nullable
  private static PsiType doNormalizeWildcardByPosition(
      final PsiType type, final GrExpression expression, final GrExpression toplevel) {
    if (type instanceof PsiCapturedWildcardType) {
      return doNormalizeWildcardByPosition(
          ((PsiCapturedWildcardType) type).getWildcard(), expression, toplevel);
    }

    if (type instanceof PsiWildcardType) {
      final PsiWildcardType wildcardType = (PsiWildcardType) type;

      if (PsiUtil.isAccessedForWriting(toplevel)) {
        return wildcardType.isSuper()
            ? wildcardType.getBound()
            : PsiCapturedWildcardType.create(wildcardType, expression);
      } else {
        if (wildcardType.isExtends()) {
          return wildcardType.getBound();
        } else {
          return PsiType.getJavaLangObject(expression.getManager(), expression.getResolveScope());
        }
      }
    } else if (type instanceof PsiArrayType) {
      final PsiType componentType = ((PsiArrayType) type).getComponentType();
      final PsiType normalizedComponentType =
          doNormalizeWildcardByPosition(componentType, expression, toplevel);
      if (normalizedComponentType != componentType) {
        assert normalizedComponentType != null;
        return normalizedComponentType.createArrayType();
      }
    }

    return type;
  }
  public static GrTypeComboBox createTypeComboBoxFromExpression(GrExpression expression) {
    PsiType type = expression.getType();

    if (GroovyRefactoringUtil.isDiamondNewOperator(expression)) {
      LOG.assertTrue(expression instanceof GrNewExpression);
      PsiType expected = PsiImplUtil.inferExpectedTypeForDiamond(expression);
      return createTypeComboboxFromBounds(
          type, expected, expression.getManager(), expression.getResolveScope());
    } else {
      return createTypeComboBoxWithDefType(type);
    }
  }
 @Nullable
 public static PsiType substituteBoxAndNormalizeType(
     @Nullable PsiType type,
     @NotNull PsiSubstitutor substitutor,
     @Nullable SpreadState state,
     @NotNull GrExpression expression) {
   if (type == null) return null;
   GlobalSearchScope resolveScope = expression.getResolveScope();
   PsiManager manager = expression.getManager();
   type = substitutor.substitute(type);
   type = boxPrimitiveType(type, manager, resolveScope);
   if (type == null) return null;
   type = PsiImplUtil.normalizeWildcardTypeByPosition(type, expression);
   type = SpreadState.apply(type, state, expression.getProject());
   return type;
 }
 @Override
 public void visitThrowStatement(GrThrowStatement throwStatement) {
   final PsiClassType throwable =
       PsiType.getJavaLangThrowable(myExpression.getManager(), throwStatement.getResolveScope());
   myResult = new TypeConstraint[] {SubtypeConstraint.create(throwable)};
 }