BooleanQueryExpression
using Newtonsoft.Json.Utilities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
namespace Newtonsoft.Json.Linq.JsonPath
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    [System.Runtime.CompilerServices.Nullable(0)]
    internal class BooleanQueryExpression : QueryExpression
    {
        public readonly object Left;
        [System.Runtime.CompilerServices.Nullable(2)]
        public readonly object Right;
        public BooleanQueryExpression(QueryOperator operator, object left, [System.Runtime.CompilerServices.Nullable(2)] object right)
            : base(operator)
        {
            Left = left;
            Right = right;
        }
        private IEnumerable<JToken> GetResult(JToken root, JToken t, [System.Runtime.CompilerServices.Nullable(2)] object o)
        {
            JToken jToken = o as JToken;
            if (jToken != null)
                return new JToken[1] {
                    jToken
                };
            List<PathFilter> list = o as List<PathFilter>;
            if (list != null)
                return JPath.Evaluate(list, root, t, false);
            return CollectionUtils.ArrayEmpty<JToken>();
        }
        public override bool IsMatch(JToken root, JToken t)
        {
            if (Operator == QueryOperator.Exists)
                return GetResult(root, t, Left).Any();
            using (IEnumerator<JToken> enumerator = GetResult(root, t, Left).GetEnumerator()) {
                if (enumerator.MoveNext()) {
                    IEnumerable<JToken> result = GetResult(root, t, Right);
                    ICollection<JToken> collection = (result as ICollection<JToken>) ?? result.ToList();
                    do {
                        JToken current = enumerator.Current;
                        foreach (JToken item in collection) {
                            if (MatchTokens(current, item))
                                return true;
                        }
                    } while (enumerator.MoveNext());
                }
            }
            return false;
        }
        private bool MatchTokens(JToken leftResult, JToken rightResult)
        {
            JValue jValue = leftResult as JValue;
            if (jValue != null) {
                JValue jValue2 = rightResult as JValue;
                if (jValue2 != null) {
                    switch (Operator) {
                    case QueryOperator.RegexEquals:
                        if (RegexEquals(jValue, jValue2))
                            return true;
                        break;
                    case QueryOperator.Equals:
                        if (EqualsWithStringCoercion(jValue, jValue2))
                            return true;
                        break;
                    case QueryOperator.StrictEquals:
                        if (EqualsWithStrictMatch(jValue, jValue2))
                            return true;
                        break;
                    case QueryOperator.NotEquals:
                        if (!EqualsWithStringCoercion(jValue, jValue2))
                            return true;
                        break;
                    case QueryOperator.StrictNotEquals:
                        if (!EqualsWithStrictMatch(jValue, jValue2))
                            return true;
                        break;
                    case QueryOperator.GreaterThan:
                        if (jValue.CompareTo(jValue2) > 0)
                            return true;
                        break;
                    case QueryOperator.GreaterThanOrEquals:
                        if (jValue.CompareTo(jValue2) >= 0)
                            return true;
                        break;
                    case QueryOperator.LessThan:
                        if (jValue.CompareTo(jValue2) < 0)
                            return true;
                        break;
                    case QueryOperator.LessThanOrEquals:
                        if (jValue.CompareTo(jValue2) <= 0)
                            return true;
                        break;
                    case QueryOperator.Exists:
                        return true;
                    }
                    goto IL_00d3;
                }
            }
            QueryOperator operator = Operator;
            if ((uint)(operator - 2) <= 1)
                return true;
            goto IL_00d3;
            IL_00d3:
            return false;
        }
        private static bool RegexEquals(JValue input, JValue pattern)
        {
            if (input.Type != JTokenType.String || pattern.Type != JTokenType.String)
                return false;
            string obj = (string)pattern.Value;
            int num = obj.LastIndexOf('/');
            string pattern2 = obj.Substring(1, num - 1);
            string optionsText = obj.Substring(num + 1);
            return Regex.IsMatch((string)input.Value, pattern2, MiscellaneousUtils.GetRegexOptions(optionsText));
        }
        internal static bool EqualsWithStringCoercion(JValue value, JValue queryValue)
        {
            if (value.Equals(queryValue))
                return true;
            if ((value.Type == JTokenType.Integer && queryValue.Type == JTokenType.Float) || (value.Type == JTokenType.Float && queryValue.Type == JTokenType.Integer))
                return JValue.Compare(value.Type, value.Value, queryValue.Value) == 0;
            if (queryValue.Type != JTokenType.String)
                return false;
            string b = (string)queryValue.Value;
            string a = default(string);
            switch (value.Type) {
            case JTokenType.Date:
                using (StringWriter stringWriter = StringUtils.CreateStringWriter(64)) {
                    object value2 = value.Value;
                    if (value2 is DateTimeOffset) {
                        DateTimeOffset value3 = (DateTimeOffset)value2;
                        DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value3, DateFormatHandling.IsoDateFormat, null, CultureInfo.InvariantCulture);
                    } else
                        DateTimeUtils.WriteDateTimeString(stringWriter, (DateTime)value.Value, DateFormatHandling.IsoDateFormat, null, CultureInfo.InvariantCulture);
                    a = stringWriter.ToString();
                }
                break;
            case JTokenType.Bytes:
                a = Convert.ToBase64String((byte[])value.Value);
                break;
            case JTokenType.Guid:
            case JTokenType.TimeSpan:
                a = value.Value.ToString();
                break;
            case JTokenType.Uri:
                a = ((Uri)value.Value).OriginalString;
                break;
            default:
                return false;
            }
            return string.Equals(a, b, StringComparison.Ordinal);
        }
        internal static bool EqualsWithStrictMatch(JValue value, JValue queryValue)
        {
            if ((value.Type == JTokenType.Integer && queryValue.Type == JTokenType.Float) || (value.Type == JTokenType.Float && queryValue.Type == JTokenType.Integer))
                return JValue.Compare(value.Type, value.Value, queryValue.Value) == 0;
            if (value.Type != queryValue.Type)
                return false;
            return value.Equals(queryValue);
        }
    }
}