private static boolean isNullLiteralExpression(PsiElement expr) {
   if (expr instanceof PsiLiteralExpression) {
     final PsiLiteralExpression literalExpression = (PsiLiteralExpression) expr;
     return PsiType.NULL.equals(literalExpression.getType());
   }
   return false;
 }
  public static PsiType getType(@NotNull PsiClassObjectAccessExpression classAccessExpression) {
    GlobalSearchScope resolveScope = classAccessExpression.getResolveScope();
    PsiManager manager = classAccessExpression.getManager();
    final PsiClass classClass =
        JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Class", resolveScope);
    if (classClass == null) {
      return new PsiClassReferenceType(
          new LightClassReference(manager, "Class", "java.lang.Class", resolveScope), null);
    }
    if (!PsiUtil.isLanguageLevel5OrHigher(classAccessExpression)) {
      // Raw java.lang.Class
      return JavaPsiFacade.getInstance(manager.getProject())
          .getElementFactory()
          .createType(classClass);
    }

    PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
    PsiType operandType = classAccessExpression.getOperand().getType();
    if (operandType instanceof PsiPrimitiveType && !PsiType.NULL.equals(operandType)) {
      if (PsiType.VOID.equals(operandType)) {
        operandType =
            JavaPsiFacade.getInstance(manager.getProject())
                .getElementFactory()
                .createTypeByFQClassName("java.lang.Void", classAccessExpression.getResolveScope());
      } else {
        operandType = ((PsiPrimitiveType) operandType).getBoxedType(classAccessExpression);
      }
    }
    final PsiTypeParameter[] typeParameters = classClass.getTypeParameters();
    if (typeParameters.length == 1) {
      substitutor = substitutor.put(typeParameters[0], operandType);
    }

    return new PsiImmediateClassType(classClass, substitutor);
  }
  @NotNull
  @Override
  public PsiDeclarationStatement createVariableDeclarationStatement(
      @NotNull String name, @NotNull PsiType type, @Nullable PsiExpression initializer)
      throws IncorrectOperationException {
    if (!isIdentifier(name)) {
      throw new IncorrectOperationException("\"" + name + "\" is not an identifier.");
    }
    if (PsiType.NULL.equals(type)) {
      throw new IncorrectOperationException("Cannot create variable with type \"null\".");
    }

    String text = "X " + name + (initializer != null ? " = x" : "") + ";";
    PsiDeclarationStatement statement =
        (PsiDeclarationStatement) createStatementFromText(text, null);

    PsiVariable variable = (PsiVariable) statement.getDeclaredElements()[0];
    replace(variable.getTypeElement(), createTypeElement(type), text);

    boolean generateFinalLocals =
        JavaCodeStyleSettingsFacade.getInstance(myManager.getProject()).isGenerateFinalLocals();
    PsiUtil.setModifierProperty(variable, PsiModifier.FINAL, generateFinalLocals);

    if (initializer != null) {
      replace(variable.getInitializer(), initializer, text);
    }

    GeneratedMarkerVisitor.markGenerated(statement);
    return statement;
  }
  /* Guesswork
   */
  @Nullable
  private static PsiSubstitutor getInheritorSubstitutorForNewExpression(
      final PsiClass baseClass,
      final PsiClass inheritor,
      final PsiSubstitutor baseSubstitutor,
      final PsiElement context) {
    final Project project = baseClass.getProject();
    JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
    final PsiResolveHelper resolveHelper = facade.getResolveHelper();
    PsiSubstitutor superSubstitutor =
        TypeConversionUtil.getClassSubstitutor(baseClass, inheritor, PsiSubstitutor.EMPTY);
    if (superSubstitutor == null) return null;
    PsiSubstitutor inheritorSubstitutor = PsiSubstitutor.EMPTY;
    for (PsiTypeParameter inheritorParameter : PsiUtil.typeParametersIterable(inheritor)) {
      for (PsiTypeParameter baseParameter : PsiUtil.typeParametersIterable(baseClass)) {
        final PsiType substituted = superSubstitutor.substitute(baseParameter);
        PsiType arg = baseSubstitutor.substitute(baseParameter);
        if (arg instanceof PsiWildcardType) arg = ((PsiWildcardType) arg).getBound();
        PsiType substitution =
            resolveHelper.getSubstitutionForTypeParameter(
                inheritorParameter, substituted, arg, true, PsiUtil.getLanguageLevel(context));
        if (PsiType.NULL.equals(substitution)) continue;
        if (substitution == null) {
          return facade.getElementFactory().createRawSubstitutor(inheritor);
        }
        inheritorSubstitutor = inheritorSubstitutor.put(inheritorParameter, substitution);
        break;
      }
    }

    return inheritorSubstitutor;
  }
  @NotNull
  @Override
  public PsiMethod createMethod(@NotNull final String name, final PsiType returnType)
      throws IncorrectOperationException {
    PsiUtil.checkIsIdentifier(myManager, name);
    if (PsiType.NULL.equals(returnType)) {
      throw new IncorrectOperationException("Cannot create method with type \"null\".");
    }

    final String canonicalText = returnType.getCanonicalText();
    final PsiJavaFile aFile =
        createDummyJavaFile("class _Dummy_ { public " + canonicalText + " " + name + "() {} }");
    final PsiClass[] classes = aFile.getClasses();
    if (classes.length < 1) {
      throw new IncorrectOperationException(
          "Class was not created. Method name: " + name + "; return type: " + canonicalText);
    }
    final PsiMethod[] methods = classes[0].getMethods();
    if (methods.length < 1) {
      throw new IncorrectOperationException(
          "Method was not created. Method name: " + name + "; return type: " + canonicalText);
    }
    PsiMethod method = methods[0];
    method =
        (PsiMethod)
            JavaCodeStyleManager.getInstance(myManager.getProject()).shortenClassReferences(method);
    return (PsiMethod) CodeStyleManager.getInstance(myManager.getProject()).reformat(method);
  }
  @NotNull
  @Override
  public PsiField createField(@NotNull final String name, @NotNull final PsiType type)
      throws IncorrectOperationException {
    PsiUtil.checkIsIdentifier(myManager, name);
    if (PsiType.NULL.equals(type)) {
      throw new IncorrectOperationException("Cannot create field with type \"null\".");
    }

    @NonNls
    final String text = "class _Dummy_ { private " + type.getCanonicalText() + " " + name + "; }";
    final PsiJavaFile aFile = createDummyJavaFile(text);
    final PsiClass[] classes = aFile.getClasses();
    if (classes.length < 1) {
      throw new IncorrectOperationException("Class was not created " + text);
    }
    final PsiClass psiClass = classes[0];
    final PsiField[] fields = psiClass.getFields();
    if (fields.length < 1) {
      throw new IncorrectOperationException("Field was not created " + text);
    }
    PsiField field = fields[0];
    field =
        (PsiField)
            JavaCodeStyleManager.getInstance(myManager.getProject()).shortenClassReferences(field);
    return (PsiField) CodeStyleManager.getInstance(myManager.getProject()).reformat(field);
  }
  private static boolean isGoodExpression(
      PsiExpression expression,
      @NotNull AllowedValues allowedValues,
      @NotNull PsiElement scope,
      @NotNull PsiManager manager) {
    expression = PsiUtil.deparenthesizeExpression(expression);
    if (expression == null) return true;
    if (expression instanceof PsiConditionalExpression) {
      PsiExpression thenExpression = ((PsiConditionalExpression) expression).getThenExpression();
      boolean thenAllowed =
          thenExpression == null || isAllowed(scope, thenExpression, allowedValues, manager);
      if (!thenAllowed) return false;
      PsiExpression elseExpression = ((PsiConditionalExpression) expression).getElseExpression();
      return elseExpression == null || isAllowed(scope, elseExpression, allowedValues, manager);
    }

    if (isOneOf(expression, allowedValues, manager)) return true;

    if (allowedValues.canBeOred) {
      PsiExpression zero = getLiteralExpression(expression, manager, "0");
      if (same(expression, zero, manager)) return true;
      PsiExpression mOne = getLiteralExpression(expression, manager, "-1");
      if (same(expression, mOne, manager)) return true;
      if (expression instanceof PsiPolyadicExpression) {
        IElementType tokenType = ((PsiPolyadicExpression) expression).getOperationTokenType();
        if (JavaTokenType.OR.equals(tokenType) || JavaTokenType.AND.equals(tokenType)) {
          for (PsiExpression operand : ((PsiPolyadicExpression) expression).getOperands()) {
            if (!isAllowed(scope, operand, allowedValues, manager)) return false;
          }
          return true;
        }
      }
      if (expression instanceof PsiPrefixExpression
          && JavaTokenType.TILDE.equals(
              ((PsiPrefixExpression) expression).getOperationTokenType())) {
        PsiExpression operand = ((PsiPrefixExpression) expression).getOperand();
        return operand == null || isAllowed(scope, operand, allowedValues, manager);
      }
    }

    PsiElement resolved = null;
    if (expression instanceof PsiReference) {
      resolved = ((PsiReference) expression).resolve();
    } else if (expression instanceof PsiCallExpression) {
      resolved = ((PsiCallExpression) expression).resolveMethod();
    }

    AllowedValues allowedForRef;
    if (resolved instanceof PsiModifierListOwner
        && (allowedForRef =
                getAllowedValues(
                    (PsiModifierListOwner) resolved,
                    getType((PsiModifierListOwner) resolved),
                    null))
            != null
        && allowedForRef.isSubsetOf(allowedValues, manager)) return true;

    return PsiType.NULL.equals(expression.getType());
  }
  @Override
  public String handleEmptyLookup(
      @NotNull final CompletionParameters parameters, final Editor editor) {
    if (!(parameters.getOriginalFile() instanceof PsiJavaFile)) return null;

    final String ad = advertise(parameters);
    final String suffix = ad == null ? "" : "; " + StringUtil.decapitalize(ad);
    if (parameters.getCompletionType() == CompletionType.SMART) {
      if (!ApplicationManager.getApplication().isUnitTestMode()) {

        final Project project = parameters.getPosition().getProject();
        final PsiFile file = parameters.getOriginalFile();

        PsiExpression expression =
            PsiTreeUtil.getContextOfType(parameters.getPosition(), PsiExpression.class, true);
        if (expression != null && expression.getParent() instanceof PsiExpressionList) {
          int lbraceOffset = expression.getParent().getTextRange().getStartOffset();
          ShowParameterInfoHandler.invoke(project, editor, file, lbraceOffset, null);
        }

        if (expression instanceof PsiLiteralExpression) {
          return LangBundle.message("completion.no.suggestions") + suffix;
        }

        if (expression instanceof PsiInstanceOfExpression) {
          final PsiInstanceOfExpression instanceOfExpression = (PsiInstanceOfExpression) expression;
          if (PsiTreeUtil.isAncestor(
              instanceOfExpression.getCheckType(), parameters.getPosition(), false)) {
            return LangBundle.message("completion.no.suggestions") + suffix;
          }
        }
      }

      final Set<PsiType> expectedTypes = JavaCompletionUtil.getExpectedTypes(parameters);
      if (expectedTypes != null) {
        PsiType type = expectedTypes.size() == 1 ? expectedTypes.iterator().next() : null;
        if (type != null) {
          final PsiType deepComponentType = type.getDeepComponentType();
          if (deepComponentType instanceof PsiClassType) {
            if (((PsiClassType) deepComponentType).resolve() != null) {
              return CompletionBundle.message(
                      "completion.no.suggestions.of.type", type.getPresentableText())
                  + suffix;
            }
            return CompletionBundle.message("completion.unknown.type", type.getPresentableText())
                + suffix;
          }
          if (!PsiType.NULL.equals(type)) {
            return CompletionBundle.message(
                    "completion.no.suggestions.of.type", type.getPresentableText())
                + suffix;
          }
        }
      }
    }
    return LangBundle.message("completion.no.suggestions") + suffix;
  }
 @Nullable
 private static PsiReferenceExpression getReferenceFromNullCheck(
     PsiBinaryExpression expression) {
   final PsiExpression lhs = ParenthesesUtils.stripParentheses(expression.getLOperand());
   final PsiExpression rhs = ParenthesesUtils.stripParentheses(expression.getROperand());
   if (lhs instanceof PsiReferenceExpression) {
     if (!(rhs instanceof PsiLiteralExpression && PsiType.NULL.equals(rhs.getType()))) {
       return null;
     }
     return (PsiReferenceExpression) lhs;
   } else if (rhs instanceof PsiReferenceExpression) {
     if (!(lhs instanceof PsiLiteralExpression && PsiType.NULL.equals(lhs.getType()))) {
       return null;
     }
     return (PsiReferenceExpression) rhs;
   } else {
     return null;
   }
 }
 @Override
 public void visitThrowStatement(PsiThrowStatement statement) {
   super.visitThrowStatement(statement);
   final PsiExpression exception = ParenthesesUtils.stripParentheses(statement.getException());
   if (!(exception instanceof PsiLiteralExpression)) {
     return;
   }
   final PsiType type = exception.getType();
   if (!PsiType.NULL.equals(type)) {
     return;
   }
   registerError(exception);
 }
    @Nullable
    public PsiType fun(GrReferenceExpressionImpl refExpr) {
      PsiType result = GrReassignedLocalVarsChecker.checkReassignedVar(refExpr, true);
      if (result != null) return result;

      if (GrUnresolvedAccessInspection.isClassReference(refExpr)) {
        GrExpression qualifier = refExpr.getQualifier();
        LOG.assertTrue(qualifier != null);
        return TypesUtil.createJavaLangClassType(
            qualifier.getType(), refExpr.getProject(), refExpr.getResolveScope());
      }

      final PsiElement resolved = refExpr.resolve();
      final PsiType inferred = getInferredTypes(refExpr, resolved);
      final PsiType nominal = refExpr.getNominalType();
      if (inferred == null || PsiType.NULL.equals(inferred)) {
        if (nominal == null) {
          // inside nested closure we could still try to infer from variable initializer. Not sound,
          // but makes sense
          if (resolved instanceof GrVariable) {
            LOG.assertTrue(resolved.isValid());
            return ((GrVariable) resolved).getTypeGroovy();
          }
        }

        return nominal;
      }

      if (nominal == null) return inferred;
      if (!TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(nominal), inferred, false)) {
        if (resolved instanceof GrVariable
            && ((GrVariable) resolved).getTypeElementGroovy() != null) {
          return nominal;
        }
      }
      return inferred;
    }
  @NotNull
  @Override
  public PsiParameter createParameter(@NotNull final String name, @NotNull final PsiType type)
      throws IncorrectOperationException {
    PsiUtil.checkIsIdentifier(myManager, name);
    if (PsiType.NULL.equals(type)) {
      throw new IncorrectOperationException("Cannot create parameter with type \"null\".");
    }

    final String text = type.getCanonicalText() + " " + name;
    PsiParameter parameter = createParameterFromText(text, null);
    final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(myManager.getProject());
    PsiUtil.setModifierProperty(
        parameter,
        PsiModifier.FINAL,
        JavaCodeStyleSettingsFacade.getInstance(myManager.getProject())
            .isGenerateFinalParameters());
    GeneratedMarkerVisitor.markGenerated(parameter);
    parameter =
        (PsiParameter)
            JavaCodeStyleManager.getInstance(myManager.getProject())
                .shortenClassReferences(parameter);
    return (PsiParameter) codeStyleManager.reformat(parameter);
  }
 @Override
 public Boolean visitPrimitiveType(PsiPrimitiveType primitiveType) {
   return PsiType.VOID.equals(primitiveType) || PsiType.NULL.equals(primitiveType)
       ? Boolean.FALSE
       : Boolean.TRUE;
 }