private static void highlightIncorrectArguments(
     ProblemsHolder holder, CallArgumentsMapping result, @NotNull TypeEvalContext context) {
   for (Map.Entry<PyExpression, EnumSet<CallArgumentsMapping.ArgFlag>> argEntry :
       result.getArgumentFlags().entrySet()) {
     EnumSet<CallArgumentsMapping.ArgFlag> flags = argEntry.getValue();
     if (!flags.isEmpty()) { // something's wrong
       PyExpression arg = argEntry.getKey();
       if (flags.contains(CallArgumentsMapping.ArgFlag.IS_DUP)) {
         holder.registerProblem(arg, PyBundle.message("INSP.duplicate.argument"));
       }
       if (flags.contains(CallArgumentsMapping.ArgFlag.IS_DUP_KWD)) {
         holder.registerProblem(arg, PyBundle.message("INSP.duplicate.doublestar.arg"));
       }
       if (flags.contains(CallArgumentsMapping.ArgFlag.IS_DUP_TUPLE)) {
         holder.registerProblem(arg, PyBundle.message("INSP.duplicate.star.arg"));
       }
       if (flags.contains(CallArgumentsMapping.ArgFlag.IS_POS_PAST_KWD)) {
         holder.registerProblem(
             arg,
             PyBundle.message("INSP.cannot.appear.past.keyword.arg"),
             ProblemHighlightType.ERROR);
       }
       if (flags.contains(CallArgumentsMapping.ArgFlag.IS_UNMAPPED)) {
         holder.registerProblem(arg, PyBundle.message("INSP.unexpected.arg"));
       }
       if (flags.contains(CallArgumentsMapping.ArgFlag.IS_TOO_LONG)) {
         final PyCallExpression.PyMarkedCallee markedCallee = result.getMarkedCallee();
         String parameterName = null;
         if (markedCallee != null) {
           final List<PyParameter> parameters =
               PyUtil.getParameters(markedCallee.getCallable(), context);
           for (int i = parameters.size() - 1; i >= 0; --i) {
             final PyParameter param = parameters.get(i);
             if (param instanceof PyNamedParameter) {
               final List<PyNamedParameter> unmappedParams = result.getUnmappedParams();
               if (!((PyNamedParameter) param).isPositionalContainer()
                   && !((PyNamedParameter) param).isKeywordContainer()
                   && param.getDefaultValue() == null
                   && !unmappedParams.contains(param)) {
                 parameterName = param.getName();
                 break;
               }
             }
           }
           holder.registerProblem(
               arg,
               parameterName != null
                   ? PyBundle.message(
                       "INSP.multiple.values.resolve.to.positional.$0", parameterName)
                   : PyBundle.message("INSP.more.args.that.pos.params"));
         }
       }
     }
   }
 }
 @Override
 public void visitPyDecoratorList(final PyDecoratorList node) {
   PyDecorator[] decorators = node.getDecorators();
   for (PyDecorator deco : decorators) {
     if (deco.hasArgumentList()) continue;
     final PyCallExpression.PyMarkedCallee markedCallee =
         deco.resolveCallee(resolveWithoutImplicits());
     if (markedCallee != null && !markedCallee.isImplicitlyResolved()) {
       final Callable callable = markedCallee.getCallable();
       int firstParamOffset = markedCallee.getImplicitOffset();
       final List<PyParameter> params = PyUtil.getParameters(callable, myTypeEvalContext);
       final PyNamedParameter allegedFirstParam =
           params.size() < firstParamOffset
               ? null
               : params.get(firstParamOffset - 1).getAsNamed();
       if (allegedFirstParam == null || allegedFirstParam.isKeywordContainer()) {
         // no parameters left to pass function implicitly, or wrong param type
         registerProblem(
             deco,
             PyBundle.message(
                 "INSP.func.$0.lacks.first.arg",
                 callable.getName())); // TODO: better names for anon lambdas
       } else { // possible unfilled params
         for (int i = firstParamOffset; i < params.size(); i += 1) {
           final PyParameter parameter = params.get(i);
           if (parameter instanceof PySingleStarParameter) continue;
           final PyNamedParameter par = parameter.getAsNamed();
           // param tuples, non-starred or non-default won't do
           if (par == null
               || (!par.isKeywordContainer()
                   && !par.isPositionalContainer()
                   && !par.hasDefaultValue())) {
             String parameterName = par != null ? par.getName() : "(...)";
             registerProblem(
                 deco, PyBundle.message("INSP.parameter.$0.unfilled", parameterName));
           }
         }
       }
     }
     // else: this case is handled by arglist visitor
   }
 }
 @Nullable
 @Override
 public PyType getCallType(
     @NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
   for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
     final PyType type = typeProvider.getCallType(this, callSite, context);
     if (type != null) {
       type.assertValid(typeProvider.toString());
       return type;
     }
   }
   final PyExpression receiver = PyTypeChecker.getReceiver(callSite, this);
   final List<PyExpression> arguments = PyTypeChecker.getArguments(callSite, this);
   final List<PyParameter> parameters = PyUtil.getParameters(this, context);
   final PyResolveContext resolveContext =
       PyResolveContext.noImplicits().withTypeEvalContext(context);
   final List<PyParameter> explicitParameters =
       PyTypeChecker.filterExplicitParameters(parameters, this, callSite, resolveContext);
   final Map<PyExpression, PyNamedParameter> mapping =
       PyCallExpressionHelper.mapArguments(arguments, explicitParameters);
   return getCallType(receiver, mapping, context);
 }