protected object AssignIndexer(AssignmentExpression node, object value)
        {
            var exp = (IndexExpression)node.Left;
            var obj = exp.Target.Accept(this);

            if (obj == null)
            {
                ExecutionException.ThrowNullError(exp.Target, node);
            }
            var args = exp.Arguments.Map(arg => arg.Accept(this)).AddLast(value);

            if (exp.Setter is null)
            {
                var indexer = exp.Target.Type
                              .FindSetIndexer(args, out ArgumentConversions conversions);
                if (indexer is null)
                {
                    ExecutionException.ThrowMissingIndexer(exp.Target.Type, "set", exp.Target, node);
                }

                exp.Conversions = conversions;
                exp.Setter      = indexer;
                // ok to be node.Right.Type instead of indexer.GetParameters().Last().ParameterType
                var valueBind = conversions[args.Length - 1];
                node.Type = (valueBind == null) ? node.Right.Type : valueBind.Type;
            }
            exp.Conversions.Invoke(ref args);
            SafeInvoke(exp, exp.Setter, obj, args);
            return(value);
        }
        static void ResolveIndexer(IndexExpression node, object[] args)
        {
            System.Reflection.MethodInfo indexer;
            var type = node.Target.Type;

            indexer = type
                      .FindGetIndexer(args, out ArgumentConversions conversions);
            if (indexer is null)
            {
                ExecutionException.ThrowMissingIndexer(type, "get", node);
            }
            node.Type        = indexer.ReturnType;
            node.Conversions = conversions;
            node.Getter      = indexer;
        }