protected string BuildResult(bool key)
        {
            var result = new StringBuilder();
            var prefix = "?";

            if (SubBuilder)
            {
                result.Append("$expand=");
                prefix = "&";
            }

            result.Append(base.BuildResult());

            var options = BuildOptionsResult(prefix, key);

            if (!string.IsNullOrWhiteSpace(options))
            {
                if (!CompareUtilities.IsDefault(Key))
                {
                    throw new ArgumentException($"{Filter} may only be used on collections. {nameof(Key)} is already applied.");
                }

                if (SubBuilder)
                {
                    result.Append("(");
                }

                result.Append(options);

                if (SubBuilder)
                {
                    result.Append(")");
                }

                prefix = "&";
            }

            if (SubEntity != null)
            {
                result.Append(prefix);
                result.Append(SubEntity.Build());
            }

            return(result.ToString());
        }
        /// <summary>
        /// Reduce number of entries in <see cref="settings"/> based on <see cref="IHistorySettings"/>.
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="settings"></param>
        /// <param name="values"></param>
        /// <param name="anomalies"></param>
        /// <param name="referenceDate"></param>
        /// <returns></returns>
        internal static long ReduceValues <TValue>(
            this IHistorySettings settings,
            ConcurrentDictionary <DateTimeOffset, TValue> values,
            ConcurrentBag <TValue> anomalies,
            DateTimeOffset referenceDate)
        {
            long result      = 0;
            var  oldestValue = values.Keys.OrderBy(x => x).FirstOrDefault();

            while (!anomalies.IsEmpty)
            {
                if (!anomalies.TryTake(out var _))
                {
                    return(result++);
                }
            }

            if (settings.PreserveTimeSpan > TimeSpan.Zero)
            {
                var preserveDate = referenceDate - settings.PreserveTimeSpan;

                while (!CompareUtilities.IsDefault(oldestValue) && oldestValue < preserveDate)
                {
                    values.TryRemove(oldestValue, out _);
                    oldestValue = values.Keys.OrderBy(x => x).FirstOrDefault();
                    result++;
                }

                return(result);
            }

            while (!CompareUtilities.IsDefault(oldestValue) && values.Keys.Count > settings.PreserveCount)
            {
                if (!values.TryRemove(oldestValue, out _))
                {
                    return(result);
                }

                oldestValue = values.Keys.OrderBy(x => x).FirstOrDefault();
                result++;
            }

            return(result);
        }
        protected override string BuildResult()
        {
            var result = new StringBuilder();

            result.Append(Entity.ToLowerInvariant());

            if (!CompareUtilities.IsDefault(Key))
            {
                if (SubBuilder)
                {
                    throw new ArgumentException($"Expand can not be used with {nameof(Key)}.");
                }

                result
                .Append("(")
                .Append(StringKey)
                .Append(")");
            }

            return(result.ToString());
        }