/// Given a syntax of someCollection { fields, to, selection, from, object }
            /// it will build a select assuming 'someCollection' is an IEnumerable
            private DataApiNode BuildDynamicSelectOnCollection(LambdaExpression exp, string name, EqlGrammerParser.EntityQueryContext context, bool isRootSelect)
            {
                var elementType      = exp.Body.Type.GetEnumerableType();
                var contextParameter = Expression.Parameter(elementType);

                var oldContext = _selectContext;

                _selectContext = contextParameter;
                // visit child fields. Will be field or entityQueries again
                var fieldExpressions = context.fields.children.Select(c => Visit(c)).Where(n => n != null).ToList();
                var relations        = fieldExpressions.Where(f => f.Expression.NodeType == ExpressionType.MemberInit || f.Expression.NodeType == ExpressionType.Call).Select(r => r.RelationExpression).ToList();

                // process at each relation
                if (_relationHandler != null && relations.Any())
                {
                    // Likely the EF handler to build .Include()s
                    exp = _relationHandler.BuildNodeForSelect(relations, contextParameter, exp, name, _schemaProvider);
                }

                // we're about to add the .Select() call. May need to do something
                if (_relationHandler != null && isRootSelect)
                {
                    exp = _relationHandler.HandleSelectComplete(exp);
                }

                // Default we select out sub objects/relations. So Select(d => new {Field = d.Field, Relation = new { d.Relation.Field }})
                var selectExpression = DataApiExpressionUtil.SelectDynamic(contextParameter, exp.Body, fieldExpressions, _schemaProvider);
                var node             = new DataApiNode(name, selectExpression, exp.Parameters.Any() ? exp.Parameters.First() : null, exp.Body);

                _selectContext = oldContext;
                return(node);
            }
            /// Given a syntax of someField { fields, to, selection, from, object }
            /// it will figure out if 'someField' is an IEnumerable or an istance of the object (not a collection) and build the correct select statement
            private DataApiNode BuildDynamicSelectForObjectGraph(string query, string name, EqlGrammerParser.EntityQueryContext context)
            {
                if (!_schemaProvider.TypeHasField(_selectContext.Type.Name, name))
                {
                    throw new EqlCompilerException($"Type {_selectContext.Type} does not have field or property {name}");
                }
                name = _schemaProvider.GetActualFieldName(_selectContext.Type.Name, name);

                // Don't really like any of this, but...
                try
                {
                    var result = EqlCompiler.CompileWith(query, _selectContext, _schemaProvider, _methodProvider);
                    var exp    = result.Expression;
                    if (exp.Body.Type.IsEnumerable())
                    {
                        return(BuildDynamicSelectOnCollection(exp, name, context, false));
                    }

                    var oldContext = _selectContext;
                    _selectContext = exp.Body;
                    // visit child fields. Will be field or entityQueries again
                    var fieldExpressions = context.fields.children.Select(c => Visit(c)).Where(n => n != null).ToList();

                    var relationsExps = fieldExpressions.Where(f => f.Expression.NodeType == ExpressionType.MemberInit || f.Expression.NodeType == ExpressionType.Call).ToList();
                    if (_relationHandler != null && relationsExps.Any())
                    {
                        var parameterExpression = Expression.Parameter(_selectContext.Type);
                        var relations           = relationsExps.Select(r => (Expression)Expression.PropertyOrField(parameterExpression, r.Name)).ToList();
                        exp = _relationHandler.BuildNodeForSelect(relations, parameterExpression, exp, name, _schemaProvider);
                    }

                    var newExp = DataApiExpressionUtil.CreateNewExpression(_selectContext, fieldExpressions, _schemaProvider);
                    _selectContext = oldContext;
                    return(new DataApiNode(_schemaProvider.GetActualFieldName(_selectContext.Type.Name, name), newExp, exp.Parameters.Any() ? exp.Parameters.First() : null, exp.Body));
                }
                catch (EqlCompilerException ex)
                {
                    throw DataApiException.MakeFieldCompileError(query, ex.Message);
                }
            }