/// <summary>
        /// Parse an array expression, and turn it into a loop. Use indexName as the loop variable. Bomb if we can't do it. If you hand in null we will make up our own.
        /// </summary>
        /// <param name="query">The query that this loop is associated with.</param>
        /// <param name="expr">The expression that evaluates to an array.</param>
        /// <param name="gc"></param>
        /// <param name="cc"></param>
        /// <param name="container"></param>
        public static IVariableScopeHolder ParseArrayExpression(IQuerySource query, Expression expr, IGeneratedQueryCode gc, ICodeContext cc, CompositionContainer container)
        {
            if (_parser == null)
            {
                _parser = new ArrayExpressionParser();
                container.SatisfyImportsOnce(_parser);
            }

            var result = _parser.GetIArrayInfo(expr, gc, cc, container);

            if (result == null)
                throw new InvalidOperationException($"Can't figure out how to loop over this array: '{expr.ToString()}' (expression: '{expr.NodeType}', type: '{expr.Type.FullyQualifiedName()}')");

            //
            // Turn it into code - any code that we need.
            //

            return result.CodeLoopOverArrayInfo(query, gc, cc, container);
        }
        /// <summary>
        /// Parse an array expression, and turn it into a loop. Use indexName as the loop variable. Bomb if we can't do it. If you hand in null we will make up our own.
        /// </summary>
        /// <param name="query">The query that this loop is associated with.</param>
        /// <param name="expr">The expression that evaluates to an array.</param>
        /// <param name="gc"></param>
        /// <param name="cc"></param>
        /// <param name="container"></param>
        public static IVariableScopeHolder ParseArrayExpression(IQuerySource query, Expression expr, IGeneratedQueryCode gc, ICodeContext cc, CompositionContainer container)
        {
            if (_parser == null)
            {
                _parser = new ArrayExpressionParser();
                container.SatisfyImportsOnce(_parser);
            }

            var result = _parser.GetIArrayInfo(expr, gc, cc, container);

            if (result == null)
            {
                throw new InvalidOperationException($"Can't figure out how to loop over this array: '{expr.ToString()}' (expression: '{expr.NodeType}', type: '{expr.Type.FullyQualifiedName()}')");
            }

            //
            // Turn it into code - any code that we need.
            //

            return(result.CodeLoopOverArrayInfo(query, gc, cc, container));
        }
 /// <summary>
 /// Used for testing - allows one to reset everything.
 /// </summary>
 internal static void ResetParser()
 {
     _parser = null;
 }
 /// <summary>
 /// Used for testing - allows one to reset everything.
 /// </summary>
 internal static void ResetParser()
 {
     _parser = null;
 }