@Override
        public PsiType fun(GrIndexPropertyImpl index) {
          GrExpression selected = index.getInvokedExpression();
          PsiType thisType = selected.getType();

          if (thisType == null) return null;

          GrArgumentList argList = index.getArgumentList();

          PsiType[] argTypes = PsiUtil.getArgumentTypes(argList);
          if (argTypes == null) return null;

          final PsiManager manager = index.getManager();
          final GlobalSearchScope resolveScope = index.getResolveScope();

          if (argTypes.length == 0) {
            PsiType arrType = null;
            if (selected instanceof GrBuiltinTypeClassExpression) {
              arrType = ((GrBuiltinTypeClassExpression) selected).getPrimitiveType();
            }

            if (selected instanceof GrReferenceExpression) {
              final PsiElement resolved = ((GrReferenceExpression) selected).resolve();
              if (resolved instanceof PsiClass) {
                String qname = ((PsiClass) resolved).getQualifiedName();
                if (qname != null) {
                  arrType = TypesUtil.createTypeByFQClassName(qname, index);
                }
              }
            }

            if (arrType != null) {
              final PsiArrayType param = arrType.createArrayType();
              return TypesUtil.createJavaLangClassType(param, index.getProject(), resolveScope);
            }
          }

          if (PsiImplUtil.isSimpleArrayAccess(
              thisType, argTypes, manager, resolveScope, PsiUtil.isLValue(index))) {
            return TypesUtil.boxPrimitiveType(
                ((PsiArrayType) thisType).getComponentType(), manager, resolveScope);
          }

          final GroovyResolveResult[] candidates = index.multiResolve(false);

          PsiType[] args =
              PsiUtil.getArgumentTypes(
                  argList.getNamedArguments(),
                  argList.getExpressionArguments(),
                  GrClosableBlock.EMPTY_ARRAY,
                  true,
                  null,
                  false);
          final GroovyResolveResult candidate = PsiImplUtil.extractUniqueResult(candidates);
          final PsiElement element = candidate.getElement();
          if (element instanceof PsiNamedElement) {
            final String name = ((PsiNamedElement) element).getName();
            if ("putAt".equals(name) && args != null) {
              args =
                  ArrayUtil.append(
                      args, TypeInferenceHelper.getInitializerFor(index), PsiType.class);
            }
          }
          PsiType overloadedOperatorType =
              ResolveUtil.extractReturnTypeFromCandidate(candidate, index, args);

          PsiType componentType = extractMapValueType(thisType, args, manager, resolveScope);

          if (overloadedOperatorType != null
              && (componentType == null
                  || !TypesUtil.isAssignable(
                      overloadedOperatorType, componentType, manager, resolveScope))) {
            return TypesUtil.boxPrimitiveType(overloadedOperatorType, manager, resolveScope);
          }
          return componentType;
        }
  private GroovyResolveResult[] resolveImpl(
      boolean incompleteCode, @Nullable GrExpression upToArgument) {
    GrExpression invoked = getInvokedExpression();
    PsiType thisType = invoked.getType();

    if (thisType == null) return GroovyResolveResult.EMPTY_ARRAY;

    GrArgumentList argList = getArgumentList();

    PsiType[] argTypes =
        PsiUtil.getArgumentTypes(
            argList.getNamedArguments(),
            argList.getExpressionArguments(),
            GrClosableBlock.EMPTY_ARRAY,
            true,
            upToArgument,
            false);
    if (argTypes == null) return GroovyResolveResult.EMPTY_ARRAY;

    final PsiManager manager = getManager();
    final GlobalSearchScope resolveScope = getResolveScope();

    if (argTypes.length == 0) {
      PsiType arrType = null;
      if (invoked instanceof GrBuiltinTypeClassExpression) {
        arrType = ((GrBuiltinTypeClassExpression) invoked).getPrimitiveType();
      }

      if (invoked instanceof GrReferenceExpression) {
        final PsiElement resolved = ((GrReferenceExpression) invoked).resolve();
        if (resolved instanceof PsiClass) {
          String qname = ((PsiClass) resolved).getQualifiedName();
          if (qname != null) {
            arrType = TypesUtil.createTypeByFQClassName(qname, this);
          }
        }
      }

      if (arrType != null) {
        return GroovyResolveResult.EMPTY_ARRAY;
      }
    }

    GroovyResolveResult[] candidates;
    final String name;
    if (PsiUtil.isLValue(this)) {
      name = "putAt";
      if (!incompleteCode) {
        argTypes =
            ArrayUtil.append(argTypes, TypeInferenceHelper.getInitializerFor(this), PsiType.class);
      }
    } else {
      name = "getAt";
    }

    if (PsiImplUtil.isSimpleArrayAccess(
        thisType, argTypes, manager, resolveScope, PsiUtil.isLValue(this))) {
      return GroovyResolveResult.EMPTY_ARRAY;
    }

    candidates =
        ResolveUtil.getMethodCandidates(
            thisType, name, this, true, incompleteCode, false, argTypes);

    // hack for remove DefaultGroovyMethods.getAt(Object, ...)
    if (candidates.length == 2) {
      for (int i = 0; i < candidates.length; i++) {
        GroovyResolveResult candidate = candidates[i];
        final PsiElement element = candidate.getElement();
        if (element instanceof GrGdkMethod) {
          final PsiMethod staticMethod = ((GrGdkMethod) element).getStaticMethod();
          final PsiParameter param = staticMethod.getParameterList().getParameters()[0];
          if (param.getType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
            return new GroovyResolveResult[] {candidates[1 - i]};
          }
        }
      }
    }

    if (candidates.length != 1) {
      final GrTupleType tupleType =
          new GrTupleType(argTypes, JavaPsiFacade.getInstance(getProject()), resolveScope);
      candidates = ResolveUtil.getMethodCandidates(thisType, name, this, tupleType);
    }
    return candidates;
  }