Extensions
Contains the LINQ to JSON extension methods.
            
                using Newtonsoft.Json.Utilities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Newtonsoft.Json.Linq
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    [System.Runtime.CompilerServices.Nullable(0)]
    public static class Extensions
    {
        public static IJEnumerable<JToken> Ancestors<[System.Runtime.CompilerServices.Nullable(0)] T>(this IEnumerable<T> source) where T : JToken
        {
            ValidationUtils.ArgumentNotNull(source, "source");
            return source.SelectMany((T j) => j.Ancestors()).AsJEnumerable();
        }
        public static IJEnumerable<JToken> AncestorsAndSelf<[System.Runtime.CompilerServices.Nullable(0)] T>(this IEnumerable<T> source) where T : JToken
        {
            ValidationUtils.ArgumentNotNull(source, "source");
            return source.SelectMany((T j) => j.AncestorsAndSelf()).AsJEnumerable();
        }
        public static IJEnumerable<JToken> Descendants<[System.Runtime.CompilerServices.Nullable(0)] T>(this IEnumerable<T> source) where T : JContainer
        {
            ValidationUtils.ArgumentNotNull(source, "source");
            return source.SelectMany((T j) => j.Descendants()).AsJEnumerable();
        }
        public static IJEnumerable<JToken> DescendantsAndSelf<[System.Runtime.CompilerServices.Nullable(0)] T>(this IEnumerable<T> source) where T : JContainer
        {
            ValidationUtils.ArgumentNotNull(source, "source");
            return source.SelectMany((T j) => j.DescendantsAndSelf()).AsJEnumerable();
        }
        public static IJEnumerable<JProperty> Properties(this IEnumerable<JObject> source)
        {
            ValidationUtils.ArgumentNotNull(source, "source");
            return source.SelectMany((JObject d) => d.Properties()).AsJEnumerable();
        }
        public static IJEnumerable<JToken> Values(this IEnumerable<JToken> source, [System.Runtime.CompilerServices.Nullable(2)] object key)
        {
            return source.Values<JToken, JToken>(key).AsJEnumerable();
        }
        public static IJEnumerable<JToken> Values(this IEnumerable<JToken> source)
        {
            return source.Values(null);
        }
        [return: System.Runtime.CompilerServices.Nullable(new byte[] {
            1,
            2
        })]
        public static IEnumerable<U> Values<[System.Runtime.CompilerServices.Nullable(2)] U>(this IEnumerable<JToken> source, object key)
        {
            return source.Values<JToken, U>(key);
        }
        [return: System.Runtime.CompilerServices.Nullable(new byte[] {
            1,
            2
        })]
        public static IEnumerable<U> Values<[System.Runtime.CompilerServices.Nullable(2)] U>(this IEnumerable<JToken> source)
        {
            return source.Values<JToken, U>(null);
        }
        [System.Runtime.CompilerServices.NullableContext(2)]
        public static U Value<U>([System.Runtime.CompilerServices.Nullable(1)] this IEnumerable<JToken> value)
        {
            return value.Value<JToken, U>();
        }
        [return: System.Runtime.CompilerServices.Nullable(2)]
        public static U Value<[System.Runtime.CompilerServices.Nullable(0)] T, [System.Runtime.CompilerServices.Nullable(2)] U>(this IEnumerable<T> value) where T : JToken
        {
            ValidationUtils.ArgumentNotNull(value, "value");
            JToken obj = value as JToken;
            if (obj == null)
                throw new ArgumentException("Source value must be a JToken.");
            return obj.Convert<JToken, U>();
        }
        [return: System.Runtime.CompilerServices.Nullable(new byte[] {
            1,
            2
        })]
        internal static IEnumerable<U> Values<[System.Runtime.CompilerServices.Nullable(0)] T, [System.Runtime.CompilerServices.Nullable(2)] U>(this IEnumerable<T> source, [System.Runtime.CompilerServices.Nullable(2)] object key) where T : JToken
        {
            ValidationUtils.ArgumentNotNull(source, "source");
            if (key == null) {
                foreach (T item in source) {
                    JValue jValue = item as JValue;
                    if (jValue != null)
                        yield return Extensions.Convert<JValue, U>(jValue);
                    else {
                        foreach (JToken item2 in item.Children()) {
                            yield return Extensions.Convert<JToken, U>(item2);
                        }
                    }
                }
            } else {
                foreach (T item3 in source) {
                    JToken jToken = item3[key];
                    if (jToken != null)
                        yield return Extensions.Convert<JToken, U>(jToken);
                }
            }
        }
        public static IJEnumerable<JToken> Children<[System.Runtime.CompilerServices.Nullable(0)] T>(this IEnumerable<T> source) where T : JToken
        {
            return source.Children<T, JToken>().AsJEnumerable();
        }
        [return: System.Runtime.CompilerServices.Nullable(new byte[] {
            1,
            2
        })]
        public static IEnumerable<U> Children<[System.Runtime.CompilerServices.Nullable(0)] T, [System.Runtime.CompilerServices.Nullable(2)] U>(this IEnumerable<T> source) where T : JToken
        {
            ValidationUtils.ArgumentNotNull(source, "source");
            return source.SelectMany((T c) => c.Children()).Convert<JToken, U>();
        }
        [return: System.Runtime.CompilerServices.Nullable(new byte[] {
            1,
            2
        })]
        internal static IEnumerable<U> Convert<[System.Runtime.CompilerServices.Nullable(0)] T, [System.Runtime.CompilerServices.Nullable(2)] U>(this IEnumerable<T> source) where T : JToken
        {
            ValidationUtils.ArgumentNotNull(source, "source");
            foreach (T item in source) {
                yield return Extensions.Convert<JToken, U>((JToken)item);
            }
        }
        [System.Runtime.CompilerServices.NullableContext(2)]
        internal static U Convert<[System.Runtime.CompilerServices.Nullable(0)] T, U>([System.Runtime.CompilerServices.Nullable(1)] this T token) where T : JToken
        {
            if (token == null)
                return default(U);
            if (token is U) {
                U result = token as U;
                if (typeof(U) != typeof(IComparable) && typeof(U) != typeof(IFormattable))
                    return result;
            }
            JValue jValue = token as JValue;
            if (jValue == null)
                throw new InvalidCastException("Cannot cast {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, token.GetType(), typeof(T)));
            object value = jValue.Value;
            if (value is U)
                return (U)value;
            Type type = typeof(U);
            if (ReflectionUtils.IsNullableType(type)) {
                if (jValue.Value == null)
                    return default(U);
                type = Nullable.GetUnderlyingType(type);
            }
            return (U)System.Convert.ChangeType(jValue.Value, type, CultureInfo.InvariantCulture);
        }
        public static IJEnumerable<JToken> AsJEnumerable(this IEnumerable<JToken> source)
        {
            return source.AsJEnumerable<JToken>();
        }
        public static IJEnumerable<T> AsJEnumerable<[System.Runtime.CompilerServices.Nullable(0)] T>(this IEnumerable<T> source) where T : JToken
        {
            if (source == null)
                return null;
            IJEnumerable<T> iJEnumerable = source as IJEnumerable<T>;
            if (iJEnumerable != null)
                return iJEnumerable;
            return new JEnumerable<T>(source);
        }
    }
}