public ArangoQueryOperation IN(List <object> list, ArangoQueryOperation aql)
        {
            var etom = new Etom();

            etom.Type = AQL.IN;

            var expression = new StringBuilder("[");

            for (int i = 0; i < list.Count; i++)
            {
                expression.Append(ToString(list[i]));

                if (i < (list.Count - 1))
                {
                    expression.Append(", ");
                }
            }

            expression.Append("]");

            etom.Value    = expression.ToString();
            etom.Children = aql.ExpressionTree;

            return(AddEtom(etom));
        }
        public ArangoQueryOperation Object(ArangoQueryOperation aql)
        {
            var etom = new Etom();

            etom.Type     = AQL.Object;
            etom.Children = aql.ExpressionTree;

            return(AddEtom(etom));
        }
        public ArangoQueryOperation Val(object value)
        {
            var etom = new Etom();

            etom.Type  = AQL.Val;
            etom.Value = value;

            return(AddEtom(etom));
        }
        public ArangoQueryOperation COLLECT(string criteria)
        {
            var etom = new Etom();

            etom.Type  = AQL.COLLECT;
            etom.Value = criteria;

            return(AddEtom(etom));
        }
        public ArangoQueryOperation Var(string name)
        {
            var etom = new Etom();

            etom.Type  = AQL.Var;
            etom.Value = name;

            return(AddEtom(etom));
        }
        /// <summary>
        /// Appends AQL query.
        /// </summary>
        /// <param name="queryString">AQL query string to be appended.</param>
        public ArangoQueryOperation Aql(string queryString)
        {
            var etom = new Etom();

            etom.Type  = AQL.String;
            etom.Value = queryString;

            return(AddEtom(etom));
        }
        public ArangoQueryOperation LIMIT(object offset, object count)
        {
            var etom = new Etom();

            etom.Type  = AQL.LIMIT;
            etom.Value = offset.ToString() + ", " + count.ToString();

            return(AddEtom(etom));
        }
        public ArangoQueryOperation LET(string variableName)
        {
            var etom = new Etom();

            etom.Type  = AQL.LET;
            etom.Value = variableName;

            return(AddEtom(etom));
        }
        public ArangoQueryOperation INTO(string group)
        {
            var etom = new Etom();

            etom.Type  = AQL.INTO;
            etom.Value = group;

            return(AddEtom(etom));
        }
        /*
         *  internal operations
         */

        public ArangoQueryOperation Direction(ArangoSortDirection sortDirection)
        {
            var etom = new Etom();

            etom.Type  = AQL.SortDirection;
            etom.Value = sortDirection.ToString();

            return(AddEtom(etom));
        }
        public ArangoQueryOperation TO_STRING(ArangoQueryOperation aql)
        {
            var etom = new Etom();

            etom.Type = AQL.TO_STRING;

            etom.Children = aql.ExpressionTree;

            return(AddEtom(etom));
        }
        public ArangoQueryOperation OR(ArangoQueryOperation expression)
        {
            var etom = new Etom();

            etom.Type = AQL.OR;

            etom.Children.AddRange(expression.ExpressionTree);

            return(AddEtom(etom));
        }
        public ArangoQueryOperation IN(string name, ArangoQueryOperation aql)
        {
            var etom = new Etom();

            etom.Type     = AQL.IN;
            etom.Value    = name;
            etom.Children = aql.ExpressionTree;

            return(AddEtom(etom));
        }
        private ArangoQueryOperation AddEtom(Etom etom)
        {
            ExpressionTree.Add(etom);

            var aqo = new ArangoQueryOperation(_cursorOperation, ExpressionTree);

            ExpressionTree.Clear();

            return(aqo);
        }
        /*
         *  standard high level operations
         */

        #region AND

        public ArangoQueryOperation AND(ArangoQueryOperation leftOperand, ArangoOperator conditionOperator, ArangoQueryOperation rightOperand)
        {
            var etom = new Etom();

            etom.Type  = AQL.AND;
            etom.Value = conditionOperator;

            etom.Children.AddRange(leftOperand.ExpressionTree);
            etom.Children.AddRange(rightOperand.ExpressionTree);

            return(AddEtom(etom));
        }
        public ArangoQueryOperation CONTAINS(ArangoQueryOperation text, ArangoQueryOperation search, bool returnIndex)
        {
            var etom = new Etom();

            etom.Type         = AQL.CONTAINS;
            etom.Value        = returnIndex;
            etom.ChildrenList = new List <List <Etom> >();
            etom.ChildrenList.Add(text.ExpressionTree);
            etom.ChildrenList.Add(search.ExpressionTree);

            return(AddEtom(etom));
        }
        public ArangoQueryOperation SORT(params ArangoQueryOperation[] criteria)
        {
            var etom = new Etom();

            etom.Type         = AQL.SORT;
            etom.ChildrenList = new List <List <Etom> >();

            for (int i = 0; i < criteria.Length; i++)
            {
                etom.ChildrenList.Add(criteria[i].ExpressionTree);
            }

            return(AddEtom(etom));
        }
        /*
         *  standard functions
         */

        public ArangoQueryOperation CONCAT(params ArangoQueryOperation[] values)
        {
            var etom = new Etom();

            etom.Type         = AQL.CONCAT;
            etom.ChildrenList = new List <List <Etom> >();

            for (int i = 0; i < values.Length; i++)
            {
                etom.ChildrenList.Add(values[i].ExpressionTree);
            }

            return(AddEtom(etom));
        }
        public ArangoQueryOperation EDGES(string collection, string vertexId, ArangoEdgeDirection edgeDirection, ArangoQueryOperation aql)
        {
            var etom = new Etom();

            etom.Type = AQL.EDGES;

            var expression = new StringBuilder(collection + ", ");

            // if vertex is valid document ID/handle enclose it with single quotes
            // otherwise it's most probably variable which shouldn't be enclosed
            if (Document.IsId(vertexId))
            {
                expression.Append("'" + vertexId + "'");
            }
            else
            {
                expression.Append(vertexId);
            }

            expression.Append(", '");

            switch (edgeDirection)
            {
            case ArangoEdgeDirection.In:
                expression.Append("inbound");
                break;

            case ArangoEdgeDirection.Out:
                expression.Append("outbound");
                break;

            case ArangoEdgeDirection.Any:
                expression.Append("any");
                break;

            default:
                break;
            }

            expression.Append("'");

            etom.Value    = expression;
            etom.Children = aql.ExpressionTree;

            return(AddEtom(etom));
        }
        public ArangoQueryOperation DOCUMENT(List <string> documentIds)
        {
            var etom = new Etom();

            etom.Type = AQL.DOCUMENT;

            // if parameter consists of more than one value it should be enclosed in square brackets
            if (documentIds.Count > 1)
            {
                var expression = new StringBuilder("[");

                for (int i = 0; i < documentIds.Count; i++)
                {
                    expression.Append(ToString(documentIds[i]));

                    if (i < (documentIds.Count - 1))
                    {
                        expression.Append(", ");
                    }
                }

                expression.Append("]");

                etom.Value = expression.ToString();
            }
            else if (documentIds.Count == 1)
            {
                // if documentId is valid document ID/handle enclose it with single quotes
                // otherwise it's most probably variable which shouldn't be enclosed
                if (Document.IsId(documentIds.First()))
                {
                    etom.Value = ToString(documentIds.First());
                }
                else
                {
                    etom.Value = documentIds.First();
                }
            }

            return(AddEtom(etom));
        }
        public ArangoQueryOperation List(List <object> values)
        {
            var etom = new Etom();

            etom.Type = AQL.List;

            var expression = new StringBuilder();

            for (int i = 0; i < values.Count; i++)
            {
                expression.Append(ToString(values[i]));

                if (i < (values.Count - 1))
                {
                    expression.Append(", ");
                }
            }

            etom.Value = expression.ToString();

            return(AddEtom(etom));
        }