| 
					
				 | 
			
			
				@@ -64,6 +64,8 @@ namespace InABox.Core 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // !!! If updating this list, make sure to update everywhere this list is used! That includes SQLiteProvider, the ToString() functions, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // the FilterExtensions.MatchOperator, but possible otherwhere to; make sure everything is updated. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public enum Operator 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         IsEqualTo, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -84,13 +86,15 @@ namespace InABox.Core 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Not = byte.MaxValue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public enum ListOperator 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Includes, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Excludes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // !!! If updating this list, make sure to update everywhere this list is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // used! That includes SQLiteProvider the FilterConstants.Resolve, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // but possible otherwhere to; make sure everything is updated. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public enum FilterConstant 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Today, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -201,6 +205,52 @@ namespace InABox.Core 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return new FilterConstant[] { }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public static object? Resolve(this FilterConstant constant, Type type) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return constant switch 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.Null => CoreUtils.GetDefault(type), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.Today => DateTime.Today, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.Now => DateTime.Now, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.Zero => CoreUtils.GetDefault(type), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.OneWeekAgo => DateTime.Today.AddDays(-7), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.OneWeekAhead => DateTime.Today.AddDays(7), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.OneMonthAgo => DateTime.Today.AddMonths(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.OneMonthAhead => DateTime.Today.AddMonths(1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.ThreeMonthsAgo => DateTime.Today.AddMonths(-3), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.ThreeMonthsAhead => DateTime.Today.AddMonths(3), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.SixMonthsAgo => DateTime.Today.AddMonths(-6), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.SixMonthsAhead => DateTime.Today.AddMonths(6), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.OneYearAgo => DateTime.Today.AddYears(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.OneYearAhead => DateTime.Today.AddYears(1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.StartOfLastWeek => DateTime.Today.StartOfWeek(DayOfWeek.Monday).AddDays(-7), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.EndOfLastWeek => DateTime.Today.StartOfWeek(DayOfWeek.Monday).AddTicks(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.StartOfThisWeek => DateTime.Today.StartOfWeek(DayOfWeek.Monday), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.EndOfThisWeek => DateTime.Today.StartOfWeek(DayOfWeek.Monday).AddDays(7).AddTicks(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.StartOfNextWeek => DateTime.Today.StartOfWeek(DayOfWeek.Monday).AddDays(7), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.EndOfNextWeek => DateTime.Today.StartOfWeek(DayOfWeek.Monday).AddDays(14).AddTicks(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.StartOfLastMonth => DateTime.Today.StartOfMonth().AddMonths(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.EndOfLastMonth => DateTime.Today.StartOfMonth().AddTicks(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.StartOfThisMonth => DateTime.Today.StartOfMonth(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.EndOfThisMonth => DateTime.Today.StartOfMonth().AddMonths(1).AddTicks(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.StartOfNextMonth => DateTime.Today.StartOfMonth().AddMonths(1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.EndOfNextMonth => DateTime.Today.StartOfMonth().AddMonths(2).AddTicks(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.StartOfLastCalendarYear => DateTime.Today.StartOfYear().AddYears(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.EndOfLastCalendarYear => DateTime.Today.StartOfYear().AddTicks(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.StartOfThisCalendarYear => DateTime.Today.StartOfYear(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.EndOfThisCalendarYear => DateTime.Today.StartOfYear().AddYears(1).AddTicks(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.StartOfNextCalendarYear => DateTime.Today.StartOfYear().AddYears(1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.EndOfNextCalendarYear => DateTime.Today.StartOfYear().AddYears(2).AddTicks(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.StartOfLastFinancialYear => DateTime.Today.AddMonths(6).StartOfYear().AddMonths(-18), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.EndOfLastFinancialYear => DateTime.Today.AddMonths(6).StartOfYear().AddMonths(-6).AddTicks(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.StartOfThisFinancialYear => DateTime.Today.AddMonths(6).StartOfYear().AddMonths(-6), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.EndOfThisFinancialYear => DateTime.Today.AddMonths(6).StartOfYear().AddMonths(6).AddTicks(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.StartOfNextFinancialYear => DateTime.Today.AddMonths(6).StartOfYear().AddMonths(6), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                FilterConstant.EndOfNextFinancialYear => DateTime.Today.AddMonths(6).StartOfYear().AddMonths(18).AddTicks(-1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                _ => throw new Exception($"Cannot handle {constant}!"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public class CustomFilterValue 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -228,7 +278,13 @@ namespace InABox.Core 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         bool IsNot { get; set; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// List of filters to apply to the main filter with boolean operator AND. The <see cref="Ands"/> take precedence over the <see cref="Ors"/>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         IEnumerable<IFilter> Ands { get; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// List of filters to apply to the main filter with boolean operator OR. The <see cref="Ands"/> take precedence over the <see cref="Ors"/>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         IEnumerable<IFilter> Ors { get; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public IFilter And(IFilter filter); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -378,11 +434,6 @@ namespace InABox.Core 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public static Filter<T> None<T>() => new Filter<T>().None(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public interface IFilter2<T> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public class Filter<T> : IFilter 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public Type Type => PropertyDefinition?.PropertyType ?? typeof(object); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -425,8 +476,14 @@ namespace InABox.Core 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				          
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public Filter<T>? Parent { get; set; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// List of filters to apply to the main filter with boolean operator AND. The <see cref="Ands"/> take precedence over the <see cref="Ors"/>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public List<Filter<T>> Ands { get; private set; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// List of filters to apply to the main filter with boolean operator OR. The <see cref="Ands"/> take precedence over the <see cref="Ors"/>. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public List<Filter<T>> Ors { get; private set; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         public Operator Operator { get; set; } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1901,6 +1958,129 @@ namespace InABox.Core 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return filter1.And(filter2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private static object? Encode(Type T, object? value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(T == typeof(string) && Equals(value, null)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private static bool MatchOperator<T>(this Filter<T> filter, T obj, IQueryProviderFactory query) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(filter.Operator == Operator.All) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else if(filter.Operator == Operator.None) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (filter.PropertyDefinition is null) return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(filter.Value is CustomFilterValue) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                throw new Exception("Custom Filter Value not able to be processed!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var valueType = filter.PropertyDefinition.PropertyType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var objValue = Encode(valueType, filter.PropertyDefinition.Getter()(obj)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(filter.Operator == Operator.InList || filter.Operator == Operator.NotInList) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if(filter.Value is Array arr && arr.Length == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return filter.Operator != Operator.InList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else if(filter.Value is IEnumerable enumerable) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    foreach(var item in enumerable) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        if (Equals(Encode(valueType, item), objValue)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            return filter.Operator == Operator.InList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return filter.Operator == Operator.NotInList; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else if(filter.Operator == Operator.InQuery || filter.Operator == Operator.NotInQuery) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if(filter.Value is ISubQuery subQuery) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var result = query.Create(subQuery.GetQueryType()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var subFilter = Filter.Create(subQuery.GetQueryType(), subQuery.GetColumn().Name, Operator.IsEqualTo, objValue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if(subQuery.GetFilter() is IFilter subQueryFilter) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        subFilter.And(subQueryFilter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var inQuery = result.Query(subFilter, Columns.None(subQuery.GetQueryType())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        .Rows.Count > 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return inQuery ? filter.Operator == Operator.InQuery : filter.Operator == Operator.NotInQuery; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                object? value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if(filter.Value is FilterConstant constant) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    value = constant.Resolve(filter.PropertyDefinition.PropertyType); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    value = filter.Value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                value = Encode(filter.PropertyDefinition.PropertyType, value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return filter.Operator switch 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Operator.IsEqualTo => Equals(objValue, value), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Operator.IsNotEqualTo => !Equals(objValue, value), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Operator.IsGreaterThan => TryCompare(objValue, value, out var comparison) && comparison > 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Operator.IsGreaterThanOrEqualTo => TryCompare(objValue, value, out var comparison) && comparison >= 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Operator.IsLessThan => TryCompare(objValue, value, out var comparison) && comparison < 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Operator.IsLessThanOrEqualTo => TryCompare(objValue, value, out var comparison) && comparison <= 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Operator.BeginsWith => (objValue?.ToString() ?? "").StartsWith(value?.ToString() ?? ""), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Operator.Contains => (objValue?.ToString() ?? "").Contains(value?.ToString() ?? ""), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Operator.EndsWith => (objValue?.ToString() ?? "").EndsWith(value?.ToString() ?? ""), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    _ => throw new Exception($"Invalid operator {filter.Operator}"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private static bool MatchFilter<T>(this Filter<T> filter, T obj, IQueryProviderFactory query) => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            filter.IsNot ? !filter.MatchOperator(obj, query) : filter.MatchOperator(obj, query); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private static bool TryCompare(object? a, object? b, out int result) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            try 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                result = Comparer.Default.Compare(a, b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            catch (ArgumentException) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                result = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// Check if <paramref name="obj"/> matches this filter; that is, that the operators return true. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// <param name="query">The query provider used to evaluate <see cref="Operator.InQuery"/> filters.</param> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public static bool Match<T>(this Filter<T>? filter, T obj, IQueryProviderFactory query) => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            filter is null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            || (filter.MatchFilter(obj, query) && filter.Ands.All(x => x.Match(obj, query))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            || filter.Ors.Any(x => x.Match(obj, query)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public class FilterJsonConverter : JsonConverter 
			 |