private static PsiType genNewMapBy(PsiType genericOwner, PsiManager manager) {
    PsiClass map =
        JavaPsiFacade.getInstance(manager.getProject())
            .findClass(JAVA_UTIL_MAP, genericOwner.getResolveScope());
    PsiElementFactory factory = JavaPsiFacade.getElementFactory(manager.getProject());
    if (map == null) return factory.createTypeFromText(JAVA_UTIL_MAP, null);

    final PsiType key = PsiUtil.substituteTypeParameter(genericOwner, JAVA_UTIL_MAP, 0, false);
    final PsiType value = PsiUtil.substituteTypeParameter(genericOwner, JAVA_UTIL_MAP, 1, false);
    return factory.createType(map, key, value);
  }
    @Override
    public void visitBinaryExpression(GrBinaryExpression expression) {
      super.visitBinaryExpression(expression);

      if (expression.getOperationTokenType() != GroovyTokenTypes.kIN) return;

      GrExpression leftOperand = expression.getLeftOperand();
      GrExpression rightOperand = expression.getRightOperand();
      if (leftOperand == null || rightOperand == null) return;

      PsiType ltype = leftOperand.getType();
      PsiType rtype = rightOperand.getType();
      if (ltype == null || rtype == null) return;

      PsiType component;

      if (rtype instanceof PsiArrayType) {
        component = ((PsiArrayType) rtype).getComponentType();
      } else if (InheritanceUtil.isInheritor(rtype, CommonClassNames.JAVA_UTIL_COLLECTION)) {
        component =
            PsiUtil.substituteTypeParameter(rtype, CommonClassNames.JAVA_UTIL_COLLECTION, 0, false);
      } else {
        checkSimpleClasses(ltype, rtype, expression);
        return;
      }

      if (component == null) return;

      if (TypesUtil.isAssignable(
          ltype, component, expression.getManager(), expression.getResolveScope(), false)) return;

      registerError(expression, ltype, rtype);
    }
  public static void addCompletions(
      @NotNull final JavaSmartCompletionParameters parameters,
      @NotNull Consumer<LookupElement> result,
      final PrefixMatcher matcher) {

    final Condition<String> shortNameCondition =
        new Condition<String>() {
          public boolean value(String s) {
            return matcher.prefixMatches(s);
          }
        };

    PsiType classParameter =
        PsiUtil.substituteTypeParameter(
            parameters.getExpectedType(), CommonClassNames.JAVA_LANG_CLASS, 0, false);

    boolean addInheritors = false;
    PsiElement position = parameters.getPosition();
    if (classParameter instanceof PsiWildcardType) {
      final PsiWildcardType wildcardType = (PsiWildcardType) classParameter;
      classParameter = wildcardType.getBound();
      addInheritors = wildcardType.isExtends() && classParameter instanceof PsiClassType;
    } else if (!matcher.getPrefix().isEmpty()) {
      addInheritors = true;
      classParameter = PsiType.getJavaLangObject(position.getManager(), position.getResolveScope());
    }
    if (classParameter != null) {
      PsiFile file = position.getContainingFile();
      addClassLiteralLookupElement(classParameter, result, file);
      if (addInheritors) {
        addInheritorClassLiterals(file, shortNameCondition, classParameter, result, matcher);
      }
    }
  }
 @Nullable
 private static PsiClass resolveExtensionPointClass(PsiField psiField) {
   final PsiType typeParameter =
       PsiUtil.substituteTypeParameter(
           psiField.getType(), ExtensionPointName.class.getName(), 0, false);
   return PsiUtil.resolveClassInClassTypeOnly(typeParameter);
 }
    public PreferExpected(
        boolean constructorPossible, ExpectedTypeInfo[] expectedTypes, PsiElement position) {
      super("expectedType");
      myConstructorPossible = constructorPossible;
      myExpectedTypes = expectedTypes;
      for (ExpectedTypeInfo info : expectedTypes) {
        ContainerUtil.addIfNotNull(
            myExpectedClasses,
            PsiUtil.substituteTypeParameter(
                info.getDefaultType(), CommonClassNames.JAVA_LANG_CLASS, 0, false));
      }

      myExpectedMemberName = calcExpectedMemberNameByParentCall(position);
    }
  static void addCollectConversion(
      PsiReferenceExpression ref,
      Collection<ExpectedTypeInfo> expectedTypes,
      Consumer<LookupElement> consumer) {
    final PsiExpression qualifier = ref.getQualifierExpression();
    PsiType component =
        qualifier == null
            ? null
            : PsiUtil.substituteTypeParameter(
                qualifier.getType(), JAVA_UTIL_STREAM_STREAM, 0, true);
    if (component == null) return;

    JavaPsiFacade facade = JavaPsiFacade.getInstance(ref.getProject());
    GlobalSearchScope scope = ref.getResolveScope();
    PsiClass list = facade.findClass(JAVA_UTIL_LIST, scope);
    PsiClass set = facade.findClass(JAVA_UTIL_SET, scope);
    if (facade.findClass(JAVA_UTIL_STREAM_COLLECTORS, scope) == null || list == null || set == null)
      return;

    boolean hasList = false;
    boolean hasSet = false;
    for (ExpectedTypeInfo info : expectedTypes) {
      PsiType type = info.getDefaultType();
      PsiClass expectedClass = PsiUtil.resolveClassInClassTypeOnly(type);
      PsiType expectedComponent = PsiUtil.extractIterableTypeParameter(type, true);
      if (expectedClass == null
          || expectedComponent == null
          || !TypeConversionUtil.isAssignable(expectedComponent, component)) continue;

      if (!hasList && InheritanceUtil.isInheritorOrSelf(list, expectedClass, true)) {
        hasList = true;
        consumer.consume(new MyLookupElement("toList", type));
      }

      if (!hasSet && InheritanceUtil.isInheritorOrSelf(set, expectedClass, true)) {
        hasSet = true;
        consumer.consume(new MyLookupElement("toSet", type));
      }
    }
  }