/// <summary>
        /// Build a subquery against a nested array property
        /// </summary>
        /// <returns></returns>
        private string BuildArrayQuery()
        {
            var sb = new StringBuilder();

            var mainFrom = Extents.FirstOrDefault();

            if (mainFrom == null)
            {
                throw new InvalidOperationException("N1QL Subquery Missing From Part");
            }

            if (WrappingFunctions != null)
            {
                foreach (string function in WrappingFunctions.AsEnumerable().Reverse())
                {
                    sb.AppendFormat("{0}(", function);
                }
            }

            if ((SelectPart != mainFrom.ItemName) || WhereParts.Any())
            {
                sb.AppendFormat("ARRAY {0} FOR {1} IN {2}", SelectPart, mainFrom.ItemName, mainFrom.Source);

                if (WhereParts.Any())
                {
                    sb.AppendFormat(" WHEN {0}", String.Join(" AND ", WhereParts));
                }

                sb.Append(" END");
            }
            else
            {
                // has no projection or predicates, so simplify

                sb.Append(mainFrom.Source);
            }

            if (WrappingFunctions != null)
            {
                sb.Append(')', WrappingFunctions.Count);
            }

            return(sb.ToString());
        }
        /// <summary>
        /// Builds a subquery using the ANY or EVERY expression to test a nested array
        /// </summary>
        /// <returns>Query string</returns>
        private string BuildAnyAllQuery()
        {
            var sb = new StringBuilder();

            var mainFrom = Extents.FirstOrDefault();

            if (mainFrom == null)
            {
                throw new InvalidOperationException("N1QL Any Subquery Missing From Part");
            }

            var extentName = mainFrom.ItemName;

            var source = mainFrom.Source;

            if (QueryType == N1QlQueryType.ArrayAll)
            {
                extentName = PropertyExtractionPart;

                if (WhereParts.Any())
                {
                    // WhereParts should be used to filter the source before the EVERY query
                    // This is done using the ARRAY operator with a WHEN clause

                    source = string.Format("(ARRAY {1} FOR {1} IN {0} WHEN {2} END)",
                                           source,
                                           mainFrom.ItemName,
                                           string.Join(" AND ", WhereParts));
                }
            }

            sb.AppendFormat("{0} {1} IN {2} ",
                            QueryType == N1QlQueryType.ArrayAny ? "ANY" : "EVERY",
                            extentName,
                            source);

            if (QueryType == N1QlQueryType.ArrayAny)
            {
                // WhereParts should be applied to the SATISFIES portion of the query

                if (WhereParts.Any())
                {
                    sb.AppendFormat("SATISFIES {0}", String.Join(" AND ", WhereParts));
                }
                else
                {
                    sb.Append("SATISFIES true");
                }
            }
            else // N1QlQueryType.All
            {
                // WhereAllPart is applied as the SATISFIES portion of the query

                sb.Append("SATISFIES ");
                sb.Append(WhereAllPart);
            }

            sb.Append(" END");

            return(sb.ToString());
        }