private AqlExpression VisitNewArrayInit(NewArrayExpression node)
        {
            // allow construction only of JsonValue[] arrays
            // (as an argument to the JsonArray constructor)
            if (node.Type.GetElementType() != typeof(JsonValue))
            {
                throw new AqlParsingException(
                          $"Expression {node} cannot be converted to AQL expression"
                          );
            }

            List <AqlExpression> args = node.Expressions.Select(Visit).ToList();

            var result = new AqlJsonArrayExpression();

            foreach (AqlExpression item in args)
            {
                result.Add(item);
            }

            return(result);
        }
        private AqlExpression VisitCall(MethodCallExpression node)
        {
            AqlExpression        instance = Visit(node.Object);
            List <AqlExpression> args     = node.Arguments
                                            .Select(Visit)
                                            .ToList();

            // === handle arango functions ===

            ArangoFunctionAttribute attribute = node.Method
                                                .GetCustomAttribute <ArangoFunctionAttribute>();

            if (attribute != null)
            {
                return(new AqlFunctionExpression(attribute, args));
            }

            // === intercept indexing on JSON objects and arrays ===

            if (possibleIndexerMethods.Contains(node.Method) &&
                args.Count == 1)
            {
                return(new AqlMemberAccessExpression(
                           instance,
                           args[0]
                           ));
            }

            // === handle JSON object construction ===

            // if we call .Add on a JsonObject instance
            if (node.Object?.Type == typeof(JsonObject) &&
                node.Method.Name == "Add")
            {
                // start construction
                if (instance is AqlConstantExpression constant)
                {
                    instance = new AqlJsonObjectExpression(constant.Value);
                }

                // continue construction
                if (instance is AqlJsonObjectExpression obj)
                {
                    return(obj.CallAddViaArgs(args));
                }
            }

            // === handle JSON array construction ===

            // if we call .Add on a JsonArray instance
            if (node.Object?.Type == typeof(JsonArray) &&
                node.Method.Name == "Add")
            {
                // start construction
                if (instance is AqlConstantExpression constant)
                {
                    instance = new AqlJsonArrayExpression(constant.Value);
                }

                // continue construction
                if (instance is AqlJsonArrayExpression arr)
                {
                    return(arr.CallAddViaArgs(args));
                }
            }

            // === expression is invalid ===

            throw new AqlParsingException(
                      $"Expression uses parameters in method '{node.Method}'" +
                      ", but this method cannot be translated to AQL"
                      );
        }