Decompiled source of TextureSwapper v1.2.0

Microsoft.CSharp.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security;
using System.Text;
using System.Threading;
using FxResources.Microsoft.CSharp;
using Microsoft.CSharp.RuntimeBinder.Errors;
using Microsoft.CSharp.RuntimeBinder.Semantics;
using Microsoft.CSharp.RuntimeBinder.Syntax;
using Microsoft.CodeAnalysis;

[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyDefaultAlias("Microsoft.CSharp")]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("Microsoft.CSharp")]
[assembly: AssemblyFileVersion("4.700.19.56404")]
[assembly: AssemblyInformationalVersion("3.1.0+0f7f38c4fd323b26da10cce95f857f77f0f09b48")]
[assembly: AssemblyProduct("Microsoft® .NET Core")]
[assembly: AssemblyTitle("Microsoft.CSharp")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyVersion("4.0.5.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[Microsoft.CodeAnalysis.Embedded]
	[CompilerGenerated]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}
namespace FxResources.Microsoft.CSharp
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR)));

		internal static string InternalCompilerError => GetResourceString("InternalCompilerError");

		internal static string BindPropertyFailedMethodGroup => GetResourceString("BindPropertyFailedMethodGroup");

		internal static string BindPropertyFailedEvent => GetResourceString("BindPropertyFailedEvent");

		internal static string BindInvokeFailedNonDelegate => GetResourceString("BindInvokeFailedNonDelegate");

		internal static string NullReferenceOnMemberException => GetResourceString("NullReferenceOnMemberException");

		internal static string BindCallToConditionalMethod => GetResourceString("BindCallToConditionalMethod");

		internal static string BindToVoidMethodButExpectResult => GetResourceString("BindToVoidMethodButExpectResult");

		internal static string EmptyDynamicView => GetResourceString("EmptyDynamicView");

		internal static string GetValueonWriteOnlyProperty => GetResourceString("GetValueonWriteOnlyProperty");

		internal static string BadBinaryOps => GetResourceString("BadBinaryOps");

		internal static string BadIndexLHS => GetResourceString("BadIndexLHS");

		internal static string BadIndexCount => GetResourceString("BadIndexCount");

		internal static string BadUnaryOp => GetResourceString("BadUnaryOp");

		internal static string NoImplicitConv => GetResourceString("NoImplicitConv");

		internal static string NoExplicitConv => GetResourceString("NoExplicitConv");

		internal static string ConstOutOfRange => GetResourceString("ConstOutOfRange");

		internal static string AmbigBinaryOps => GetResourceString("AmbigBinaryOps");

		internal static string AmbigUnaryOp => GetResourceString("AmbigUnaryOp");

		internal static string ValueCantBeNull => GetResourceString("ValueCantBeNull");

		internal static string NoSuchMember => GetResourceString("NoSuchMember");

		internal static string ObjectRequired => GetResourceString("ObjectRequired");

		internal static string AmbigCall => GetResourceString("AmbigCall");

		internal static string BadAccess => GetResourceString("BadAccess");

		internal static string AssgLvalueExpected => GetResourceString("AssgLvalueExpected");

		internal static string NoConstructors => GetResourceString("NoConstructors");

		internal static string PropertyLacksGet => GetResourceString("PropertyLacksGet");

		internal static string ObjectProhibited => GetResourceString("ObjectProhibited");

		internal static string AssgReadonly => GetResourceString("AssgReadonly");

		internal static string AssgReadonlyStatic => GetResourceString("AssgReadonlyStatic");

		internal static string AssgReadonlyProp => GetResourceString("AssgReadonlyProp");

		internal static string UnsafeNeeded => GetResourceString("UnsafeNeeded");

		internal static string BadBoolOp => GetResourceString("BadBoolOp");

		internal static string MustHaveOpTF => GetResourceString("MustHaveOpTF");

		internal static string ConstOutOfRangeChecked => GetResourceString("ConstOutOfRangeChecked");

		internal static string AmbigMember => GetResourceString("AmbigMember");

		internal static string NoImplicitConvCast => GetResourceString("NoImplicitConvCast");

		internal static string InaccessibleGetter => GetResourceString("InaccessibleGetter");

		internal static string InaccessibleSetter => GetResourceString("InaccessibleSetter");

		internal static string BadArity => GetResourceString("BadArity");

		internal static string TypeArgsNotAllowed => GetResourceString("TypeArgsNotAllowed");

		internal static string HasNoTypeVars => GetResourceString("HasNoTypeVars");

		internal static string NewConstraintNotSatisfied => GetResourceString("NewConstraintNotSatisfied");

		internal static string GenericConstraintNotSatisfiedRefType => GetResourceString("GenericConstraintNotSatisfiedRefType");

		internal static string GenericConstraintNotSatisfiedNullableEnum => GetResourceString("GenericConstraintNotSatisfiedNullableEnum");

		internal static string GenericConstraintNotSatisfiedNullableInterface => GetResourceString("GenericConstraintNotSatisfiedNullableInterface");

		internal static string GenericConstraintNotSatisfiedValType => GetResourceString("GenericConstraintNotSatisfiedValType");

		internal static string CantInferMethTypeArgs => GetResourceString("CantInferMethTypeArgs");

		internal static string RefConstraintNotSatisfied => GetResourceString("RefConstraintNotSatisfied");

		internal static string ValConstraintNotSatisfied => GetResourceString("ValConstraintNotSatisfied");

		internal static string AmbigUDConv => GetResourceString("AmbigUDConv");

		internal static string BindToBogus => GetResourceString("BindToBogus");

		internal static string CantCallSpecialMethod => GetResourceString("CantCallSpecialMethod");

		internal static string ConvertToStaticClass => GetResourceString("ConvertToStaticClass");

		internal static string IncrementLvalueExpected => GetResourceString("IncrementLvalueExpected");

		internal static string BadArgCount => GetResourceString("BadArgCount");

		internal static string BadArgTypes => GetResourceString("BadArgTypes");

		internal static string BadProtectedAccess => GetResourceString("BadProtectedAccess");

		internal static string BindToBogusProp2 => GetResourceString("BindToBogusProp2");

		internal static string BindToBogusProp1 => GetResourceString("BindToBogusProp1");

		internal static string BadDelArgCount => GetResourceString("BadDelArgCount");

		internal static string BadDelArgTypes => GetResourceString("BadDelArgTypes");

		internal static string BadCtorArgCount => GetResourceString("BadCtorArgCount");

		internal static string NonInvocableMemberCalled => GetResourceString("NonInvocableMemberCalled");

		internal static string BadNamedArgument => GetResourceString("BadNamedArgument");

		internal static string BadNamedArgumentForDelegateInvoke => GetResourceString("BadNamedArgumentForDelegateInvoke");

		internal static string DuplicateNamedArgument => GetResourceString("DuplicateNamedArgument");

		internal static string NamedArgumentUsedInPositional => GetResourceString("NamedArgumentUsedInPositional");

		internal static string TypeArgumentRequiredForStaticCall => GetResourceString("TypeArgumentRequiredForStaticCall");

		internal static string DynamicArgumentNeedsValue => GetResourceString("DynamicArgumentNeedsValue");

		internal static string BadNonTrailingNamedArgument => GetResourceString("BadNonTrailingNamedArgument");

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString = null)
		{
			if (UsingResourceKeys())
			{
				return defaultString ?? resourceKey;
			}
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text))
			{
				return defaultString;
			}
			return text;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}
	}
}
namespace System.Numerics.Hashing
{
	internal static class HashHelpers
	{
		public static readonly int RandomSeed = new Random().Next(int.MinValue, int.MaxValue);

		public static int Combine(int h1, int h2)
		{
			uint num = (uint)(h1 << 5) | ((uint)h1 >> 27);
			return ((int)num + h1) ^ h2;
		}
	}
}
namespace Microsoft.CSharp.RuntimeBinder
{
	internal readonly struct ArgumentObject
	{
		internal readonly object Value;

		internal readonly CSharpArgumentInfo Info;

		internal readonly Type Type;

		public ArgumentObject(object value, CSharpArgumentInfo info, Type type)
		{
			Value = value;
			Info = info;
			Type = type;
		}
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	public static class Binder
	{
		public static CallSiteBinder BinaryOperation(CSharpBinderFlags flags, ExpressionType operation, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
		{
			bool isChecked = (flags & CSharpBinderFlags.CheckedContext) != 0;
			bool flag = (flags & CSharpBinderFlags.BinaryOperationLogical) != 0;
			CSharpBinaryOperationFlags cSharpBinaryOperationFlags = CSharpBinaryOperationFlags.None;
			if (flag)
			{
				cSharpBinaryOperationFlags |= CSharpBinaryOperationFlags.LogicalOperation;
			}
			return new CSharpBinaryOperationBinder(operation, isChecked, cSharpBinaryOperationFlags, context, argumentInfo).TryGetExisting();
		}

		public static CallSiteBinder Convert(CSharpBinderFlags flags, Type type, Type context)
		{
			CSharpConversionKind conversionKind = (((flags & CSharpBinderFlags.ConvertExplicit) != 0) ? CSharpConversionKind.ExplicitConversion : (((flags & CSharpBinderFlags.ConvertArrayIndex) != 0) ? CSharpConversionKind.ArrayCreationConversion : CSharpConversionKind.ImplicitConversion));
			bool isChecked = (flags & CSharpBinderFlags.CheckedContext) != 0;
			return new CSharpConvertBinder(type, conversionKind, isChecked, context).TryGetExisting();
		}

		public static CallSiteBinder GetIndex(CSharpBinderFlags flags, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
		{
			return new CSharpGetIndexBinder(context, argumentInfo).TryGetExisting();
		}

		public static CallSiteBinder GetMember(CSharpBinderFlags flags, string name, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
		{
			bool resultIndexed = (flags & CSharpBinderFlags.ResultIndexed) != 0;
			return new CSharpGetMemberBinder(name, resultIndexed, context, argumentInfo).TryGetExisting();
		}

		public static CallSiteBinder Invoke(CSharpBinderFlags flags, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
		{
			bool flag = (flags & CSharpBinderFlags.ResultDiscarded) != 0;
			CSharpCallFlags cSharpCallFlags = CSharpCallFlags.None;
			if (flag)
			{
				cSharpCallFlags |= CSharpCallFlags.ResultDiscarded;
			}
			return new CSharpInvokeBinder(cSharpCallFlags, context, argumentInfo).TryGetExisting();
		}

		public static CallSiteBinder InvokeMember(CSharpBinderFlags flags, string name, IEnumerable<Type> typeArguments, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
		{
			bool flag = (flags & CSharpBinderFlags.InvokeSimpleName) != 0;
			bool flag2 = (flags & CSharpBinderFlags.InvokeSpecialName) != 0;
			bool flag3 = (flags & CSharpBinderFlags.ResultDiscarded) != 0;
			CSharpCallFlags cSharpCallFlags = CSharpCallFlags.None;
			if (flag)
			{
				cSharpCallFlags |= CSharpCallFlags.SimpleNameCall;
			}
			if (flag2)
			{
				cSharpCallFlags |= CSharpCallFlags.EventHookup;
			}
			if (flag3)
			{
				cSharpCallFlags |= CSharpCallFlags.ResultDiscarded;
			}
			return new CSharpInvokeMemberBinder(cSharpCallFlags, name, context, typeArguments, argumentInfo).TryGetExisting();
		}

		public static CallSiteBinder InvokeConstructor(CSharpBinderFlags flags, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
		{
			return new CSharpInvokeConstructorBinder(CSharpCallFlags.None, context, argumentInfo).TryGetExisting();
		}

		public static CallSiteBinder IsEvent(CSharpBinderFlags flags, string name, Type context)
		{
			return new CSharpIsEventBinder(name, context).TryGetExisting();
		}

		public static CallSiteBinder SetIndex(CSharpBinderFlags flags, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
		{
			bool isCompoundAssignment = (flags & CSharpBinderFlags.ValueFromCompoundAssignment) != 0;
			bool isChecked = (flags & CSharpBinderFlags.CheckedContext) != 0;
			return new CSharpSetIndexBinder(isCompoundAssignment, isChecked, context, argumentInfo).TryGetExisting();
		}

		public static CallSiteBinder SetMember(CSharpBinderFlags flags, string name, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
		{
			bool isCompoundAssignment = (flags & CSharpBinderFlags.ValueFromCompoundAssignment) != 0;
			bool isChecked = (flags & CSharpBinderFlags.CheckedContext) != 0;
			return new CSharpSetMemberBinder(name, isCompoundAssignment, isChecked, context, argumentInfo).TryGetExisting();
		}

		public static CallSiteBinder UnaryOperation(CSharpBinderFlags flags, ExpressionType operation, Type context, IEnumerable<CSharpArgumentInfo> argumentInfo)
		{
			bool isChecked = (flags & CSharpBinderFlags.CheckedContext) != 0;
			return new CSharpUnaryOperationBinder(operation, isChecked, context, argumentInfo).TryGetExisting();
		}
	}
	internal static class BinderEquivalence
	{
		internal class BinderEqualityComparer : IEqualityComparer<ICSharpBinder>
		{
			public bool Equals(ICSharpBinder x, ICSharpBinder y)
			{
				return x.IsEquivalentTo(y);
			}

			public int GetHashCode(ICSharpBinder obj)
			{
				return obj.GetGetBinderEquivalenceHash();
			}
		}

		private static int cachedBinderCount;

		private static readonly ConcurrentDictionary<ICSharpBinder, ICSharpBinder> binderEquivalenceCache = new ConcurrentDictionary<ICSharpBinder, ICSharpBinder>(2, 32, new BinderEqualityComparer());

		internal static T TryGetExisting<T>(this T binder) where T : ICSharpBinder
		{
			ICSharpBinder orAdd = binderEquivalenceCache.GetOrAdd(binder, binder);
			if (orAdd == (object)binder)
			{
				int num = Interlocked.Increment(ref cachedBinderCount);
				if ((uint)num > 4096u)
				{
					binderEquivalenceCache.Clear();
					cachedBinderCount = 0;
				}
			}
			return (T)orAdd;
		}
	}
	internal static class BinderHelper
	{
		private static MethodInfo s_DoubleIsNaN;

		private static MethodInfo s_SingleIsNaN;

		internal static DynamicMetaObject Bind(ICSharpBinder action, RuntimeBinder binder, DynamicMetaObject[] args, IEnumerable<CSharpArgumentInfo> arginfos, DynamicMetaObject onBindingError)
		{
			Expression[] array = new Expression[args.Length];
			BindingRestrictions bindingRestrictions = BindingRestrictions.Empty;
			ICSharpInvokeOrInvokeMemberBinder callPayload = action as ICSharpInvokeOrInvokeMemberBinder;
			ParameterExpression parameterExpression = null;
			IEnumerator<CSharpArgumentInfo> enumerator = (arginfos ?? Array.Empty<CSharpArgumentInfo>()).GetEnumerator();
			for (int i = 0; i < args.Length; i++)
			{
				DynamicMetaObject dynamicMetaObject = args[i];
				CSharpArgumentInfo cSharpArgumentInfo = (enumerator.MoveNext() ? enumerator.Current : null);
				if (i == 0 && IsIncrementOrDecrementActionOnLocal(action))
				{
					object value = dynamicMetaObject.Value;
					parameterExpression = (ParameterExpression)(array[0] = Expression.Variable((value != null) ? value.GetType() : typeof(object), "t0"));
				}
				else
				{
					array[i] = dynamicMetaObject.Expression;
				}
				BindingRestrictions restrictions = DeduceArgumentRestriction(i, callPayload, dynamicMetaObject, cSharpArgumentInfo);
				bindingRestrictions = bindingRestrictions.Merge(restrictions);
				if (cSharpArgumentInfo != null && cSharpArgumentInfo.LiteralConstant)
				{
					if (dynamicMetaObject.Value is double && double.IsNaN((double)dynamicMetaObject.Value))
					{
						MethodInfo method = s_DoubleIsNaN ?? (s_DoubleIsNaN = typeof(double).GetMethod("IsNaN"));
						Expression expression = Expression.Call(null, method, dynamicMetaObject.Expression);
						bindingRestrictions = bindingRestrictions.Merge(BindingRestrictions.GetExpressionRestriction(expression));
					}
					else if (dynamicMetaObject.Value is float && float.IsNaN((float)dynamicMetaObject.Value))
					{
						MethodInfo method2 = s_SingleIsNaN ?? (s_SingleIsNaN = typeof(float).GetMethod("IsNaN"));
						Expression expression2 = Expression.Call(null, method2, dynamicMetaObject.Expression);
						bindingRestrictions = bindingRestrictions.Merge(BindingRestrictions.GetExpressionRestriction(expression2));
					}
					else
					{
						Expression expression3 = Expression.Equal(dynamicMetaObject.Expression, Expression.Constant(dynamicMetaObject.Value, dynamicMetaObject.Expression.Type));
						restrictions = BindingRestrictions.GetExpressionRestriction(expression3);
						bindingRestrictions = bindingRestrictions.Merge(restrictions);
					}
				}
			}
			try
			{
				Expression expression4 = binder.Bind(action, array, args, out var deferredBinding);
				if (deferredBinding != null)
				{
					expression4 = ConvertResult(deferredBinding.Expression, action);
					bindingRestrictions = deferredBinding.Restrictions.Merge(bindingRestrictions);
					return new DynamicMetaObject(expression4, bindingRestrictions);
				}
				if (parameterExpression != null)
				{
					DynamicMetaObject dynamicMetaObject2 = args[0];
					expression4 = Expression.Block(new ParameterExpression[1] { parameterExpression }, Expression.Assign(parameterExpression, Expression.Convert(dynamicMetaObject2.Expression, dynamicMetaObject2.Value.GetType())), expression4, Expression.Assign(dynamicMetaObject2.Expression, Expression.Convert(parameterExpression, dynamicMetaObject2.Expression.Type)));
				}
				expression4 = ConvertResult(expression4, action);
				return new DynamicMetaObject(expression4, bindingRestrictions);
			}
			catch (RuntimeBinderException ex)
			{
				if (onBindingError != null)
				{
					return onBindingError;
				}
				return new DynamicMetaObject(Expression.Throw(Expression.New(typeof(RuntimeBinderException).GetConstructor(new Type[1] { typeof(string) }), Expression.Constant(ex.Message)), GetTypeForErrorMetaObject(action, args)), bindingRestrictions);
			}
		}

		public static void ValidateBindArgument(DynamicMetaObject argument, string paramName)
		{
			if (argument == null)
			{
				throw Error.ArgumentNull(paramName);
			}
			if (!argument.HasValue)
			{
				throw Error.DynamicArgumentNeedsValue(paramName);
			}
		}

		public static void ValidateBindArgument(DynamicMetaObject[] arguments, string paramName)
		{
			if (arguments != null)
			{
				for (int i = 0; i != arguments.Length; i++)
				{
					ValidateBindArgument(arguments[i], $"{paramName}[{i}]");
				}
			}
		}

		private static bool IsTypeOfStaticCall(int parameterIndex, ICSharpInvokeOrInvokeMemberBinder callPayload)
		{
			if (parameterIndex == 0 && callPayload != null)
			{
				return callPayload.StaticCall;
			}
			return false;
		}

		private static bool IsComObject(object obj)
		{
			if (obj != null)
			{
				return Marshal.IsComObject(obj);
			}
			return false;
		}

		private static bool IsTransparentProxy(object obj)
		{
			return false;
		}

		private static bool IsDynamicallyTypedRuntimeProxy(DynamicMetaObject argument, CSharpArgumentInfo info)
		{
			return info != null && !info.UseCompileTimeType && (IsComObject(argument.Value) || IsTransparentProxy(argument.Value));
		}

		private static BindingRestrictions DeduceArgumentRestriction(int parameterIndex, ICSharpInvokeOrInvokeMemberBinder callPayload, DynamicMetaObject argument, CSharpArgumentInfo info)
		{
			if (argument.Value != null && !IsTypeOfStaticCall(parameterIndex, callPayload) && !IsDynamicallyTypedRuntimeProxy(argument, info))
			{
				return BindingRestrictions.GetTypeRestriction(argument.Expression, argument.RuntimeType);
			}
			return BindingRestrictions.GetInstanceRestriction(argument.Expression, argument.Value);
		}

		private static Expression ConvertResult(Expression binding, ICSharpBinder action)
		{
			if (action is CSharpInvokeConstructorBinder)
			{
				return binding;
			}
			if (binding.Type == typeof(void))
			{
				if (action is ICSharpInvokeOrInvokeMemberBinder iCSharpInvokeOrInvokeMemberBinder && iCSharpInvokeOrInvokeMemberBinder.ResultDiscarded)
				{
					return Expression.Block(binding, Expression.Default(action.ReturnType));
				}
				throw Error.BindToVoidMethodButExpectResult();
			}
			if (binding.Type.IsValueType && !action.ReturnType.IsValueType)
			{
				return Expression.Convert(binding, action.ReturnType);
			}
			return binding;
		}

		private static Type GetTypeForErrorMetaObject(ICSharpBinder action, DynamicMetaObject[] args)
		{
			if (action is CSharpInvokeConstructorBinder)
			{
				return args[0].Value as Type;
			}
			return action.ReturnType;
		}

		private static bool IsIncrementOrDecrementActionOnLocal(ICSharpBinder action)
		{
			if (action is CSharpUnaryOperationBinder cSharpUnaryOperationBinder)
			{
				if (cSharpUnaryOperationBinder.Operation != ExpressionType.Increment)
				{
					return cSharpUnaryOperationBinder.Operation == ExpressionType.Decrement;
				}
				return true;
			}
			return false;
		}

		internal static T[] Cons<T>(T sourceHead, T[] sourceTail)
		{
			if (sourceTail == null || sourceTail.Length != 0)
			{
				T[] array = new T[sourceTail.Length + 1];
				array[0] = sourceHead;
				sourceTail.CopyTo(array, 1);
				return array;
			}
			return new T[1] { sourceHead };
		}

		internal static T[] Cons<T>(T sourceHead, T[] sourceMiddle, T sourceLast)
		{
			if (sourceMiddle == null || sourceMiddle.Length != 0)
			{
				T[] array = new T[sourceMiddle.Length + 2];
				array[0] = sourceHead;
				array[^1] = sourceLast;
				sourceMiddle.CopyTo(array, 1);
				return array;
			}
			return new T[2] { sourceHead, sourceLast };
		}

		internal static T[] ToArray<T>(IEnumerable<T> source)
		{
			if (source != null)
			{
				return source.ToArray();
			}
			return Array.Empty<T>();
		}

		internal static CallInfo CreateCallInfo(ref IEnumerable<CSharpArgumentInfo> argInfos, int discard)
		{
			int num = 0;
			List<string> list = new List<string>();
			CSharpArgumentInfo[] array = (CSharpArgumentInfo[])(argInfos = ToArray(argInfos));
			foreach (CSharpArgumentInfo cSharpArgumentInfo in array)
			{
				if (cSharpArgumentInfo.NamedArgument)
				{
					list.Add(cSharpArgumentInfo.Name);
				}
				num++;
			}
			return new CallInfo(num - discard, list);
		}

		internal static string GetCLROperatorName(this ExpressionType p)
		{
			return p switch
			{
				ExpressionType.Add => "op_Addition", 
				ExpressionType.Subtract => "op_Subtraction", 
				ExpressionType.Multiply => "op_Multiply", 
				ExpressionType.Divide => "op_Division", 
				ExpressionType.Modulo => "op_Modulus", 
				ExpressionType.LeftShift => "op_LeftShift", 
				ExpressionType.RightShift => "op_RightShift", 
				ExpressionType.LessThan => "op_LessThan", 
				ExpressionType.GreaterThan => "op_GreaterThan", 
				ExpressionType.LessThanOrEqual => "op_LessThanOrEqual", 
				ExpressionType.GreaterThanOrEqual => "op_GreaterThanOrEqual", 
				ExpressionType.Equal => "op_Equality", 
				ExpressionType.NotEqual => "op_Inequality", 
				ExpressionType.And => "op_BitwiseAnd", 
				ExpressionType.ExclusiveOr => "op_ExclusiveOr", 
				ExpressionType.Or => "op_BitwiseOr", 
				ExpressionType.AddAssign => "op_Addition", 
				ExpressionType.SubtractAssign => "op_Subtraction", 
				ExpressionType.MultiplyAssign => "op_Multiply", 
				ExpressionType.DivideAssign => "op_Division", 
				ExpressionType.ModuloAssign => "op_Modulus", 
				ExpressionType.AndAssign => "op_BitwiseAnd", 
				ExpressionType.ExclusiveOrAssign => "op_ExclusiveOr", 
				ExpressionType.OrAssign => "op_BitwiseOr", 
				ExpressionType.LeftShiftAssign => "op_LeftShift", 
				ExpressionType.RightShiftAssign => "op_RightShift", 
				ExpressionType.Negate => "op_UnaryNegation", 
				ExpressionType.UnaryPlus => "op_UnaryPlus", 
				ExpressionType.Not => "op_LogicalNot", 
				ExpressionType.OnesComplement => "op_OnesComplement", 
				ExpressionType.IsTrue => "op_True", 
				ExpressionType.IsFalse => "op_False", 
				ExpressionType.Increment => "op_Increment", 
				ExpressionType.Decrement => "op_Decrement", 
				_ => null, 
			};
		}

		internal static int AddArgHashes(int hash, Type[] typeArguments, CSharpArgumentInfo[] argInfos)
		{
			foreach (Type type in typeArguments)
			{
				hash = HashHelpers.Combine(hash, type.GetHashCode());
			}
			return AddArgHashes(hash, argInfos);
		}

		internal static int AddArgHashes(int hash, CSharpArgumentInfo[] argInfos)
		{
			foreach (CSharpArgumentInfo cSharpArgumentInfo in argInfos)
			{
				hash = HashHelpers.Combine(hash, (int)cSharpArgumentInfo.Flags);
				string name = cSharpArgumentInfo.Name;
				if (!string.IsNullOrEmpty(name))
				{
					hash = HashHelpers.Combine(hash, name.GetHashCode());
				}
			}
			return hash;
		}

		internal static bool CompareArgInfos(Type[] typeArgs, Type[] otherTypeArgs, CSharpArgumentInfo[] argInfos, CSharpArgumentInfo[] otherArgInfos)
		{
			for (int i = 0; i < typeArgs.Length; i++)
			{
				if (typeArgs[i] != otherTypeArgs[i])
				{
					return false;
				}
			}
			return CompareArgInfos(argInfos, otherArgInfos);
		}

		internal static bool CompareArgInfos(CSharpArgumentInfo[] argInfos, CSharpArgumentInfo[] otherArgInfos)
		{
			for (int i = 0; i < argInfos.Length; i++)
			{
				CSharpArgumentInfo cSharpArgumentInfo = argInfos[i];
				CSharpArgumentInfo cSharpArgumentInfo2 = otherArgInfos[i];
				if (cSharpArgumentInfo.Flags != cSharpArgumentInfo2.Flags || cSharpArgumentInfo.Name != cSharpArgumentInfo2.Name)
				{
					return false;
				}
			}
			return true;
		}
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	public sealed class CSharpArgumentInfo
	{
		internal static readonly CSharpArgumentInfo None = new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null);

		internal CSharpArgumentInfoFlags Flags { get; }

		internal string Name { get; }

		internal bool UseCompileTimeType => (Flags & CSharpArgumentInfoFlags.UseCompileTimeType) != 0;

		internal bool LiteralConstant => (Flags & CSharpArgumentInfoFlags.Constant) != 0;

		internal bool NamedArgument => (Flags & CSharpArgumentInfoFlags.NamedArgument) != 0;

		internal bool IsByRefOrOut => (Flags & (CSharpArgumentInfoFlags.IsRef | CSharpArgumentInfoFlags.IsOut)) != 0;

		internal bool IsOut => (Flags & CSharpArgumentInfoFlags.IsOut) != 0;

		internal bool IsStaticType => (Flags & CSharpArgumentInfoFlags.IsStaticType) != 0;

		private CSharpArgumentInfo(CSharpArgumentInfoFlags flags, string name)
		{
			Flags = flags;
			Name = name;
		}

		public static CSharpArgumentInfo Create(CSharpArgumentInfoFlags flags, string name)
		{
			return new CSharpArgumentInfo(flags, name);
		}
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[Flags]
	public enum CSharpArgumentInfoFlags
	{
		None = 0,
		UseCompileTimeType = 1,
		Constant = 2,
		NamedArgument = 4,
		IsRef = 8,
		IsOut = 0x10,
		IsStaticType = 0x20
	}
	internal sealed class CSharpBinaryOperationBinder : BinaryOperationBinder, ICSharpBinder
	{
		private readonly CSharpBinaryOperationFlags _binopFlags;

		private readonly CSharpArgumentInfo[] _argumentInfo;

		private readonly RuntimeBinder _binder;

		private readonly Type _callingContext;

		[ExcludeFromCodeCoverage]
		public string Name => null;

		public BindingFlag BindingFlags => (BindingFlag)0;

		public bool IsBinderThatCanHaveRefReceiver => false;

		internal bool IsLogicalOperation => (_binopFlags & CSharpBinaryOperationFlags.LogicalOperation) != 0;

		private bool IsChecked => _binder.IsChecked;

		public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals)
		{
			return runtimeBinder.BindBinaryOperation(this, arguments, locals);
		}

		public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments)
		{
			string cLROperatorName = base.Operation.GetCLROperatorName();
			SymbolTable.PopulateSymbolTableWithName(cLROperatorName, null, arguments[0].Type);
			SymbolTable.PopulateSymbolTableWithName(cLROperatorName, null, arguments[1].Type);
		}

		CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index)
		{
			return _argumentInfo[index];
		}

		public CSharpBinaryOperationBinder(ExpressionType operation, bool isChecked, CSharpBinaryOperationFlags binaryOperationFlags, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
			: base(operation)
		{
			_binopFlags = binaryOperationFlags;
			_callingContext = callingContext;
			_argumentInfo = BinderHelper.ToArray(argumentInfo);
			_binder = new RuntimeBinder(callingContext, isChecked);
		}

		public int GetGetBinderEquivalenceHash()
		{
			int h = _callingContext?.GetHashCode() ?? 0;
			h = HashHelpers.Combine(h, (int)_binopFlags);
			if (IsChecked)
			{
				h = HashHelpers.Combine(h, 1);
			}
			h = HashHelpers.Combine(h, (int)base.Operation);
			return BinderHelper.AddArgHashes(h, _argumentInfo);
		}

		public bool IsEquivalentTo(ICSharpBinder other)
		{
			if (!(other is CSharpBinaryOperationBinder cSharpBinaryOperationBinder))
			{
				return false;
			}
			if (_binopFlags != cSharpBinaryOperationBinder._binopFlags || base.Operation != cSharpBinaryOperationBinder.Operation || IsChecked != cSharpBinaryOperationBinder.IsChecked || _callingContext != cSharpBinaryOperationBinder._callingContext)
			{
				return false;
			}
			return BinderHelper.CompareArgInfos(_argumentInfo, cSharpBinaryOperationBinder._argumentInfo);
		}

		public override DynamicMetaObject FallbackBinaryOperation(DynamicMetaObject target, DynamicMetaObject arg, DynamicMetaObject errorSuggestion)
		{
			BinderHelper.ValidateBindArgument(target, "target");
			BinderHelper.ValidateBindArgument(arg, "arg");
			return BinderHelper.Bind(this, _binder, new DynamicMetaObject[2] { target, arg }, _argumentInfo, errorSuggestion);
		}
	}
	[Flags]
	internal enum CSharpBinaryOperationFlags
	{
		None = 0,
		MemberAccess = 1,
		LogicalOperation = 2
	}
	[Flags]
	[EditorBrowsable(EditorBrowsableState.Never)]
	public enum CSharpBinderFlags
	{
		None = 0,
		CheckedContext = 1,
		InvokeSimpleName = 2,
		InvokeSpecialName = 4,
		BinaryOperationLogical = 8,
		ConvertExplicit = 0x10,
		ConvertArrayIndex = 0x20,
		ResultIndexed = 0x40,
		ValueFromCompoundAssignment = 0x80,
		ResultDiscarded = 0x100
	}
	[Flags]
	internal enum CSharpCallFlags
	{
		None = 0,
		SimpleNameCall = 1,
		EventHookup = 2,
		ResultDiscarded = 4
	}
	internal enum CSharpConversionKind
	{
		ImplicitConversion,
		ExplicitConversion,
		ArrayCreationConversion
	}
	internal sealed class CSharpConvertBinder : ConvertBinder, ICSharpBinder
	{
		private readonly RuntimeBinder _binder;

		private readonly Type _callingContext;

		[ExcludeFromCodeCoverage]
		public string Name => null;

		public BindingFlag BindingFlags => (BindingFlag)0;

		public bool IsBinderThatCanHaveRefReceiver => false;

		private CSharpConversionKind ConversionKind { get; }

		private bool IsChecked => _binder.IsChecked;

		public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals)
		{
			if (!base.Explicit)
			{
				return runtimeBinder.BindImplicitConversion(arguments, base.Type, locals, ConversionKind == CSharpConversionKind.ArrayCreationConversion);
			}
			return runtimeBinder.BindExplicitConversion(arguments, base.Type, locals);
		}

		public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments)
		{
		}

		CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index)
		{
			return CSharpArgumentInfo.None;
		}

		public CSharpConvertBinder(Type type, CSharpConversionKind conversionKind, bool isChecked, Type callingContext)
			: base(type, conversionKind == CSharpConversionKind.ExplicitConversion)
		{
			ConversionKind = conversionKind;
			_callingContext = callingContext;
			_binder = new RuntimeBinder(callingContext, isChecked);
		}

		public int GetGetBinderEquivalenceHash()
		{
			int h = _callingContext?.GetHashCode() ?? 0;
			h = HashHelpers.Combine(h, (int)ConversionKind);
			if (IsChecked)
			{
				h = HashHelpers.Combine(h, 1);
			}
			return HashHelpers.Combine(h, base.Type.GetHashCode());
		}

		public bool IsEquivalentTo(ICSharpBinder other)
		{
			if (!(other is CSharpConvertBinder cSharpConvertBinder))
			{
				return false;
			}
			if (ConversionKind != cSharpConvertBinder.ConversionKind || IsChecked != cSharpConvertBinder.IsChecked || _callingContext != cSharpConvertBinder._callingContext || base.Type != cSharpConvertBinder.Type)
			{
				return false;
			}
			return true;
		}

		public override DynamicMetaObject FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
		{
			BinderHelper.ValidateBindArgument(target, "target");
			return BinderHelper.Bind(this, _binder, new DynamicMetaObject[1] { target }, null, errorSuggestion);
		}
	}
	internal sealed class CSharpGetIndexBinder : GetIndexBinder, ICSharpBinder
	{
		private readonly CSharpArgumentInfo[] _argumentInfo;

		private readonly RuntimeBinder _binder;

		private readonly Type _callingContext;

		public string Name => "$Item$";

		public BindingFlag BindingFlags => BindingFlag.BIND_RVALUEREQUIRED;

		public bool IsBinderThatCanHaveRefReceiver => true;

		public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals)
		{
			Expr optionalIndexerArguments = runtimeBinder.CreateArgumentListEXPR(arguments, locals, 1, arguments.Length);
			return runtimeBinder.BindProperty(this, arguments[0], locals[0], optionalIndexerArguments);
		}

		public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments)
		{
			SymbolTable.PopulateSymbolTableWithName("$Item$", null, arguments[0].Type);
		}

		CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index)
		{
			return _argumentInfo[index];
		}

		public CSharpGetIndexBinder(Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
			: base(BinderHelper.CreateCallInfo(ref argumentInfo, 1))
		{
			_argumentInfo = argumentInfo as CSharpArgumentInfo[];
			_callingContext = callingContext;
			_binder = new RuntimeBinder(callingContext);
		}

		public int GetGetBinderEquivalenceHash()
		{
			int hash = _callingContext?.GetHashCode() ?? 0;
			return BinderHelper.AddArgHashes(hash, _argumentInfo);
		}

		public bool IsEquivalentTo(ICSharpBinder other)
		{
			if (!(other is CSharpGetIndexBinder cSharpGetIndexBinder))
			{
				return false;
			}
			if (_callingContext != cSharpGetIndexBinder._callingContext || _argumentInfo.Length != cSharpGetIndexBinder._argumentInfo.Length)
			{
				return false;
			}
			return BinderHelper.CompareArgInfos(_argumentInfo, cSharpGetIndexBinder._argumentInfo);
		}

		public override DynamicMetaObject FallbackGetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject errorSuggestion)
		{
			BinderHelper.ValidateBindArgument(target, "target");
			BinderHelper.ValidateBindArgument(indexes, "indexes");
			return BinderHelper.Bind(this, _binder, BinderHelper.Cons(target, indexes), _argumentInfo, errorSuggestion);
		}
	}
	internal sealed class CSharpGetMemberBinder : GetMemberBinder, IInvokeOnGetBinder, ICSharpBinder
	{
		private readonly CSharpArgumentInfo[] _argumentInfo;

		private readonly RuntimeBinder _binder;

		private readonly Type _callingContext;

		public BindingFlag BindingFlags => BindingFlag.BIND_RVALUEREQUIRED;

		public bool IsBinderThatCanHaveRefReceiver => false;

		bool IInvokeOnGetBinder.InvokeOnGet => !ResultIndexed;

		private bool ResultIndexed { get; }

		public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals)
		{
			return runtimeBinder.BindProperty(this, arguments[0], locals[0], null);
		}

		public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments)
		{
			SymbolTable.PopulateSymbolTableWithName(base.Name, null, arguments[0].Type);
		}

		CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index)
		{
			return _argumentInfo[index];
		}

		public CSharpGetMemberBinder(string name, bool resultIndexed, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
			: base(name, ignoreCase: false)
		{
			ResultIndexed = resultIndexed;
			_argumentInfo = BinderHelper.ToArray(argumentInfo);
			_callingContext = callingContext;
			_binder = new RuntimeBinder(callingContext);
		}

		public int GetGetBinderEquivalenceHash()
		{
			int h = _callingContext?.GetHashCode() ?? 0;
			if (ResultIndexed)
			{
				h = HashHelpers.Combine(h, 1);
			}
			h = HashHelpers.Combine(h, base.Name.GetHashCode());
			return BinderHelper.AddArgHashes(h, _argumentInfo);
		}

		public bool IsEquivalentTo(ICSharpBinder other)
		{
			if (!(other is CSharpGetMemberBinder cSharpGetMemberBinder))
			{
				return false;
			}
			if (base.Name != cSharpGetMemberBinder.Name || ResultIndexed != cSharpGetMemberBinder.ResultIndexed || _callingContext != cSharpGetMemberBinder._callingContext || _argumentInfo.Length != cSharpGetMemberBinder._argumentInfo.Length)
			{
				return false;
			}
			return BinderHelper.CompareArgInfos(_argumentInfo, cSharpGetMemberBinder._argumentInfo);
		}

		public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
		{
			BinderHelper.ValidateBindArgument(target, "target");
			return BinderHelper.Bind(this, _binder, new DynamicMetaObject[1] { target }, _argumentInfo, errorSuggestion);
		}

		[SpecialName]
		string ICSharpBinder.get_Name()
		{
			return base.Name;
		}
	}
	internal sealed class CSharpInvokeBinder : InvokeBinder, ICSharpInvokeOrInvokeMemberBinder, ICSharpBinder
	{
		private readonly CSharpCallFlags _flags;

		private readonly CSharpArgumentInfo[] _argumentInfo;

		private readonly RuntimeBinder _binder;

		private readonly Type _callingContext;

		public BindingFlag BindingFlags => (BindingFlag)0;

		public bool IsBinderThatCanHaveRefReceiver => true;

		bool ICSharpInvokeOrInvokeMemberBinder.StaticCall
		{
			get
			{
				if (_argumentInfo[0] != null)
				{
					return _argumentInfo[0].IsStaticType;
				}
				return false;
			}
		}

		string ICSharpBinder.Name => "Invoke";

		Type[] ICSharpInvokeOrInvokeMemberBinder.TypeArguments => Array.Empty<Type>();

		CSharpCallFlags ICSharpInvokeOrInvokeMemberBinder.Flags => _flags;

		bool ICSharpInvokeOrInvokeMemberBinder.ResultDiscarded => (_flags & CSharpCallFlags.ResultDiscarded) != 0;

		public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals)
		{
			return runtimeBinder.DispatchPayload(this, arguments, locals);
		}

		public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments)
		{
			RuntimeBinder.PopulateSymbolTableWithPayloadInformation(this, callingType, arguments);
		}

		CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index)
		{
			return _argumentInfo[index];
		}

		public CSharpInvokeBinder(CSharpCallFlags flags, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
			: base(BinderHelper.CreateCallInfo(ref argumentInfo, 1))
		{
			_flags = flags;
			_callingContext = callingContext;
			_argumentInfo = argumentInfo as CSharpArgumentInfo[];
			_binder = new RuntimeBinder(callingContext);
		}

		public int GetGetBinderEquivalenceHash()
		{
			int h = _callingContext?.GetHashCode() ?? 0;
			h = HashHelpers.Combine(h, (int)_flags);
			return BinderHelper.AddArgHashes(h, _argumentInfo);
		}

		public bool IsEquivalentTo(ICSharpBinder other)
		{
			if (!(other is CSharpInvokeBinder cSharpInvokeBinder))
			{
				return false;
			}
			if (_flags != cSharpInvokeBinder._flags || _callingContext != cSharpInvokeBinder._callingContext || _argumentInfo.Length != cSharpInvokeBinder._argumentInfo.Length)
			{
				return false;
			}
			return BinderHelper.CompareArgInfos(_argumentInfo, cSharpInvokeBinder._argumentInfo);
		}

		public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
		{
			BinderHelper.ValidateBindArgument(target, "target");
			BinderHelper.ValidateBindArgument(args, "args");
			return BinderHelper.Bind(this, _binder, BinderHelper.Cons(target, args), _argumentInfo, errorSuggestion);
		}
	}
	internal sealed class CSharpInvokeConstructorBinder : DynamicMetaObjectBinder, ICSharpInvokeOrInvokeMemberBinder, ICSharpBinder
	{
		private readonly CSharpArgumentInfo[] _argumentInfo;

		private readonly RuntimeBinder _binder;

		private readonly Type _callingContext;

		public BindingFlag BindingFlags => (BindingFlag)0;

		public bool IsBinderThatCanHaveRefReceiver => true;

		public CSharpCallFlags Flags { get; }

		public bool StaticCall => true;

		public Type[] TypeArguments => Array.Empty<Type>();

		public string Name => ".ctor";

		bool ICSharpInvokeOrInvokeMemberBinder.ResultDiscarded => false;

		public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals)
		{
			return runtimeBinder.DispatchPayload(this, arguments, locals);
		}

		public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments)
		{
			RuntimeBinder.PopulateSymbolTableWithPayloadInformation(this, callingType, arguments);
		}

		CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index)
		{
			return _argumentInfo[index];
		}

		public CSharpInvokeConstructorBinder(CSharpCallFlags flags, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
		{
			Flags = flags;
			_callingContext = callingContext;
			_argumentInfo = BinderHelper.ToArray(argumentInfo);
			_binder = new RuntimeBinder(callingContext);
		}

		public int GetGetBinderEquivalenceHash()
		{
			int h = _callingContext?.GetHashCode() ?? 0;
			h = HashHelpers.Combine(h, (int)Flags);
			h = HashHelpers.Combine(h, Name.GetHashCode());
			return BinderHelper.AddArgHashes(h, TypeArguments, _argumentInfo);
		}

		public bool IsEquivalentTo(ICSharpBinder other)
		{
			if (!(other is CSharpInvokeConstructorBinder cSharpInvokeConstructorBinder))
			{
				return false;
			}
			if (Flags != cSharpInvokeConstructorBinder.Flags || _callingContext != cSharpInvokeConstructorBinder._callingContext || Name != cSharpInvokeConstructorBinder.Name || TypeArguments.Length != cSharpInvokeConstructorBinder.TypeArguments.Length || _argumentInfo.Length != cSharpInvokeConstructorBinder._argumentInfo.Length)
			{
				return false;
			}
			return BinderHelper.CompareArgInfos(TypeArguments, cSharpInvokeConstructorBinder.TypeArguments, _argumentInfo, cSharpInvokeConstructorBinder._argumentInfo);
		}

		public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
		{
			BinderHelper.ValidateBindArgument(target, "target");
			BinderHelper.ValidateBindArgument(args, "args");
			return BinderHelper.Bind(this, _binder, BinderHelper.Cons(target, args), _argumentInfo, null);
		}
	}
	internal sealed class CSharpInvokeMemberBinder : InvokeMemberBinder, ICSharpInvokeOrInvokeMemberBinder, ICSharpBinder
	{
		private readonly CSharpArgumentInfo[] _argumentInfo;

		private readonly RuntimeBinder _binder;

		public BindingFlag BindingFlags => (BindingFlag)0;

		public bool IsBinderThatCanHaveRefReceiver => true;

		bool ICSharpInvokeOrInvokeMemberBinder.StaticCall => _argumentInfo[0]?.IsStaticType ?? false;

		public CSharpCallFlags Flags { get; }

		public Type CallingContext { get; }

		public Type[] TypeArguments { get; }

		bool ICSharpInvokeOrInvokeMemberBinder.ResultDiscarded => (Flags & CSharpCallFlags.ResultDiscarded) != 0;

		public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals)
		{
			return runtimeBinder.DispatchPayload(this, arguments, locals);
		}

		public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments)
		{
			RuntimeBinder.PopulateSymbolTableWithPayloadInformation(this, callingType, arguments);
		}

		public CSharpArgumentInfo GetArgumentInfo(int index)
		{
			return _argumentInfo[index];
		}

		public CSharpArgumentInfo[] ArgumentInfoArray()
		{
			CSharpArgumentInfo[] array = new CSharpArgumentInfo[_argumentInfo.Length];
			_argumentInfo.CopyTo(array, 0);
			return array;
		}

		public CSharpInvokeMemberBinder(CSharpCallFlags flags, string name, Type callingContext, IEnumerable<Type> typeArguments, IEnumerable<CSharpArgumentInfo> argumentInfo)
			: base(name, ignoreCase: false, BinderHelper.CreateCallInfo(ref argumentInfo, 1))
		{
			Flags = flags;
			CallingContext = callingContext;
			TypeArguments = BinderHelper.ToArray(typeArguments);
			_argumentInfo = BinderHelper.ToArray(argumentInfo);
			_binder = new RuntimeBinder(callingContext);
		}

		public int GetGetBinderEquivalenceHash()
		{
			int h = CallingContext?.GetHashCode() ?? 0;
			h = HashHelpers.Combine(h, (int)Flags);
			h = HashHelpers.Combine(h, base.Name.GetHashCode());
			return BinderHelper.AddArgHashes(h, TypeArguments, _argumentInfo);
		}

		public bool IsEquivalentTo(ICSharpBinder other)
		{
			if (!(other is CSharpInvokeMemberBinder cSharpInvokeMemberBinder))
			{
				return false;
			}
			if (Flags != cSharpInvokeMemberBinder.Flags || CallingContext != cSharpInvokeMemberBinder.CallingContext || base.Name != cSharpInvokeMemberBinder.Name || TypeArguments.Length != cSharpInvokeMemberBinder.TypeArguments.Length || _argumentInfo.Length != cSharpInvokeMemberBinder._argumentInfo.Length)
			{
				return false;
			}
			return BinderHelper.CompareArgInfos(TypeArguments, cSharpInvokeMemberBinder.TypeArguments, _argumentInfo, cSharpInvokeMemberBinder._argumentInfo);
		}

		public override DynamicMetaObject FallbackInvokeMember(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
		{
			BinderHelper.ValidateBindArgument(target, "target");
			BinderHelper.ValidateBindArgument(args, "args");
			return BinderHelper.Bind(this, _binder, BinderHelper.Cons(target, args), _argumentInfo, errorSuggestion);
		}

		public override DynamicMetaObject FallbackInvoke(DynamicMetaObject target, DynamicMetaObject[] args, DynamicMetaObject errorSuggestion)
		{
			CSharpInvokeBinder cSharpInvokeBinder = new CSharpInvokeBinder(Flags, CallingContext, _argumentInfo).TryGetExisting();
			return cSharpInvokeBinder.Defer(target, args);
		}

		[SpecialName]
		string ICSharpBinder.get_Name()
		{
			return base.Name;
		}
	}
	internal sealed class CSharpIsEventBinder : DynamicMetaObjectBinder, ICSharpBinder
	{
		private readonly RuntimeBinder _binder;

		private readonly Type _callingContext;

		public BindingFlag BindingFlags => (BindingFlag)0;

		public bool IsBinderThatCanHaveRefReceiver => false;

		public string Name { get; }

		public override Type ReturnType => typeof(bool);

		public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals)
		{
			return runtimeBinder.BindIsEvent(this, arguments, locals);
		}

		public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments)
		{
			SymbolTable.PopulateSymbolTableWithName(Name, null, arguments[0].Info.IsStaticType ? (arguments[0].Value as Type) : arguments[0].Type);
		}

		CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index)
		{
			return CSharpArgumentInfo.None;
		}

		public CSharpIsEventBinder(string name, Type callingContext)
		{
			Name = name;
			_callingContext = callingContext;
			_binder = new RuntimeBinder(callingContext);
		}

		public int GetGetBinderEquivalenceHash()
		{
			int h = _callingContext?.GetHashCode() ?? 0;
			return HashHelpers.Combine(h, Name.GetHashCode());
		}

		public bool IsEquivalentTo(ICSharpBinder other)
		{
			if (!(other is CSharpIsEventBinder cSharpIsEventBinder))
			{
				return false;
			}
			if (_callingContext != cSharpIsEventBinder._callingContext || Name != cSharpIsEventBinder.Name)
			{
				return false;
			}
			return true;
		}

		public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
		{
			BinderHelper.ValidateBindArgument(target, "target");
			return BinderHelper.Bind(this, _binder, new DynamicMetaObject[1] { target }, null, null);
		}
	}
	internal sealed class CSharpSetIndexBinder : SetIndexBinder, ICSharpBinder
	{
		private readonly CSharpArgumentInfo[] _argumentInfo;

		private readonly RuntimeBinder _binder;

		private readonly Type _callingContext;

		public string Name => "$Item$";

		public BindingFlag BindingFlags => (BindingFlag)0;

		public bool IsBinderThatCanHaveRefReceiver => true;

		internal bool IsCompoundAssignment { get; }

		private bool IsChecked => _binder.IsChecked;

		public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals)
		{
			return runtimeBinder.BindAssignment(this, arguments, locals);
		}

		public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments)
		{
			SymbolTable.PopulateSymbolTableWithName("$Item$", null, arguments[0].Type);
		}

		CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index)
		{
			return _argumentInfo[index];
		}

		public CSharpSetIndexBinder(bool isCompoundAssignment, bool isChecked, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
			: base(BinderHelper.CreateCallInfo(ref argumentInfo, 2))
		{
			IsCompoundAssignment = isCompoundAssignment;
			_argumentInfo = argumentInfo as CSharpArgumentInfo[];
			_callingContext = callingContext;
			_binder = new RuntimeBinder(callingContext, isChecked);
		}

		public int GetGetBinderEquivalenceHash()
		{
			int num = _callingContext?.GetHashCode() ?? 0;
			if (IsChecked)
			{
				num = HashHelpers.Combine(num, 1);
			}
			if (IsCompoundAssignment)
			{
				num = HashHelpers.Combine(num, 1);
			}
			return BinderHelper.AddArgHashes(num, _argumentInfo);
		}

		public bool IsEquivalentTo(ICSharpBinder other)
		{
			if (!(other is CSharpSetIndexBinder cSharpSetIndexBinder))
			{
				return false;
			}
			if (_callingContext != cSharpSetIndexBinder._callingContext || IsChecked != cSharpSetIndexBinder.IsChecked || IsCompoundAssignment != cSharpSetIndexBinder.IsCompoundAssignment || _argumentInfo.Length != cSharpSetIndexBinder._argumentInfo.Length)
			{
				return false;
			}
			return BinderHelper.CompareArgInfos(_argumentInfo, cSharpSetIndexBinder._argumentInfo);
		}

		public override DynamicMetaObject FallbackSetIndex(DynamicMetaObject target, DynamicMetaObject[] indexes, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
		{
			BinderHelper.ValidateBindArgument(target, "target");
			BinderHelper.ValidateBindArgument(indexes, "indexes");
			BinderHelper.ValidateBindArgument(value, "value");
			return BinderHelper.Bind(this, _binder, BinderHelper.Cons(target, indexes, value), _argumentInfo, errorSuggestion);
		}
	}
	internal sealed class CSharpSetMemberBinder : SetMemberBinder, ICSharpBinder
	{
		private readonly CSharpArgumentInfo[] _argumentInfo;

		private readonly RuntimeBinder _binder;

		private readonly Type _callingContext;

		public BindingFlag BindingFlags => (BindingFlag)0;

		public bool IsBinderThatCanHaveRefReceiver => false;

		internal bool IsCompoundAssignment { get; }

		private bool IsChecked => _binder.IsChecked;

		public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals)
		{
			return runtimeBinder.BindAssignment(this, arguments, locals);
		}

		public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments)
		{
			SymbolTable.PopulateSymbolTableWithName(base.Name, null, arguments[0].Type);
		}

		CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index)
		{
			return _argumentInfo[index];
		}

		public CSharpSetMemberBinder(string name, bool isCompoundAssignment, bool isChecked, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
			: base(name, ignoreCase: false)
		{
			IsCompoundAssignment = isCompoundAssignment;
			_argumentInfo = BinderHelper.ToArray(argumentInfo);
			_callingContext = callingContext;
			_binder = new RuntimeBinder(callingContext, isChecked);
		}

		public int GetGetBinderEquivalenceHash()
		{
			int h = _callingContext?.GetHashCode() ?? 0;
			if (IsChecked)
			{
				h = HashHelpers.Combine(h, 1);
			}
			if (IsCompoundAssignment)
			{
				h = HashHelpers.Combine(h, 1);
			}
			h = HashHelpers.Combine(h, base.Name.GetHashCode());
			return BinderHelper.AddArgHashes(h, _argumentInfo);
		}

		public bool IsEquivalentTo(ICSharpBinder other)
		{
			if (!(other is CSharpSetMemberBinder cSharpSetMemberBinder))
			{
				return false;
			}
			if (base.Name != cSharpSetMemberBinder.Name || _callingContext != cSharpSetMemberBinder._callingContext || IsChecked != cSharpSetMemberBinder.IsChecked || IsCompoundAssignment != cSharpSetMemberBinder.IsCompoundAssignment || _argumentInfo.Length != cSharpSetMemberBinder._argumentInfo.Length)
			{
				return false;
			}
			return BinderHelper.CompareArgInfos(_argumentInfo, cSharpSetMemberBinder._argumentInfo);
		}

		public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion)
		{
			BinderHelper.ValidateBindArgument(target, "target");
			BinderHelper.ValidateBindArgument(value, "value");
			return BinderHelper.Bind(this, _binder, new DynamicMetaObject[2] { target, value }, _argumentInfo, errorSuggestion);
		}

		[SpecialName]
		string ICSharpBinder.get_Name()
		{
			return base.Name;
		}
	}
	internal sealed class CSharpUnaryOperationBinder : UnaryOperationBinder, ICSharpBinder
	{
		private readonly CSharpArgumentInfo[] _argumentInfo;

		private readonly RuntimeBinder _binder;

		private readonly Type _callingContext;

		[ExcludeFromCodeCoverage]
		public string Name => null;

		public BindingFlag BindingFlags => (BindingFlag)0;

		public bool IsBinderThatCanHaveRefReceiver => false;

		private bool IsChecked => _binder.IsChecked;

		public Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals)
		{
			return runtimeBinder.BindUnaryOperation(this, arguments, locals);
		}

		public void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments)
		{
			SymbolTable.PopulateSymbolTableWithName(base.Operation.GetCLROperatorName(), null, arguments[0].Type);
		}

		CSharpArgumentInfo ICSharpBinder.GetArgumentInfo(int index)
		{
			return _argumentInfo[index];
		}

		public CSharpUnaryOperationBinder(ExpressionType operation, bool isChecked, Type callingContext, IEnumerable<CSharpArgumentInfo> argumentInfo)
			: base(operation)
		{
			_argumentInfo = BinderHelper.ToArray(argumentInfo);
			_callingContext = callingContext;
			_binder = new RuntimeBinder(callingContext, isChecked);
		}

		public int GetGetBinderEquivalenceHash()
		{
			int h = _callingContext?.GetHashCode() ?? 0;
			h = HashHelpers.Combine(h, (int)base.Operation);
			if (IsChecked)
			{
				h = HashHelpers.Combine(h, 1);
			}
			return BinderHelper.AddArgHashes(h, _argumentInfo);
		}

		public bool IsEquivalentTo(ICSharpBinder other)
		{
			if (!(other is CSharpUnaryOperationBinder cSharpUnaryOperationBinder))
			{
				return false;
			}
			if (base.Operation != cSharpUnaryOperationBinder.Operation || IsChecked != cSharpUnaryOperationBinder.IsChecked || _callingContext != cSharpUnaryOperationBinder._callingContext)
			{
				return false;
			}
			return BinderHelper.CompareArgInfos(_argumentInfo, cSharpUnaryOperationBinder._argumentInfo);
		}

		public override DynamicMetaObject FallbackUnaryOperation(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
		{
			BinderHelper.ValidateBindArgument(target, "target");
			return BinderHelper.Bind(this, _binder, new DynamicMetaObject[1] { target }, _argumentInfo, errorSuggestion);
		}
	}
	[Serializable]
	[EditorBrowsable(EditorBrowsableState.Never)]
	internal sealed class DynamicBindingFailedException : Exception
	{
		public DynamicBindingFailedException()
		{
		}

		private DynamicBindingFailedException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}
	}
	internal sealed class GetMemberValueBinder : GetMemberBinder
	{
		public GetMemberValueBinder(string name, bool ignoreCase)
			: base(name, ignoreCase)
		{
		}

		public override DynamicMetaObject FallbackGetMember(DynamicMetaObject self, DynamicMetaObject onBindingError)
		{
			if (onBindingError == null)
			{
				List<DynamicMetaObject> contributingObjects = new List<DynamicMetaObject> { self };
				return new DynamicMetaObject(Expression.Throw(Expression.Constant(new DynamicBindingFailedException(), typeof(Exception)), typeof(object)), BindingRestrictions.Combine(contributingObjects));
			}
			return onBindingError;
		}
	}
	internal sealed class DynamicMetaObjectProviderDebugView
	{
		[DebuggerDisplay("{value}", Name = "{name, nq}", Type = "{type, nq}")]
		internal class DynamicProperty
		{
			[DebuggerBrowsable(DebuggerBrowsableState.Never)]
			private readonly string name;

			[DebuggerBrowsable(DebuggerBrowsableState.Never)]
			private readonly object value;

			[DebuggerBrowsable(DebuggerBrowsableState.Never)]
			private readonly string type;

			public DynamicProperty(string name, object value)
			{
				this.name = name;
				this.value = value;
				type = ((value == null) ? "<null>" : value.GetType().ToString());
			}
		}

		[Serializable]
		internal class DynamicDebugViewEmptyException : Exception
		{
			public string Empty => System.SR.EmptyDynamicView;

			public DynamicDebugViewEmptyException()
			{
			}

			protected DynamicDebugViewEmptyException(SerializationInfo info, StreamingContext context)
				: base(info, context)
			{
			}
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private IList<KeyValuePair<string, object>> results;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private object obj;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private static readonly ParameterExpression parameter = Expression.Parameter(typeof(object), "debug");

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		internal DynamicProperty[] Items
		{
			get
			{
				if (results == null || results.Count == 0)
				{
					results = QueryDynamicObject(obj);
					if (results == null || results.Count == 0)
					{
						throw new DynamicDebugViewEmptyException();
					}
				}
				DynamicProperty[] array = new DynamicProperty[results.Count];
				for (int i = 0; i < results.Count; i++)
				{
					array[i] = new DynamicProperty(results[i].Key, results[i].Value);
				}
				return array;
			}
		}

		public DynamicMetaObjectProviderDebugView(object arg)
		{
			obj = arg;
		}

		public static object TryEvalBinaryOperators<T1, T2>(T1 arg1, T2 arg2, CSharpArgumentInfoFlags arg1Flags, CSharpArgumentInfoFlags arg2Flags, ExpressionType opKind, Type accessibilityContext)
		{
			CSharpArgumentInfo cSharpArgumentInfo = CSharpArgumentInfo.Create(arg1Flags, null);
			CSharpArgumentInfo cSharpArgumentInfo2 = CSharpArgumentInfo.Create(arg2Flags, null);
			CSharpBinaryOperationBinder binder = new CSharpBinaryOperationBinder(opKind, isChecked: false, CSharpBinaryOperationFlags.None, accessibilityContext, new CSharpArgumentInfo[2] { cSharpArgumentInfo, cSharpArgumentInfo2 });
			CallSite<Func<CallSite, T1, T2, object>> callSite = CallSite<Func<CallSite, T1, T2, object>>.Create(binder);
			return callSite.Target(callSite, arg1, arg2);
		}

		public static object TryEvalUnaryOperators<T>(T obj, ExpressionType oper, Type accessibilityContext)
		{
			if (oper == ExpressionType.IsTrue || oper == ExpressionType.IsFalse)
			{
				CallSite<Func<CallSite, T, bool>> callSite = CallSite<Func<CallSite, T, bool>>.Create(new CSharpUnaryOperationBinder(oper, isChecked: false, accessibilityContext, new CSharpArgumentInfo[1] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
				return callSite.Target(callSite, obj);
			}
			CallSite<Func<CallSite, T, object>> callSite2 = CallSite<Func<CallSite, T, object>>.Create(new CSharpUnaryOperationBinder(oper, isChecked: false, accessibilityContext, new CSharpArgumentInfo[1] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));
			return callSite2.Target(callSite2, obj);
		}

		public static K TryEvalCast<T, K>(T obj, Type type, CSharpBinderFlags kind, Type accessibilityContext)
		{
			CallSite<Func<CallSite, T, K>> callSite = CallSite<Func<CallSite, T, K>>.Create(Binder.Convert(kind, type, accessibilityContext));
			return callSite.Target(callSite, obj);
		}

		private static void CreateDelegateSignatureAndArgumentInfos(object[] args, Type[] argTypes, CSharpArgumentInfoFlags[] argFlags, out Type[] delegateSignatureTypes, out CSharpArgumentInfo[] argInfos)
		{
			int num = args.Length;
			delegateSignatureTypes = new Type[num + 2];
			delegateSignatureTypes[0] = typeof(CallSite);
			argInfos = new CSharpArgumentInfo[num];
			for (int i = 0; i < num; i++)
			{
				if (argTypes[i] != null)
				{
					delegateSignatureTypes[i + 1] = argTypes[i];
				}
				else if (args[i] != null)
				{
					delegateSignatureTypes[i + 1] = args[i].GetType();
				}
				else
				{
					delegateSignatureTypes[i + 1] = typeof(object);
				}
				argInfos[i] = CSharpArgumentInfo.Create(argFlags[i], null);
			}
			delegateSignatureTypes[num + 1] = typeof(object);
		}

		private static object CreateDelegateAndInvoke(Type[] delegateSignatureTypes, CallSiteBinder binder, object[] args)
		{
			Type delegateType = Expression.GetDelegateType(delegateSignatureTypes);
			CallSite callSite = CallSite.Create(delegateType, binder);
			Delegate @delegate = (Delegate)callSite.GetType().GetField("Target").GetValue(callSite);
			object[] array = new object[args.Length + 1];
			array[0] = callSite;
			args.CopyTo(array, 1);
			return @delegate.DynamicInvoke(array);
		}

		public static object TryEvalMethodVarArgs(object[] methodArgs, Type[] argTypes, CSharpArgumentInfoFlags[] argFlags, string methodName, Type accessibilityContext, Type[] typeArguments)
		{
			Type[] delegateSignatureTypes = null;
			CSharpArgumentInfo[] argInfos = null;
			CreateDelegateSignatureAndArgumentInfos(methodArgs, argTypes, argFlags, out delegateSignatureTypes, out argInfos);
			return CreateDelegateAndInvoke(binder: (!string.IsNullOrEmpty(methodName)) ? ((CallSiteBinder)new CSharpInvokeMemberBinder(CSharpCallFlags.ResultDiscarded, methodName, accessibilityContext, typeArguments, argInfos)) : ((CallSiteBinder)new CSharpInvokeBinder(CSharpCallFlags.ResultDiscarded, accessibilityContext, argInfos)), delegateSignatureTypes: delegateSignatureTypes, args: methodArgs);
		}

		public static object TryGetMemberValue<T>(T obj, string propName, Type accessibilityContext, bool isResultIndexed)
		{
			CSharpGetMemberBinder binder = new CSharpGetMemberBinder(propName, isResultIndexed, accessibilityContext, new CSharpArgumentInfo[1] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
			CallSite<Func<CallSite, T, object>> callSite = CallSite<Func<CallSite, T, object>>.Create(binder);
			return callSite.Target(callSite, obj);
		}

		public static object TryGetMemberValueVarArgs(object[] propArgs, Type[] argTypes, CSharpArgumentInfoFlags[] argFlags, Type accessibilityContext)
		{
			Type[] delegateSignatureTypes = null;
			CSharpArgumentInfo[] argInfos = null;
			CreateDelegateSignatureAndArgumentInfos(propArgs, argTypes, argFlags, out delegateSignatureTypes, out argInfos);
			CallSiteBinder binder = new CSharpGetIndexBinder(accessibilityContext, argInfos);
			return CreateDelegateAndInvoke(delegateSignatureTypes, binder, propArgs);
		}

		public static object TrySetMemberValue<TObject, TValue>(TObject obj, string propName, TValue value, CSharpArgumentInfoFlags valueFlags, Type accessibilityContext)
		{
			CSharpArgumentInfo cSharpArgumentInfo = CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
			CSharpArgumentInfo cSharpArgumentInfo2 = CSharpArgumentInfo.Create(valueFlags, null);
			CSharpSetMemberBinder binder = new CSharpSetMemberBinder(propName, isCompoundAssignment: false, isChecked: false, accessibilityContext, new CSharpArgumentInfo[2] { cSharpArgumentInfo, cSharpArgumentInfo2 });
			CallSite<Func<CallSite, TObject, TValue, object>> callSite = CallSite<Func<CallSite, TObject, TValue, object>>.Create(binder);
			return callSite.Target(callSite, obj, value);
		}

		public static object TrySetMemberValueVarArgs(object[] propArgs, Type[] argTypes, CSharpArgumentInfoFlags[] argFlags, Type accessibilityContext)
		{
			Type[] delegateSignatureTypes = null;
			CSharpArgumentInfo[] argInfos = null;
			CreateDelegateSignatureAndArgumentInfos(propArgs, argTypes, argFlags, out delegateSignatureTypes, out argInfos);
			CallSiteBinder binder = new CSharpSetIndexBinder(isCompoundAssignment: false, isChecked: false, accessibilityContext, argInfos);
			return CreateDelegateAndInvoke(delegateSignatureTypes, binder, propArgs);
		}

		internal static object TryGetMemberValue(object obj, string name, bool ignoreException)
		{
			bool ignoreCase = false;
			object obj2 = null;
			CallSite<Func<CallSite, object, object>> callSite = CallSite<Func<CallSite, object, object>>.Create(new GetMemberValueBinder(name, ignoreCase));
			try
			{
				return callSite.Target(callSite, obj);
			}
			catch (DynamicBindingFailedException ex)
			{
				if (ignoreException)
				{
					return null;
				}
				throw ex;
			}
			catch (MissingMemberException ex2)
			{
				if (ignoreException)
				{
					return System.SR.GetValueonWriteOnlyProperty;
				}
				throw ex2;
			}
		}

		private static IList<KeyValuePair<string, object>> QueryDynamicObject(object obj)
		{
			if (obj is IDynamicMetaObjectProvider dynamicMetaObjectProvider)
			{
				DynamicMetaObject metaObject = dynamicMetaObjectProvider.GetMetaObject(parameter);
				List<string> list = new List<string>(metaObject.GetDynamicMemberNames());
				list.Sort();
				if (list != null)
				{
					List<KeyValuePair<string, object>> list2 = new List<KeyValuePair<string, object>>();
					{
						foreach (string item in list)
						{
							object value;
							if ((value = TryGetMemberValue(obj, item, ignoreException: true)) != null)
							{
								list2.Add(new KeyValuePair<string, object>(item, value));
							}
						}
						return list2;
					}
				}
			}
			return new KeyValuePair<string, object>[0];
		}
	}
	internal static class Error
	{
		internal static Exception InternalCompilerError()
		{
			return new RuntimeBinderInternalCompilerException(System.SR.InternalCompilerError);
		}

		internal static Exception BindPropertyFailedMethodGroup(object p0)
		{
			return new RuntimeBinderException(System.SR.Format(System.SR.BindPropertyFailedMethodGroup, p0));
		}

		internal static Exception BindPropertyFailedEvent(object p0)
		{
			return new RuntimeBinderException(System.SR.Format(System.SR.BindPropertyFailedEvent, p0));
		}

		internal static Exception BindInvokeFailedNonDelegate()
		{
			return new RuntimeBinderException(System.SR.BindInvokeFailedNonDelegate);
		}

		internal static Exception BindStaticRequiresType(string paramName)
		{
			return new ArgumentException(System.SR.TypeArgumentRequiredForStaticCall, paramName);
		}

		internal static Exception NullReferenceOnMemberException()
		{
			return new RuntimeBinderException(System.SR.NullReferenceOnMemberException);
		}

		internal static Exception BindCallToConditionalMethod(object p0)
		{
			return new RuntimeBinderException(System.SR.Format(System.SR.BindCallToConditionalMethod, p0));
		}

		internal static Exception BindToVoidMethodButExpectResult()
		{
			return new RuntimeBinderException(System.SR.BindToVoidMethodButExpectResult);
		}

		internal static Exception ArgumentNull(string paramName)
		{
			return new ArgumentNullException(paramName);
		}

		internal static Exception DynamicArgumentNeedsValue(string paramName)
		{
			return new ArgumentException(System.SR.DynamicArgumentNeedsValue, paramName);
		}
	}
	internal sealed class ExpressionTreeCallRewriter : ExprVisitorBase
	{
		private sealed class ExpressionExpr : Expr
		{
			public readonly Expression Expression;

			public ExpressionExpr(Expression e)
				: base(ExpressionKind.NoOp)
			{
				Expression = e;
			}
		}

		private readonly Dictionary<ExprCall, Expression> _DictionaryOfParameters;

		private readonly Expression[] _ListOfParameters;

		private int _currentParameterIndex;

		private ExpressionTreeCallRewriter(Expression[] listOfParameters)
		{
			_DictionaryOfParameters = new Dictionary<ExprCall, Expression>();
			_ListOfParameters = listOfParameters;
		}

		public static Expression Rewrite(ExprBinOp binOp, Expression[] listOfParameters)
		{
			ExpressionTreeCallRewriter expressionTreeCallRewriter = new ExpressionTreeCallRewriter(listOfParameters);
			expressionTreeCallRewriter.Visit(binOp.OptionalLeftChild);
			ExprCall pExpr = (ExprCall)binOp.OptionalRightChild;
			ExpressionExpr expressionExpr = expressionTreeCallRewriter.Visit(pExpr) as ExpressionExpr;
			return expressionExpr.Expression;
		}

		protected override Expr VisitSAVE(ExprBinOp pExpr)
		{
			ExprCall key = (ExprCall)pExpr.OptionalLeftChild;
			Expression value = _ListOfParameters[_currentParameterIndex++];
			_DictionaryOfParameters.Add(key, value);
			return null;
		}

		protected override Expr VisitCALL(ExprCall pExpr)
		{
			if (pExpr.PredefinedMethod == PREDEFMETH.PM_COUNT)
			{
				return pExpr;
			}
			Expression e;
			switch (pExpr.PredefinedMethod)
			{
			case PREDEFMETH.PM_EXPRESSION_LAMBDA:
				return GenerateLambda(pExpr);
			case PREDEFMETH.PM_EXPRESSION_CALL:
				e = GenerateCall(pExpr);
				break;
			case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX:
			case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2:
				e = GenerateArrayIndex(pExpr);
				break;
			case PREDEFMETH.PM_EXPRESSION_CONVERT:
			case PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED:
			case PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED:
				e = GenerateConvert(pExpr);
				break;
			case PREDEFMETH.PM_EXPRESSION_PROPERTY:
				e = GenerateProperty(pExpr);
				break;
			case PREDEFMETH.PM_EXPRESSION_FIELD:
				e = GenerateField(pExpr);
				break;
			case PREDEFMETH.PM_EXPRESSION_INVOKE:
				e = GenerateInvoke(pExpr);
				break;
			case PREDEFMETH.PM_EXPRESSION_NEW:
				e = GenerateNew(pExpr);
				break;
			case PREDEFMETH.PM_EXPRESSION_ADD:
			case PREDEFMETH.PM_EXPRESSION_ADDCHECKED:
			case PREDEFMETH.PM_EXPRESSION_AND:
			case PREDEFMETH.PM_EXPRESSION_ANDALSO:
			case PREDEFMETH.PM_EXPRESSION_DIVIDE:
			case PREDEFMETH.PM_EXPRESSION_EQUAL:
			case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR:
			case PREDEFMETH.PM_EXPRESSION_GREATERTHAN:
			case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL:
			case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT:
			case PREDEFMETH.PM_EXPRESSION_LESSTHAN:
			case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL:
			case PREDEFMETH.PM_EXPRESSION_MODULO:
			case PREDEFMETH.PM_EXPRESSION_MULTIPLY:
			case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED:
			case PREDEFMETH.PM_EXPRESSION_NOTEQUAL:
			case PREDEFMETH.PM_EXPRESSION_OR:
			case PREDEFMETH.PM_EXPRESSION_ORELSE:
			case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT:
			case PREDEFMETH.PM_EXPRESSION_SUBTRACT:
			case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED:
				e = GenerateBinaryOperator(pExpr);
				break;
			case PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED:
				e = GenerateUserDefinedBinaryOperator(pExpr);
				break;
			case PREDEFMETH.PM_EXPRESSION_NEGATE:
			case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED:
			case PREDEFMETH.PM_EXPRESSION_NOT:
				e = GenerateUnaryOperator(pExpr);
				break;
			case PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED:
				e = GenerateUserDefinedUnaryOperator(pExpr);
				break;
			case PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE:
				e = GenerateConstantType(pExpr);
				break;
			case PREDEFMETH.PM_EXPRESSION_ASSIGN:
				e = GenerateAssignment(pExpr);
				break;
			default:
				throw Error.InternalCompilerError();
			}
			return new ExpressionExpr(e);
		}

		protected override Expr VisitWRAP(ExprWrap pExpr)
		{
			return new ExpressionExpr(GetExpression(pExpr));
		}

		private Expr GenerateLambda(ExprCall pExpr)
		{
			return Visit(((ExprList)pExpr.OptionalArguments).OptionalElement);
		}

		private Expression GenerateCall(ExprCall pExpr)
		{
			ExprList exprList = (ExprList)pExpr.OptionalArguments;
			ExprMethodInfo exprMethodInfo;
			ExprArrayInit arrinit;
			if (exprList.OptionalNextListNode is ExprList exprList2)
			{
				exprMethodInfo = (ExprMethodInfo)exprList2.OptionalElement;
				arrinit = (ExprArrayInit)exprList2.OptionalNextListNode;
			}
			else
			{
				exprMethodInfo = (ExprMethodInfo)exprList.OptionalNextListNode;
				arrinit = null;
			}
			Expression instance = null;
			MethodInfo methodInfo = exprMethodInfo.MethodInfo;
			Expression[] argumentsFromArrayInit = GetArgumentsFromArrayInit(arrinit);
			if (methodInfo == null)
			{
				throw Error.InternalCompilerError();
			}
			if (!methodInfo.IsStatic)
			{
				instance = GetExpression(((ExprList)pExpr.OptionalArguments).OptionalElement);
			}
			return Expression.Call(instance, methodInfo, argumentsFromArrayInit);
		}

		private Expression GenerateArrayIndex(ExprCall pExpr)
		{
			ExprList exprList = (ExprList)pExpr.OptionalArguments;
			Expression expression = GetExpression(exprList.OptionalElement);
			Expression[] indexes = ((pExpr.PredefinedMethod != PREDEFMETH.PM_EXPRESSION_ARRAYINDEX) ? GetArgumentsFromArrayInit((ExprArrayInit)exprList.OptionalNextListNode) : new Expression[1] { GetExpression(exprList.OptionalNextListNode) });
			return Expression.ArrayAccess(expression, indexes);
		}

		private Expression GenerateConvert(ExprCall pExpr)
		{
			PREDEFMETH predefinedMethod = pExpr.PredefinedMethod;
			Expression expression;
			Type associatedSystemType;
			if (predefinedMethod == PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED || predefinedMethod == PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED)
			{
				ExprList exprList = (ExprList)pExpr.OptionalArguments;
				ExprList exprList2 = (ExprList)exprList.OptionalNextListNode;
				expression = GetExpression(exprList.OptionalElement);
				associatedSystemType = ((ExprTypeOf)exprList2.OptionalElement).SourceType.AssociatedSystemType;
				if (expression.Type.MakeByRefType() == associatedSystemType)
				{
					return expression;
				}
				MethodInfo methodInfo = ((ExprMethodInfo)exprList2.OptionalNextListNode).MethodInfo;
				if (predefinedMethod == PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED)
				{
					return Expression.Convert(expression, associatedSystemType, methodInfo);
				}
				return Expression.ConvertChecked(expression, associatedSystemType, methodInfo);
			}
			ExprList exprList3 = (ExprList)pExpr.OptionalArguments;
			expression = GetExpression(exprList3.OptionalElement);
			associatedSystemType = ((ExprTypeOf)exprList3.OptionalNextListNode).SourceType.AssociatedSystemType;
			if (expression.Type.MakeByRefType() == associatedSystemType)
			{
				return expression;
			}
			if ((pExpr.Flags & EXPRFLAG.EXF_USERCALLABLE) != 0)
			{
				return Expression.Unbox(expression, associatedSystemType);
			}
			if (predefinedMethod == PREDEFMETH.PM_EXPRESSION_CONVERT)
			{
				return Expression.Convert(expression, associatedSystemType);
			}
			return Expression.ConvertChecked(expression, associatedSystemType);
		}

		private Expression GenerateProperty(ExprCall pExpr)
		{
			ExprList exprList = (ExprList)pExpr.OptionalArguments;
			Expr optionalElement = exprList.OptionalElement;
			Expr optionalNextListNode = exprList.OptionalNextListNode;
			ExprPropertyInfo exprPropertyInfo;
			ExprArrayInit exprArrayInit;
			if (optionalNextListNode is ExprList exprList2)
			{
				exprPropertyInfo = exprList2.OptionalElement as ExprPropertyInfo;
				exprArrayInit = exprList2.OptionalNextListNode as ExprArrayInit;
			}
			else
			{
				exprPropertyInfo = optionalNextListNode as ExprPropertyInfo;
				exprArrayInit = null;
			}
			PropertyInfo propertyInfo = exprPropertyInfo.PropertyInfo;
			if (propertyInfo == null)
			{
				throw Error.InternalCompilerError();
			}
			if (exprArrayInit == null)
			{
				return Expression.Property(GetExpression(optionalElement), propertyInfo);
			}
			return Expression.Property(GetExpression(optionalElement), propertyInfo, GetArgumentsFromArrayInit(exprArrayInit));
		}

		private Expression GenerateField(ExprCall pExpr)
		{
			ExprList exprList = (ExprList)pExpr.OptionalArguments;
			ExprFieldInfo exprFieldInfo = (ExprFieldInfo)exprList.OptionalNextListNode;
			Type type = exprFieldInfo.FieldType.AssociatedSystemType;
			FieldInfo fieldInfo = exprFieldInfo.Field.AssociatedFieldInfo;
			if (!type.IsGenericType && !type.IsNested)
			{
				type = fieldInfo.DeclaringType;
			}
			if (type.IsGenericType)
			{
				fieldInfo = type.GetField(fieldInfo.Name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
			return Expression.Field(GetExpression(exprList.OptionalElement), fieldInfo);
		}

		private Expression GenerateInvoke(ExprCall pExpr)
		{
			ExprList exprList = (ExprList)pExpr.OptionalArguments;
			return Expression.Invoke(GetExpression(exprList.OptionalElement), GetArgumentsFromArrayInit(exprList.OptionalNextListNode as ExprArrayInit));
		}

		private Expression GenerateNew(ExprCall pExpr)
		{
			ExprList exprList = (ExprList)pExpr.OptionalArguments;
			ConstructorInfo constructorInfo = ((ExprMethodInfo)exprList.OptionalElement).ConstructorInfo;
			Expression[] argumentsFromArrayInit = GetArgumentsFromArrayInit(exprList.OptionalNextListNode as ExprArrayInit);
			return Expression.New(constructorInfo, argumentsFromArrayInit);
		}

		private static Expression GenerateConstantType(ExprCall pExpr)
		{
			ExprList exprList = (ExprList)pExpr.OptionalArguments;
			return Expression.Constant(exprList.OptionalElement.Object, ((ExprTypeOf)exprList.OptionalNextListNode).SourceType.AssociatedSystemType);
		}

		private Expression GenerateAssignment(ExprCall pExpr)
		{
			ExprList exprList = (ExprList)pExpr.OptionalArguments;
			return Expression.Assign(GetExpression(exprList.OptionalElement), GetExpression(exprList.OptionalNextListNode));
		}

		private Expression GenerateBinaryOperator(ExprCall pExpr)
		{
			ExprList exprList = (ExprList)pExpr.OptionalArguments;
			Expression expression = GetExpression(exprList.OptionalElement);
			Expression expression2 = GetExpression(exprList.OptionalNextListNode);
			return pExpr.PredefinedMethod switch
			{
				PREDEFMETH.PM_EXPRESSION_ADD => Expression.Add(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_AND => Expression.And(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_DIVIDE => Expression.Divide(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_EQUAL => Expression.Equal(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR => Expression.ExclusiveOr(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_GREATERTHAN => Expression.GreaterThan(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL => Expression.GreaterThanOrEqual(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_LEFTSHIFT => Expression.LeftShift(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_LESSTHAN => Expression.LessThan(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL => Expression.LessThanOrEqual(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_MODULO => Expression.Modulo(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_MULTIPLY => Expression.Multiply(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_NOTEQUAL => Expression.NotEqual(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_OR => Expression.Or(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT => Expression.RightShift(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_SUBTRACT => Expression.Subtract(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_ORELSE => Expression.OrElse(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_ANDALSO => Expression.AndAlso(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_ADDCHECKED => Expression.AddChecked(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED => Expression.MultiplyChecked(expression, expression2), 
				PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED => Expression.SubtractChecked(expression, expression2), 
				_ => throw Error.InternalCompilerError(), 
			};
		}

		private Expression GenerateUserDefinedBinaryOperator(ExprCall pExpr)
		{
			ExprList exprList = (ExprList)pExpr.OptionalArguments;
			Expression expression = GetExpression(exprList.OptionalElement);
			Expression expression2 = GetExpression(((ExprList)exprList.OptionalNextListNode).OptionalElement);
			exprList = (ExprList)exprList.OptionalNextListNode;
			bool liftToNull = false;
			MethodInfo methodInfo;
			if (exprList.OptionalNextListNode is ExprList exprList2)
			{
				ExprConstant exprConstant = (ExprConstant)exprList2.OptionalElement;
				liftToNull = exprConstant.Val.Int32Val == 1;
				methodInfo = ((ExprMethodInfo)exprList2.OptionalNextListNode).MethodInfo;
			}
			else
			{
				methodInfo = ((ExprMethodInfo)exprList.OptionalNextListNode).MethodInfo;
			}
			return pExpr.PredefinedMethod switch
			{
				PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED => Expression.Add(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED => Expression.And(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED => Expression.Divide(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED => Expression.Equal(expression, expression2, liftToNull, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED => Expression.ExclusiveOr(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED => Expression.GreaterThan(expression, expression2, liftToNull, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED => Expression.GreaterThanOrEqual(expression, expression2, liftToNull, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED => Expression.LeftShift(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED => Expression.LessThan(expression, expression2, liftToNull, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED => Expression.LessThanOrEqual(expression, expression2, liftToNull, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED => Expression.Modulo(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED => Expression.Multiply(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED => Expression.NotEqual(expression, expression2, liftToNull, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED => Expression.Or(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED => Expression.RightShift(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED => Expression.Subtract(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED => Expression.OrElse(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED => Expression.AndAlso(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED => Expression.AddChecked(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED => Expression.MultiplyChecked(expression, expression2, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED => Expression.SubtractChecked(expression, expression2, methodInfo), 
				_ => throw Error.InternalCompilerError(), 
			};
		}

		private Expression GenerateUnaryOperator(ExprCall pExpr)
		{
			PREDEFMETH predefinedMethod = pExpr.PredefinedMethod;
			Expression expression = GetExpression(pExpr.OptionalArguments);
			return predefinedMethod switch
			{
				PREDEFMETH.PM_EXPRESSION_NOT => Expression.Not(expression), 
				PREDEFMETH.PM_EXPRESSION_NEGATE => Expression.Negate(expression), 
				PREDEFMETH.PM_EXPRESSION_NEGATECHECKED => Expression.NegateChecked(expression), 
				_ => throw Error.InternalCompilerError(), 
			};
		}

		private Expression GenerateUserDefinedUnaryOperator(ExprCall pExpr)
		{
			PREDEFMETH predefinedMethod = pExpr.PredefinedMethod;
			ExprList exprList = (ExprList)pExpr.OptionalArguments;
			Expression expression = GetExpression(exprList.OptionalElement);
			MethodInfo methodInfo = ((ExprMethodInfo)exprList.OptionalNextListNode).MethodInfo;
			return predefinedMethod switch
			{
				PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED => Expression.Not(expression, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED => Expression.Negate(expression, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED => Expression.UnaryPlus(expression, methodInfo), 
				PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED => Expression.NegateChecked(expression, methodInfo), 
				_ => throw Error.InternalCompilerError(), 
			};
		}

		private Expression GetExpression(Expr pExpr)
		{
			if (pExpr is ExprWrap exprWrap)
			{
				return _DictionaryOfParameters[(ExprCall)exprWrap.OptionalExpression];
			}
			if (pExpr is ExprConstant)
			{
				return null;
			}
			ExprCall exprCall = (ExprCall)pExpr;
			switch (exprCall.PredefinedMethod)
			{
			case PREDEFMETH.PM_EXPRESSION_CALL:
				return GenerateCall(exprCall);
			case PREDEFMETH.PM_EXPRESSION_CONVERT:
			case PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED:
			case PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED:
				return GenerateConvert(exprCall);
			case PREDEFMETH.PM_EXPRESSION_NEWARRAYINIT:
			{
				ExprList exprList = (ExprList)exprCall.OptionalArguments;
				return Expression.NewArrayInit(((ExprTypeOf)exprList.OptionalElement).SourceType.AssociatedSystemType, GetArgumentsFromArrayInit((ExprArrayInit)exprList.OptionalNextListNode));
			}
			case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX:
			case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2:
				return GenerateArrayIndex(exprCall);
			case PREDEFMETH.PM_EXPRESSION_NEW:
				return GenerateNew(exprCall);
			case PREDEFMETH.PM_EXPRESSION_PROPERTY:
				return GenerateProperty(exprCall);
			case PREDEFMETH.PM_EXPRESSION_FIELD:
				return GenerateField(exprCall);
			case PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE:
				return GenerateConstantType(exprCall);
			case PREDEFMETH.PM_EXPRESSION_ASSIGN:
				return GenerateAssignment(exprCall);
			case PREDEFMETH.PM_EXPRESSION_ADD:
			case PREDEFMETH.PM_EXPRESSION_ADDCHECKED:
			case PREDEFMETH.PM_EXPRESSION_AND:
			case PREDEFMETH.PM_EXPRESSION_ANDALSO:
			case PREDEFMETH.PM_EXPRESSION_DIVIDE:
			case PREDEFMETH.PM_EXPRESSION_EQUAL:
			case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR:
			case PREDEFMETH.PM_EXPRESSION_GREATERTHAN:
			case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL:
			case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT:
			case PREDEFMETH.PM_EXPRESSION_LESSTHAN:
			case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL:
			case PREDEFMETH.PM_EXPRESSION_MODULO:
			case PREDEFMETH.PM_EXPRESSION_MULTIPLY:
			case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED:
			case PREDEFMETH.PM_EXPRESSION_NOTEQUAL:
			case PREDEFMETH.PM_EXPRESSION_OR:
			case PREDEFMETH.PM_EXPRESSION_ORELSE:
			case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT:
			case PREDEFMETH.PM_EXPRESSION_SUBTRACT:
			case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED:
				return GenerateBinaryOperator(exprCall);
			case PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED:
				return GenerateUserDefinedBinaryOperator(exprCall);
			case PREDEFMETH.PM_EXPRESSION_NEGATE:
			case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED:
			case PREDEFMETH.PM_EXPRESSION_NOT:
				return GenerateUnaryOperator(exprCall);
			case PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED:
			case PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED:
				return GenerateUserDefinedUnaryOperator(exprCall);
			default:
				throw Error.InternalCompilerError();
			}
		}

		private Expression[] GetArgumentsFromArrayInit(ExprArrayInit arrinit)
		{
			List<Expression> list = new List<Expression>();
			if (arrinit != null)
			{
				Expr expr = arrinit.OptionalArguments;
				while (expr != null)
				{
					Expr pExpr;
					if (expr is ExprList exprList)
					{
						pExpr = exprList.OptionalElement;
						expr = exprList.OptionalNextListNode;
					}
					else
					{
						pExpr = expr;
						expr = null;
					}
					list.Add(GetExpression(pExpr));
				}
			}
			return list.ToArray();
		}
	}
	internal interface ICSharpBinder
	{
		bool IsBinderThatCanHaveRefReceiver { get; }

		BindingFlag BindingFlags { get; }

		string Name { get; }

		Type ReturnType { get; }

		CSharpArgumentInfo GetArgumentInfo(int index);

		void PopulateSymbolTableWithName(Type callingType, ArgumentObject[] arguments);

		Expr DispatchPayload(RuntimeBinder runtimeBinder, ArgumentObject[] arguments, LocalVariableSymbol[] locals);

		int GetGetBinderEquivalenceHash();

		bool IsEquivalentTo(ICSharpBinder other);
	}
	internal interface ICSharpInvokeOrInvokeMemberBinder : ICSharpBinder
	{
		bool StaticCall { get; }

		bool ResultDiscarded { get; }

		CSharpCallFlags Flags { get; }

		Type[] TypeArguments { get; }
	}
	internal readonly struct RuntimeBinder
	{
		private static readonly object s_bindLock = new object();

		private readonly ExpressionBinder _binder;

		internal bool IsChecked => _binder.Context.Checked;

		public RuntimeBinder(Type contextType, bool isChecked = false)
		{
			AggregateSymbol context;
			if (contextType != null)
			{
				lock (s_bindLock)
				{
					context = ((AggregateType)SymbolTable.GetCTypeFromType(contextType)).OwningAggregate;
				}
			}
			else
			{
				context = null;
			}
			_binder = new ExpressionBinder(new BindingContext(context, isChecked));
		}

		public Expression Bind(ICSharpBinder payload, Expression[] parameters, DynamicMetaObject[] args, out DynamicMetaObject deferredBinding)
		{
			lock (s_bindLock)
			{
				return BindCore(payload, parameters, args, out deferredBinding);
			}
		}

		private Expression BindCore(ICSharpBinder payload, Expression[] parameters, DynamicMetaObject[] args, out DynamicMetaObject deferredBinding)
		{
			ArgumentObject[] array = CreateArgumentArray(payload, parameters, args);
			payload.PopulateSymbolTableWithName(array[0].Type, array);
			AddConversionsForArguments(array);
			Scope pScope = SymFactory.CreateScope();
			LocalVariableSymbol[] locals = PopulateLocalScope(payload, pScope, array, parameters);
			if (DeferBinding(payload, array, args, locals, out deferredBinding))
			{
				return null;
			}
			Expr pResult = payload.DispatchPayload(this, array, locals);
			return CreateExpressionTreeFromResult(parameters, pScope, pResult);
		}

		private bool DeferBinding(ICSharpBinder payload, ArgumentObject[] arguments, DynamicMetaObject[] args, LocalVariableSymbol[] locals, out DynamicMetaObject deferredBinding)
		{
			if (payload is CSharpInvokeMemberBinder cSharpInvokeMemberBinder)
			{
				Type[] typeArguments = cSharpInvokeMemberBinder.TypeArguments;
				int arity = ((typeArguments != null) ? typeArguments.Length : 0);
				MemberLookup mem = new MemberLookup();
				Expr callingObject = CreateCallingObjectForCall(cSharpInvokeMemberBinder, arguments, locals);
				SymWithType symWithType = SymbolTable.LookupMember(cSharpInvokeMemberBinder.Name, callingObject, _binder.Context.ContextForMemberLookup, arity, mem, (cSharpInvokeMemberBinder.Flags & CSharpCallFlags.EventHookup) != 0, requireInvocable: true);
				if (symWithType != null && symWithType.Sym.getKind() != SYMKIND.SK_MethodSymbol)
				{
					CSharpGetMemberBinder cSharpGetMemberBinder = new CSharpGetMemberBinder(cSharpInvokeMemberBinder.Name, resultIndexed: false, cSharpInvokeMemberBinder.CallingContext, new CSharpArgumentInfo[1] { cSharpInvokeMemberBinder.GetArgumentInfo(0) }).TryGetExisting();
					CSharpArgumentInfo[] array = cSharpInvokeMemberBinder.ArgumentInfoArray();
					array[0] = CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
					CSharpInvokeBinder cSharpInvokeBinder = new CSharpInvokeBinder(cSharpInvokeMemberBinder.Flags, cSharpInvokeMemberBinder.CallingContext, array).TryGetExisting();
					DynamicMetaObject[] array2 = new DynamicMetaObject[args.Length - 1];
					Array.Copy(args, 1, array2, 0, args.Length - 1);
					deferredBinding = cSharpInvokeBinder.Defer(cSharpGetMemberBinder.Defer(args[0]), array2);
					return true;
				}
			}
			deferredBinding = null;
			return false;
		}

		private static Expression CreateExpressionTreeFromResult(Expression[] parameters, Scope pScope, Expr pResult)
		{
			ExprBoundLambda expr = GenerateBoundLambda(pScope, pResult);
			ExprBinOp binOp = ExpressionTreeRewriter.Rewrite(expr);
			return ExpressionTreeCallRewriter.Rewrite(binOp, parameters);
		}

		private Type GetArgumentType(ICSharpBinder p, CSharpArgumentInfo argInfo, Expression param, DynamicMetaObject arg, int index)
		{
			Type type = (argInfo.UseCompileTimeType ? param.Type : arg.LimitType);
			if (argInfo.IsByRefOrOut)
			{
				if (index != 0 || !p.IsBinderThatCanHaveRefReceiver)
				{
					type = type.MakeByRefType();
				}
			}
			else if (!argInfo.UseCompileTimeType)
			{
				CType cTypeFromType = SymbolTable.GetCTypeFromType(type);
				CType bestAccessibleType = TypeManager.GetBestAccessibleType(_binder.Context.ContextForMemberLookup, cTypeFromType);
				type = bestAccessibleType.AssociatedSystemType;
			}
			return type;
		}

		private ArgumentObject[] CreateArgumentArray(ICSharpBinder payload, Expression[] parameters, DynamicMetaObject[] args)
		{
			ArgumentObject[] array = new ArgumentObject[parameters.Length];
			for (int i = 0; i < parameters.Length; i++)
			{
				CSharpArgumentInfo argumentInfo = payload.GetArgumentInfo(i);
				array[i] = new ArgumentObject(args[i].Value, argumentInfo, GetArgumentType(payload, argumentInfo, parameters[i], args[i], i));
			}
			return array;
		}

		internal static void PopulateSymbolTableWithPayloadInformation(ICSharpInvokeOrInvokeMemberBinder callOrInvoke, Type callingType, ArgumentObject[] arguments)
		{
			Type type;
			if (callOrInvoke.StaticCall)
			{
				type = arguments[0].Value as Type;
				if (type == null)
				{
					throw Error.BindStaticRequiresType(arguments[0].Info.Name);
				}
			}
			else
			{
				type = callingType;
			}
			SymbolTable.PopulateSymbolTableWithName(callOrInvoke.Name, callOrInvoke.TypeArguments, type);
			if (callOrInvoke.Name.StartsWith("set_", StringComparison.Ordinal) || callOrInvoke.Name.StartsWith("get_", StringComparison.Ordinal))
			{
				SymbolTable.PopulateSymbolTableWithName(callOrInvoke.Name.Substring(4), callOrInvoke.TypeArguments, type);
			}
		}

		private static void AddConversionsForArguments(ArgumentObject[] arguments)
		{
			for (int i = 0; i < arguments.Length; i++)
			{
				ArgumentObject argumentObject = arguments[i];
				SymbolTable.AddConversionsForType(argumentObject.Type);
			}
		}

		internal ExprWithArgs DispatchPayload(ICSharpInvokeOrInvokeMemberBinder payload, ArgumentObject[] arguments, LocalVariableSymbol[] locals)
		{
			return BindCall(payload, CreateCallingObjectForCall(payload, arguments, locals), arguments, locals);
		}

		private static LocalVariableSymbol[] PopulateLocalScope(ICSharpBinder payload, Scope pScope, ArgumentObject[] arguments, Expression[] parameterExpressions)
		{
			LocalVariableSymbol[] array = new LocalVariableSymbol[parameterExpressions.Length];
			for (int i = 0; i < parameterExpressions.Length; i++)
			{
				Expression expression = parameterExpressions[i];
				CType cType = SymbolTable.GetCTypeFromType(expression.Type);
				if ((i != 0 || !payload.IsBinderThatCanHaveRefReceiver) && expression is ParameterExpression parameterExpression && parameterExpression.IsByRef)
				{
					CSharpArgumentInfo info = arguments[i].Info;
					if (info.IsByRefOrOut)
					{
						cType = TypeManager.GetParameterModifier(cType, info.IsOut);
					}
				}
				LocalVariableSymbol localVariableSymbol = SymFactory.CreateLocalVar(NameManager.Add("p" + i), pScope, cType);
				array[i] = localVariableSymbol;
			}
			return array;
		}

		private static ExprBoundLambda GenerateBoundLambda(Scope pScope, Expr call)
		{
			AggregateType predefindType = SymbolLoader.GetPredefindType(PredefinedType.PT_FUNC);
			return ExprFactory.CreateAnonymousMethod(predefindType, pScope, call);
		}

		private Expr CreateLocal(Type type, bool isOut, LocalVariableSymbol local)
		{
			CType dest = ((!isOut) ? SymbolTable.GetCTypeFromType(type) : TypeManager.GetParameterModifier(SymbolTable.GetCTypeFromType(type.GetElementType()), isOut: true));
			ExprLocal expr = ExprFactory.CreateLocal(local);
			Expr expr2 = _binder.tryConvert(expr, dest) ?? _binder.mustCast(expr, dest);
			expr2.Flags |= EXPRFLAG.EXF_LVALUE;
			return expr2;
		}

		internal Expr CreateArgumentListEXPR(ArgumentObject[] arguments, LocalVariableSymbol[] locals, int startIndex, int endIndex)
		{
			Expr first = null;
			Expr last = null;
			if (arguments != null)
			{
				for (int i = startIndex; i < endIndex; i++)
				{
					ArgumentObject argument = arguments[i];
					Expr expr = CreateArgumentEXPR(argument, locals[i]);
					if (first == null)
					{
						first = expr;
						last = first;
					}
					else
					{
						ExprFactory.AppendItemToList(expr, ref first, ref last);
					}
				}
			}
			return first;
		}

		private Expr CreateArgumentEXPR(ArgumentObject argument, LocalVariableSymbol local)
		{
			Expr expr = (argument.Info.LiteralConstant ? ((argument.Value != null) ? ExprFactory.CreateConstant(SymbolTable.GetCTypeFromType(argument.Type), ConstVal.Get(argument.Value)) : ((!argument.Info.UseCompileTimeType) ? ExprFactory.CreateNull() : ExprFactory.CreateConstant(SymbolTable.GetCTypeFromType(argument.Type), default(ConstVal)))) : ((argument.Info.UseCompileTimeType || argument.Value != null) ? CreateLocal(argument.Type, argument.Info.IsOut, local) : ExprFactory.CreateNull()));
			if (argument.Info.NamedArgument)
			{
				expr = ExprFactory.CreateNamedArgumentSpecification(NameManager.Add(argument.Info.Name), expr);
			}
			if (!argument.Info.UseCompileTimeType && argument.Value != null)
			{
				expr.RuntimeObject = argument.Value;

TextureSwapper.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Security;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Authentication;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon.StructWrapping;
using FFMpegCore;
using FFMpegCore.Enums;
using HarmonyLib;
using ImageMagick;
using ImageMagick.Formats;
using KeybindLib.Classes;
using Microsoft.CodeAnalysis;
using NAudio.Wave;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Photon.Pun;
using REPOLib.Modules;
using Sirenix.Utilities;
using Steamworks;
using TMPro;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Video;
using io.wispforest.endec;
using io.wispforest.endec.format.binary;
using io.wispforest.endec.format.newtonsoft;
using io.wispforest.endec.impl;
using io.wispforest.endec.util;
using io.wispforest.textureswapper.api;
using io.wispforest.textureswapper.api.components;
using io.wispforest.textureswapper.api.components.holders;
using io.wispforest.textureswapper.api.config;
using io.wispforest.textureswapper.api.core;
using io.wispforest.textureswapper.api.query;
using io.wispforest.textureswapper.api.query.impl;
using io.wispforest.textureswapper.api.tooltip;
using io.wispforest.textureswapper.patches;
using io.wispforest.textureswapper.patches.ui;
using io.wispforest.textureswapper.utils;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TextureSwapper")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+aff31c16e96127ad6e487f441af26a7c219986c6")]
[assembly: AssemblyProduct("Texture Swapper")]
[assembly: AssemblyTitle("TextureSwapper")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string? Message { get; }

		public string? Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string? message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CollectionBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public string MethodName { get; }

		public CollectionBuilderAttribute(Type builderType, string methodName)
		{
			BuilderType = builderType;
			MethodName = methodName;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public const string RefStructs = "RefStructs";

		public const string RequiredMembers = "RequiredMembers";

		public string FeatureName { get; }

		public bool IsOptional { get; set; }

		public CompilerFeatureRequiredAttribute(string featureName)
		{
			FeatureName = featureName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
	{
		public string[] Arguments { get; }

		public InterpolatedStringHandlerArgumentAttribute(string argument)
		{
			Arguments = new string[1] { argument };
		}

		public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
		{
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal static class IsExternalInit
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class OverloadResolutionPriorityAttribute : Attribute
	{
		public int Priority { get; }

		public OverloadResolutionPriorityAttribute(int priority)
		{
			Priority = priority;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ParamCollectionAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SkipLocalsInitAttribute : Attribute
	{
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ConstantExpectedAttribute : Attribute
	{
		public object? Min { get; set; }

		public object? Max { get; set; }
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ExperimentalAttribute : Attribute
	{
		public string DiagnosticId { get; }

		public string? UrlFormat { get; set; }

		public ExperimentalAttribute(string diagnosticId)
		{
			DiagnosticId = diagnosticId;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object?[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = new object[0];
		}

		public StringSyntaxAttribute(string syntax, params object?[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
}
namespace io.wispforest.textureswapper
{
	public delegate bool LevelPredicate(RunManager manager, Level currentLevel);
	public delegate Level LevelGetter(RunManager manager);
	public enum Operation
	{
		ANY,
		NONE
	}
	public static class LevelUtils
	{
		public static readonly LevelGetter[] INVALID_LEVELS = new LevelGetter[5]
		{
			(RunManager m) => m.levelLobby,
			(RunManager m) => m.levelLobbyMenu,
			(RunManager m) => m.levelMainMenu,
			(RunManager m) => m.levelSplashScreen,
			(RunManager m) => m.levelTutorial
		};

		public static readonly LevelPredicate GENERAL_VALID_PREDICATE = of(Operation.NONE, INVALID_LEVELS);

		public static LevelPredicate and(this LevelPredicate predicate1, LevelPredicate predicate2)
		{
			LevelPredicate predicate3 = predicate1;
			LevelPredicate predicate4 = predicate2;
			return (RunManager manager, Level level) => predicate3(manager, level) && predicate4(manager, level);
		}

		public static LevelPredicate or(this LevelPredicate predicate1, LevelPredicate predicate2)
		{
			LevelPredicate predicate3 = predicate1;
			LevelPredicate predicate4 = predicate2;
			return (RunManager manager, Level level) => predicate3(manager, level) || predicate4(manager, level);
		}

		public static bool isValid(this LevelPredicate predicate)
		{
			RunManager instance = RunManager.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			Level levelCurrent = instance.levelCurrent;
			if ((Object)(object)levelCurrent == (Object)null)
			{
				return false;
			}
			return predicate(instance, levelCurrent);
		}

		public static bool isCurrentLevel(this RunManager manager, Level otherLevel)
		{
			if ((Object)(object)otherLevel == (Object)null)
			{
				return false;
			}
			Level levelCurrent = manager.levelCurrent;
			return (Object)(object)levelCurrent != (Object)null && (Object)(object)levelCurrent == (Object)(object)otherLevel;
		}

		public static LevelPredicate of(Operation operation, params LevelGetter[] getters)
		{
			LevelGetter[] getters2 = getters;
			if (1 == 0)
			{
			}
			LevelPredicate result = operation switch
			{
				Operation.ANY => delegate(RunManager manager, Level _)
				{
					RunManager manager3 = manager;
					return getters2.Select((LevelGetter getter) => getter(manager3)).Any(manager3.isCurrentLevel);
				}, 
				Operation.NONE => delegate(RunManager manager, Level _)
				{
					RunManager manager2 = manager;
					return getters2.Select((LevelGetter getter) => getter(manager2)).Any((Level level) => !manager2.isCurrentLevel(level));
				}, 
				_ => throw new ArgumentOutOfRangeException("operation", operation, "Invalid operation based when creating level predicate"), 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public static LevelGetter ofName(string name)
		{
			string name2 = name;
			return of((string s) => s == name2);
		}

		public static LevelGetter of(Predicate<string> namePredicate)
		{
			Predicate<string> namePredicate2 = namePredicate;
			return (RunManager manager) => manager.levels.Find((Level level) => namePredicate2(((Object)level).name));
		}
	}
	public class TooltipUI : SemiUI
	{
		private enum ChangingState
		{
			HIDDEN,
			SHOWING,
			SHOWN
		}

		private TextMeshProUGUI Text;

		private SemiUI parentUi;

		private string dumpedText = "None";

		private RectTransform baseRect;

		private RectTransform textRect;

		private RectTransform panelRect;

		private float xAxis;

		private float yAxis;

		private float width;

		private float height;

		private float xPivot;

		private float yPivot;

		private float fontSize;

		private SortedDictionary<TooltipKey, string> messageParts = new SortedDictionary<TooltipKey, string>();

		private string? message;

		private bool hasMessageChanged = false;

		private ChangingState state = ChangingState.SHOWN;

		public static readonly TooltipKey BASIC = new TooltipKey(0, "Basic");

		public static readonly TooltipKey DEBUG = new TooltipKey(100, "Debug Info", showName: true, (RunManager _, Level _) => true);

		public static TooltipUI? instance { get; private set; }

		public static void setupTooltipUI(SemiUI parent)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Transform parent2 = ((Component)parent).transform.parent;
				if ((Object)(object)parent2 == (Object)null)
				{
					return;
				}
				GameObject orAddChild = parent2.getOrAddChild("TextureSwapperTooltip");
				TooltipUI tooltipUI = orAddChild.GetComponent<TooltipUI>();
				GameObject orAddChild2 = orAddChild.getOrAddChild("Panel");
				GameObject orAddChild3 = orAddChild.getOrAddChild("Tooltip");
				if ((Object)(object)tooltipUI == (Object)null)
				{
					tooltipUI = orAddChild.AddComponent<TooltipUI>();
					((SemiUI)tooltipUI).textRectTransform = (Transform)(object)ComponentHolderProtocol.GetOrAddComponent<RectTransform>((Object)(object)orAddChild);
					((SemiUI)tooltipUI).uiText = orAddChild3.AddComponent<TextMeshProUGUI>();
					((SemiUI)tooltipUI).showPosition = new Vector2(135f, 105f);
					((SemiUI)tooltipUI).hidePosition = new Vector2(500f, 105f);
					RectTransform orAddComponent = ComponentHolderProtocol.GetOrAddComponent<RectTransform>((Object)(object)orAddChild2);
					Image orAddComponent2 = ComponentHolderProtocol.GetOrAddComponent<Image>((Object)(object)orAddChild2);
					((Graphic)orAddComponent2).color = new Color(0f, 0f, 0f, 0.5765f);
					orAddComponent.anchorMin = Vector2.zero;
					orAddComponent.anchorMax = Vector2.one;
					orAddComponent.pivot = new Vector2(0.5f, 0.5f);
					orAddComponent.offsetMin = Vector2.zero;
					orAddComponent.offsetMax = Vector2.zero;
					if ((Object)(object)instance != (Object)null)
					{
						Object.Destroy((Object)(object)instance);
					}
				}
				tooltipUI.setParentUI(parent);
				instance = tooltipUI;
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)"Unable to handle creating TooltipUI due to an error");
				Plugin.Logger.LogError((object)ex);
			}
		}

		private void setParentUI(SemiUI parent)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			parentUi = parent;
			TextMeshProUGUI uiText = parent.uiText;
			if ((Object)(object)uiText != (Object)null)
			{
				((TMP_Text)Text).font = ((TMP_Text)uiText).font;
				((TMP_Text)Text).fontMaterial = ((TMP_Text)uiText).fontMaterial;
				((TMP_Text)Text).fontMaterials = ((TMP_Text)uiText).fontMaterials;
				((TMP_Text)Text).fontStyle = ((TMP_Text)uiText).fontStyle;
				((TMP_Text)Text).fontSharedMaterial = ((TMP_Text)uiText).fontSharedMaterial;
				((TMP_Text)Text).fontSharedMaterials = ((TMP_Text)uiText).fontSharedMaterials;
				((Graphic)Text).material = ((Graphic)uiText).material;
			}
		}

		protected override void Start()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			instance = this;
			((SemiUI)this).Start();
			Text = base.uiText;
			ref RectTransform reference = ref baseRect;
			Transform textRectTransform = base.textRectTransform;
			reference = (RectTransform)(object)((textRectTransform is RectTransform) ? textRectTransform : null);
			textRect = ((Component)Text).gameObject.GetComponent<RectTransform>();
			panelRect = ((Component)baseRect).gameObject.getOrAddChild("Panel").GetComponent<RectTransform>();
			((TMP_Text)Text).text = "";
			setupTransform(textRect, new Vector2(300f, 300f));
			setupTransform(baseRect, new Vector2(300f, 300f));
			((TMP_Text)Text).fontSize = 6f;
			((TMP_Text)Text).enableAutoSizing = false;
			((TMP_Text)Text).enableWordWrapping = false;
			((TMP_Text)Text).richText = false;
			xAxis = textRect.anchoredPosition.x;
			yAxis = textRect.anchoredPosition.y;
			width = textRect.sizeDelta.x;
			height = textRect.sizeDelta.y;
			xPivot = textRect.pivot.x;
			yPivot = textRect.pivot.y;
			fontSize = ((TMP_Text)Text).fontSize;
		}

		private void setSize(Vector2 size)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			((Vector2)(ref size))..ctor(Math.Max(size.x, 200f), Math.Max(size.y, 0f));
			textRect.sizeDelta = size;
			baseRect.sizeDelta = size;
		}

		private static void setupTransform(RectTransform rectTransform, Vector2 size)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			rectTransform.anchoredPosition = new Vector2(0f, 0f);
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(0f, 1f);
			rectTransform.pivot = new Vector2(0f, 1f);
			rectTransform.sizeDelta = size;
		}

		public void clearMessage(ICollection<TooltipKey> keys)
		{
			if (messageParts.isEmpty())
			{
				return;
			}
			foreach (TooltipKey key in keys)
			{
				messageParts.Remove(key);
			}
			hasMessageChanged = true;
		}

		public void clearMessage()
		{
			if (!messageParts.isEmpty())
			{
				messageParts.Clear();
				hasMessageChanged = true;
			}
		}

		public void removeMessage(TooltipKey key)
		{
			setMessage(key, null);
		}

		public void setMessage(TooltipKey key, string? message)
		{
			if (!messageParts.ContainsKey(key))
			{
				if (message == null)
				{
					return;
				}
			}
			else
			{
				string text = messageParts[key];
				if (text == message)
				{
					if (text == null)
					{
						messageParts.Remove(key);
					}
					return;
				}
			}
			if (message == null)
			{
				messageParts.Remove(key);
			}
			else
			{
				messageParts[key] = message;
			}
			hasMessageChanged = true;
		}

		public ICollection<TooltipKey> getInvalidKeys()
		{
			if (messageParts.isEmpty())
			{
				return new List<TooltipKey>();
			}
			SortedDictionary<TooltipKey, string>.KeyCollection keys = messageParts.Keys;
			RunManager val = RunManager.instance;
			if ((Object)(object)val == (Object)null)
			{
				return keys;
			}
			Level levelCurrent = val.levelCurrent;
			if ((Object)(object)levelCurrent == (Object)null)
			{
				return keys;
			}
			List<TooltipKey> list = new List<TooltipKey>();
			foreach (TooltipKey item in keys)
			{
				if (!item.predicate(val, levelCurrent))
				{
					list.Add(item);
				}
			}
			return list;
		}

		protected override void Update()
		{
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			if (messageParts.isEmpty())
			{
				if (state != 0)
				{
					((SemiUI)this).Hide();
					state = ChangingState.HIDDEN;
				}
			}
			else if (state == ChangingState.HIDDEN)
			{
				((SemiUI)this).Show();
				state = ChangingState.SHOWING;
			}
			else if (!base.isHidden)
			{
				state = ChangingState.SHOWN;
			}
			((SemiUI)this).Update();
			ICollection<TooltipKey> invalidKeys = getInvalidKeys();
			if (invalidKeys.isNotEmpty())
			{
				clearMessage(invalidKeys);
			}
			else if (hasMessageChanged)
			{
				string text = ((!messageParts.isNotEmpty()) ? "" : string.Join("\n", messageParts.Select<KeyValuePair<TooltipKey, string>, string>(delegate(KeyValuePair<TooltipKey, string> pair)
				{
					pair.Deconstruct(out var key, out var value);
					return string.Join("\n", key.name, value);
				})));
				((TMP_Text)Text).text = text;
				hasMessageChanged = false;
			}
			setSize(new Vector2(((TMP_Text)Text).preferredWidth, ((TMP_Text)Text).preferredHeight));
		}
	}
	public class TooltipKey : IComparable<TooltipKey>
	{
		public readonly bool showName;

		public readonly LevelPredicate predicate;

		public int index { get; }

		public string name { get; }

		public TooltipKey(int index, string name, bool showName = false, LevelPredicate? predicate = null)
		{
			this.index = index;
			this.name = name;
			this.showName = showName;
			this.predicate = predicate ?? LevelUtils.GENERAL_VALID_PREDICATE;
			base..ctor();
		}

		public int CompareTo(TooltipKey? other)
		{
			if (this == other)
			{
				return 0;
			}
			return (other == null) ? 1 : index.CompareTo(other.index);
		}

		public override bool Equals(object? obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (this == obj)
			{
				return true;
			}
			if (!(obj is TooltipKey tooltipKey))
			{
				return false;
			}
			return index == tooltipKey.index && name == tooltipKey.name;
		}

		public override int GetHashCode()
		{
			return (index * 397) ^ name.GetHashCode();
		}
	}
	public class ConfigInstance : LayeredConfigFile
	{
		public readonly Getter<bool> enableDebugLogging;

		public readonly Getter<bool> clientSideMode;

		public readonly Getter<IList<string>> textureSwapTargets;

		public readonly Getter<bool> shouldRestrictQueries;

		public readonly Getter<float> tooltipRange;

		public readonly Getter<float> tooltipWaitTime;

		public readonly Getter<bool> showBasicTooltipInfo;

		public readonly Getter<bool> showDescriptionInTooltipInfo;

		public readonly Getter<bool> showTagsInTooltipInfo;

		public readonly Getter<bool> showDebugTooltipInfo;

		public readonly Getter<bool> sendTooltipInfoToLog;

		public readonly Getter<int> infoUnpackingAmount;

		public readonly Getter<float> targetDebugRendererLifeSpan;

		public readonly Getter<bool> showTargetDebugRenderer;

		public readonly Getter<int> dynamicQueriesLevelCount;

		public readonly Getter<bool> onlyFirstAnimationFrame;

		public readonly Getter<bool> allowTranscodingVideos;

		public readonly Getter<bool> prioritizeNewPictures;

		public readonly Getter<bool> prioritizeNewPicturesAcrossLevels;

		public readonly Getter<float> minAudioDistance;

		public readonly Getter<float> maxAudioDistance;

		public readonly Getter<IList<string>> directoryLocations;

		public readonly Getter<IList<string>> staticWebMedia;

		public readonly Getter<bool> funny;

		public readonly Getter<IList<string>> blacklistedTags;

		public readonly Getter<bool> enableGlobalBlacklist;

		public readonly Getter<IList<string>> whitelistedTags;

		private readonly ConfigFile primaryConfigFile;

		private readonly ConfigFile userSettingsConfigFile;

		private static readonly IList<string> DEFAULT_TEXTURE_TARGETS = new List<string>(4) { "\"^(?=.*painting.*)((?!.*frame.*)).*$\"mi", "\"^(magazine\\d*) \\(Instance\\)$\"mi", "\"(magazine stack)\"mi", "\"(Graffiti)\"mi" };

		public ConfigInstance(BaseUnityPlugin plugin, ConfigFile primaryConfigFile)
			: base(plugin)
		{
			this.primaryConfigFile = primaryConfigFile;
			userSettingsConfigFile = (ConfigFile)(object)new DummyConfigFile("user_settings", MetadataHelper.GetMetadata((object)plugin));
			configFileOrder.Add(primaryConfigFile);
			configFileOrder.Add(userSettingsConfigFile);
			io.wispforest.textureswapper.utils.Converter<string, IList<string>> converter = Converter.COMMA_SEPARATED_LIST.xmap((IList<string> input) => input.Where((string s) => !Utility.IsNullOrWhiteSpace(s) && s.Length > 0).ToList(), (IList<string> input) => input);
			primaryConfigFile.section("Common").bind("ClientSideMode", "Enables the ability to use a client based random value that pseudo syncs if the photos are the same on all clients", defaultValue: false, out clientSideMode, (Builder<bool, bool>?)null).bind<string, IList<string>>("TextureTargets", "All texture targets to replace with custom images, Seperated by commas (,) without any spaces", DEFAULT_TEXTURE_TARGETS, out textureSwapTargets, converter)
				.bind<string, IList<string>>("DisallowedTags", "A list of tags that are disallowed from being shown, Seperated by commas (,) without any spaces", new List<string>(), out blacklistedTags, converter)
				.bind("EnableGlobalBlacklist", "Enables the Global Blacklist for generally unsafe queries, disable at your own risk when allowing Restrictive Queries", defaultValue: false, out enableGlobalBlacklist, (Builder<bool, bool>?)null)
				.bind<string, IList<string>>("AllowedTags", "A list of tags that are allowed to be shown, Seperated by commas (,) without any spaces", new List<string>(), out whitelistedTags, converter);
			userSettingsConfigFile.section("Tooltip").bind("WaitTime", "Adjust the time between checking for a tooltip object the player is looking at", UserSettings.property((UserSettings.SettingsData data) => data.tooltipWaitTime, (UserSettings.SettingsData data, float v) => data.tooltipWaitTime = v).setGetter(out tooltipWaitTime)).bind("Range", "Adjust how far a given tooltip object may be picked up", UserSettings.property((UserSettings.SettingsData data) => data.tooltipRange, (UserSettings.SettingsData data, float v) => data.tooltipRange = v).setGetter(out tooltipRange))
				.bind("ShowBasicInfoInTooltip", "Adjust if the basic info should show within the tooltip", UserSettings.property((UserSettings.SettingsData data) => data.showBasicTooltipInfo, (UserSettings.SettingsData data, bool v) => data.showBasicTooltipInfo = v).setGetter(out showBasicTooltipInfo))
				.bind("ShowDebugInfoInTooltip", "Toggles if debug info will show within tooltip info", UserSettings.property((UserSettings.SettingsData data) => data.showDebugTooltipInfo, (UserSettings.SettingsData data, bool v) => data.showDebugTooltipInfo = v).setGetter(out showDebugTooltipInfo))
				.bind("ShowTagsInTooltipInfo", "Toggles if tag information will show up in tooltip info", UserSettings.property((UserSettings.SettingsData data) => data.showTagsInTooltipInfo, (UserSettings.SettingsData data, bool v) => data.showTagsInTooltipInfo = v).setGetter(out showTagsInTooltipInfo))
				.bind("ShowDescriptionInTooltipInfo", "Toggles if description information will show up in tooltip info", UserSettings.property((UserSettings.SettingsData data) => data.showDescriptionInTooltipInfo, (UserSettings.SettingsData data, bool v) => data.showDescriptionInTooltipInfo = v).setGetter(out showDescriptionInTooltipInfo))
				.bind("SendTooltipInfoToLog", "Attempt to send tooltip info to log", UserSettings.property((UserSettings.SettingsData data) => data.sendTooltipInfoToLog, (UserSettings.SettingsData data, bool v) => data.sendTooltipInfoToLog = v).setGetter(out sendTooltipInfoToLog));
			primaryConfigFile.section("DebugInfo").bind("UnpackingAmount", "Adjust how many parents will be unpacked before getting the info from the given targeted object", 1, out infoUnpackingAmount, (Builder<int, int>?)null).bind("ShowTargetDebugRenderer", "When enabled, will add a line renderer to the targeted object when ray casting", defaultValue: false, out showTargetDebugRenderer, (Builder<bool, bool>?)null)
				.bind("TargetDebugRendererLifeSpan", "Adjust the amount of time the given targeted objects debug renderer will persist for", 6f, out targetDebugRendererLifeSpan, (Builder<float, float>?)null);
			primaryConfigFile.section("SwapperSettings").bind("DynamicQueriesLevelCount", "Max levels required to complete before dynamic queries are reloaded for new entries", 4, out dynamicQueriesLevelCount, (Builder<int, int>?)null).bind("OnlyFirstAnimationFrame", "Only uses the first frame of animation instead of all frames", defaultValue: false, out onlyFirstAnimationFrame, (Builder<bool, bool>?)null)
				.bind("AllowTranscodingVideos", "Allows for the ability to transcode video if codec or format is not directly support by unity", defaultValue: false, out allowTranscodingVideos, (Builder<bool, bool>?)null)
				.bind("PrioritizeNewPictures", "Attempts to place newer pictures first over already existing pictures", defaultValue: true, out prioritizeNewPictures, (Builder<bool, bool>?)null)
				.bind("PrioritizeNewPicturesAcrossLevels", "Transfers PrioritizeNewPictures data across levels to fully  place newer pictures first over already existing pictures", defaultValue: true, out prioritizeNewPicturesAcrossLevels, (Builder<bool, bool>?)null)
				.bind("MinAudioDistance", "Minimum distance from the swapped asset in which audio will stay at maximum", 0.5f, out minAudioDistance, (Builder<float, float>?)null)
				.bind("MaxAudioDistance", "Maximum distance from the swapped asset in which audio can be heard", 6.5f, out maxAudioDistance, (Builder<float, float>?)null);
			primaryConfigFile.section("BuiltinQuerySettings").bind<string, IList<string>>("DirectoryLocations", "Location of all directories to be looked at for images, Seperated by commas (,) without any spaces", new List<string>(), out directoryLocations, converter).bind<string, IList<string>>("StaticWebMedia", "Location of all photos to be downloaded, Seperated by commas (,) without any spaces", new List<string>(), out staticWebMedia, converter)
				.bind("Funny", "Its funny", defaultValue: true, out funny, (Builder<bool, bool>?)null);
			System.Converter<TagFilteringData, IList<string>> converter2 = (TagFilteringData input) => input.tags;
			io.wispforest.textureswapper.utils.Converter<string, TagFilteringData> converter3 = converter.xmap((IList<string> input) => new TagFilteringData(input), converter2);
			userSettingsConfigFile.section("User Specific").bind("DebugLogging", "Enables some useful debug logging to check and or validate if things are going properly", UserSettings.property((UserSettings.SettingsData data) => data.debugLogging, (UserSettings.SettingsData data, bool v) => data.debugLogging = v).setGetter(out enableDebugLogging)).bind("RestrictiveQueries", "Will attempt to restrict the queries allowed as an attempt to be safer with image content that is requested", UserSettings.property((UserSettings.SettingsData data) => data.restrictiveQueries, (UserSettings.SettingsData data, bool v) => data.restrictiveQueries = v).setGetter(out shouldRestrictQueries))
				.bind("DisallowedTags", "A list of tags that are disallowed from being shown, Seperated by commas (,) without any spaces", UserSettings.property((UserSettings.SettingsData data) => data.blackListData, (UserSettings.SettingsData data, TagFilteringData v) => data.blackListData = v).setGetter(out blacklistedTags, converter2), converter3)
				.bind("AllowedTags", "A list of tags that are allowed to be shown, Seperated by commas (,) without any spaces", UserSettings.property((UserSettings.SettingsData data) => data.whiteListData, (UserSettings.SettingsData data, TagFilteringData v) => data.whiteListData = v).setGetter(out whitelistedTags, converter2), converter3);
		}

		public void reloadPrimaryConfig()
		{
			primaryConfigFile.Reload();
		}
	}
	public static class PropertyExt
	{
		public static Property<T> setGetter<T>(this Property<T> property, out Getter<T> getter)
		{
			getter = property.asGetter();
			return property;
		}

		public static Property<T> setGetter<T, R>(this Property<T> property, out Getter<R> getter, System.Converter<T, R> converter)
		{
			System.Converter<T, R> converter2 = converter;
			Property<T> property2 = property;
			getter = () => converter2(property2.get());
			return property2;
		}

		public static Getter<T> asGetter<T>(this Property<T> property)
		{
			return property.get;
		}
	}
	public class PhotonEndecAddon
	{
		private static bool hasTypeBeenRegistered;

		internal static void init()
		{
			if (!hasTypeBeenRegistered)
			{
				hasTypeBeenRegistered = true;
			}
		}

		static PhotonEndecAddon()
		{
			hasTypeBeenRegistered = false;
			init();
		}
	}
	public static class PhotonStreamExtensions
	{
		static PhotonStreamExtensions()
		{
			PhotonEndecAddon.init();
		}

		public static PhotonStreamOperation handleObject<T>(this PhotonStream stream, Func<T> encodeGetter, Action<T> decodeHandler) where T : EndecGetter<T>
		{
			if (stream.IsWriting)
			{
				stream.addObject<T>(encodeGetter());
				return PhotonStreamOperation.ENCODE;
			}
			decodeHandler(stream.getObject<T>());
			return PhotonStreamOperation.DECODE;
		}

		public static PhotonStreamOperation handleObject<T>(this PhotonStream stream, ref T t) where T : EndecGetter<T>
		{
			if (stream.IsWriting)
			{
				stream.addObject<T>(t);
				return PhotonStreamOperation.ENCODE;
			}
			t = stream.getObject<T>();
			return PhotonStreamOperation.DECODE;
		}

		public static void addObject<T>(this PhotonStream stream, T data) where T : EndecGetter<T>
		{
			if (!stream.IsWriting)
			{
				throw new Exception("You can not write a object to a PhotonStream that is currently reading!");
			}
			stream.SendNext((object)new EndecedStructWrapper<T>(data).getBytes());
		}

		public static T getObject<T>(this PhotonStream stream) where T : EndecGetter<T>
		{
			if (!stream.IsReading)
			{
				throw new Exception("You can not read an object from a PhotonStream that is currently writting!");
			}
			object obj = stream.PeekNext();
			if (obj is byte[] bytes)
			{
				stream.ReceiveNext();
				return ByteDataAccess.decodeFromBytes<T>(EndecGetter.Endec<T>(), bytes);
			}
			throw new Exception($"Unable to use the current peeked object from a PhotonStream due to the type mismatch! [Type: {obj.GetType()}, Required Type: PhotonEndecHolder]");
		}

		public static void dumpPhotonStreamToLog(this PhotonStream stream, Action<Action<Action<string>>> logActionCallback)
		{
			Type type2 = ((object)stream).GetType();
			FieldInfo field = type2.GetField("currentItem", BindingFlags.Instance);
			List<object> list = new List<object>();
			int currentIndex = (field?.GetValue(stream) as int?).GetValueOrDefault(-1);
			list.AddRange(stream.ToArray());
			logActionCallback(delegate(Action<string> logAction)
			{
				logAction("Dumping the given PhotonStream Data: ");
			});
			for (int i = 0; i < list.Count; i++)
			{
				object obj = list[i];
				Type type = obj.GetType();
				logActionCallback(delegate(Action<string> logAction)
				{
					logAction(string.Format("    [{0}, {1}]: Type=({2}), Object:({3})", i, (currentIndex == i) ? "X" : "O", type.FullName, obj));
				});
			}
		}
	}
	public enum PhotonStreamOperation
	{
		ENCODE,
		DECODE
	}
	public class ByteDataHolder : ByteDataAccess
	{
		private byte[] bytes = new byte[0];

		public ByteDataAccess setBytes(byte[] bytes)
		{
			this.bytes = bytes;
			return this;
		}

		public byte[] getBytes()
		{
			return bytes;
		}

		public override bool Equals(object? obj)
		{
			if (this == obj)
			{
				return true;
			}
			if (this != null)
			{
				return getBytes().Equals(((ByteDataAccess)this).getBytes());
			}
			return false;
		}

		public override int GetHashCode()
		{
			return bytes.GetHashCode();
		}
	}
	public interface ByteDataAccess
	{
		byte[] getBytes();

		static byte[] encodeAsBytes<T>(Endec<T> endec, T data)
		{
			MemoryStream stream = new MemoryStream();
			((Endec<BinaryWriter>)(object)endec).encodeFully<BinaryWriter>((Func<Serializer<BinaryWriter>>)(() => (Serializer<BinaryWriter>)(object)BinaryWriterSerializer.of(new BinaryWriter(stream))), (BinaryWriter)data);
			return stream.GetBuffer();
		}

		static T decodeFromBytes<T>(Endec<T> endec, byte[] bytes)
		{
			return ((Endec<BinaryReader>)(object)endec).decodeFully<BinaryReader>((Func<BinaryReader, Deserializer<BinaryReader>>)((BinaryReader reader) => (Deserializer<BinaryReader>)(object)BinaryReaderDeserializer.of(reader)), new BinaryReader(new MemoryStream(bytes)));
		}
	}
	internal sealed class EndecedStructWrapper<T> : StructWrapper, ByteDataAccess where T : EndecGetter<T>
	{
		public readonly T data;

		public EndecedStructWrapper(T data)
			: base(typeof(ByteDataAccess), (WrappedType)0)
		{
			this.data = data;
		}

		public static EndecedStructWrapper<T> of<T>(object obj) where T : EndecGetter<T>
		{
			if (!(obj is T val) || 1 == 0)
			{
				throw new Exception($"Unable to create EndecedStructWrapper as the object is not the correct type! [Type: {typeof(object)}, Obj: {obj}]");
			}
			return new EndecedStructWrapper<T>(val);
		}

		public byte[] getBytes()
		{
			return ByteDataAccess.encodeAsBytes(EndecGetter.Endec<T>(), data);
		}

		public override bool Equals(object? obj)
		{
			if (this == obj)
			{
				return true;
			}
			if (obj is EndecedStructWrapper<T> endecedStructWrapper)
			{
				return ((object)data).Equals((object?)endecedStructWrapper.data);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return ((object)data).GetHashCode();
		}

		public override object Box()
		{
			return data;
		}

		public override void DisconnectFromPool()
		{
		}

		public override void Dispose()
		{
		}

		public override string ToString()
		{
			return ((object)StructWrapperUtility.Unwrap<T>((object)this)).ToString();
		}

		public override string ToString(bool writeTypeInfo)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return writeTypeInfo ? $"(EndecedStructWrapper<{base.wrappedType}>){((object)StructWrapperUtility.Unwrap<T>((object)this)).ToString()}" : ((object)this).ToString();
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("TextureSwapper", "Texture Swapper", "1.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		public delegate void AdditionalQueryLookup(Action<Identifier, IList<MediaQuery>> addCallback);

		internal static readonly List<string> RAW_NAMES = new List<string>(4) { "texture_swapper_queries", "painting_swapper_images", "RandomPaintingSwap_Images", "CustomPaintings" };

		private static Plugin? _INSTANCE = null;

		private static ManualLogSource? _LOGGER = null;

		private static ConfigInstance? _CONFIG_ACCESS = null;

		private static Thread? _MAIN_THREAD = null;

		private readonly Harmony _harmony = new Harmony("TextureSwapper");

		internal static string id = "texture_swapper";

		private static MonoEvent _EVENTS;

		private static bool? _IS_FUNNY_PERSON;

		private List<string> directoriesToBeLoaded = new List<string>();

		internal static Identifier funnyId = Identifier.ofUri("https://i.imgur.com/0GTrjm7.jpeg");

		private bool hasLoadedQueries = false;

		private readonly Dictionary<Identifier, IList<MediaQuery>> dynamicTypeToQueries = new Dictionary<Identifier, IList<MediaQuery>>();

		private int pastLevelsCompleted = 0;

		private ISet<Guid> oldDynamicQueries = new HashSet<Guid>();

		private bool mustLoadQueriesFirst = true;

		internal static int funnyChance = 3;

		internal static Plugin Instance => getOrThrow(_INSTANCE, "Texture Swapper _instance");

		internal static ManualLogSource Logger => getOrThrow<ManualLogSource>(_LOGGER, "Texture Swapper _logger");

		internal static ConfigInstance config => getOrThrow(_CONFIG_ACCESS, "Texture Swapper _config_access");

		internal static ActiveSwapperStats? prevHolder { get; set; } = null;


		internal static string TempStoragePath => Path.Combine(Application.temporaryCachePath, "painting_swapper");

		internal static string TempVideoStoragePath => Path.Combine(TempStoragePath, "videos");

		internal static string TempImageStoragePath => Path.Combine(TempStoragePath, "images");

		internal static string TempAudioStoragePath => Path.Combine(TempStoragePath, "audio");

		internal static MonoEvent Events => getOrThrow(_EVENTS, "Texture Swapper _instance");

		public static bool isFunnyPerson
		{
			get
			{
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				if (!config.funny())
				{
					return false;
				}
				if (!_IS_FUNNY_PERSON.HasValue && SteamClient.IsValid)
				{
					_IS_FUNNY_PERSON = SteamClient.SteamId.Value == 76561198385078416L;
					Logger.LogInfo((object)$"Current User SteamID: {SteamClient.SteamId.Value}");
				}
				return _IS_FUNNY_PERSON.GetValueOrDefault();
			}
		}

		public static Keybind refreshClientData { get; private set; }

		public static event AdditionalQueryLookup ADDITIONAL_QUERY_LOOKUP;

		private static T getOrThrow<T>(T? value, string fieldName)
		{
			if (value != null)
			{
				return value;
			}
			throw new NullReferenceException("Unable to get " + fieldName + " as it has not been initialized yet.");
		}

		public static void logIfDebugging(Action<ManualLogSource> logAction, Func<bool>? predicate = null)
		{
			if (config.enableDebugLogging() && (predicate == null || predicate()))
			{
				logAction(Logger);
			}
		}

		public static void logIfDebugging(Func<string> message, Func<bool>? predicate = null)
		{
			if (config.enableDebugLogging() && (predicate == null || predicate()))
			{
				Logger.LogInfo((object)message());
			}
		}

		public static bool isMainThread()
		{
			return Thread.CurrentThread == _MAIN_THREAD;
		}

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			_LOGGER = ((BaseUnityPlugin)this).Logger;
			_INSTANCE = this;
			GameObject val = new GameObject("TextureSwapperEventHolder");
			((Object)val).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)val);
			_EVENTS = val.AddComponent<MonoEvent>();
			Events.onUpdateCallback += delegate
			{
				onUpdate();
			};
			_CONFIG_ACCESS = new ConfigInstance((BaseUnityPlugin)(object)this, ((BaseUnityPlugin)this).Config);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Texture Swapper has begun setup...");
			logIfDebugging(delegate(ManualLogSource source)
			{
				source.LogError((object)("Using the following path to store files temporarily: " + TempStoragePath));
			});
			FileUtils.deleteOldFiles(TempStoragePath, 2);
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			if (_MAIN_THREAD == null)
			{
				_MAIN_THREAD = Thread.CurrentThread;
			}
			LocalFiles.init();
			MediaIdentifiers.initErrorImages(directoryName);
			_harmony.PatchAll(typeof(SemiFuncPatch));
			_harmony.PatchAll(typeof(RunManagerPatch));
			_harmony.PatchAll(typeof(DefaultPoolPatch));
			_harmony.PatchAll(typeof(UnityEngineObjectPatch));
			_harmony.PatchAll(typeof(EnergyUIPatch));
			_harmony.PatchAll(typeof(HealthUIPatch));
			if (Chainloader.PluginInfos.ContainsKey("bulletbot.keybindlib"))
			{
				_harmony.PatchAll(typeof(KeybindsPatch));
			}
			PhotonEndecAddon.init();
			PrefabInstantiationEvent.onPrefabInstantiation += delegate(GameObject gameObject, string _, Vector3 _, Quaternion _)
			{
				SwapperComponentSetupUtils.commonSide(gameObject);
			};
			ObjectInstantiateEvent.onObjectInstantiation += delegate(Object o, Vector3? position, Quaternion? rotation)
			{
				GameObject val2 = (GameObject)(object)((o is GameObject) ? o : null);
				if (val2 != null)
				{
					if (!SemiFunc.IsMultiplayer() && hasLoadedQueries)
					{
						SwapperComponentSetupUtils.commonSide(val2);
					}
					MeshRenderer[] componentsInChildren = val2.GetComponentsInChildren<MeshRenderer>();
					if (componentsInChildren != null)
					{
						MeshRendererCache.getOrCreate().addRenderers(new List<MeshRenderer>(componentsInChildren));
					}
				}
				else
				{
					MeshRenderer val3 = (MeshRenderer)(object)((o is MeshRenderer) ? o : null);
					if (val3 != null)
					{
						MeshRendererCache.getOrCreate().addRenderer(val3);
					}
				}
			};
			SceneManager.sceneLoaded += delegate
			{
				MeshRendererCache.getOrCreate().getRenderers(refreshRenderers: true);
			};
			LevelEvents.ON_CHANGE += handleDynamicQueries;
			BasicTooltipInfo.init();
			DebugTooltipInfo.init();
			refreshClientData = Keybinds.Bind("Refresh", "Refresh Client Side Data", "<No Binding>");
			DebugErrors.decodeErrorHook = delegate(object o, Exception exception)
			{
				object o2 = o;
				Exception exception2 = exception;
				logIfDebugging(delegate(ManualLogSource logger)
				{
					logger.LogError((object)"Error occured within endec when decoding object: ");
					logger.LogError((object)("Object: " + o2.ToString()));
					logger.LogError((object)exception2);
				});
			};
			Logger.LogInfo((object)"Plugin Texture Swapper loaded Successfully!");
		}

		public void Start()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			Logger.LogInfo((object)"Plugin Texture Swapper starting!");
			List<string> list = new List<string>();
			list.Add(Path.Combine(directoryName, RAW_NAMES[0]));
			list.AddRange(config.directoryLocations());
			list.Add(Path.Combine(Paths.ConfigPath, "texture_swapper_queries"));
			foreach (string directory in list)
			{
				try
				{
					if (!Directory.Exists(directory))
					{
						Directory.CreateDirectory(directory);
						logIfDebugging(delegate(ManualLogSource source)
						{
							source.LogInfo((object)("Folder " + directory + " created successfully!"));
						});
					}
					else
					{
						logIfDebugging(delegate(ManualLogSource source)
						{
							source.LogInfo((object)("Folder " + directory + " detected!)"));
						});
					}
				}
				catch (Exception ex)
				{
					Exception ex2 = ex;
					Exception e = ex2;
					logIfDebugging(delegate(ManualLogSource source)
					{
						source.LogError((object)("Unable to create directory [" + directory + "]:"));
						source.LogError((object)e);
					});
				}
			}
			string directoryName2 = Path.GetDirectoryName(directoryName);
			string[] directories = Directory.GetDirectories(directoryName2);
			foreach (string text in directories)
			{
				foreach (string rAW_NAME in RAW_NAMES)
				{
					string item = Path.Combine(text, rAW_NAME);
					if (Directory.Exists(text))
					{
						list.Add(item);
					}
				}
			}
			directoriesToBeLoaded = list;
			hasLoadedQueries = false;
			if (config.funny())
			{
				ADDITIONAL_QUERY_LOOKUP += delegate(Action<Identifier, IList<MediaQuery>> callback)
				{
					callback(StaticWebQueryType.ID, new List<MediaQuery>(1) { StaticWebQuery.of(new List<string>(1) { "https://i.imgur.com/0GTrjm7.jpeg" }) });
				};
			}
			Logger.LogInfo((object)"Plugin Texture Swapper started Successfully!");
		}

		internal void loadQueries(string? levelName = null)
		{
			if (hasLoadedQueries)
			{
				return;
			}
			if (levelName != null)
			{
				RunManager instance = RunManager.instance;
				if (levelName.Equals(((Object)instance.levelMainMenu).name) || levelName.Equals(((Object)instance.levelSplashScreen).name) || levelName.Equals(((Object)instance.levelTutorial).name))
				{
					return;
				}
			}
			Logger.LogInfo((object)"Attempting Texture Swapper Loading!");
			Dictionary<Identifier, IList<MediaQuery>> typeToQueries = new Dictionary<Identifier, IList<MediaQuery>>();
			Plugin.ADDITIONAL_QUERY_LOOKUP?.Invoke(delegate(Identifier identifier, IList<MediaQuery> list)
			{
				typeToQueries.computeIfAbsent(identifier, (Identifier _) => new List<MediaQuery>()).addAll(list);
			});
			StructEndec<QueryEntries> queryEntriesEndec = StructEndecBuilder.of<QueryEntries, IDictionary<Identifier, IList<MediaQuery>>, IDictionary<Identifier, IList<MediaQuery>>>(MediaQueryTypeRegistry.GROUPED_QUERY_DATA.optionalFieldOf<QueryEntries>("query_entries", (Func<QueryEntries, IDictionary<Identifier, IList<MediaQuery>>>)((QueryEntries pair) => pair.queries), (Func<IDictionary<Identifier, IList<MediaQuery>>>)(() => new Dictionary<Identifier, IList<MediaQuery>>())), MediaQueryTypeRegistry.GROUPED_QUERY_DATA.optionalFieldOf<QueryEntries>("dynamic_query_entries", (Func<QueryEntries, IDictionary<Identifier, IList<MediaQuery>>>)((QueryEntries pair) => pair.queries), (Func<IDictionary<Identifier, IList<MediaQuery>>>)(() => new Dictionary<Identifier, IList<MediaQuery>>())), (Func<IDictionary<Identifier, IList<MediaQuery>>, IDictionary<Identifier, IList<MediaQuery>>, QueryEntries>)((IDictionary<Identifier, IList<MediaQuery>> queries, IDictionary<Identifier, IList<MediaQuery>> dynamicQueries) => new QueryEntries(queries, dynamicQueries)));
			Task.Run(delegate
			{
				foreach (string item in directoriesToBeLoaded)
				{
					try
					{
						typeToQueries.computeIfAbsent(LocalMediaQueryType.ID, (Identifier _) => new List<MediaQuery>()).Add(LocalMediaQuery.ofDirectory(item));
					}
					catch (Exception arg)
					{
						Logger.LogError((object)$"Unable to query local directory: {arg}");
					}
					if (Directory.Exists(item))
					{
						string[] files = Directory.GetFiles(item, "*.json");
						string[] array = files;
						foreach (string text in array)
						{
							try
							{
								QueryEntries queryEntries = JsonUtils.parseFromFile<QueryEntries>(text, (Endec<QueryEntries>)(object)queryEntriesEndec);
								if (queryEntries != null)
								{
									typeToQueries.merge(queryEntries.queries);
									dynamicTypeToQueries.merge(queryEntries.dynamicQueries);
								}
							}
							catch (Exception arg2)
							{
								Logger.LogError((object)$"Unable to parse the given file [{text}] as MediaQueries: {arg2}");
							}
						}
					}
				}
				runQueries("alternative_censor_images", UserSettings.data.alternativeCensorImages);
				runQueries("static_queries", typeToQueries);
				runQueries("dynamic_queries", dynamicTypeToQueries);
			});
			Logger.LogInfo((object)"Queued up all loading for Texture Swapper!");
			hasLoadedQueries = true;
		}

		private void handleDynamicQueries(int levelsCompleted, string level)
		{
			int num = config.dynamicQueriesLevelCount();
			funnyChance = Math.Min(100, funnyChance * 2);
			if (levelsCompleted == 0)
			{
				foreach (Guid oldDynamicQuery in oldDynamicQueries)
				{
					MediaSwapperStorage.removeMediaWithGuid(oldDynamicQuery);
				}
				oldDynamicQueries.Clear();
				return;
			}
			int num2 = levelsCompleted - pastLevelsCompleted;
			if (num2 >= num - 1 && mustLoadQueriesFirst)
			{
				Dictionary<Identifier, IList<MediaQuery>> newDynamicTypeToQueries = new Dictionary<Identifier, IList<MediaQuery>>();
				dynamicTypeToQueries.forEach<Identifier, IList<MediaQuery>>(delegate(Identifier identifier, IList<MediaQuery> list)
				{
					newDynamicTypeToQueries[identifier] = list.Select(delegate(MediaQuery query)
					{
						oldDynamicQueries.Add(query.guid);
						return query.createFrom();
					}).ToList();
				});
				runQueries("dynamic_queries", newDynamicTypeToQueries);
				mustLoadQueriesFirst = false;
			}
			else if (num2 >= num)
			{
				MediaSwapperStorage.removeMediaWithGuids(oldDynamicQueries);
				oldDynamicQueries.Clear();
				mustLoadQueriesFirst = true;
				pastLevelsCompleted = levelsCompleted;
			}
		}

		internal static void runQueries(string entryName, IDictionary<Identifier, IList<MediaQuery>> typeToQueries)
		{
			string entryName2 = entryName;
			IDictionary<Identifier, IList<MediaQuery>> typeToQueries2 = typeToQueries;
			if (typeToQueries2.Count <= 0)
			{
				return;
			}
			Task.Run(delegate
			{
				Logger.LogInfo((object)("Running Media Queries in Texture Swapper [" + entryName2 + "]"));
				foreach (KeyValuePair<Identifier, IList<MediaQuery>> entry in typeToQueries2)
				{
					Identifier key = entry.Key;
					SemaphoreIdentifier semaphoreIdentifier = MediaQueryTypeRegistry.getTypeDyn(key).createSemaphoreIdentifier(true);
					MultiThreadHelper.run(semaphoreIdentifier, delegate
					{
						foreach (MediaQuery item in entry.Value)
						{
							if (!MediaQueryTypeRegistry.attemptToHandleQuery(item))
							{
								Logger.LogError((object)$"Unable to handle the given query: [Id: {entry.Key}]");
							}
						}
					});
				}
				Logger.LogInfo((object)"Ran all queries, results are to be appearing within the future");
			});
		}

		private void onUpdate()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			MediaSwapperStorage.handleToBeStoredHandlers();
			MainThreadHelper.handleActionsOnMainThread();
			ImageSequenceHolder.actIfPresent(delegate(ImageSequenceHolder holder)
			{
				holder.checkIfMaterialsLoaded();
			});
			MultiThreadHelper.INSTANCE.pruneTasks();
			DebugTooltipInfo.update();
			BasicTooltipInfo.update();
			if (!SemiFunc.InputDown(refreshClientData.inputKey))
			{
				return;
			}
			config.reloadPrimaryConfig();
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
			GameObject[] array = rootGameObjects;
			foreach (GameObject val in array)
			{
				if (((Object)val).name.Equals("Level Generator"))
				{
					SwapperComponentSetupUtils.unswapScene(val);
					ActiveSwapperStats.getOrCreate().reset();
					SwapperComponentSetupUtils.commonSide(val);
				}
			}
		}
	}
	public class QueryEntries
	{
		public IDictionary<Identifier, IList<MediaQuery>> queries { get; }

		public IDictionary<Identifier, IList<MediaQuery>> dynamicQueries { get; }

		public QueryEntries(IDictionary<Identifier, IList<MediaQuery>> queries, IDictionary<Identifier, IList<MediaQuery>> dynamicQueries)
		{
			this.queries = queries;
			this.dynamicQueries = dynamicQueries;
			base..ctor();
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TextureSwapper";

		public const string PLUGIN_NAME = "Texture Swapper";

		public const string PLUGIN_VERSION = "1.2.0";
	}
}
namespace io.wispforest.textureswapper.patches
{
	[HarmonyPatch(typeof(DefaultPool))]
	public class DefaultPoolPatch
	{
		[HarmonyPatch("Instantiate")]
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void AwakePatch(string prefabId, Vector3 position, Quaternion rotation, ref GameObject __result)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			PrefabInstantiationEvent.onInstantiation(__result, prefabId, position, rotation);
		}
	}
	[HarmonyPatch(typeof(Keybinds))]
	public class KeybindsPatch
	{
		[HarmonyPatch("GetPluginByCallingAssembly")]
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void AlterAssemblyCheck(Assembly assembly, ref BepInPlugin __result)
		{
			if (__result == null)
			{
				__result = (from x in assembly.GetTypes()
					select ((MemberInfo)x).GetCustomAttribute<BepInPlugin>()).selectNonNull().FirstOrDefault() ?? (from x in assembly.GetExportedTypes()
					select ((MemberInfo)x).GetCustomAttribute<BepInPlugin>()).selectNonNull().FirstOrDefault();
			}
		}
	}
	[HarmonyPatch(typeof(RunManager))]
	internal static class RunManagerPatch
	{
		[HarmonyPatch("RestartScene")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		private static void RestartScenePatch()
		{
			RunManager instance = RunManager.instance;
			LevelEvents.onLevelChange(instance.levelsCompleted, ((Object)instance.levelCurrent).name);
		}
	}
	[HarmonyPatch(typeof(SemiFunc))]
	public class SemiFuncPatch
	{
		[HarmonyPatch("MenuActionSingleplayerGame")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		private static void singlePlayerStart()
		{
			Plugin.logIfDebugging(() => "Starting SinglePlayer!");
			Plugin.Instance.loadQueries();
		}

		[HarmonyPatch("MenuActionHostGame")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		private static void multiplayerStart()
		{
			Plugin.logIfDebugging(() => "Starting MultiPlayer!");
			Plugin.Instance.loadQueries();
		}

		[HarmonyPatch("OnSceneSwitch")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		private static void onSceneSwitch(bool _gameOver, bool _leaveGame)
		{
			string levelName = ((Object)RunManager.instance.levelCurrent).name;
			Plugin.logIfDebugging(() => "Switching scene! Level: " + levelName);
			Plugin.Instance.loadQueries(levelName);
		}
	}
	[HarmonyPatch(typeof(Object))]
	public class UnityEngineObjectPatch
	{
		[CompilerGenerated]
		private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<MethodInfo> <allMethods>5__1;

			private IEnumerator<MethodInfo> <>s__2;

			private MethodInfo <method>5__3;

			private ParameterInfo[] <parameters>5__4;

			private int <length>5__5;

			private Type[] <genericTypes>5__6;

			private Type[] <>s__7;

			private int <>s__8;

			private Type <genericType>5__9;

			private Type[] <>s__10;

			private int <>s__11;

			private Type <genericType>5__12;

			private Type[] <>s__13;

			private int <>s__14;

			private Type <genericType>5__15;

			MethodBase IEnumerator<MethodBase>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TargetMethods>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 7u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<allMethods>5__1 = null;
				<>s__2 = null;
				<method>5__3 = null;
				<parameters>5__4 = null;
				<genericTypes>5__6 = null;
				<>s__7 = null;
				<genericType>5__9 = null;
				<>s__10 = null;
				<genericType>5__12 = null;
				<>s__13 = null;
				<genericType>5__15 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<allMethods>5__1 = from m in typeof(Object).GetMethods(BindingFlags.Static | BindingFlags.Public)
							where m.Name == "Instantiate"
							select m;
						<>s__2 = <allMethods>5__1.GetEnumerator();
						<>1__state = -3;
						goto IL_05a7;
					case 1:
						<>1__state = -3;
						goto IL_0591;
					case 2:
						<>1__state = -3;
						<genericType>5__9 = null;
						<>s__8++;
						goto IL_01d1;
					case 3:
						<>1__state = -3;
						goto IL_0591;
					case 4:
						<>1__state = -3;
						<genericType>5__12 = null;
						<>s__11++;
						goto IL_030d;
					case 5:
						<>1__state = -3;
						goto IL_03b6;
					case 6:
						<>1__state = -3;
						goto IL_0591;
					case 7:
						<>1__state = -3;
						goto IL_0591;
					case 8:
						{
							<>1__state = -3;
							<genericType>5__15 = null;
							<>s__14++;
							goto IL_0578;
						}
						IL_01d1:
						if (<>s__8 < <>s__7.Length)
						{
							<genericType>5__9 = <>s__7[<>s__8];
							<>2__current = <method>5__3.MakeGenericMethod(<genericType>5__9);
							<>1__state = 2;
							return true;
						}
						<>s__7 = null;
						goto IL_0591;
						IL_0591:
						<parameters>5__4 = null;
						<genericTypes>5__6 = null;
						<method>5__3 = null;
						goto IL_05a7;
						IL_05a7:
						if (<>s__2.MoveNext())
						{
							<method>5__3 = <>s__2.Current;
							<parameters>5__4 = <method>5__3.GetParameters();
							<length>5__5 = <parameters>5__4.Length;
							<genericTypes>5__6 = new Type[1] { typeof(Object) };
							if (<length>5__5 == 1)
							{
								if (!<method>5__3.IsGenericMethodDefinition)
								{
									<>2__current = <method>5__3;
									<>1__state = 1;
									return true;
								}
								<>s__7 = <genericTypes>5__6;
								<>s__8 = 0;
								goto IL_01d1;
							}
							if (<length>5__5 == 2)
							{
								if (!<method>5__3.IsGenericMethodDefinition)
								{
									if (<parameters>5__4.isMatch(typeof(Object), typeof(Scene)))
									{
										<>2__current = <method>5__3;
										<>1__state = 3;
										return true;
									}
								}
								else if (<parameters>5__4.isMatch(1, typeof(InstantiateParameters)))
								{
									<>s__10 = <genericTypes>5__6;
									<>s__11 = 0;
									goto IL_030d;
								}
							}
							else if (<length>5__5 == 3)
							{
								if (!<method>5__3.IsGenericMethodDefinition)
								{
									if (<parameters>5__4.isMatch(typeof(Object), typeof(Vector3), typeof(Quaternion)))
									{
										<>2__current = <method>5__3;
										<>1__state = 5;
										return true;
									}
									goto IL_03b6;
								}
							}
							else if (<length>5__5 == 4)
							{
								if (!<method>5__3.IsGenericMethodDefinition)
								{
									if (<parameters>5__4.isMatch(typeof(Object), typeof(Vector3), typeof(Quaternion), typeof(Transform)))
									{
										<>2__current = <method>5__3;
										<>1__state = 7;
										return true;
									}
								}
								else if (<parameters>5__4.isMatch(typeof(Object), typeof(Vector3), typeof(Quaternion), typeof(InstantiateParameters)))
								{
									<>s__13 = <genericTypes>5__6;
									<>s__14 = 0;
									goto IL_0578;
								}
							}
							goto IL_0591;
						}
						<>m__Finally1();
						<>s__2 = null;
						return false;
						IL_03b6:
						if (<parameters>5__4.isMatch(typeof(Object), typeof(Transform), typeof(bool)))
						{
							<>2__current = <method>5__3;
							<>1__state = 6;
							return true;
						}
						goto IL_0591;
						IL_0578:
						if (<>s__14 < <>s__13.Length)
						{
							<genericType>5__15 = <>s__13[<>s__14];
							<>2__current = <method>5__3.MakeGenericMethod(<genericType>5__15);
							<>1__state = 8;
							return true;
						}
						<>s__13 = null;
						goto IL_0591;
						IL_030d:
						if (<>s__11 < <>s__10.Length)
						{
							<genericType>5__12 = <>s__10[<>s__11];
							<>2__current = <method>5__3.MakeGenericMethod(<genericType>5__12);
							<>1__state = 4;
							return true;
						}
						<>s__10 = null;
						goto IL_0591;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__2 != null)
				{
					<>s__2.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <TargetMethods>d__0(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MethodBase>)this).GetEnumerator();
			}
		}

		[IteratorStateMachine(typeof(<TargetMethods>d__0))]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TargetMethods>d__0(-2);
		}

		[HarmonyPostfix]
		public static void afterObjectInstantiation(Object __result)
		{
			ObjectInstantiateEvent.setupAndRun(__result);
		}
	}
	internal static class ParameterInfosExt
	{
		public static bool isMatch(this ParameterInfo[] array, params Type[] pattern)
		{
			return array.isMatch(0, pattern);
		}

		public static bool isMatch(this ParameterInfo[] array, int offset = 0, params Type[] pattern)
		{
			if (array.Length < pattern.Length + offset)
			{
				return false;
			}
			for (int i = 0; i < pattern.Length; i++)
			{
				ParameterInfo parameterInfo = array[offset + i];
				Type type = pattern[i];
				if (parameterInfo.GetType() != type)
				{
					return false;
				}
			}
			return true;
		}
	}
}
namespace io.wispforest.textureswapper.patches.ui
{
	[HarmonyPatch(typeof(EnergyUI))]
	public class EnergyUIPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		private static void StartHook(EnergyUI __instance)
		{
			TooltipUI.setupTooltipUI((SemiUI)(object)__instance);
		}
	}
	[HarmonyPatch(typeof(HealthUI))]
	public class HealthUIPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		private static void StartHook(EnergyUI __instance)
		{
			TooltipUI.setupTooltipUI((SemiUI)(object)__instance);
		}
	}
}
namespace io.wispforest.textureswapper.utils
{
	public static class ConfigFileExtensions
	{
		public static SectionBinder section(this ConfigFile file, string section)
		{
			return new SectionBinder(file, section);
		}

		public static void settingsChangedSafe<T>(this ConfigEntry<T> entry, EntryChangedHandler<T> changedHandler)
		{
			EntryChangedHandler<T> changedHandler2 = changedHandler;
			bool isLocked = false;
			entry.SettingChanged += delegate(object sender, EventArgs _)
			{
				if (!isLocked)
				{
					ConfigEntry<T> changedEntry = sender as ConfigEntry<T>;
					if (changedEntry != null)
					{
						isLocked = true;
						changedHandler2((ConfigEntryBase)(object)changedEntry, changedEntry.Value, (T t) => changedEntry.Value = t);
						isLocked = false;
					}
				}
			};
		}
	}
	public class ConfigEntryBuilder<T, R>
	{
		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private SectionBinder <binder>P;

		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private string <key>P;

		private Converter<T, R> converter;

		private R _defaultValue;

		private bool hasDefaultValue;

		private string? _description;

		private AcceptableValueBase? _acceptableValues;

		private object[]? _tags;

		internal EntryChangedHandler<R>? _onChangeCallback;

		private bool hasDescription;

		public ConfigEntryBuilder(SectionBinder binder, string key, Converter<T, R> converter)
		{
			<binder>P = binder;
			<key>P = key;
			this.converter = converter;
			hasDefaultValue = false;
			hasDescription = false;
			base..ctor();
		}

		internal ConfigEntryBuilder<T, R> handle(Builder<T, R>? builder)
		{
			builder?.Invoke(this);
			return this;
		}

		public ConfigEntryBuilder<T, R> defaultValue(R defaultValue)
		{
			_defaultValue = defaultValue;
			hasDefaultValue = true;
			return this;
		}

		public ConfigEntryBuilder<T, R> description(string? description)
		{
			_description = description;
			return this;
		}

		public ConfigEntryBuilder<T, R> description(AcceptableValueBase acceptableValues)
		{
			_acceptableValues = acceptableValues;
			return this;
		}

		public ConfigEntryBuilder<T, R> tags(object[]? tags)
		{
			_tags = tags;
			return this;
		}

		public ConfigEntryBuilder<T, R> onChange(EntryChangedHandler<R> callback)
		{
			_onChangeCallback = _onChangeCallback?.and(callback) ?? callback;
			return this;
		}

		public ConfigEntryBuilder<T, R> onChange(Validator<R> validator)
		{
			Validator<R> validator2 = validator;
			return onChange(delegate(ConfigEntryBase _, R newValue, Func<R, R> setter)
			{
				R value = validator2(newValue);
				setter(value);
				Plugin.logIfDebugging(() => $"{<key>P} value has been updated! Value: [{value}]");
			});
		}

		public SectionBinder bind(out ConfigEntry<T> field)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			ConfigDescription configDescription = ((!hasDescription) ? ((ConfigDescription)null) : new ConfigDescription(_description ?? "", _acceptableValues, _tags ?? Array.Empty<object>()));
			<binder>P.bind(out field, <key>P, hasDefaultValue ? converter.from(_defaultValue) : default(T), configDescription);
			if (_onChangeCallback != null)
			{
				field.settingsChangedSafe(delegate(ConfigEntryBase entry, T value, Func<T, T> setter)
				{
					Func<T, T> setter2 = setter;
					_onChangeCallback(entry, converter.to(value), (R v) => converter.to(setter2(converter.from(v))));
				});
			}
			return <binder>P;
		}
	}
	public delegate void Builder<T, R>(ConfigEntryBuilder<T, R> builder);
	public delegate T Validator<T>(T t);
	public delegate void EntryChangedHandler<T>(ConfigEntryBase entry, T newValue, Func<T, T> setter);
	public static class EntryChangedHandlerExt
	{
		public static EntryChangedHandler<T> and<T>(this EntryChangedHandler<T> baseHandler, EntryChangedHandler<T> extraHandler)
		{
			EntryChangedHandler<T> baseHandler2 = baseHandler;
			EntryChangedHandler<T> extraHandler2 = extraHandler;
			return delegate(ConfigEntryBase entry, T value, Func<T, T> setter)
			{
				baseHandler2(entry, value, setter);
				extraHandler2(entry, value, setter);
			};
		}
	}
	public interface Converter
	{
		static readonly Converter<string, IList<string>> COMMA_SEPARATED_LIST = of((string input) => input.Split(",").ToList(), (IList<string> input) => GeneralExtensions.Join<string>((IEnumerable<string>)input, (Func<string, string>)null, ","));

		static Converter<T, R> of<T, R>(System.Converter<T, R> to, System.Converter<R, T> from)
		{
			return new ConvertorImpl<T, R>(to, from);
		}

		static Converter<T, T> of<T>()
		{
			return new ConvertorImpl<T, T>((T t) => t, (T t) => t);
		}
	}
	public interface Converter<T, R> : Converter
	{
		R to(T t);

		T from(R r);

		Converter<T, A> xmap<A>(System.Converter<R, A> to, System.Converter<A, R> from)
		{
			System.Converter<R, A> to2 = to;
			System.Converter<A, R> from2 = from;
			return new ConvertorImpl<T, A>((T t) => to2(this.to(t)), (A a) => this.from(from2(a)));
		}
	}
	internal class ConvertorImpl<T, R> : Converter<T, R>, Converter
	{
		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private System.Converter<T, R> <_to>P;

		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private System.Converter<R, T> <_from>P;

		public ConvertorImpl(System.Converter<T, R> _to, System.Converter<R, T> _from)
		{
			<_to>P = _to;
			<_from>P = _from;
			base..ctor();
		}

		public R to(T t)
		{
			return <_to>P(t);
		}

		public T from(R r)
		{
			return <_from>P(r);
		}
	}
	public class SectionBinder
	{
		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private ConfigFile <configFile>P;

		[CompilerGenerated]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private string <section>P;

		public SectionBinder(ConfigFile configFile, string section)
		{
			<configFile>P = configFile;
			<section>P = section;
			base..ctor();
		}

		public SectionBinder bind<T>(string key, T defaultValue, Builder<T, T>? builderAction)
		{
			ConfigEntry<T> field;
			return bind(key, (string?)null, defaultValue, out field, builderAction);
		}

		public SectionBinder bind<T>(string key, T defaultValue, out ConfigEntry<T> field, Builder<T, T>? builderAction)
		{
			return bind(key, (string?)null, defaultValue, out field, builderAction);
		}

		public SectionBinder bind<T>(string key, string description, T defaultValue, Builder<T, T>? builderAction = null)
		{
			ConfigEntry<T> field;
			return bind(key, description, defaultValue, out field, builderAction);
		}

		public SectionBinder bind<T>(string key, string description, Property<T> property, Builder<T, T>? builderAction = null)
		{
			Builder<T, T> builderAction2 = builderAction;
			Property<T> property2 = property;
			ConfigEntry<T> field;
			return bind(key, description, property2.get(), out field, (Builder<T, T>?)delegate(ConfigEntryBuilder<T, T> builder)
			{
				builder.handle(builderAction2).onChange(property2.set);
			});
		}

		public SectionBinder bind<T, R>(string key, string description, Property<R> property, Converter<T, R> converter, Builder<T, R>? builderAction = null)
		{
			Builder<T, R> builderAction2 = builderAction;
			Property<R> property2 = property;
			Getter<R> getter;
			return bind(key, description, property2.get(), out getter, converter, delegate(ConfigEntryBuilder<T, R> builder)
			{
				builder.handle(builderAction2).onChange(property2.set);
			});
		}

		public SectionBinder bind<T>(string key, string? description, T defaultValue, out ConfigEntry<T> field, Builder<T, T>? builderAction = null)
		{
			new ConfigEntryBuilder<T, T>(this, key, Converter.of<T>()).description(description).defaultValue(defaultValue).handle(builderAction)
				.bind(out field);
			return this;
		}

		public SectionBinder bind<T>(string key, string? description, T defaultValue, out Getter<T> getter, Builder<T, T>? builderAction = null)
		{
			bind(key, description, defaultValue, out ConfigEntry<T> entry, builderAction);
			getter = () => entry.Value;
			return this;
		}

		public SectionBinder bind<T, R>(string key, string? description, R defaultValue, Converter<T, R> converter, Builder<T, R>? builderAction = null)
		{
			Getter<R> getter;
			return bind(key, description, defaultValue, out getter, converter, builderAction);
		}

		public SectionBinder bind<T, R>(string key, string? description, R defaultValue, out Getter<R> getter, Converter<T, R> converter, Builder<T, R>? builderAction = null)
		{
			Converter<T, R> converter2 = converter;
			bool hasChanged = true;
			new ConfigEntryBuilder<T, R>(this, key, converter2).description(description).defaultValue(defaultValue).handle(builderAction)
				.onChange(delegate
				{
					hasChanged = true;
				})
				.bind(out ConfigEntry<T> field);
			R value = converter2.to(field.Value);
			getter = delegate
			{
				if (hasChanged)
				{
					value = converter2.to(field.Value);
				}
				return value;
			};
			return this;
		}

		internal SectionBinder bind<T>(out ConfigEntry<T> field, string key, T defaultValue, ConfigDescription? configDescription = null)
		{
			field = <configFile>P.Bind<T>(<section>P, key, defaultValue, configDescription);
			return this;
		}
	}
	public class ObjectInstantiateEvent
	{
		public delegate void PostInstantiation(Object obj, Vector3? position, Quaternion? rotation);

		public static event PostInstantiation? onObjectInstantiation;

		public static void setupAndRun(object __result, object[]? __args = null)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			Object val = (Object)((__result is Object) ? __result : null);
			if (val == null)
			{
				return;
			}
			Plugin.Logger.LogInfo((object)$"Name: {val.name}, Type: {((object)val).GetType()}");
			try
			{
				Vector3? position = null;
				Quaternion? rotation = null;
				if (__args != null)
				{
					foreach (object obj in __args)
					{
						if (obj is Vector3 value)
						{
							position = value;
						}
						else if (obj is Quaternion value2)
						{
							rotation = value2;
						}
					}
				}
				onInstantiation(val, position, rotation);
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)ex);
			}
		}

		public static void onInstantiation(Object obj, Vector3? position, Quaternion? rotation)
		{
			ObjectInstantiateEvent.onObjectInstantiation?.Invoke(obj, position, rotation);
		}
	}
	public class SwapperComponentSetupUtils
	{
		public delegate bool MeshEntryMatcher(MeshRenderer renderer, int materialIndex, Material material, Action<Material> setCallback);

		public delegate void MeshEntryHandler(MeshRenderer renderer, int materialIndex, Material material, Action<Material> setCallback);

		public static void unswapScene(GameObject rootObject)
		{
			if (!Plugin.config.clientSideMode())
			{
				return;
			}
			foreach (GameObject item in rootObject.unpackGameObject())
			{
				item.GetComponent<SwapperHandlerHolder>()?.unswapAllTextures(item);
			}
		}

		public static void commonSide(GameObject rootObject, bool clientSideOverride = false)
		{
			Level levelCurrent = RunManager.instance.levelCurrent;
			try
			{
				foreach (GameObject obj in rootObject.unpackGameObject())
				{
					tryToAdjustMaterial(levelCurrent, obj, delegate(MeshRenderer mesh, int i, Material material, Action<Material> setAction)
					{
						MeshRenderer mesh2 = mesh;
						Material material2 = material;
						Action<Material> setAction2 = setAction;
						if (Plugin.config.clientSideMode() || clientSideOverride)
						{
							fullClientSideSetup(obj, mesh2, i, material2, setAction2);
						}
						else
						{
							MediaIdentifierComponent orAddComponent = ComponentHolderProtocol.GetOrAddComponent<MediaIdentifierComponent>((Object)(object)obj);
							if (PhotonNetwork.LocalPlayer.IsMasterClient)
							{
								Identifier identifier = ActiveSwapperStats.getOrCreate().actOrWaitWithHandler(delegate(MeshSwapper handler)
								{
									obj.setSwapperHolder(mesh2, i, material2, setAction2, handler);
								});
								if (identifier == null)
								{
									return;
								}
								if (orAddComponent != null)
								{
									orAddComponent.setId(identifier);
								}
								else
								{
									Plugin.logIfDebugging(delegate(ManualLogSource source)
									{
										source.LogWarning((object)"Unable to create or get the needed Painting Component for given obj");
									});
								}
							}
							PhotonView orAddComponent2 = ComponentHolderProtocol.GetOrAddComponent<PhotonView>((Object)(object)obj);
							Plugin.logIfDebugging(delegate(ManualLogSource source)
							{
								source.LogInfo((object)("Target Object preparing for Texture Component Replacment: " + ((Object)obj).name));
							});
							if ((Object)(object)orAddComponent2 == (Object)null)
							{
								Plugin.logIfDebugging(delegate(ManualLogSource source)
								{
									source.LogInfo((object)"Target Object was unable to have a Photon View\n");
								});
							}
							else
							{
								Plugin.logIfDebugging(delegate(ManualLogSource source)
								{
									source.LogInfo((object)"Target Object View will now track Painting Component!\n");
								});
								PhotonView photonView = PunExtensions.GetPhotonView(obj);
								(photonView.ObservedComponents ?? (photonView.ObservedComponents = new List<Component>())).Add((Component)(object)orAddComponent);
							}
						}
					});
				}
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)"An error has occured when adjusting painting material!");
				Plugin.Logger.LogError((object)ex);
			}
		}

		public static void fullClientSideSetup(GameObject obj, MeshRenderer mesh, int i, Material material, Action<Material> setAction)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj2 = obj;
			MeshRenderer mesh2 = mesh;
			Material material2 = material;
			Action<Material> setAction2 = setAction;
			Vector3 position = obj2.transform.position;
			int value = BitConverter.ToInt32(SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes($"{position.x:R},{position.y:R},{position.z:R}")), 0);
			ActiveSwapperStats.getOrCreate().actOrWaitWithHandler(delegate(MeshSwapper handler)
			{
				obj2.setSwapperHolder(mesh2, i, material2, setAction2, handler);
			}, value);
		}

		public static void clientPaintingDataChange(GameObject obj, FullMediaData fullData)
		{
			FullMediaData fullData2 = fullData;
			GameObject obj2 = obj;
			MediaSwapperStorage.loadIfNotFound(fullData2);
			Level levelCurrent = RunManager.instance.levelCurrent;
			tryToAdjustMaterial(levelCurrent, obj2, delegate(MeshRenderer mesh, int i, Material material, Action<Material> setAction)
			{
				MeshRenderer mesh2 = mesh;
				Material material2 = material;
				Action<Material> setAction2 = setAction;
				Identifier id = fullData2.id;
				if (MediaIdentifiers.ERROR.Equals(id) || !MediaSwapperStorage.hasMaterial(id))
				{
					Plugin.logIfDebugging(delegate(ManualLogSource source)
					{
						source.LogInfo((object)$"Unable to Set Clients Material: {id}");
					});
				}
				MediaSwapperStorage.getOrActWithHandler(id, delegate(MeshSwapper handler)
				{
					if (isCensored(MediaSwapperStorage.getResult(id)))
					{
						handler = MediaSwapperStorage.getHandler<MeshSwapper>(UserSettings.getAlternativeCensorImage() ?? MediaIdentifiers.CENSORED);
						Plugin.logIfDebugging(delegate(ManualLogSource source)
						{
							source.LogInfo((object)$"The given entry {id} has been censored due to being blacklisted!");
						});
					}
					obj2.gameObject.setSwapperHolder(mesh2, i, material2, setAction2, handler);
					Plugin.logIfDebugging(delegate(ManualLogSource source)
					{
						source.LogInfo((object)$"Set Clients Material: {id}");
					});
				});
			});
		}

		public static bool doseObjectSupportMeshSwapping(Level level, GameObject gameObject)
		{
			return searchMaterial(level, gameObject);
		}

		public static void tryToAdjustMaterial(Level level, GameObject gameObject, MeshEntryHandler handler)
		{
			MeshEntryHandler handler2 = handler;
			searchMaterial(level, gameObject, delegate(MeshRenderer mesh, int i, Material material, Action<Material> setAction)
			{
				handler2(mesh, i, material, setAction);
				return false;
			});
		}

		public static bool searchMaterial(Level level, GameObject gameObject, MeshEntryMatcher? matcher = null)
		{
			List<Regex> source = Plugin.config.textureSwapTargets().Select(RegexUtils.parseRegexWithFlags).ToList();
			MeshRenderer[] components = gameObject.GetComponents<MeshRenderer>();
			foreach (MeshRenderer mesh in components)
			{
				Material[] sharedMaterials = ((Renderer)mesh).sharedMaterials;
				if (sharedMaterials == null)
				{
					continue;
				}
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					Material val = sharedMaterials[j];
					if (!((Object)(object)val != (Object)null))
					{
						continue;
					}
					string name = ((Object)val).name;
					if (source.Any((Regex regex) => regex.IsMatch(name)) || source.Any((Regex regex) => regex.IsMatch(((Object)((Component)mesh).gameObject).name)))
					{
						int targetIndex = j;
						Action<Material> setCallback = delegate(Material newMaterial)
						{
							sharedMaterials[targetIndex] = newMaterial;
							((Renderer)mesh).sharedMaterials = sharedMaterials;
						};
						if (matcher == null || matcher(mesh, targetIndex, val, setCallback))
						{
							return true;
						}
					}
				}
			}
			return false;
		}

		public static bool isCensored(MediaQueryResult queryResult)
		{
			if (Plugin.config.shouldRestrictQueries() && queryResult is RatedMediaResult ratedMediaResult && !ratedMediaResult.isSafe())
			{
				return true;
			}
			if (queryResult is TaggedMediaResult taggedMediaResult)
			{
				foreach (string item in Plugin.config.blacklistedTags())
				{
					if (taggedMediaResult.hasTag(item))
					{
						return true;
					}
				}
			}
			return false;
		}
	}
	public static class DebugTooltipInfo
	{
		private static bool toggledTooltipEnabled = Plugin.config.showDebugTooltipInfo();

		private static float countDown = 0f;

		public static Keybind dumpInfoBind { get; private set; }

		public static Keybind toggleTooltipInfoBind { get; private set; }

		public static void init()
		{
			dumpInfoBind = Keybinds.Bind("Debug", "Dump Debug Info", "<No Binding>");
			toggleTooltipInfoBind = Keybinds.Bind("Debug", "Toggle Debug Tooltip Info", "<No Binding>");
			ArgKey<float> rangeKey = ArgKey.optional("range", ArgumentParsers.floatNum(), 50f);
			ArgKey<int> unpackAmountKey = ArgKey.optional("unpack", ArgumentParsers.integerNum(), 1);
			ArgumentChatCommand.createAndRegister(Plugin.Logger, "rayCastToObj", "Attempts to raycast an object in the scene and dump its structure", new List<ArgKey>(2) { rangeKey, unpackAmountKey }, delegate(bool _, Arguments arguments)
			{
				dumpInfo(arguments.get(rangeKey), arguments.get(unpackAmountKey), findNewObj: true);
			});
		}

		private static void dumpInfo(float? range = null, int? unpackAmount = null, bool findNewObj = false, Func<string?, bool>? messageHandler = null)
		{
			float range2 = range ?? Plugin.config.tooltipRange();
			int unpackAmount2 = unpackAmount ?? Plugin.config.infoUnpackingAmount();
			string info = getInfo(range2, unpackAmount2, findNewObj);
			if (messageHandler == null || messageHandler(info))
			{
				Plugin.Logger.LogInfo((object)("Dumped Debug Info: \n" + (info ?? "No target found!")));
			}
		}

		public static string? getInfo(float range, int unpackAmount, bool findNewObj = false)
		{
			MeshRayCaster orCreate = MeshRayCaster.getOrCreate();
			Component val = (findNewObj ? orCreate.raycast(range) : orCreate.currentComponent);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject gameObject = ((Component)val.transform).gameObject;
			gameObject = gameObject.getParent(unpackAmount);
			return gameObject.dumpDebugInfoTree("  ", "  -> ", delegate(object o, List<object> list)
			{
				MeshRenderer val2 = (MeshRenderer)((o is MeshRenderer) ? o : null);
				if (val2 != null)
				{
					list.Add(((Renderer)val2).material);
					list.addAll(((Renderer)val2).materials);
					list.Add(((Renderer)val2).sharedMaterial);
					list.addAll(((Renderer)val2).sharedMaterials);
				}
			}, (object o) => o is MeshWireframeRenderer);
		}

		internal static void update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.InputDown(dumpInfoBind.inputKey))
			{
				dumpInfo(null, null, findNewObj: true);
			}
			if (SemiFunc.InputDown(toggleTooltipInfoBind.inputKey))
			{
				toggledTooltipEnabled = !toggledTooltipEnabled;
			}
			if (!TooltipUI.DEBUG.predicate.isValid())
			{
				return;
			}
			if (toggledTooltipEnabled)
			{
				countDown -= Time.deltaTime;
				if (countDown < 0f)
				{
					dumpInfo(null, null, findNewObj: false, delegate(string? info)
					{
						TooltipUI.instance?.setMessage(TooltipUI.DEBUG, info);
						return false;
					});
					countDown = Plugin.config.tooltipWaitTime();
				}
			}
			else
			{
				TooltipUI.instance?.removeMessage(TooltipUI.BASIC);
			}
		}
	}
	public delegate void ExecuteFunc(bool isDebug, Arguments args);
	public delegate bool AccessPredicate();
	public class ArgumentChatCommand : ChatCommand
	{
		public ArgumentChatCommand(ManualLogSource logger, string name, string description, List<ArgKey> arguments, ExecuteFunc func, AccessPredicate? predicate = null, bool debugOnly = true)
			: base(name, description, fromExecuteFunc(name, logger, arguments, func), createSuggestionProvider(logger, arguments), (predicate == null) ? ((Func<bool>)(() => true)) : new Func<bool>(predicate.Invoke), debugOnly)
		{
		}

		public static void createAndRegister(ManualLogSource logger, string name, string description, List<ArgKey> arguments, ExecuteFunc func, AccessPredicate? predicate = null, bool debugOnly = true)
		{
			ArgumentChatCommand argumentChatCommand = new ArgumentChatCommand(logger, name, description, arguments, func, predicate, debugOnly);
			Commands.RegisterCommand((ChatCommand)(object)argumentChatCommand);
		}

		private static Action<bool, string[]> fromExecuteFunc(string name, ManualLogSource logger, List<ArgKey> arguments, ExecuteFunc func)
		{
			ManualLogSource logger2 = logger;
			List<ArgKey> arguments2 = arguments;
			string name2 = name;
			ExecuteFunc func2 = func;
			return delegate(bool isDebugConsole, string[] strArgs)
			{
				Arguments arguments3 = new Arguments().parseArgs(logger2, arguments2, strArgs);
				IList<ArgKey> missingArgs = arguments3.getMissingArgs(arguments2);
				if (missingArgs.isNotEmpty())
				{
					logger2.LogError((object)("Unable to execute '" + name2 + "' as its missing the required args: " + missingArgs.toPrettyString()));
				}
				else
				{
					func2(isDebugConsole, new Arguments().parseArgs(logger2, arguments2, strArgs));
				}
			};
		}

		private static Func<bool, string, string[], List<string>> createSuggestionProvider(ManualLogSource logger, List<ArgKey> arguments)
		{
			ManualLogSource logger2 = logger;
			List<ArgKey> arguments2 = arguments;
			return delegate(bool _, string partial, string[] strArgs)
			{
				string partial2 = partial;
				return (from @base in new Arguments().parseArgs(logger2, arguments2, strArgs).getMissingArgs(arguments2)
					select @base.name + ":" into s
					where s.StartsWith(partial2) || s.Contains(partial2)
					select s).ToList();
			};
		}
	}
	public class Arguments
	{
		private Dictionary<ArgKey, dynamic> _arguments = new Dictionary<ArgKey, object>();

		public Arguments parseArgs(ManualLogSource logger, List<ArgKey> argKeys, string[] args)
		{
			foreach (string text in args)
			{
				string[] array = text.Split(":");
				if (array.Length <= 1)
				{
					continue;
				}
				bool flag = false;
				foreach (ArgKey argKey in argKeys)
				{
					if (argKey.matches(array[0]))
					{
						argKey.setArg(logger, _arguments, array[1]);
						flag = true;
					}
				}
				if (!flag && !string.IsNullOrWhiteSpace(array[1]))
				{
					logger.LogWarning((object)("'" + array[0] + "' is not a valid argument name."));
				}
			}
			return this;
		}

		public IList<ArgKey> getMissingArgs(List<ArgKey> argKeys)
		{
			return argKeys.Where((ArgKey key) => !_arguments.ContainsKey(key) && !key.isDefaulted).ToList();
		}

		public T get<T>(ArgKey<T> key)
		{
			return key.getArg(_arguments);
		}
	}
	public interface ArgKey
	{
		bool isDefaulted { get; }

		string name { get; }

		static ArgKey<T> required<T>(string name, ArgumentParser<T> parser)
		{
			return new ArgKey<T>(name, parser, isDefaulted: false);
		}

		static ArgKey<T> optional<T>(string name, ArgumentParser<T> parser, T defaultValue = default(T))
		{
			return new ArgKey<T>(name, parser, isDefaulted: false, defaultValue);
		}

		bool matches(string name);

		void setArg(ManualLogSource logger, Dictionary<ArgKey, dynamic> parsedArgs, string strValue);
	}
	public class ArgKey<T> : ArgKey
	{
		private readonly ArgumentParser<T?> _parser;

		private readonly T _defaultValue;

		public bool isDefaulted { get; }

		public string name { get; }

		internal ArgKey(string name, ArgumentParser<T?> parser, bool isDefaulted, T defaultValue = default(T))
		{
			_parser = parser;
			_defaultValue = defaultValue;
			this.isDefaulted = isDefaulted;
			this.name = name;
		}

		public bool matches(string name)
		{
			return this.name.Equals(name);
		}

		public void setArg(ManualLogSource logger, Dictionary<ArgKey, dynamic> parsedArgs, string strValue)
		{
			Result<T> result = _parser(strValue);
			if (result.hasErrored)
			{
				logger.LogWarning((object)("Argument [" + name + "]: " + result.errorMsg));
			}
			else
			{
				parsedArgs[this] = result.result;
			}
		}

		public T getArg(Dictionary<ArgKey, dynamic> parsedArgs)
		{
			dynamic val = (parsedArgs.ContainsKey(this) ? parsedArgs[this] : null);
			if (val == null && !isDefaulted)
			{
				throw new Exception("Unable to get arg '" + name + "' as the value is not defaulted and was never parsed into arguments!");
			}
			return !(val ?? ((object)_defaultValue));
		}
	}
	public delegate Result<T?> ArgumentParser<T>(string str);
	public static class ArgumentParsers
	{
		public static ArgumentParser<int> integerNum()
		{
			int result;
			return (string str) => of(int.TryParse(str, out result), result, str);
		}

		public static ArgumentParser<float> floatNum()
		{
			float result;
			return (string str) => of(float.TryParse(str, out result), result, str);
		}

		public static Result<T?> of<T>(bool wasParsed, T result, string str)
		{
			return new Result<T>(result, !wasParsed, "Unable to parse value '" + str + "'");
		}
	}
	public class Result<T>
	{
		public T? result { get; }

		public bool hasErrored { get; }

		public string? errorMsg { get; }

		public Result(T? result, bool hasErrored, string? errorMsg)
		{
			this.result = result;
			this.hasErrored = hasErrored;
			this.errorMsg = errorMsg;
			base..ctor();
		}
	}
	public delegate void EntryHandler<T>(T t);
	public delegate void EntryUnpacker<T>(T t, List<T> list);
	public delegate bool EntryIgnorer<in T>(T t);
	public delegate string EntryNameGetter<T>(T t);
	public delegate void EntryNestScopeCallback(Action action);
	public class Extensions
	{
	}
	public static class DictionaryExtensions
	{
		public static V computeIfAbsent<K, V>(this IDictionary<K, V> dict, K k, Func<V> func)
		{
			Func<V> func2 = func;
			return dict.computeIfAbsent(k, (K _) => func2());
		}

		public static V computeIfAbsent<K, V>(this IDictionary<K, V> dict, K k, Func<K, V> func)
		{
			if (!dict.ContainsKey(k))
			{
				dict[k] = func(k);
			}
			return dict[k];
		}

		public static V? removeIfPresent<K, V>(this IDictionary<K, V> dict, K k) where V : class
		{
			V result = null;
			if (dict.ContainsKey(k))
			{
				result = dict[k];
				dict.Remove(k);
			}
			return result;
		}

		public static void forEach<K, V>(this IDictionary<K, V> dict, Action<K, V> func)
		{
			foreach (KeyValuePair<K, V> item in dict)
			{
				func(item.Key, item.Value);
			}
		}

		public static void merge<K, V>(this IDictionary<K, IList<V>> dict, IDictionary<K, IList<V>> otherDict)
		{
			dict.merge<K, IList<V>, V>(otherDict);
		}

		public static void merge<K, C1, V>(this IDictionary<K, C1> dict, IDictionary<K, C1> otherDict) where C1 : ICollection<V>
		{
			IDictionary<K, C1> dict2 = dict;
			otherDict.forEach(delegate(K k, C1 vs)
			{
				if (dict2.ContainsKey(k))
				{
					dict2[k].addAll(vs);
				}
				else
				{
					dict2[k] = vs;
				}
			});
		}
	}
	public static class ICollectionExtensions
	{
		public static void addAll<T>(this ICollection<T> collection, IEnumerable<T> values)
		{
			if (collection is List<T> list && values is List<T> collection2)
			{
				list.AddRange(collection2);
			}
			foreach (T value in values)
			{
				collection.Add(value);
			}
		}
	}
	public static class IListExtensions
	{
		public static IList<T> getSublistSafe<T>(this IList<T> list, int startInclusiveIndex, int endInclusiveIndex = -1)
		{
			IList<T> result;
			if (list.Count <= 0)
			{
				IList<T> list2 = new List<T>();
				result = list2;
			}
			else
			{
				result = list.getSublist(startInclusiveIndex, endInclusiveIndex);
			}
			return result;
		}

		public static IList<T> getSublist<T>(this IList<T> list, int startInclusiveIndex, int endInclusiveIndex = -1)
		{
			if (endInclusiveIndex <= -1)
			{
				endInclusiveIndex = list.Count - 1;
			}
			if (endInclusiveIndex >= list.Count)
			{
				throw new ArgumentOutOfRangeException($"End Index is out of bounds of the given list size: [Index: {endInclusiveIndex}, Size: {list.Count}");
			}
			if (startInclusiveIndex >= endInclusiveIndex)
			{
				throw new ArgumentOutOfRangeException($"Start Index is out of bounds of a Lists Rnage: [Start: {startInclusiveIndex}");
			}
			if (startInclusiveIndex < 0)
			{
				throw new ArgumentOutOfRangeException($"End Index is out of bounds of the given list size: [Index: {endInclusiveIndex}, Size: {list.Count}");
			}
			int num = endInclusiveIndex - startInclusiveIndex;
			List<T> list2 = new List<T>(num);
			for (int i = num; i < num; i++)
			{
				list2.Add(list[i]);
			}
			return list2;
		}
	}
	public static class PairedTupleExtensions
	{
		public static L? getLeftOrMapRight<L, R>(this (L?, R?) tuple, Func<R, L?> func)
		{
			var (val, val2) = tuple;
			if (val != null)
			{
				return val;
			}
			if (val2 == null)
			{
				throw new NullReferenceException("Unable to handle Either based tuple method due to the Left and Right values are both Null");
			}
			return func(val2);
		}
	}
	public static class EnumerableUtils
	{
		private class DelegatingEnumerable<T> : IEnumerable<T>, IEnumerable
		{
			[CompilerGenerated]
			[DebuggerBrowsable(DebuggerBrowsableState.Never)]
			private Func<IEnumerator<T>> <enumeratorMaker>P;

			public DelegatingEnumerable(Func<IEnumerator<T>> enumeratorMaker)
			{
				<enumeratorMaker>P = enumeratorMaker;
				base..ctor();
			}

			public IEnumerator<T> GetEnumerator()
			{
				return <enumeratorMaker>P();
			}

			IEnumerator IEnumerable.GetEnumerator()
			{
				return GetEnumerator();
			}
		}

		public static IEnumerable<T> delegating<T>(Func<IEnumerator<T>> enumeratorMaker)
		{
			return new DelegatingEnumerable<T>(enumeratorMaker);
		}

		public static IEnumerable<T> Concat<T>(this IEnumerable<T> first, Func<IEnumerator<T>> enumeratorMaker)
		{
			return first.Concat(delegating(enumeratorMaker));
		}

		public static IEnumerable<T> selectNonNull<T>(this IEnumerable<T?> source)
		{
			return from source1 in source
				where source1 != null
				select (source1);
		}

		public static bool isNotEmpty<T>(this IEnumerable<T> source)
		{
			return !source.isEmpty();
		}

		public static bool isEmpty<T>(this IEnumerable<T> source)
		{
			return (s

Endec.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using Microsoft.CodeAnalysis;
using io.wispforest.endec.impl;
using io.wispforest.endec.impl.trace;
using io.wispforest.endec.util;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("blodhgarm")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("MIT")]
[assembly: AssemblyDescription(" A format-agnostic serialization framework ")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+30862a8a5b6a25fe4d608be0613663ff9fef3569")]
[assembly: AssemblyProduct("Endec")]
[assembly: AssemblyTitle("Endec")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Dragon-Seeker/endec.csharp")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace io.wispforest.endec
{
	public interface Deserializer<out T> where T : class
	{
		SerializationContext setupContext(SerializationContext ctx)
		{
			return ctx;
		}

		byte readByte(SerializationContext ctx);

		short readShort(SerializationContext ctx);

		int readInt(SerializationContext ctx);

		long readLong(SerializationContext ctx);

		float readFloat(SerializationContext ctx);

		double readDouble(SerializationContext ctx);

		int readVarInt(SerializationContext ctx);

		long readVarLong(SerializationContext ctx);

		bool readBoolean(SerializationContext ctx);

		string readString(SerializationContext ctx);

		byte[] readBytes(SerializationContext ctx);

		V? readOptional<V>(SerializationContext ctx, Endec<V> endec);

		SequenceDeserializer<E> sequence<E>(SerializationContext ctx, Endec<E> elementEndec);

		MapDeserializer<V> map<V>(SerializationContext ctx, Endec<V> valueEndec);

		StructDeserializer structed();

		V tryRead<V>(Func<Deserializer<T>, V> reader);
	}
	public interface SequenceDeserializer<E> : IEnumerator<E>, IEnumerator, IDisposable, IEnumerable<E>, IEnumerable
	{
		object? IEnumerator.Current => Current;

		IEnumerator<E> IEnumerable<E>.GetEnumerator()
		{
			return this;
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return this;
		}

		int estimatedSize();
	}
	public interface MapDeserializer<E> : IEnumerator<KeyValuePair<string, E>>, IEnumerator, IDisposable, IEnumerable<KeyValuePair<string, E>>, IEnumerable
	{
		object? IEnumerator.Current => Current;

		IEnumerator<KeyValuePair<string, E>> IEnumerable<KeyValuePair<string, E>>.GetEnumerator()
		{
			return this;
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return this;
		}

		int estimatedSize();
	}
	public interface StructDeserializer
	{
		F? field<F>(string name, SerializationContext ctx, Endec<F> endec)
		{
			return field(name, ctx, endec, null);
		}

		F? field<F>(string name, SerializationContext ctx, Endec<F> endec, Func<F>? defaultValueFactory);
	}
	public interface SelfDescribedDeserializer<out T> : Deserializer<T> where T : class
	{
		void readAny<S>(SerializationContext ctx, Serializer<S> visitor) where S : class;
	}
	public delegate T IntFunction<out T>(int size);
	public delegate void Encoder<in T>(SerializationContext ctx, Serializer<dynamic> serializer, T value);
	public delegate T Decoder<out T>(SerializationContext ctx, Deserializer<dynamic> deserializer);
	public delegate T DecoderWithError<out T>(SerializationContext ctx, Deserializer<dynamic> deserializer, Exception exception);
	public abstract class Endec<T> : Endec
	{
		public abstract void encode<E>(SerializationContext ctx, Serializer<E> serializer, T value) where E : class;

		public abstract T decode<E>(SerializationContext ctx, Deserializer<E> deserializer) where E : class;

		public E encodeFully<E>(SerializationContext ctx, Func<Serializer<E>> serializerConstructor, T value) where E : class
		{
			Serializer<E> serializer = serializerConstructor();
			encode(serializer.setupContext(ctx), serializer, value);
			return serializer.result();
		}

		public E encodeFully<E>(Func<Serializer<E>> serializerConstructor, T value) where E : class
		{
			return encodeFully(SerializationContext.empty(), serializerConstructor, value);
		}

		public T decodeFully<E>(SerializationContext ctx, Func<E, Deserializer<E>> deserializerConstructor, E value) where E : class
		{
			Deserializer<E> deserializer = deserializerConstructor(value);
			return decode(deserializer.setupContext(ctx), deserializer);
		}

		public T decodeFully<E>(Func<E, Deserializer<E>> deserializerConstructor, E value) where E : class
		{
			return decodeFully(SerializationContext.empty(), deserializerConstructor, value);
		}

		public Endec<IList<T>> listOf()
		{
			return Endec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, IList<T> list)
			{
				using SequenceSerializer<T> sequenceSerializer = serializer.sequence(ctx, this, list.Count);
				foreach (T item in list)
				{
					sequenceSerializer.element(item);
				}
			}, delegate(SerializationContext ctx, Deserializer<dynamic> deserializer)
			{
				SequenceDeserializer<T> sequenceDeserializer = deserializer.sequence(ctx, this);
				List<T> list2 = new List<T>(sequenceDeserializer.estimatedSize());
				foreach (T item2 in sequenceDeserializer)
				{
					list2.Add(item2);
				}
				return list2;
			});
		}

		public Endec<T[]> arrayOf()
		{
			return listOf().xmap((IList<T> list) => list.ToArray(), (T[] array) => new List<T>(array));
		}

		public Endec<IDictionary<string, T>> mapOf()
		{
			return mapOf(Endec.DefaultDictionary<string, T>());
		}

		public Endec<M> mapOf<M>(IntFunction<M> mapConstructor) where M : IDictionary<string, T>
		{
			IntFunction<M> mapConstructor2 = mapConstructor;
			return Endec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, M map)
			{
				using MapSerializer<T> mapSerializer = serializer.map(ctx, this, map.Count);
				foreach (KeyValuePair<string, T> item in map)
				{
					mapSerializer.entry(item.Key, item.Value);
				}
			}, delegate(SerializationContext ctx, Deserializer<dynamic> deserializer)
			{
				MapDeserializer<T> mapDeserializer = deserializer.map(ctx, this);
				M result = mapConstructor2(mapDeserializer.estimatedSize());
				foreach (KeyValuePair<string, T> item2 in mapDeserializer)
				{
					ref M reference = ref result;
					M val = default(M);
					if (val == null)
					{
						val = reference;
						reference = ref val;
					}
					reference[item2.Key] = item2.Value;
				}
				return result;
			});
		}

		public Endec<IDictionary<K, T>> mapOf<K>(Func<K, string> keyToString, Func<string, K> stringToKey)
		{
			return mapOf(Endec.DefaultDictionary<K, T>(), keyToString, stringToKey);
		}

		public Endec<M> mapOf<K, M>(IntFunction<M> mapConstructor, Func<K, string> keyToString, Func<string, K> stringToKey) where M : IDictionary<K, T>
		{
			return Endec.map(mapConstructor, keyToString, stringToKey, this);
		}

		public Endec<T?> optionalOf()
		{
			return Endec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, T value)
			{
				serializer.writeOptional(ctx, this, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => deserializer.readOptional(ctx, this));
		}

		public Endec<R> xmap<R>(Func<T, R> to, Func<R, T> from)
		{
			Func<R, T> from2 = from;
			Func<T, R> to2 = to;
			return Endec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, R value)
			{
				encode(ctx, serializer, from2(value));
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => to2(decode(ctx, deserializer)));
		}

		public Endec<R> xmapWithContext<R>(Func<SerializationContext, T, R> to, Func<SerializationContext, R, T> from)
		{
			Func<SerializationContext, R, T> from2 = from;
			Func<SerializationContext, T, R> to2 = to;
			return Endec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, R value)
			{
				encode(ctx, serializer, from2(ctx, value));
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => to2(ctx, decode(ctx, deserializer)));
		}

		public Endec<T> validate(Action<T> validator)
		{
			Action<T> validator2 = validator;
			return xmap(delegate(T t)
			{
				validator2(t);
				return t;
			}, delegate(T t)
			{
				validator2(t);
				return t;
			});
		}

		public Endec<T> catchErrors(DecoderWithError<T> decodeOnError)
		{
			DecoderWithError<T> decodeOnError2 = decodeOnError;
			return Endec.of(encode, delegate(SerializationContext ctx, Deserializer<dynamic> deserializer)
			{
				SerializationContext ctx2 = ctx;
				try
				{
					return deserializer.tryRead((Deserializer<dynamic> deserializer1) => decode(ctx2, deserializer1));
				}
				catch (Exception exception)
				{
					return decodeOnError2(ctx2, deserializer, exception);
				}
			});
		}

		public Endec<ISet<T>> setOf()
		{
			return listOf().xmap((IList<T> list) => new HashSet<T>(list), (ISet<T> set) => new List<T>(set));
		}

		public KeyedEndec<T> keyed(string key, T defaultValue)
		{
			return new KeyedEndec<T>(key, this, defaultValue);
		}

		public KeyedEndec<T> keyed(string key, Func<T> defaultValueFactory)
		{
			return new KeyedEndec<T>(key, this, defaultValueFactory);
		}

		public StructEndec<T> structOf(string name)
		{
			string name2 = name;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> _, StructSerializer instance, T value)
			{
				instance.field(name2, ctx, this, value);
			}, (SerializationContext ctx, Deserializer<dynamic> _, StructDeserializer instance) => instance.field(name2, ctx, this));
		}

		public StructField<S, T> fieldOf<S>(string name, Func<S, T> getter)
		{
			return new StructField<S, T>(name, this, getter);
		}

		public StructField<S, T> optionalFieldOf<S>(string name, Func<S, T?> getter)
		{
			return optionalFieldOf(name, getter, null);
		}

		public StructField<S, T> optionalFieldOf<S>(string name, Func<S, T?> getter, T? defaultValue)
		{
			return new StructField<S, T>(name, optionalOf(), getter, defaultValue);
		}

		public StructField<S, T> optionalFieldOf<S>(string name, Func<S, T?> getter, Func<T?> defaultValue)
		{
			if (defaultValue == null)
			{
				throw new NullReferenceException("Supplier was found to be null which is not permitted for optionalFieldOf");
			}
			return new StructField<S, T>(name, optionalOf(), getter, defaultValue);
		}
	}
	public interface Endec
	{
		public enum Test
		{
			One = 1,
			Two
		}

		static readonly StructEndec<object> VOID = unit<object>(null);

		static readonly Endec<bool> BOOLEAN = of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, bool value)
		{
			serializer.writeBoolean(ctx, value);
		}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => deserializer.readBoolean(ctx));

		static readonly Endec<byte> BYTE = of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, byte value)
		{
			serializer.writeByte(ctx, value);
		}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => deserializer.readByte(ctx));

		static readonly Endec<short> SHORT = of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, short value)
		{
			serializer.writeShort(ctx, value);
		}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => deserializer.readShort(ctx));

		static readonly Endec<int> INT = of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, int value)
		{
			serializer.writeInt(ctx, value);
		}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => deserializer.readInt(ctx));

		static readonly Endec<int> VAR_INT = of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, int value)
		{
			serializer.writeVarInt(ctx, value);
		}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => deserializer.readVarInt(ctx));

		static readonly Endec<long> LONG = of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, long value)
		{
			serializer.writeLong(ctx, value);
		}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => deserializer.readLong(ctx));

		static readonly Endec<long> VAR_LONG = of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, long value)
		{
			serializer.writeVarLong(ctx, value);
		}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => deserializer.readVarLong(ctx));

		static readonly Endec<float> FLOAT = of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, float value)
		{
			serializer.writeFloat(ctx, value);
		}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => deserializer.readFloat(ctx));

		static readonly Endec<double> DOUBLE = of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, double value)
		{
			serializer.writeDouble(ctx, value);
		}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => deserializer.readDouble(ctx));

		static readonly Endec<string> STRING = of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, string value)
		{
			serializer.writeString(ctx, value);
		}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => deserializer.readString(ctx));

		static readonly Endec<byte[]> BYTES = of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, byte[] value)
		{
			serializer.writeBytes(ctx, value);
		}, (SerializationContext ctx, Deserializer<dynamic> deserializer) => deserializer.readBytes(ctx));

		static readonly Endec<int[]> INT_ARRAY = INT.listOf().xmap((IList<int> list) => list.ToArray(), (int[] ints) => new List<int>(ints));

		static readonly Endec<long[]> LONG_ARRAY = LONG.listOf().xmap((IList<long> list) => list.ToArray(), (long[] longs) => new List<long>(longs));

		static readonly Endec<Guid> GUID = ifAttr(SerializationAttributes.HUMAN_READABLE, STRING.xmap(Guid.Parse, (Guid guid) => guid.ToString())).orElse(BYTES.xmap((byte[] bytes) => new Guid(bytes), (Guid guid) => guid.ToByteArray()));

		static Endec<V> vectorEndec<C, V>(string name, Endec<C> componentEndec, Func<C, C, V> constructor, Func<V, C> xGetter, Func<V, C> yGetter)
		{
			Func<C, C, V> constructor2 = constructor;
			Func<V, C> xGetter2 = xGetter;
			Func<V, C> yGetter2 = yGetter;
			return componentEndec.listOf().validate(validateSize<C>(name, 2)).xmap((IList<C> components) => constructor2(components[0], components[1]), (V vector) => new List<C>(2)
			{
				xGetter2(vector),
				yGetter2(vector)
			});
		}

		static Endec<V> vectorEndec<C, V>(string name, Endec<C> componentEndec, Func<C, C, C, V> constructor, Func<V, C> xGetter, Func<V, C> yGetter, Func<V, C> zGetter)
		{
			Func<C, C, C, V> constructor2 = constructor;
			Func<V, C> xGetter2 = xGetter;
			Func<V, C> yGetter2 = yGetter;
			Func<V, C> zGetter2 = zGetter;
			return componentEndec.listOf().validate(validateSize<C>(name, 3)).xmap((IList<C> components) => constructor2(components[0], components[1], components[2]), (V vector) => new List<C>(3)
			{
				xGetter2(vector),
				yGetter2(vector),
				zGetter2(vector)
			});
		}

		static Endec<V> vectorEndec<C, V>(string name, Endec<C> componentEndec, Func<C, C, C, C, V> constructor, Func<V, C> xGetter, Func<V, C> yGetter, Func<V, C> zGetter, Func<V, C> wGetter)
		{
			Func<C, C, C, C, V> constructor2 = constructor;
			Func<V, C> xGetter2 = xGetter;
			Func<V, C> yGetter2 = yGetter;
			Func<V, C> zGetter2 = zGetter;
			Func<V, C> wGetter2 = wGetter;
			return componentEndec.listOf().validate(validateSize<C>(name, 4)).xmap((IList<C> components) => constructor2(components[0], components[1], components[2], components[3]), (V vector) => new List<C>(4)
			{
				xGetter2(vector),
				yGetter2(vector),
				zGetter2(vector),
				wGetter2(vector)
			});
		}

		private static Action<IList<C>> validateSize<C>(string name, int requiredSize)
		{
			string name2 = name;
			return delegate(IList<C> collection)
			{
				if (collection.Count() != 4)
				{
					throw new ArgumentException(name2 + "collection must have " + requiredSize + " elements");
				}
			};
		}

		internal static IntFunction<IDictionary<K, V>> DefaultDictionary<K, V>()
		{
			return (int i) => new Dictionary<K, V>(i);
		}

		static Endec<T> of<T>(Encoder<T> encoder, Decoder<T> decoder)
		{
			return new EndecImpl<T>(encoder, decoder);
		}

		static Endec<T> recursive<T>(Func<Endec<T>, Endec<T>> builderFunc)
		{
			return new RecursiveEndec<T>(builderFunc);
		}

		static StructEndec<T> unit<T>(T instance)
		{
			T instance2 = instance;
			return unit(() => instance2);
		}

		static StructEndec<T> unit<T>(Func<T> instanceGetter)
		{
			Func<T> instanceGetter2 = instanceGetter;
			return StructEndec.of(delegate
			{
			}, (SerializationContext _, Deserializer<dynamic> _, StructDeserializer _) => instanceGetter2());
		}

		static Endec<IDictionary<K, V>> map<K, V>(Endec<K> keyEndec, Endec<V> valueEndec)
		{
			return StructEndecBuilder.of(keyEndec.fieldOf("k", (KeyValuePair<K, V> s) => s.Key), valueEndec.fieldOf("v", (KeyValuePair<K, V> s) => s.Value), (K k, V v) => new KeyValuePair<K, V>(k, v)).listOf().xmap(delegate(IList<KeyValuePair<K, V>> entries)
			{
				Dictionary<K, V> dictionary = new Dictionary<K, V>(entries.Count);
				dictionary.AddAll(entries);
				return dictionary;
			}, (IDictionary<K, V> kvMap) => new List<KeyValuePair<K, V>>(kvMap));
		}

		static Endec<IDictionary<K, V>> map<K, V>(Func<K, string> keyToString, Func<string, K> stringToKey, Endec<V> valueEndec)
		{
			return map(DefaultDictionary<K, V>(), keyToString, stringToKey, valueEndec);
		}

		static Endec<M> map<K, V, M>(IntFunction<M> mapConstructor, Func<K, string> keyToString, Func<string, K> stringToKey, Endec<V> valueEndec) where M : IDictionary<K, V>
		{
			Endec<V> valueEndec2 = valueEndec;
			Func<K, string> keyToString2 = keyToString;
			IntFunction<M> mapConstructor2 = mapConstructor;
			Func<string, K> stringToKey2 = stringToKey;
			return of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, M map)
			{
				using MapSerializer<V> mapSerializer = serializer.map(ctx, valueEndec2, map.Count);
				foreach (KeyValuePair<K, V> item in map)
				{
					mapSerializer.entry(keyToString2(item.Key), item.Value);
				}
			}, delegate(SerializationContext ctx, Deserializer<dynamic> deserializer)
			{
				MapDeserializer<V> mapDeserializer = deserializer.map(ctx, valueEndec2);
				M result = mapConstructor2(mapDeserializer.estimatedSize());
				foreach (KeyValuePair<string, V> item2 in mapDeserializer)
				{
					ref M reference = ref result;
					M val = default(M);
					if (val == null)
					{
						val = reference;
						reference = ref val;
					}
					reference[stringToKey2(item2.Key)] = item2.Value;
				}
				return result;
			});
		}

		static Endec<E> forEnum<E>() where E : Enum
		{
			return forEnum((E arg) => Enum.GetName(typeof(E), arg));
		}

		static void test()
		{
			forEnum<Test>();
		}

		static Endec<E> forEnum<E>(Func<E, string?> nameLookup) where E : Enum
		{
			Func<E, string?> nameLookup2 = nameLookup;
			Array enumValues = Enum.GetValues(typeof(E));
			Dictionary<string, E?> serializedNames = new Dictionary<string, E>();
			Dictionary<E, int> entryToIndex = new Dictionary<E, int>();
			int num = 0;
			foreach (E item in enumValues)
			{
				serializedNames[nameLookup2(item)] = item;
				entryToIndex[item] = num;
				num++;
			}
			Type type = typeof(E);
			return ifAttr(SerializationAttributes.HUMAN_READABLE, STRING.xmap((string name) => serializedNames[name] ?? throw new Exception(type.Name + " constant with the name of [" + name + "] could not be located!"), (E value) => nameLookup2(value) ?? throw new Exception($"{type.Name} constant with the value of [{value}] could not be located!"))).orElse(VAR_INT.xmap((int ordinal) => (E)enumValues.GetValue(ordinal), (E value) => entryToIndex[value]));
		}

		static StructEndec<T> dispatchedStruct<T, K>(Func<K, StructEndec<T>> variantToEndec, Func<T, K> instanceToVariant, Endec<K> variantEndec)
		{
			return dispatchedStruct(variantToEndec, instanceToVariant, variantEndec, "type");
		}

		static StructEndec<T> dispatchedStruct<T, K>(Func<K, StructEndec<T>> variantToEndec, Func<T, K> instanceToVariant, Endec<K> variantEndec, string variantKey)
		{
			Func<T, K> instanceToVariant2 = instanceToVariant;
			string variantKey2 = variantKey;
			Endec<K> variantEndec2 = variantEndec;
			Func<K, StructEndec<T>> variantToEndec2 = variantToEndec;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, T value)
			{
				K val = instanceToVariant2(value);
				instance.field(variantKey2, ctx, variantEndec2, val);
				variantToEndec2(val).encodeStruct(ctx, serializer, instance, value);
			}, delegate(SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance)
			{
				K arg = instance.field(variantKey2, ctx, variantEndec2);
				return variantToEndec2(arg).decodeStruct(ctx, deserializer, instance);
			});
		}

		static StructEndec<T> dispatched<T, K>(Func<K, Endec<T>> variantToEndec, Func<T, K> instanceToVariant, Endec<K> variantEndec)
		{
			Func<T, K> instanceToVariant2 = instanceToVariant;
			Endec<K> variantEndec2 = variantEndec;
			Func<K, Endec<T>> variantToEndec2 = variantToEndec;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> _, StructSerializer instance, T value)
			{
				K val = instanceToVariant2(value);
				instance.field("variant", ctx, variantEndec2, val);
				instance.field("instance", ctx, variantToEndec2(val), value);
			}, delegate(SerializationContext ctx, Deserializer<dynamic> _, StructDeserializer instance)
			{
				K arg = instance.field("variant", ctx, variantEndec2);
				return instance.field("instance", ctx, variantToEndec2(arg));
			});
		}

		static StructEndec<T> dispatchedFlatable<T, K>(string variantKey, string instanceKey, Func<K, Endec<T>> variantToEndec, Func<T, K> instanceToVariant, Endec<K> variantEndec)
		{
			Func<T, K> instanceToVariant2 = instanceToVariant;
			Endec<K> variantEndec2 = variantEndec;
			Func<K, Endec<T>> variantToEndec2 = variantToEndec;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, T value)
			{
				K val = instanceToVariant2(value);
				instance.field("variant", ctx, variantEndec2, val);
				Endec<T> endec2 = variantToEndec2(val);
				if (endec2 is StructEndec<T> structEndec2)
				{
					structEndec2.encodeStruct(ctx, serializer, instance, value);
				}
				else
				{
					instance.field("instance", ctx, endec2, value);
				}
			}, delegate(SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance)
			{
				K arg = instance.field("variant", ctx, variantEndec2);
				Endec<T> endec = variantToEndec2(arg);
				return (T)((!(endec is StructEndec<T> structEndec)) ? ((object)instance.field("instance", ctx, endec)) : ((object)structEndec.decodeStruct(ctx, deserializer, instance)));
			});
		}

		static AttributeEndecBuilder<T> ifAttr<T>(SerializationAttribute attribute, Endec<T> endec)
		{
			return new AttributeEndecBuilder<T>(endec, attribute);
		}
	}
	public sealed class EndecGetter
	{
		public static Endec<T> Endec<T>() where T : EndecGetter<T>
		{
			return EndecGetter<T>.Endec();
		}
	}
	public interface EndecGetter<T> where T : EndecGetter<T>
	{
		static Endec<T> Endec()
		{
			return (typeof(T).GetMethod("Endec", BindingFlags.Static | BindingFlags.Public).Invoke(null, null) as Endec<T>) ?? throw new InvalidCastException("Unable to get Endec due to it being the incorrect type!");
		}
	}
	public class SerializationAttributes
	{
		public static readonly SerializationAttributeMarker HUMAN_READABLE = SerializationAttribute.marker("human_readable");
	}
	public abstract class SerializationAttribute
	{
		public readonly string name;

		protected SerializationAttribute(string name)
		{
			this.name = name;
		}

		public static SerializationAttributeMarker marker(string name)
		{
			return new SerializationAttributeMarker(name);
		}

		public static SerializationAttributeWithValue<T> withValue<T>(string name)
		{
			return new SerializationAttributeWithValue<T>(name);
		}
	}
	public sealed class SerializationAttributeMarker : SerializationAttribute, SerializationAttributeInstance
	{
		internal SerializationAttributeMarker(string name)
			: base(name)
		{
		}

		public SerializationAttribute attribute()
		{
			return this;
		}

		public object value()
		{
			return null;
		}
	}
	public sealed class SerializationAttributeWithValue<T> : SerializationAttribute
	{
		internal SerializationAttributeWithValue(string name)
			: base(name)
		{
		}

		public SerializationAttributeInstance instance(T value)
		{
			return new InstanceImpl(this, value);
		}
	}
	public interface SerializationAttributeInstance
	{
		SerializationAttribute attribute();

		object value();
	}
	internal class InstanceImpl : SerializationAttributeInstance
	{
		private readonly SerializationAttribute attribute;

		private readonly object value;

		internal InstanceImpl(SerializationAttribute attribute, object value)
		{
			this.attribute = attribute;
			this.value = value;
		}

		SerializationAttribute SerializationAttributeInstance.attribute()
		{
			return attribute;
		}

		object SerializationAttributeInstance.value()
		{
			return value;
		}
	}
	public class SerializationContext
	{
		private static readonly SerializationContext EMPTY = new SerializationContext(new Dictionary<SerializationAttribute, object>(), new HashSet<SerializationAttribute>(), new EndecTrace());

		private readonly IDictionary<SerializationAttribute, object> attributeValues;

		private readonly ISet<SerializationAttribute> suppressedAttributes;

		private readonly EndecTrace trace;

		private SerializationContext(IDictionary<SerializationAttribute, object> attributeValues, ISet<SerializationAttribute> suppressedAttributes, EndecTrace trace)
		{
			this.attributeValues = attributeValues.ImmutableWrap();
			this.suppressedAttributes = suppressedAttributes.ImmutableWrap();
			this.trace = trace;
		}

		public static SerializationContext empty()
		{
			return EMPTY;
		}

		public static SerializationContext attributes(params SerializationAttributeInstance[] attributes)
		{
			if (attributes.Length != 0)
			{
				return new SerializationContext(unpackAttributes(attributes), new HashSet<SerializationAttribute>(), new EndecTrace());
			}
			return EMPTY;
		}

		public static SerializationContext suppressed(params SerializationAttribute[] attributes)
		{
			if (attributes.Length != 0)
			{
				return new SerializationContext(new Dictionary<SerializationAttribute, object>(), new HashSet<SerializationAttribute>(attributes), new EndecTrace());
			}
			return EMPTY;
		}

		public SerializationContext withAttributes(params SerializationAttributeInstance[] attributes)
		{
			IDictionary<SerializationAttribute, object> dictionary = unpackAttributes(attributes);
			foreach (KeyValuePair<SerializationAttribute, object> attributeValue in attributeValues)
			{
				if (!dictionary.ContainsKey(attributeValue.Key))
				{
					dictionary.Add(attributeValue);
				}
			}
			return new SerializationContext(dictionary, suppressedAttributes, new EndecTrace());
		}

		public SerializationContext withoutAttributes(params SerializationAttribute[] attributes)
		{
			Dictionary<SerializationAttribute, object> dictionary = new Dictionary<SerializationAttribute, object>(attributeValues);
			foreach (SerializationAttribute key in attributes)
			{
				dictionary.Remove(key);
			}
			return new SerializationContext(dictionary, suppressedAttributes, new EndecTrace());
		}

		public SerializationContext withSuppressed(params SerializationAttribute[] attributes)
		{
			HashSet<SerializationAttribute> set = new HashSet<SerializationAttribute>(suppressedAttributes);
			set.AddAll(attributes);
			return new SerializationContext(attributeValues, set, new EndecTrace());
		}

		public SerializationContext withoutSuppressed(params SerializationAttribute[] attributes)
		{
			HashSet<SerializationAttribute> hashSet = new HashSet<SerializationAttribute>(suppressedAttributes);
			foreach (SerializationAttribute item in attributes)
			{
				hashSet.Remove(item);
			}
			return new SerializationContext(attributeValues, hashSet, new EndecTrace());
		}

		public SerializationContext and(SerializationContext other)
		{
			Dictionary<SerializationAttribute, object> dictionary = new Dictionary<SerializationAttribute, object>(attributeValues);
			dictionary.AddAll(other.attributeValues);
			HashSet<SerializationAttribute> set = new HashSet<SerializationAttribute>(suppressedAttributes);
			set.AddAll(other.suppressedAttributes);
			return new SerializationContext(dictionary, set, new EndecTrace());
		}

		public bool hasAttribute(SerializationAttribute attribute)
		{
			if (attributeValues.ContainsKey(attribute))
			{
				return !suppressedAttributes.Contains(attribute);
			}
			return false;
		}

		public A getAttributeValue<A>(SerializationAttributeWithValue<A> attribute)
		{
			return (A)attributeValues[attribute];
		}

		public A requireAttributeValue<A>(SerializationAttributeWithValue<A> attribute)
		{
			if (hasAttribute(attribute))
			{
				return getAttributeValue(attribute);
			}
			throw new MissingAttributeValueException("Context did not provide a value for attribute '" + attribute.name + "'");
		}

		private static IDictionary<SerializationAttribute, object> unpackAttributes(params SerializationAttributeInstance[] attributes)
		{
			Dictionary<SerializationAttribute, object> dictionary = new Dictionary<SerializationAttribute, object>();
			foreach (SerializationAttributeInstance serializationAttributeInstance in attributes)
			{
				dictionary.Add(serializationAttributeInstance.attribute(), serializationAttributeInstance.value());
			}
			return dictionary;
		}

		public SerializationContext pushField(string fieldName)
		{
			return new SerializationContext(attributeValues, suppressedAttributes, trace.push(new FieldTraceElement(fieldName)));
		}

		public SerializationContext pushIndex(int index)
		{
			return new SerializationContext(attributeValues, suppressedAttributes, trace.push(new IndexTraceElement(index)));
		}

		public void throwMalformedInput(string message)
		{
			throw new EndecMalformedInputException(trace, message);
		}

		public E exceptionWithTrace<E>(Func<EndecTrace, E> exceptionFactory) where E : Exception
		{
			return exceptionFactory(trace);
		}

		public override string ToString()
		{
			return $"SerializationContext[Attributes: {attributeValues}, SuppressedAttributes: {suppressedAttributes}, CurrentTrace: {trace}]";
		}
	}
	public interface Serializer<out T> where T : class
	{
		SerializationContext setupContext(SerializationContext ctx)
		{
			return ctx;
		}

		void writeByte(SerializationContext ctx, byte value);

		void writeShort(SerializationContext ctx, short value);

		void writeInt(SerializationContext ctx, int value);

		void writeLong(SerializationContext ctx, long value);

		void writeFloat(SerializationContext ctx, float value);

		void writeDouble(SerializationContext ctx, double value);

		void writeVarInt(SerializationContext ctx, int value);

		void writeVarLong(SerializationContext ctx, long value);

		void writeBoolean(SerializationContext ctx, bool value);

		void writeString(SerializationContext ctx, string value);

		void writeBytes(SerializationContext ctx, byte[] bytes);

		void writeOptional<V>(SerializationContext ctx, Endec<V> endec, V? optional);

		SequenceSerializer<E> sequence<E>(SerializationContext ctx, Endec<E> elementEndec, int size);

		MapSerializer<V> map<V>(SerializationContext ctx, Endec<V> valueEndec, int size);

		StructSerializer structed();

		T result();
	}
	public interface SequenceSerializer<E> : Endable, IDisposable
	{
		void element(E element);
	}
	public interface MapSerializer<V> : Endable, IDisposable
	{
		void entry(string key, V value);
	}
	public interface StructSerializer : Endable, IDisposable
	{
		StructSerializer field<F>(string name, SerializationContext ctx, Endec<F> endec, F value)
		{
			return field(name, ctx, endec, value, mayOmit: false);
		}

		StructSerializer field<F>(string name, SerializationContext ctx, Endec<F> endec, F value, bool mayOmit);
	}
	public interface SelfDescribedSerializer<T> : Serializer<T> where T : class
	{
	}
	public delegate void StructuredEncoder<in T>(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, T value);
	public delegate T StructuredDecoder<out T>(SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance);
	public delegate T StructuredDecoderWithError<out T>(SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance, Exception exception);
	public abstract class StructEndec<T> : Endec<T>, StructEndec, Endec
	{
		public abstract void encodeStruct<E>(SerializationContext ctx, Serializer<E> serializer, StructSerializer instance, T value) where E : class;

		public abstract T decodeStruct<E>(SerializationContext ctx, Deserializer<E> deserializer, StructDeserializer instance) where E : class;

		public override void encode<E>(SerializationContext ctx, Serializer<E> serializer, T value)
		{
			using StructSerializer instance = serializer.structed();
			encodeStruct(ctx, serializer, instance, value);
		}

		public override T decode<E>(SerializationContext ctx, Deserializer<E> deserializer)
		{
			return decodeStruct(ctx, deserializer, deserializer.structed());
		}

		public StructField<S, T> flatFieldOf<S>(Func<S, T> getter)
		{
			return new FlatStructField<S, T>(this, getter);
		}

		public StructField<M, T> flatInheritedFieldOf<M>() where M : T
		{
			return new FlatStructField<M, T>(this, (M m) => (T)(object)m);
		}

		public new StructEndec<R> xmap<R>(Func<T, R> to, Func<R, T> from)
		{
			Func<R, T> from2 = from;
			Func<T, R> to2 = to;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, R value)
			{
				encodeStruct(ctx, serializer, instance, from2(value));
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => to2(decodeStruct(ctx, deserializer, instance)));
		}

		public new StructEndec<R> xmapWithContext<R>(Func<SerializationContext, T, R> to, Func<SerializationContext, R, T> from)
		{
			Func<SerializationContext, R, T> from2 = from;
			Func<SerializationContext, T, R> to2 = to;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, R value)
			{
				encodeStruct(ctx, serializer, instance, from2(ctx, value));
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => to2(ctx, decodeStruct(ctx, deserializer, instance)));
		}

		public StructEndec<T> structuredCatchErrors(StructuredDecoderWithError<T> decodeOnError)
		{
			StructuredDecoderWithError<T> decodeOnError2 = decodeOnError;
			return StructEndec.of(encodeStruct, delegate(SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance)
			{
				SerializationContext ctx2 = ctx;
				StructDeserializer instance2 = instance;
				try
				{
					return deserializer.tryRead((Deserializer<dynamic> deserializer1) => decodeStruct(ctx2, deserializer1, instance2));
				}
				catch (Exception exception)
				{
					return decodeOnError2(ctx2, deserializer, instance2, exception);
				}
			});
		}

		public new StructEndec<T> validate(Action<T> validator)
		{
			Action<T> validator2 = validator;
			return xmap(delegate(T t)
			{
				validator2(t);
				return t;
			}, delegate(T t)
			{
				validator2(t);
				return t;
			});
		}
	}
	public interface StructEndec : Endec
	{
		static StructEndec<T> of<T>(StructuredEncoder<T> encoder, StructuredDecoder<T> decoder)
		{
			return new StructEndecImpl<T>(encoder, decoder);
		}

		static StructEndec<T> recursive<T>(Func<StructEndec<T>, StructEndec<T>> builderFunc)
		{
			return new RecursiveStructEndec<T>(builderFunc);
		}

		static AttributeStructEndecBuilder<T> ifAttr<T>(SerializationAttribute attribute, StructEndec<T> endec)
		{
			return new AttributeStructEndecBuilder<T>(endec, attribute);
		}
	}
}
namespace io.wispforest.endec.util
{
	public class BlockWriter
	{
		private readonly StringWriter result = new StringWriter();

		private readonly Stack<(bool incrementIndentation, string value)> blocks = new Stack<(bool, string)>();

		private int indentLevel;

		public BlockWriter write(string value)
		{
			result.Write(value);
			return this;
		}

		public BlockWriter writeln()
		{
			writeln("");
			return this;
		}

		public BlockWriter writeln(string value)
		{
			result.Write(value + "\n" + "  ".repeat(Math.Max(0, indentLevel)));
			return this;
		}

		public BlockWriter startBlock(string startDelimiter, string endDelimiter)
		{
			return startBlock(startDelimiter, endDelimiter, incrementIndentation: true);
		}

		public BlockWriter startBlock(string startDelimiter, string endDelimiter, bool incrementIndentation)
		{
			if (incrementIndentation)
			{
				indentLevel++;
				writeln(startDelimiter);
			}
			else
			{
				write(startDelimiter);
			}
			blocks.Push((incrementIndentation, endDelimiter));
			return this;
		}

		public BlockWriter writeBlock(string startDelimiter, string endDelimiter, Action<BlockWriter> consumer)
		{
			return writeBlock(startDelimiter, endDelimiter, incrementIndentation: true, consumer);
		}

		public BlockWriter writeBlock(string startDelimiter, string endDelimiter, bool incrementIndentation, Action<BlockWriter> consumer)
		{
			startBlock(startDelimiter, endDelimiter, incrementIndentation);
			consumer(this);
			endBlock();
			return this;
		}

		public BlockWriter endBlock()
		{
			(bool, string) tuple = blocks.Pop();
			if (tuple.Item1)
			{
				indentLevel--;
				writeln();
			}
			write(tuple.Item2);
			return this;
		}

		public string buildResult()
		{
			return result.ToString();
		}
	}
	public static class StringExtension
	{
		public static string repeat(this string str, int amount)
		{
			return new StringBuilder().Insert(0, str, 3).ToString();
		}
	}
	public interface Endable : IDisposable
	{
		void end();

		void IDisposable.Dispose()
		{
			end();
		}
	}
	public static class DictionaryExtensions
	{
		public static IDictionary<TKey, TValue> ImmutableWrap<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
		{
			return new ReadOnlyDictionary<TKey, TValue>(dictionary);
		}

		public static void AddAll<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, IDictionary<TKey, TValue> additional)
		{
			foreach (KeyValuePair<TKey, TValue> item in additional)
			{
				dictionary.Add(item);
			}
		}

		public static void AddAll<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, IEnumerable<KeyValuePair<TKey, TValue>> additional)
		{
			foreach (KeyValuePair<TKey, TValue> item in additional)
			{
				dictionary.Add(item);
			}
		}

		public static void PutIfAbsent<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
		{
			if (!dictionary.ContainsKey(key))
			{
				dictionary[key] = value;
			}
		}
	}
	public static class SetExtensions
	{
		public static ISet<T> ImmutableWrap<T>(this ISet<T> set)
		{
			return new ReadOnlySet<T>(set);
		}

		public static void AddAll<T>(this ISet<T> set, IEnumerable<T> additional)
		{
			set.UnionWith(additional);
		}
	}
	public static class EnumerableExtensions
	{
		public static ISet<T> ImmutableSet<T>(this IEnumerable<T> set)
		{
			return new ReadOnlySet<T>(set);
		}
	}
	public static class CustomAttributeExtensions
	{
		public static bool HasCustomAttribute<T>(this Assembly element) where T : Attribute
		{
			return element.GetCustomAttribute<T>() != null;
		}

		public static bool HasCustomAttribute<T>(this Module element) where T : Attribute
		{
			return element.GetCustomAttribute<T>() != null;
		}

		public static bool HasCustomAttribute<T>(this MemberInfo element) where T : Attribute
		{
			return element.GetCustomAttribute<T>() != null;
		}

		public static bool HasCustomAttribute<T>(this ParameterInfo element) where T : Attribute
		{
			return element.GetCustomAttribute<T>() != null;
		}
	}
	public interface IndexedEnumerator<out T> : IEnumerator<T>, IEnumerator, IDisposable
	{
		int index { get; }
	}
	public static class IEnumeratorExtensions
	{
		public static IndexedEnumerator<T> GetIndexedEnumerator<T>(this IList<T> list)
		{
			return new WrappedIEnumerator<T>(list.GetEnumerator());
		}
	}
	public class WrappedIEnumerator<T> : IndexedEnumerator<T>, IEnumerator<T>, IEnumerator, IDisposable
	{
		[CompilerGenerated]
		private IEnumerator<T> <enumerator>P;

		public int index { get; private set; }

		public T Current => <enumerator>P.Current;

		object? IEnumerator.Current => Current;

		public WrappedIEnumerator(IEnumerator<T> enumerator)
		{
			<enumerator>P = enumerator;
			base..ctor();
		}

		public bool MoveNext()
		{
			bool num = <enumerator>P.MoveNext();
			if (num)
			{
				index++;
			}
			return num;
		}

		public void Reset()
		{
			<enumerator>P.Reset();
		}

		public void Dispose()
		{
			<enumerator>P.Dispose();
		}
	}
	public interface MapCarrier
	{
		T getWithErrors<T>(SerializationContext ctx, KeyedEndec<T> key);

		T getWithErrors<T>(KeyedEndec<T> key)
		{
			return getWithErrors(SerializationContext.empty(), key);
		}

		void put<T>(SerializationContext ctx, KeyedEndec<T> key, T value);

		void put<T>(KeyedEndec<T> key, T value)
		{
			put(SerializationContext.empty(), key, value);
		}

		void delete<T>(KeyedEndec<T> key);

		bool has<T>(KeyedEndec<T> key);

		T get<T>(SerializationContext ctx, KeyedEndec<T> key)
		{
			try
			{
				return getWithErrors(ctx, key);
			}
			catch (Exception)
			{
				return key.defaultValue();
			}
		}

		T get<T>(KeyedEndec<T> key)
		{
			return get(SerializationContext.empty(), key);
		}

		void putIfNotNull<T>(KeyedEndec<T> key, T? value)
		{
			putIfNotNull(SerializationContext.empty(), key, value);
		}

		void putIfNotNull<T>(SerializationContext ctx, KeyedEndec<T> key, T? value)
		{
			if (value != null)
			{
				put(ctx, key, value);
			}
		}

		void copy<T>(KeyedEndec<T> key, MapCarrier other)
		{
			copy(SerializationContext.empty(), key, other);
		}

		void copy<T>(SerializationContext ctx, KeyedEndec<T> key, MapCarrier other)
		{
			other.put(ctx, key, get(ctx, key));
		}

		void copyIfPresent<T>(KeyedEndec<T> key, MapCarrier other)
		{
			copyIfPresent(SerializationContext.empty(), key, other);
		}

		void copyIfPresent<T>(SerializationContext ctx, KeyedEndec<T> key, MapCarrier other)
		{
			if (has(key))
			{
				copy(ctx, key, other);
			}
		}

		void mutate<T>(KeyedEndec<T> key, Func<T, T> mutator)
		{
			mutate(SerializationContext.empty(), key, mutator);
		}

		void mutate<T>(SerializationContext ctx, KeyedEndec<T> key, Func<T, T> mutator)
		{
			put(ctx, key, mutator(get(ctx, key)));
		}
	}
	public class ReadOnlySet<T> : ISet<T>, ICollection<T>, IEnumerable<T>, IEnumerable
	{
		private readonly ISet<T> _set;

		public int Count => _set.Count;

		public bool IsReadOnly => true;

		public ReadOnlySet(ISet<T> set)
		{
			_set = set;
		}

		public ReadOnlySet(IEnumerable<T> enumerable)
		{
			_set = new HashSet<T>(enumerable);
		}

		public ReadOnlySet(params T[] entries)
		{
			_set = new HashSet<T>(entries);
		}

		public void Add(T item)
		{
			throw new NotSupportedException("Adding an item is not supported due to being read-only.");
		}

		public void ExceptWith(IEnumerable<T> other)
		{
			throw new NotSupportedException("Adding an item is not supported due to being read-only.");
		}

		public void IntersectWith(IEnumerable<T> other)
		{
			throw new NotSupportedException("Adding an item is not supported due to being read-only.");
		}

		public bool IsProperSubsetOf(IEnumerable<T> other)
		{
			return _set.IsProperSubsetOf(other);
		}

		public bool IsProperSupersetOf(IEnumerable<T> other)
		{
			return _set.IsProperSupersetOf(other);
		}

		public bool IsSubsetOf(IEnumerable<T> other)
		{
			return _set.IsSubsetOf(other);
		}

		public bool IsSupersetOf(IEnumerable<T> other)
		{
			return _set.IsSupersetOf(other);
		}

		public bool Overlaps(IEnumerable<T> other)
		{
			return _set.Overlaps(other);
		}

		public bool SetEquals(IEnumerable<T> other)
		{
			return _set.SetEquals(other);
		}

		public void SymmetricExceptWith(IEnumerable<T> other)
		{
			throw new NotSupportedException("Adding an item is not supported due to being read-only.");
		}

		public void UnionWith(IEnumerable<T> other)
		{
			throw new NotSupportedException("Adding an item is not supported due to being read-only.");
		}

		bool ISet<T>.Add(T item)
		{
			throw new NotSupportedException("Adding an item is not supported due to being read-only.");
		}

		public void Clear()
		{
			throw new NotSupportedException("Adding an item is not supported due to being read-only.");
		}

		public bool Contains(T item)
		{
			return _set.Contains(item);
		}

		public void CopyTo(T[] array, int arrayIndex)
		{
			_set.CopyTo(array, arrayIndex);
		}

		public bool Remove(T item)
		{
			throw new NotSupportedException("Adding an item is not supported due to being read-only.");
		}

		public IEnumerator<T> GetEnumerator()
		{
			return _set.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	public abstract class RecursiveDeserializer<T> : Deserializer<T> where T : class
	{
		private readonly LinkedList<Func<T>> frames = new LinkedList<Func<T>>();

		private readonly T serialized;

		protected RecursiveDeserializer(T serialized)
		{
			this.serialized = serialized;
			frames.AddFirst(() => this.serialized);
		}

		protected T getValue()
		{
			return frames.First.Value();
		}

		protected V frame<V>(Func<T> nextValue, Func<V> action)
		{
			try
			{
				frames.AddFirst(nextValue);
				return action();
			}
			finally
			{
				frames.RemoveFirst();
			}
		}

		public V tryRead<V>(Func<Deserializer<T>, V> reader)
		{
			LinkedList<Func<T>> linkedList = new LinkedList<Func<T>>(frames);
			try
			{
				return reader(this);
			}
			catch (Exception ex)
			{
				frames.Clear();
				foreach (Func<T> item in linkedList)
				{
					frames.AddFirst(item);
				}
				throw ex;
			}
		}

		public abstract byte readByte(SerializationContext ctx);

		public abstract short readShort(SerializationContext ctx);

		public abstract int readInt(SerializationContext ctx);

		public abstract long readLong(SerializationContext ctx);

		public abstract float readFloat(SerializationContext ctx);

		public abstract double readDouble(SerializationContext ctx);

		public abstract int readVarInt(SerializationContext ctx);

		public abstract long readVarLong(SerializationContext ctx);

		public abstract bool readBoolean(SerializationContext ctx);

		public abstract string readString(SerializationContext ctx);

		public abstract byte[] readBytes(SerializationContext ctx);

		public abstract V? readOptional<V>(SerializationContext ctx, Endec<V> endec);

		public abstract SequenceDeserializer<E> sequence<E>(SerializationContext ctx, Endec<E> elementEndec);

		public abstract MapDeserializer<V> map<V>(SerializationContext ctx, Endec<V> valueEndec);

		public abstract StructDeserializer structed();
	}
	public abstract class RecursiveSerializer<T> : Serializer<T> where T : class
	{
		private readonly LinkedList<Action<T>> _frames = new LinkedList<Action<T>>();

		private T _result;

		protected RecursiveSerializer(T initialResult)
		{
			_result = initialResult;
			_frames.AddFirst(delegate(T t)
			{
				_result = t;
			});
		}

		protected void consume(T value)
		{
			_frames.First.Value(value);
		}

		protected void frame(FrameAction<T> action)
		{
			EncodedValue<T> encodedValue = new EncodedValue<T>();
			_frames.AddFirst(encodedValue.set);
			action(encodedValue);
			_frames.RemoveFirst();
		}

		public T result()
		{
			return _result;
		}

		public abstract void writeByte(SerializationContext ctx, byte value);

		public abstract void writeShort(SerializationContext ctx, short value);

		public abstract void writeInt(SerializationContext ctx, int value);

		public abstract void writeLong(SerializationContext ctx, long value);

		public abstract void writeFloat(SerializationContext ctx, float value);

		public abstract void writeDouble(SerializationContext ctx, double value);

		public abstract void writeVarInt(SerializationContext ctx, int value);

		public abstract void writeVarLong(SerializationContext ctx, long value);

		public abstract void writeBoolean(SerializationContext ctx, bool value);

		public abstract void writeString(SerializationContext ctx, string value);

		public abstract void writeBytes(SerializationContext ctx, byte[] bytes);

		public abstract void writeOptional<V>(SerializationContext ctx, Endec<V> endec, V? optional);

		public abstract SequenceSerializer<E> sequence<E>(SerializationContext ctx, Endec<E> elementEndec, int size);

		public abstract MapSerializer<V> map<V>(SerializationContext ctx, Endec<V> valueEndec, int size);

		public abstract StructSerializer structed();
	}
	public delegate void FrameAction<T>(EncodedValue<T> encoded);
	public class EncodedValue<T>
	{
		private T? _value;

		private bool _encoded;

		internal void set(T value)
		{
			_value = value;
			_encoded = true;
		}

		public T value()
		{
			return _value;
		}

		public bool wasEncoded()
		{
			return _encoded;
		}

		public T require(string name)
		{
			if (!_encoded)
			{
				throw new Exception("Endec for " + name + " serialized nothing");
			}
			return value();
		}
	}
	public class VarInts
	{
		public const int SEGMENT_BITS = 127;

		public const int CONTINUE_BIT = 128;

		public static int getSizeInBytesFromInt(int i)
		{
			for (int j = 1; j < 5; j++)
			{
				if ((i & (-1 << j * 7)) == 0)
				{
					return j;
				}
			}
			return 5;
		}

		public static int getSizeInBytesFromLong(long l)
		{
			for (int i = 1; i < 10; i++)
			{
				if ((l & (-1L << i * 7)) == 0L)
				{
					return i;
				}
			}
			return 10;
		}

		public static int readInt(Func<byte> readByteSup)
		{
			int num = 0;
			int num2 = 0;
			while (true)
			{
				byte b = readByteSup();
				num |= (b & 0x7F) << num2;
				if ((b & 0x80) == 0)
				{
					break;
				}
				num2 += 7;
				if (num2 >= 32)
				{
					throw new Exception("VarInt is too big");
				}
			}
			return num;
		}

		public static void writeInt(int value, Action<byte> writeByteFunc)
		{
			while (((uint)value & 0xFFFFFF80u) != 0)
			{
				writeByteFunc((byte)(((uint)value & 0x7Fu) | 0x80u));
				value >>>= 7;
			}
			writeByteFunc((byte)value);
		}

		public static long readLong(Func<byte> readByteSup)
		{
			long num = 0L;
			int num2 = 0;
			while (true)
			{
				byte b = readByteSup();
				num |= (long)(b & 0x7F) << num2;
				if ((b & 0x80) == 0)
				{
					break;
				}
				num2 += 7;
				if (num2 >= 64)
				{
					throw new Exception("VarLong is too big");
				}
			}
			return num;
		}

		public static void writeLong(long value, Action<byte> writeByteFunc)
		{
			while ((value & -128) != 0L)
			{
				writeByteFunc((byte)((value & 0x7F) | 0x80));
				value >>>= 7;
			}
			writeByteFunc((byte)value);
		}
	}
}
namespace io.wispforest.endec.impl
{
	public class AttributeEndecBuilder<T>
	{
		private readonly List<(SerializationAttribute, Endec<T>)> _branches = new List<(SerializationAttribute, Endec<T>)>();

		public AttributeEndecBuilder(Endec<T> endec, SerializationAttribute attribute)
		{
			_branches.Add((attribute, endec));
		}

		public AttributeEndecBuilder<T> orElseIf(Endec<T> endec, SerializationAttribute attribute)
		{
			return orElseIf(attribute, endec);
		}

		public AttributeEndecBuilder<T> orElseIf(SerializationAttribute attribute, Endec<T> endec)
		{
			SerializationAttribute attribute2 = attribute;
			if (_branches.Exists(((SerializationAttribute, Endec<T>) tuple) => tuple.Item1.Equals(attribute2)))
			{
				throw new ArgumentException("Cannot have more than one branch for attribute " + attribute2.name);
			}
			_branches.Add((attribute2, endec));
			return this;
		}

		public Endec<T> orElse(Endec<T> endec)
		{
			Endec<T> endec2 = endec;
			return Endec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, T value)
			{
				Endec<T> endec4 = endec2;
				foreach (var branch in _branches)
				{
					if (ctx.hasAttribute(branch.Item1))
					{
						endec4 = branch.Item2;
						break;
					}
				}
				endec4.encode(ctx, serializer, value);
			}, delegate(SerializationContext ctx, Deserializer<dynamic> deserializer)
			{
				Endec<T> endec3 = endec2;
				foreach (var branch2 in _branches)
				{
					if (ctx.hasAttribute(branch2.Item1))
					{
						endec3 = branch2.Item2;
						break;
					}
				}
				return endec3.decode(ctx, deserializer);
			});
		}
	}
	public class AttributeStructEndecBuilder<T>
	{
		private readonly List<(SerializationAttribute, StructEndec<T>)> branches = new List<(SerializationAttribute, StructEndec<T>)>();

		public AttributeStructEndecBuilder(StructEndec<T> endec, SerializationAttribute attribute)
		{
			branches.Add((attribute, endec));
		}

		public AttributeStructEndecBuilder<T> orElseIf(StructEndec<T> endec, SerializationAttribute attribute)
		{
			return orElseIf(attribute, endec);
		}

		public AttributeStructEndecBuilder<T> orElseIf(SerializationAttribute attribute, StructEndec<T> endec)
		{
			SerializationAttribute attribute2 = attribute;
			if (branches.Exists(((SerializationAttribute, StructEndec<T>) tuple) => tuple.Item1.Equals(attribute2)))
			{
				throw new ArgumentException("Cannot have more than one branch for attribute " + attribute2.name);
			}
			branches.Add((attribute2, endec));
			return this;
		}

		public StructEndec<T> orElse(StructEndec<T> endec)
		{
			StructEndec<T> endec2 = endec;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, T value)
			{
				StructEndec<T> structEndec2 = endec2;
				foreach (var branch in branches)
				{
					if (ctx.hasAttribute(branch.Item1))
					{
						structEndec2 = branch.Item2;
						break;
					}
				}
				structEndec2.encodeStruct(ctx, serializer, instance, value);
			}, delegate(SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance)
			{
				StructEndec<T> structEndec = endec2;
				foreach (var branch2 in branches)
				{
					if (ctx.hasAttribute(branch2.Item1))
					{
						structEndec = branch2.Item2;
						break;
					}
				}
				return structEndec.decodeStruct(ctx, deserializer, instance);
			});
		}
	}
	public static class DebugErrors
	{
		public static Action<object, Exception>? decodeErrorHook;
	}
	public class EndecImpl<T> : Endec<T>
	{
		private readonly Encoder<T> _encoder;

		private readonly Decoder<T> _decoder;

		public EndecImpl(Encoder<T> encoder, Decoder<T> decoder)
		{
			_encoder = encoder;
			_decoder = decoder;
		}

		public override void encode<E>(SerializationContext ctx, Serializer<E> serializer, T value)
		{
			_encoder(ctx, serializer, value);
		}

		public override T decode<E>(SerializationContext ctx, Deserializer<E> deserializer)
		{
			return _decoder(ctx, deserializer);
		}
	}
	public class KeyedEndec<F>
	{
		public string key { get; }

		public Endec<F> endec { get; }

		public Func<F> defaultValueFactory { get; }

		public KeyedEndec(string key, Endec<F> endec, Func<F> defaultValueFactory)
		{
			this.key = key;
			this.endec = endec;
			this.defaultValueFactory = defaultValueFactory;
		}

		public KeyedEndec(string key, Endec<F> endec, F defaultValue)
		{
			F defaultValue2 = defaultValue;
			this..ctor(key, endec, (Func<F>)(() => defaultValue2));
		}

		public F defaultValue()
		{
			return defaultValueFactory();
		}
	}
	public class MissingAttributeValueException : Exception
	{
		public MissingAttributeValueException(string message)
			: base(message)
		{
		}
	}
	public class RecursiveEndec<T> : Endec<T>
	{
		public readonly Endec<T> endec;

		public RecursiveEndec(Func<Endec<T>, Endec<T>> builder)
		{
			endec = builder(this);
		}

		public override void encode<E>(SerializationContext ctx, Serializer<E> serializer, T value)
		{
			endec.encode(ctx, serializer, value);
		}

		public override T decode<E>(SerializationContext ctx, Deserializer<E> deserializer)
		{
			return endec.decode(ctx, deserializer);
		}
	}
	public class RecursiveStructEndec<T> : StructEndec<T>
	{
		public readonly StructEndec<T> structEndec;

		public RecursiveStructEndec(Func<StructEndec<T>, StructEndec<T>> builder)
		{
			structEndec = builder(this);
		}

		public override void encodeStruct<E>(SerializationContext ctx, Serializer<E> serializer, StructSerializer instance, T value)
		{
			structEndec.encodeStruct(ctx, serializer, instance, value);
		}

		public override T decodeStruct<E>(SerializationContext ctx, Deserializer<E> deserializer, StructDeserializer instance)
		{
			return structEndec.decodeStruct(ctx, deserializer, instance);
		}
	}
	public class StructEndecBuilder
	{
		public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, in T17, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16, T17 arg17);

		public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, in T9, in T10, in T11, in T12, in T13, in T14, in T15, in T16, in T17, in T18, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16, T17 arg17, T18 arg18);

		public static StructEndec<S> of<S, F1>(StructField<S, F1> f1, Func<F1, S> constructor)
		{
			StructField<S, F1> f2 = f1;
			Func<F1, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f2.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f2.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2>(StructField<S, F1> f1, StructField<S, F2> f2, Func<F1, F2, S> constructor)
		{
			StructField<S, F1> f3 = f1;
			StructField<S, F2> f4 = f2;
			Func<F1, F2, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f3.encodeField(ctx, serializer, instance, value);
				f4.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f3.decodeField(ctx, deserializer, instance), f4.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, Func<F1, F2, F3, S> constructor)
		{
			StructField<S, F1> f4 = f1;
			StructField<S, F2> f5 = f2;
			StructField<S, F3> f6 = f3;
			Func<F1, F2, F3, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f4.encodeField(ctx, serializer, instance, value);
				f5.encodeField(ctx, serializer, instance, value);
				f6.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f4.decodeField(ctx, deserializer, instance), f5.decodeField(ctx, deserializer, instance), f6.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, Func<F1, F2, F3, F4, S> constructor)
		{
			StructField<S, F1> f5 = f1;
			StructField<S, F2> f6 = f2;
			StructField<S, F3> f7 = f3;
			StructField<S, F4> f8 = f4;
			Func<F1, F2, F3, F4, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f5.encodeField(ctx, serializer, instance, value);
				f6.encodeField(ctx, serializer, instance, value);
				f7.encodeField(ctx, serializer, instance, value);
				f8.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f5.decodeField(ctx, deserializer, instance), f6.decodeField(ctx, deserializer, instance), f7.decodeField(ctx, deserializer, instance), f8.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, Func<F1, F2, F3, F4, F5, S> constructor)
		{
			StructField<S, F1> f6 = f1;
			StructField<S, F2> f7 = f2;
			StructField<S, F3> f8 = f3;
			StructField<S, F4> f9 = f4;
			StructField<S, F5> f10 = f5;
			Func<F1, F2, F3, F4, F5, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f6.encodeField(ctx, serializer, instance, value);
				f7.encodeField(ctx, serializer, instance, value);
				f8.encodeField(ctx, serializer, instance, value);
				f9.encodeField(ctx, serializer, instance, value);
				f10.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f6.decodeField(ctx, deserializer, instance), f7.decodeField(ctx, deserializer, instance), f8.decodeField(ctx, deserializer, instance), f9.decodeField(ctx, deserializer, instance), f10.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, Func<F1, F2, F3, F4, F5, F6, S> constructor)
		{
			StructField<S, F1> f7 = f1;
			StructField<S, F2> f8 = f2;
			StructField<S, F3> f9 = f3;
			StructField<S, F4> f10 = f4;
			StructField<S, F5> f11 = f5;
			StructField<S, F6> f12 = f6;
			Func<F1, F2, F3, F4, F5, F6, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f7.encodeField(ctx, serializer, instance, value);
				f8.encodeField(ctx, serializer, instance, value);
				f9.encodeField(ctx, serializer, instance, value);
				f10.encodeField(ctx, serializer, instance, value);
				f11.encodeField(ctx, serializer, instance, value);
				f12.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f7.decodeField(ctx, deserializer, instance), f8.decodeField(ctx, deserializer, instance), f9.decodeField(ctx, deserializer, instance), f10.decodeField(ctx, deserializer, instance), f11.decodeField(ctx, deserializer, instance), f12.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6, F7>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, StructField<S, F7> f7, Func<F1, F2, F3, F4, F5, F6, F7, S> constructor)
		{
			StructField<S, F1> f8 = f1;
			StructField<S, F2> f9 = f2;
			StructField<S, F3> f10 = f3;
			StructField<S, F4> f11 = f4;
			StructField<S, F5> f12 = f5;
			StructField<S, F6> f13 = f6;
			StructField<S, F7> f14 = f7;
			Func<F1, F2, F3, F4, F5, F6, F7, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f8.encodeField(ctx, serializer, instance, value);
				f9.encodeField(ctx, serializer, instance, value);
				f10.encodeField(ctx, serializer, instance, value);
				f11.encodeField(ctx, serializer, instance, value);
				f12.encodeField(ctx, serializer, instance, value);
				f13.encodeField(ctx, serializer, instance, value);
				f14.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f8.decodeField(ctx, deserializer, instance), f9.decodeField(ctx, deserializer, instance), f10.decodeField(ctx, deserializer, instance), f11.decodeField(ctx, deserializer, instance), f12.decodeField(ctx, deserializer, instance), f13.decodeField(ctx, deserializer, instance), f14.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6, F7, F8>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, StructField<S, F7> f7, StructField<S, F8> f8, Func<F1, F2, F3, F4, F5, F6, F7, F8, S> constructor)
		{
			StructField<S, F1> f9 = f1;
			StructField<S, F2> f10 = f2;
			StructField<S, F3> f11 = f3;
			StructField<S, F4> f12 = f4;
			StructField<S, F5> f13 = f5;
			StructField<S, F6> f14 = f6;
			StructField<S, F7> f15 = f7;
			StructField<S, F8> f16 = f8;
			Func<F1, F2, F3, F4, F5, F6, F7, F8, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f9.encodeField(ctx, serializer, instance, value);
				f10.encodeField(ctx, serializer, instance, value);
				f11.encodeField(ctx, serializer, instance, value);
				f12.encodeField(ctx, serializer, instance, value);
				f13.encodeField(ctx, serializer, instance, value);
				f14.encodeField(ctx, serializer, instance, value);
				f15.encodeField(ctx, serializer, instance, value);
				f16.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f9.decodeField(ctx, deserializer, instance), f10.decodeField(ctx, deserializer, instance), f11.decodeField(ctx, deserializer, instance), f12.decodeField(ctx, deserializer, instance), f13.decodeField(ctx, deserializer, instance), f14.decodeField(ctx, deserializer, instance), f15.decodeField(ctx, deserializer, instance), f16.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6, F7, F8, F9>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, StructField<S, F7> f7, StructField<S, F8> f8, StructField<S, F9> f9, Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, S> constructor)
		{
			StructField<S, F1> f10 = f1;
			StructField<S, F2> f11 = f2;
			StructField<S, F3> f12 = f3;
			StructField<S, F4> f13 = f4;
			StructField<S, F5> f14 = f5;
			StructField<S, F6> f15 = f6;
			StructField<S, F7> f16 = f7;
			StructField<S, F8> f17 = f8;
			StructField<S, F9> f18 = f9;
			Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f10.encodeField(ctx, serializer, instance, value);
				f11.encodeField(ctx, serializer, instance, value);
				f12.encodeField(ctx, serializer, instance, value);
				f13.encodeField(ctx, serializer, instance, value);
				f14.encodeField(ctx, serializer, instance, value);
				f15.encodeField(ctx, serializer, instance, value);
				f16.encodeField(ctx, serializer, instance, value);
				f17.encodeField(ctx, serializer, instance, value);
				f18.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f10.decodeField(ctx, deserializer, instance), f11.decodeField(ctx, deserializer, instance), f12.decodeField(ctx, deserializer, instance), f13.decodeField(ctx, deserializer, instance), f14.decodeField(ctx, deserializer, instance), f15.decodeField(ctx, deserializer, instance), f16.decodeField(ctx, deserializer, instance), f17.decodeField(ctx, deserializer, instance), f18.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, StructField<S, F7> f7, StructField<S, F8> f8, StructField<S, F9> f9, StructField<S, F10> f10, Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, S> constructor)
		{
			StructField<S, F1> f11 = f1;
			StructField<S, F2> f13 = f2;
			StructField<S, F3> f14 = f3;
			StructField<S, F4> f15 = f4;
			StructField<S, F5> f16 = f5;
			StructField<S, F6> f17 = f6;
			StructField<S, F7> f18 = f7;
			StructField<S, F8> f19 = f8;
			StructField<S, F9> f20 = f9;
			StructField<S, F10> f12 = f10;
			Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f11.encodeField(ctx, serializer, instance, value);
				f13.encodeField(ctx, serializer, instance, value);
				f14.encodeField(ctx, serializer, instance, value);
				f15.encodeField(ctx, serializer, instance, value);
				f16.encodeField(ctx, serializer, instance, value);
				f17.encodeField(ctx, serializer, instance, value);
				f18.encodeField(ctx, serializer, instance, value);
				f19.encodeField(ctx, serializer, instance, value);
				f20.encodeField(ctx, serializer, instance, value);
				f12.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f11.decodeField(ctx, deserializer, instance), f13.decodeField(ctx, deserializer, instance), f14.decodeField(ctx, deserializer, instance), f15.decodeField(ctx, deserializer, instance), f16.decodeField(ctx, deserializer, instance), f17.decodeField(ctx, deserializer, instance), f18.decodeField(ctx, deserializer, instance), f19.decodeField(ctx, deserializer, instance), f20.decodeField(ctx, deserializer, instance), f12.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, StructField<S, F7> f7, StructField<S, F8> f8, StructField<S, F9> f9, StructField<S, F10> f10, StructField<S, F11> f11, Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, S> constructor)
		{
			StructField<S, F1> f12 = f1;
			StructField<S, F2> f15 = f2;
			StructField<S, F3> f16 = f3;
			StructField<S, F4> f17 = f4;
			StructField<S, F5> f18 = f5;
			StructField<S, F6> f19 = f6;
			StructField<S, F7> f20 = f7;
			StructField<S, F8> f21 = f8;
			StructField<S, F9> f22 = f9;
			StructField<S, F10> f13 = f10;
			StructField<S, F11> f14 = f11;
			Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f12.encodeField(ctx, serializer, instance, value);
				f15.encodeField(ctx, serializer, instance, value);
				f16.encodeField(ctx, serializer, instance, value);
				f17.encodeField(ctx, serializer, instance, value);
				f18.encodeField(ctx, serializer, instance, value);
				f19.encodeField(ctx, serializer, instance, value);
				f20.encodeField(ctx, serializer, instance, value);
				f21.encodeField(ctx, serializer, instance, value);
				f22.encodeField(ctx, serializer, instance, value);
				f13.encodeField(ctx, serializer, instance, value);
				f14.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f12.decodeField(ctx, deserializer, instance), f15.decodeField(ctx, deserializer, instance), f16.decodeField(ctx, deserializer, instance), f17.decodeField(ctx, deserializer, instance), f18.decodeField(ctx, deserializer, instance), f19.decodeField(ctx, deserializer, instance), f20.decodeField(ctx, deserializer, instance), f21.decodeField(ctx, deserializer, instance), f22.decodeField(ctx, deserializer, instance), f13.decodeField(ctx, deserializer, instance), f14.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, StructField<S, F7> f7, StructField<S, F8> f8, StructField<S, F9> f9, StructField<S, F10> f10, StructField<S, F11> f11, StructField<S, F12> f12, Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, S> constructor)
		{
			StructField<S, F1> f13 = f1;
			StructField<S, F2> f17 = f2;
			StructField<S, F3> f18 = f3;
			StructField<S, F4> f19 = f4;
			StructField<S, F5> f20 = f5;
			StructField<S, F6> f21 = f6;
			StructField<S, F7> f22 = f7;
			StructField<S, F8> f23 = f8;
			StructField<S, F9> f24 = f9;
			StructField<S, F10> f14 = f10;
			StructField<S, F11> f15 = f11;
			StructField<S, F12> f16 = f12;
			Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f13.encodeField(ctx, serializer, instance, value);
				f17.encodeField(ctx, serializer, instance, value);
				f18.encodeField(ctx, serializer, instance, value);
				f19.encodeField(ctx, serializer, instance, value);
				f20.encodeField(ctx, serializer, instance, value);
				f21.encodeField(ctx, serializer, instance, value);
				f22.encodeField(ctx, serializer, instance, value);
				f23.encodeField(ctx, serializer, instance, value);
				f24.encodeField(ctx, serializer, instance, value);
				f14.encodeField(ctx, serializer, instance, value);
				f15.encodeField(ctx, serializer, instance, value);
				f16.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f13.decodeField(ctx, deserializer, instance), f17.decodeField(ctx, deserializer, instance), f18.decodeField(ctx, deserializer, instance), f19.decodeField(ctx, deserializer, instance), f20.decodeField(ctx, deserializer, instance), f21.decodeField(ctx, deserializer, instance), f22.decodeField(ctx, deserializer, instance), f23.decodeField(ctx, deserializer, instance), f24.decodeField(ctx, deserializer, instance), f14.decodeField(ctx, deserializer, instance), f15.decodeField(ctx, deserializer, instance), f16.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, StructField<S, F7> f7, StructField<S, F8> f8, StructField<S, F9> f9, StructField<S, F10> f10, StructField<S, F11> f11, StructField<S, F12> f12, StructField<S, F13> f13, Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, S> constructor)
		{
			StructField<S, F1> f14 = f1;
			StructField<S, F2> f19 = f2;
			StructField<S, F3> f20 = f3;
			StructField<S, F4> f21 = f4;
			StructField<S, F5> f22 = f5;
			StructField<S, F6> f23 = f6;
			StructField<S, F7> f24 = f7;
			StructField<S, F8> f25 = f8;
			StructField<S, F9> f26 = f9;
			StructField<S, F10> f15 = f10;
			StructField<S, F11> f16 = f11;
			StructField<S, F12> f17 = f12;
			StructField<S, F13> f18 = f13;
			Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f14.encodeField(ctx, serializer, instance, value);
				f19.encodeField(ctx, serializer, instance, value);
				f20.encodeField(ctx, serializer, instance, value);
				f21.encodeField(ctx, serializer, instance, value);
				f22.encodeField(ctx, serializer, instance, value);
				f23.encodeField(ctx, serializer, instance, value);
				f24.encodeField(ctx, serializer, instance, value);
				f25.encodeField(ctx, serializer, instance, value);
				f26.encodeField(ctx, serializer, instance, value);
				f15.encodeField(ctx, serializer, instance, value);
				f16.encodeField(ctx, serializer, instance, value);
				f17.encodeField(ctx, serializer, instance, value);
				f18.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f14.decodeField(ctx, deserializer, instance), f19.decodeField(ctx, deserializer, instance), f20.decodeField(ctx, deserializer, instance), f21.decodeField(ctx, deserializer, instance), f22.decodeField(ctx, deserializer, instance), f23.decodeField(ctx, deserializer, instance), f24.decodeField(ctx, deserializer, instance), f25.decodeField(ctx, deserializer, instance), f26.decodeField(ctx, deserializer, instance), f15.decodeField(ctx, deserializer, instance), f16.decodeField(ctx, deserializer, instance), f17.decodeField(ctx, deserializer, instance), f18.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, StructField<S, F7> f7, StructField<S, F8> f8, StructField<S, F9> f9, StructField<S, F10> f10, StructField<S, F11> f11, StructField<S, F12> f12, StructField<S, F13> f13, StructField<S, F14> f14, Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, S> constructor)
		{
			StructField<S, F1> f15 = f1;
			StructField<S, F2> f21 = f2;
			StructField<S, F3> f22 = f3;
			StructField<S, F4> f23 = f4;
			StructField<S, F5> f24 = f5;
			StructField<S, F6> f25 = f6;
			StructField<S, F7> f26 = f7;
			StructField<S, F8> f27 = f8;
			StructField<S, F9> f28 = f9;
			StructField<S, F10> f16 = f10;
			StructField<S, F11> f17 = f11;
			StructField<S, F12> f18 = f12;
			StructField<S, F13> f19 = f13;
			StructField<S, F14> f20 = f14;
			Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f15.encodeField(ctx, serializer, instance, value);
				f21.encodeField(ctx, serializer, instance, value);
				f22.encodeField(ctx, serializer, instance, value);
				f23.encodeField(ctx, serializer, instance, value);
				f24.encodeField(ctx, serializer, instance, value);
				f25.encodeField(ctx, serializer, instance, value);
				f26.encodeField(ctx, serializer, instance, value);
				f27.encodeField(ctx, serializer, instance, value);
				f28.encodeField(ctx, serializer, instance, value);
				f16.encodeField(ctx, serializer, instance, value);
				f17.encodeField(ctx, serializer, instance, value);
				f18.encodeField(ctx, serializer, instance, value);
				f19.encodeField(ctx, serializer, instance, value);
				f20.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f15.decodeField(ctx, deserializer, instance), f21.decodeField(ctx, deserializer, instance), f22.decodeField(ctx, deserializer, instance), f23.decodeField(ctx, deserializer, instance), f24.decodeField(ctx, deserializer, instance), f25.decodeField(ctx, deserializer, instance), f26.decodeField(ctx, deserializer, instance), f27.decodeField(ctx, deserializer, instance), f28.decodeField(ctx, deserializer, instance), f16.decodeField(ctx, deserializer, instance), f17.decodeField(ctx, deserializer, instance), f18.decodeField(ctx, deserializer, instance), f19.decodeField(ctx, deserializer, instance), f20.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, StructField<S, F7> f7, StructField<S, F8> f8, StructField<S, F9> f9, StructField<S, F10> f10, StructField<S, F11> f11, StructField<S, F12> f12, StructField<S, F13> f13, StructField<S, F14> f14, StructField<S, F15> f15, Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, S> constructor)
		{
			StructField<S, F1> f16 = f1;
			StructField<S, F2> f23 = f2;
			StructField<S, F3> f24 = f3;
			StructField<S, F4> f25 = f4;
			StructField<S, F5> f26 = f5;
			StructField<S, F6> f27 = f6;
			StructField<S, F7> f28 = f7;
			StructField<S, F8> f29 = f8;
			StructField<S, F9> f30 = f9;
			StructField<S, F10> f17 = f10;
			StructField<S, F11> f18 = f11;
			StructField<S, F12> f19 = f12;
			StructField<S, F13> f20 = f13;
			StructField<S, F14> f21 = f14;
			StructField<S, F15> f22 = f15;
			Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f16.encodeField(ctx, serializer, instance, value);
				f23.encodeField(ctx, serializer, instance, value);
				f24.encodeField(ctx, serializer, instance, value);
				f25.encodeField(ctx, serializer, instance, value);
				f26.encodeField(ctx, serializer, instance, value);
				f27.encodeField(ctx, serializer, instance, value);
				f28.encodeField(ctx, serializer, instance, value);
				f29.encodeField(ctx, serializer, instance, value);
				f30.encodeField(ctx, serializer, instance, value);
				f17.encodeField(ctx, serializer, instance, value);
				f18.encodeField(ctx, serializer, instance, value);
				f19.encodeField(ctx, serializer, instance, value);
				f20.encodeField(ctx, serializer, instance, value);
				f21.encodeField(ctx, serializer, instance, value);
				f22.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f16.decodeField(ctx, deserializer, instance), f23.decodeField(ctx, deserializer, instance), f24.decodeField(ctx, deserializer, instance), f25.decodeField(ctx, deserializer, instance), f26.decodeField(ctx, deserializer, instance), f27.decodeField(ctx, deserializer, instance), f28.decodeField(ctx, deserializer, instance), f29.decodeField(ctx, deserializer, instance), f30.decodeField(ctx, deserializer, instance), f17.decodeField(ctx, deserializer, instance), f18.decodeField(ctx, deserializer, instance), f19.decodeField(ctx, deserializer, instance), f20.decodeField(ctx, deserializer, instance), f21.decodeField(ctx, deserializer, instance), f22.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, StructField<S, F7> f7, StructField<S, F8> f8, StructField<S, F9> f9, StructField<S, F10> f10, StructField<S, F11> f11, StructField<S, F12> f12, StructField<S, F13> f13, StructField<S, F14> f14, StructField<S, F15> f15, StructField<S, F16> f16, Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, S> constructor)
		{
			StructField<S, F1> f17 = f1;
			StructField<S, F2> f25 = f2;
			StructField<S, F3> f26 = f3;
			StructField<S, F4> f27 = f4;
			StructField<S, F5> f28 = f5;
			StructField<S, F6> f29 = f6;
			StructField<S, F7> f30 = f7;
			StructField<S, F8> f31 = f8;
			StructField<S, F9> f32 = f9;
			StructField<S, F10> f18 = f10;
			StructField<S, F11> f19 = f11;
			StructField<S, F12> f20 = f12;
			StructField<S, F13> f21 = f13;
			StructField<S, F14> f22 = f14;
			StructField<S, F15> f23 = f15;
			StructField<S, F16> f24 = f16;
			Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f17.encodeField(ctx, serializer, instance, value);
				f25.encodeField(ctx, serializer, instance, value);
				f26.encodeField(ctx, serializer, instance, value);
				f27.encodeField(ctx, serializer, instance, value);
				f28.encodeField(ctx, serializer, instance, value);
				f29.encodeField(ctx, serializer, instance, value);
				f30.encodeField(ctx, serializer, instance, value);
				f31.encodeField(ctx, serializer, instance, value);
				f32.encodeField(ctx, serializer, instance, value);
				f18.encodeField(ctx, serializer, instance, value);
				f19.encodeField(ctx, serializer, instance, value);
				f20.encodeField(ctx, serializer, instance, value);
				f21.encodeField(ctx, serializer, instance, value);
				f22.encodeField(ctx, serializer, instance, value);
				f23.encodeField(ctx, serializer, instance, value);
				f24.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f17.decodeField(ctx, deserializer, instance), f25.decodeField(ctx, deserializer, instance), f26.decodeField(ctx, deserializer, instance), f27.decodeField(ctx, deserializer, instance), f28.decodeField(ctx, deserializer, instance), f29.decodeField(ctx, deserializer, instance), f30.decodeField(ctx, deserializer, instance), f31.decodeField(ctx, deserializer, instance), f32.decodeField(ctx, deserializer, instance), f18.decodeField(ctx, deserializer, instance), f19.decodeField(ctx, deserializer, instance), f20.decodeField(ctx, deserializer, instance), f21.decodeField(ctx, deserializer, instance), f22.decodeField(ctx, deserializer, instance), f23.decodeField(ctx, deserializer, instance), f24.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, StructField<S, F7> f7, StructField<S, F8> f8, StructField<S, F9> f9, StructField<S, F10> f10, StructField<S, F11> f11, StructField<S, F12> f12, StructField<S, F13> f13, StructField<S, F14> f14, StructField<S, F15> f15, StructField<S, F16> f16, StructField<S, F17> f17, Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, S> constructor)
		{
			StructField<S, F1> f18 = f1;
			StructField<S, F2> f27 = f2;
			StructField<S, F3> f28 = f3;
			StructField<S, F4> f29 = f4;
			StructField<S, F5> f30 = f5;
			StructField<S, F6> f31 = f6;
			StructField<S, F7> f32 = f7;
			StructField<S, F8> f33 = f8;
			StructField<S, F9> f34 = f9;
			StructField<S, F10> f19 = f10;
			StructField<S, F11> f20 = f11;
			StructField<S, F12> f21 = f12;
			StructField<S, F13> f22 = f13;
			StructField<S, F14> f23 = f14;
			StructField<S, F15> f24 = f15;
			StructField<S, F16> f25 = f16;
			StructField<S, F17> f26 = f17;
			Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f18.encodeField(ctx, serializer, instance, value);
				f27.encodeField(ctx, serializer, instance, value);
				f28.encodeField(ctx, serializer, instance, value);
				f29.encodeField(ctx, serializer, instance, value);
				f30.encodeField(ctx, serializer, instance, value);
				f31.encodeField(ctx, serializer, instance, value);
				f32.encodeField(ctx, serializer, instance, value);
				f33.encodeField(ctx, serializer, instance, value);
				f34.encodeField(ctx, serializer, instance, value);
				f19.encodeField(ctx, serializer, instance, value);
				f20.encodeField(ctx, serializer, instance, value);
				f21.encodeField(ctx, serializer, instance, value);
				f22.encodeField(ctx, serializer, instance, value);
				f23.encodeField(ctx, serializer, instance, value);
				f24.encodeField(ctx, serializer, instance, value);
				f25.encodeField(ctx, serializer, instance, value);
				f26.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f18.decodeField(ctx, deserializer, instance), f27.decodeField(ctx, deserializer, instance), f28.decodeField(ctx, deserializer, instance), f29.decodeField(ctx, deserializer, instance), f30.decodeField(ctx, deserializer, instance), f31.decodeField(ctx, deserializer, instance), f32.decodeField(ctx, deserializer, instance), f33.decodeField(ctx, deserializer, instance), f34.decodeField(ctx, deserializer, instance), f19.decodeField(ctx, deserializer, instance), f20.decodeField(ctx, deserializer, instance), f21.decodeField(ctx, deserializer, instance), f22.decodeField(ctx, deserializer, instance), f23.decodeField(ctx, deserializer, instance), f24.decodeField(ctx, deserializer, instance), f25.decodeField(ctx, deserializer, instance), f26.decodeField(ctx, deserializer, instance)));
		}

		public static StructEndec<S> of<S, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18>(StructField<S, F1> f1, StructField<S, F2> f2, StructField<S, F3> f3, StructField<S, F4> f4, StructField<S, F5> f5, StructField<S, F6> f6, StructField<S, F7> f7, StructField<S, F8> f8, StructField<S, F9> f9, StructField<S, F10> f10, StructField<S, F11> f11, StructField<S, F12> f12, StructField<S, F13> f13, StructField<S, F14> f14, StructField<S, F15> f15, StructField<S, F16> f16, StructField<S, F17> f17, StructField<S, F18> f18, Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, S> constructor)
		{
			StructField<S, F1> f19 = f1;
			StructField<S, F2> f29 = f2;
			StructField<S, F3> f30 = f3;
			StructField<S, F4> f31 = f4;
			StructField<S, F5> f32 = f5;
			StructField<S, F6> f33 = f6;
			StructField<S, F7> f34 = f7;
			StructField<S, F8> f35 = f8;
			StructField<S, F9> f36 = f9;
			StructField<S, F10> f20 = f10;
			StructField<S, F11> f21 = f11;
			StructField<S, F12> f22 = f12;
			StructField<S, F13> f23 = f13;
			StructField<S, F14> f24 = f14;
			StructField<S, F15> f25 = f15;
			StructField<S, F16> f26 = f16;
			StructField<S, F17> f27 = f17;
			StructField<S, F18> f28 = f18;
			Func<F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, S> constructor2 = constructor;
			return StructEndec.of(delegate(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S value)
			{
				f19.encodeField(ctx, serializer, instance, value);
				f29.encodeField(ctx, serializer, instance, value);
				f30.encodeField(ctx, serializer, instance, value);
				f31.encodeField(ctx, serializer, instance, value);
				f32.encodeField(ctx, serializer, instance, value);
				f33.encodeField(ctx, serializer, instance, value);
				f34.encodeField(ctx, serializer, instance, value);
				f35.encodeField(ctx, serializer, instance, value);
				f36.encodeField(ctx, serializer, instance, value);
				f20.encodeField(ctx, serializer, instance, value);
				f21.encodeField(ctx, serializer, instance, value);
				f22.encodeField(ctx, serializer, instance, value);
				f23.encodeField(ctx, serializer, instance, value);
				f24.encodeField(ctx, serializer, instance, value);
				f25.encodeField(ctx, serializer, instance, value);
				f26.encodeField(ctx, serializer, instance, value);
				f27.encodeField(ctx, serializer, instance, value);
				f28.encodeField(ctx, serializer, instance, value);
			}, (SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance) => constructor2(f19.decodeField(ctx, deserializer, instance), f29.decodeField(ctx, deserializer, instance), f30.decodeField(ctx, deserializer, instance), f31.decodeField(ctx, deserializer, instance), f32.decodeField(ctx, deserializer, instance), f33.decodeField(ctx, deserializer, instance), f34.decodeField(ctx, deserializer, instance), f35.decodeField(ctx, deserializer, instance), f36.decodeField(ctx, deserializer, instance), f20.decodeField(ctx, deserializer, instance), f21.decodeField(ctx, deserializer, instance), f22.decodeField(ctx, deserializer, instance), f23.decodeField(ctx, deserializer, instance), f24.decodeField(ctx, deserializer, instance), f25.decodeField(ctx, deserializer, instance), f26.decodeField(ctx, deserializer, instance), f27.decodeField(ctx, deserializer, instance), f28.decodeField(ctx, deserializer, instance)));
		}
	}
	public class StructEndecImpl<T> : StructEndec<T>
	{
		private readonly StructuredEncoder<T> _encoder;

		private readonly StructuredDecoder<T> _decoder;

		public StructEndecImpl(StructuredEncoder<T> encoder, StructuredDecoder<T> decoder)
		{
			_encoder = encoder;
			_decoder = decoder;
		}

		public override void encodeStruct<E>(SerializationContext ctx, Serializer<E> serializer, StructSerializer instance, T value)
		{
			_encoder(ctx, serializer, instance, value);
		}

		public override T decodeStruct<E>(SerializationContext ctx, Deserializer<E> deserializer, StructDeserializer instance)
		{
			return _decoder(ctx, deserializer, instance);
		}
	}
	public class StructField<S, F>
	{
		protected readonly string _name;

		protected readonly Endec<F> _endec;

		protected readonly Func<S, F> _getter;

		protected readonly Func<F>? _defaultValueFactory;

		public StructField(string name, Endec<F> endec, Func<S, F> getter, Func<F> defaultValueFactory)
		{
			_name = name;
			_endec = endec;
			_getter = getter;
			_defaultValueFactory = defaultValueFactory;
		}

		public StructField(string name, Endec<F> endec, Func<S, F> getter, F? defaultValue)
		{
			F defaultValue2 = defaultValue;
			this..ctor(name, endec, getter, (Func<F>)(() => defaultValue2));
		}

		public StructField(string name, Endec<F> endec, Func<S, F> getter)
			: this(name, endec, getter, (Func<F>)null)
		{
		}

		public virtual void encodeField(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S obj)
		{
			try
			{
				instance.field(_name, ctx, _endec, _getter(obj), _defaultValueFactory != null);
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Exception e = ex2;
				throw ctx.pushField(_name).exceptionWithTrace((Func<EndecTrace, StructFieldException>)delegate(EndecTrace trace)
				{
					throw new StructFieldException("Exception occurred when encoding a given StructField: " + trace.ToString(), e);
				});
			}
		}

		public virtual F decodeField(SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance)
		{
			try
			{
				return instance.field(_name, ctx, _endec, _defaultValueFactory);
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Exception e = ex2;
				throw ctx.pushField(_name).exceptionWithTrace((Func<EndecTrace, StructFieldException>)delegate(EndecTrace trace)
				{
					throw new StructFieldException("Exception occurred when decoding a given StructField: " + trace.ToString(), e);
				});
			}
		}
	}
	public sealed class FlatStructField<S, F> : StructField<S, F>
	{
		public FlatStructField(StructEndec<F> endec, Func<S, F> getter)
			: base("", (Endec<F>)endec, getter, (Func<F>)null)
		{
		}

		public override void encodeField(SerializationContext ctx, Serializer<dynamic> serializer, StructSerializer instance, S obj)
		{
			(_endec as StructEndec<F>).encodeStruct(ctx, serializer, instance, _getter(obj));
		}

		public override F decodeField(SerializationContext ctx, Deserializer<dynamic> deserializer, StructDeserializer instance)
		{
			return (_endec as StructEndec<F>).decodeStruct(ctx, deserializer, instance);
		}
	}
	public class StructFieldException : Exception
	{
		public StructFieldException(string message, Exception cause)
			: base(message, cause)
		{
		}
	}
}
namespace io.wispforest.endec.impl.trace
{
	public class EndecMalformedInputException : Exception
	{
		public readonly EndecTrace location;

		public readonly string message;

		public EndecMalformedInputException(EndecTrace location, string message)
		{
			this.location = location;
			this.message = message;
			base..ctor(createMessage(location, message));
		}

		private static string createMessage(EndecTrace location, string message)
		{
			return "Malformed input at " + location.ToString() + ": " + message;
		}
	}
	public class EndecTrace
	{
		private readonly IList<EndecTraceElement> elements;

		public EndecTrace(List<EndecTraceElement> elements)
		{
			this.elements = elements;
			base..ctor();
		}

		public EndecTrace()
			: this(new List<EndecTraceElement>())
		{
		}

		public EndecTrace push(EndecTraceElement element)
		{
			IList<EndecTraceElement> list = elements;
			List<EndecTraceElement> list2 = new List<EndecTraceElement>(1 + list.Count);
			list2.AddRange(list);
			list2.Add(element);
			return new EndecTrace(list2);
		}

		public override string ToString()
		{
			return "$" + string.Join(",", elements.Select((EndecTraceElement element) => element.toFormatedString()));
		}
	}
	public interface EndecTraceElement
	{
		string toFormatedString();
	}
	public sealed class FieldTraceElement : EndecTraceElement
	{
		[CompilerGenerated]
		private string <name>P;

		public FieldTraceElement(string name)
		{
			<name>P = name;
			base..ctor();
		}

		public string toFormatedString()
		{
			return "." + <name>P;
		}
	}
	public sealed class IndexTraceElement : EndecTraceElement
	{
		[CompilerGenerated]
		private int <index>P;

		public IndexTraceElement(int index)
		{
			<index>P = index;
			base..ctor();
		}

		public string toFormatedString()
		{
			return "[" + <index>P + "]";
		}
	}
}
namespace io.wispforest.endec.format.edm
{
	public class EdmDeserializer : RecursiveDeserializer<EdmElement>, SelfDescribedDeserializer<EdmElement>, Deserializer<EdmElement>
	{
		internal class Sequence<V> : SequenceDeserializer<V>, IEnumerator<V>, IEnumerator, IDisposable, IEnumerable<V>, IEnumerable
		{
			private readonly EdmDeserializer deserializer;

			private readonly SerializationContext ctx;

			private readonly Endec<V> valueEndec;

			private readonly IndexedEnumerator<EdmElement> elements;

			private readonly int size;

			public V Current
			{
				get
				{
					EdmElement element = elements.Current;
					return deserializer.frame(() => element, () => valueEndec.decode(ctx.pushIndex(elements.index), deserializer));
				}
			}

			public Sequence(EdmDeserializer deserializer, SerializationContext ctx, Endec<V> valueEndec, IList<EdmElement> elements)
			{
				this.deserializer = deserializer;
				this.ctx = ctx;
				this.valueEndec = valueEndec;
				this.elements = elements.GetIndexedEnumerator();
				size = elements.Count();
			}

			public int estimatedSize()
			{
				return size;
			}

			public bool MoveNext()
			{
				return elements.MoveNext();
			}

			public void Reset()
			{
				elements.Reset();
			}

			public void Dispose()
			{
				elements.Dispose();
			}
		}

		internal class Map<V> : MapDeserializer<V>, IEnumerator<KeyValuePair<string, V>>, IEnumerator, IDisposable, IEnumerable<KeyValuePair<string, V>>, IEnumerable
		{
			private readonly EdmDeserializer deserializer;

			private readonly SerializationContext ctx;

			private readonly Endec<V> valueEndec;

			private readonly IEnumerator<KeyValuePair<string, EdmElement>> entries;

			private readonly int size;

			public KeyValuePair<string, V> Current
			{
				get
				{
					KeyValuePair<string, EdmElement> entry = entries.Current;
					return deserializer.frame(() => entry.Value, () => new KeyValuePair<string, V>(entry.Key, valueEndec.decode(ctx, deserializer)));
				}
			}

			public Map(EdmDeserializer deserializer, SerializationContext ctx, Endec<V> valueEndec, IDictionary<string, EdmElement> entrie

Endec.Json.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using io.wispforest.endec.impl;
using io.wispforest.endec.util;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("blodhgarm")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("MIT")]
[assembly: AssemblyDescription("Newtonsoft Json Module for Endec")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+7f78aff8b1f8229e8fc9be6479841eb1fdaadc08")]
[assembly: AssemblyProduct("Endec.Json")]
[assembly: AssemblyTitle("Endec.Json")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Dragon-Seeker/endec.csharp")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace io.wispforest.endec.format.newtonsoft
{
	public class JsonDeserializer : RecursiveDeserializer<JToken>, SelfDescribedDeserializer<JToken>, Deserializer<JToken>
	{
		private class JsonSequenceDeserializer<V> : SequenceDeserializer<V>, IEnumerator<V>, IEnumerator, IDisposable, IEnumerable<V>, IEnumerable
		{
			private readonly JsonDeserializer deserializer;

			private readonly SerializationContext ctx;

			private readonly Endec<V> valueEndec;

			private readonly IndexedEnumerator<JToken> elements;

			private readonly int size;

			public V Current
			{
				get
				{
					JToken element = ((IEnumerator<JToken>)elements).Current;
					return ((RecursiveDeserializer<JToken>)(object)deserializer).frame<V>((Func<JToken>)(() => element), (Func<V>)(() => valueEndec.decode<JToken>(ctx.pushIndex(elements.index), (Deserializer<JToken>)(object)deserializer)));
				}
			}

			public JsonSequenceDeserializer(JsonDeserializer deserializer, SerializationContext ctx, Endec<V> valueEndec, JArray elements)
			{
				this.deserializer = deserializer;
				this.ctx = ctx;
				this.valueEndec = valueEndec;
				this.elements = IEnumeratorExtensions.GetIndexedEnumerator<JToken>((IList<JToken>)elements);
				size = ((JContainer)elements).Count;
			}

			public int estimatedSize()
			{
				return size;
			}

			public bool MoveNext()
			{
				return ((IEnumerator)elements).MoveNext();
			}

			public void Reset()
			{
				((IEnumerator)elements).Reset();
			}

			public void Dispose()
			{
				((IDisposable)elements).Dispose();
			}
		}

		private class JsonMapDeserializer<V> : MapDeserializer<V>, IEnumerator<KeyValuePair<string, V>>, IEnumerator, IDisposable, IEnumerable<KeyValuePair<string, V>>, IEnumerable
		{
			private readonly JsonDeserializer deserializer;

			private readonly SerializationContext ctx;

			private readonly Endec<V> valueEndec;

			private readonly IEnumerator<KeyValuePair<string, JToken?>> entries;

			private readonly int size;

			public KeyValuePair<string, V> Current => next();

			public JsonMapDeserializer(JsonDeserializer deserializer, SerializationContext ctx, Endec<V> valueEndec, JObject entries)
			{
				this.deserializer = deserializer;
				this.ctx = ctx;
				this.valueEndec = valueEndec;
				this.entries = entries.GetEnumerator();
				size = ((JContainer)entries).Count;
			}

			public int estimatedSize()
			{
				return size;
			}

			public bool MoveNext()
			{
				return entries.MoveNext();
			}

			public KeyValuePair<string, V> next()
			{
				KeyValuePair<string, JToken?> entry = entries.Current;
				return ((RecursiveDeserializer<JToken>)(object)deserializer).frame<KeyValuePair<string, V>>((Func<JToken>)(() => entry.Value), (Func<KeyValuePair<string, V>>)(() => new KeyValuePair<string, V>(entry.Key, valueEndec.decode<JToken>(ctx.pushField(entry.Key), (Deserializer<JToken>)(object)deserializer))));
			}

			public void Reset()
			{
				entries.Reset();
			}

			public void Dispose()
			{
				entries.Dispose();
			}
		}

		private class JsonStructDeserializer : StructDeserializer
		{
			private readonly JsonDeserializer deserializer;

			private readonly JObject obj;

			public JsonStructDeserializer(JsonDeserializer deserializer, JObject obj)
			{
				this.deserializer = deserializer;
				this.obj = obj;
			}

			public F? field<F>(string name, SerializationContext ctx, Endec<F> endec, Func<F>? defaultValueFactory)
			{
				Endec<F> endec2 = endec;
				SerializationContext ctx2 = ctx;
				string name2 = name;
				JToken element = obj[name2];
				if (element == null)
				{
					if (defaultValueFactory == null)
					{
						throw new Exception("Field '" + name2 + "' was missing from serialized data, but no default value was provided");
					}
					return defaultValueFactory();
				}
				try
				{
					return ((RecursiveDeserializer<JToken>)(object)deserializer).frame<F>((Func<JToken>)(() => element), (Func<F>)(() => ((Endec<JToken>)(object)endec2).decode<JToken>(ctx2.pushField(name2), (Deserializer<JToken>)(object)deserializer)));
				}
				catch (Exception ex)
				{
					DebugErrors.decodeErrorHook?.Invoke(obj, ex);
					throw ex;
				}
			}
		}

		protected JsonDeserializer(JToken serialized)
			: base(serialized)
		{
		}

		public static JsonDeserializer of(JToken serialized)
		{
			return new JsonDeserializer(serialized);
		}

		public SerializationContext setupContext(SerializationContext ctx)
		{
			return ctx.withAttributes((SerializationAttributeInstance[])(object)new SerializationAttributeInstance[1] { (SerializationAttributeInstance)SerializationAttributes.HUMAN_READABLE });
		}

		public override byte readByte(SerializationContext ctx)
		{
			return readPrimitive((IConvertible convertible) => convertible.ToByte(CultureInfo.CurrentCulture));
		}

		public override short readShort(SerializationContext ctx)
		{
			return readPrimitive((IConvertible convertible) => convertible.ToInt16(CultureInfo.CurrentCulture));
		}

		public override int readInt(SerializationContext ctx)
		{
			return readPrimitive((IConvertible convertible) => convertible.ToInt32(CultureInfo.CurrentCulture));
		}

		public override long readLong(SerializationContext ctx)
		{
			return readPrimitive((IConvertible convertible) => convertible.ToInt64(CultureInfo.CurrentCulture));
		}

		public override float readFloat(SerializationContext ctx)
		{
			return readPrimitive((IConvertible convertible) => convertible.ToSingle(CultureInfo.CurrentCulture));
		}

		public override double readDouble(SerializationContext ctx)
		{
			return readPrimitive((IConvertible convertible) => convertible.ToDouble(CultureInfo.CurrentCulture));
		}

		public override int readVarInt(SerializationContext ctx)
		{
			return ((RecursiveDeserializer<JToken>)(object)this).readInt(ctx);
		}

		public override long readVarLong(SerializationContext ctx)
		{
			return ((RecursiveDeserializer<JToken>)(object)this).readLong(ctx);
		}

		public override bool readBoolean(SerializationContext ctx)
		{
			return readPrimitive((IConvertible convertible) => convertible.ToBoolean(CultureInfo.CurrentCulture));
		}

		public override string readString(SerializationContext ctx)
		{
			return readPrimitive((IConvertible convertible) => convertible.ToString(CultureInfo.CurrentCulture));
		}

		private T readPrimitive<T>(Func<IConvertible, T> func) where T : IConvertible
		{
			return readPrimitive(base.getValue(), func);
		}

		private T readPrimitive<T>(JToken token, Func<IConvertible, T> func) where T : IConvertible
		{
			JValue val = (JValue)(object)((token is JValue) ? token : null);
			if (val == null)
			{
				throw new Exception($"Unable to read JToken as it is not a JValue: {token}");
			}
			if (token == null)
			{
				throw new Exception($"Unable to read JToken as the given value is null and can not be converted to the needed type: {typeof(T)}");
			}
			if (!(val.Value is IConvertible arg))
			{
				throw new Exception($"Unable to read JValue as it is not a the correct type: [Type: {typeof(T)}, Obj Type: {val.Value}]");
			}
			return func(arg);
		}

		private T getValueSafe<T>() where T : JToken
		{
			JToken value = base.getValue();
			if (value == null)
			{
				throw new NullReferenceException("Value was found to be null meaning something has gone wrong");
			}
			return ((T)(object)((value is T) ? value : null)) ?? throw new Exception($"Unable to cast value safely to `{typeof(T)}` as it was found to be '{((object)value).GetType()}'");
		}

		public override byte[] readBytes(SerializationContext ctx)
		{
			JArray valueSafe = getValueSafe<JArray>();
			byte[] array = new byte[((JContainer)valueSafe).Count];
			for (int i = 0; i < ((JContainer)valueSafe).Count; i++)
			{
				array[i] = readPrimitive(valueSafe[i], (IConvertible convertible) => convertible.ToByte(CultureInfo.CurrentCulture));
			}
			return array;
		}

		public override V? readOptional<V>(SerializationContext ctx, Endec<V> endec)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			JTokenType type = base.getValue().Type;
			if (((object)(JTokenType)(ref type)).Equals((object)(JTokenType)10))
			{
				return default(V);
			}
			return ((Endec<JToken>)(object)endec).decode<JToken>(ctx, (Deserializer<JToken>)(object)this);
		}

		public override SequenceDeserializer<E> sequence<E>(SerializationContext ctx, Endec<E> elementEndec)
		{
			return (SequenceDeserializer<E>)(object)new JsonSequenceDeserializer<E>(this, ctx, elementEndec, getValueSafe<JArray>());
		}

		public override MapDeserializer<V> map<V>(SerializationContext ctx, Endec<V> valueEndec)
		{
			return (MapDeserializer<V>)(object)new JsonMapDeserializer<V>(this, ctx, valueEndec, getValueSafe<JObject>());
		}

		public override StructDeserializer structed()
		{
			return (StructDeserializer)(object)new JsonStructDeserializer(this, getValueSafe<JObject>());
		}

		public void readAny<S>(SerializationContext ctx, Serializer<S> visitor) where S : class
		{
			decodeValue<S>(ctx, visitor, base.getValue());
		}

		private void decodeValue<S>(SerializationContext ctx, Serializer<S> visitor, JToken element) where S : class
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			bool flag = true;
			JTokenType type = element.Type;
			if (((object)(JTokenType)(ref type)).Equals((object)(JTokenType)10))
			{
				((Serializer<JToken>)(object)visitor).writeOptional<JToken>(ctx, (Endec<JToken>)(object)JsonEndec.INSTANCE, (JToken)null);
			}
			else
			{
				JValue val = (JValue)(object)((element is JValue) ? element : null);
				if (val != null)
				{
					if (val.Value is string text)
					{
						visitor.writeString(ctx, text);
					}
					else if (val.Value is bool flag2)
					{
						visitor.writeBoolean(ctx, flag2);
					}
					else if (val.Value is IConvertible convertible)
					{
						try
						{
							long num = convertible.ToInt64(CultureInfo.CurrentCulture);
							if ((byte)num == num)
							{
								visitor.writeByte(ctx, convertible.ToByte(CultureInfo.CurrentCulture));
							}
							else if ((short)num == num)
							{
								visitor.writeShort(ctx, convertible.ToInt16(CultureInfo.CurrentCulture));
							}
							else if ((int)num == num)
							{
								visitor.writeInt(ctx, convertible.ToInt32(CultureInfo.CurrentCulture));
							}
							else
							{
								visitor.writeLong(ctx, num);
							}
						}
						catch (Exception ex) when (ex is FormatException || ex is OverflowException)
						{
							double num2 = convertible.ToDouble(CultureInfo.CurrentCulture);
							if ((double)(float)num2 == num2)
							{
								visitor.writeFloat(ctx, convertible.ToSingle(CultureInfo.CurrentCulture));
							}
							else
							{
								visitor.writeDouble(ctx, num2);
							}
						}
					}
					else
					{
						flag = false;
					}
				}
				else
				{
					JArray val2 = (JArray)(object)((element is JArray) ? element : null);
					if (val2 != null)
					{
						SequenceSerializer<JToken> val3 = ((Serializer<JToken>)(object)visitor).sequence<JToken>(ctx, Endec.of<JToken>((Encoder<JToken>)decodeValue<object>, (Decoder<JToken>)((SerializationContext _, Deserializer<dynamic> _) => (JToken)(object)JValue.CreateNull())), ((JContainer)val2).Count);
						try
						{
							foreach (JToken item in val2)
							{
								val3.element(item);
							}
						}
						finally
						{
							((IDisposable)val3)?.Dispose();
						}
					}
					else
					{
						JObject val4 = (JObject)(object)((element is JObject) ? element : null);
						if (val4 != null)
						{
							MapSerializer<JToken> val5 = ((Serializer<JToken>)(object)visitor).map<JToken>(ctx, Endec.of<JToken>((Encoder<JToken>)decodeValue<object>, (Decoder<JToken>)((SerializationContext _, Deserializer<dynamic> _) => (JToken)(object)JValue.CreateNull())), ((JContainer)val4).Count);
							try
							{
								foreach (KeyValuePair<string, JToken> item2 in val4)
								{
									val5.entry(item2.Key, item2.Value);
								}
							}
							finally
							{
								((IDisposable)val5)?.Dispose();
							}
						}
						else
						{
							flag = false;
						}
					}
				}
			}
			if (!flag)
			{
				throw new Exception($"Non-standard, unrecognized JsonElement implementation cannot be decoded: {element}");
			}
		}
	}
	public class JsonEndec : Endec<JToken>
	{
		public static readonly JsonEndec INSTANCE = new JsonEndec();

		private JsonEndec()
		{
		}

		public override void encode<E>(SerializationContext ctx, Serializer<E> serializer, JToken value)
		{
			if (serializer is SelfDescribedSerializer<E>)
			{
				JsonDeserializer.of(value).readAny<E>(ctx, serializer);
			}
			else
			{
				serializer.writeString(ctx, JsonUtils.writeToString(value));
			}
		}

		public override JToken decode<E>(SerializationContext ctx, Deserializer<E> deserializer)
		{
			if (deserializer is SelfDescribedDeserializer<E> val)
			{
				JsonSerializer jsonSerializer = JsonSerializer.of();
				((SelfDescribedDeserializer<JToken>)(object)val).readAny<JToken>(ctx, (Serializer<JToken>)(object)jsonSerializer);
				return ((RecursiveSerializer<JToken>)(object)jsonSerializer).result();
			}
			return JsonUtils.readFromString(deserializer.readString(ctx));
		}
	}
	public class JsonSerializer : RecursiveSerializer<JToken>, SelfDescribedSerializer<JToken>, Serializer<JToken>
	{
		private class JsonStructSerializer : StructSerializer, Endable, IDisposable
		{
			private readonly JsonSerializer _serializer;

			private readonly JObject _result;

			public JsonStructSerializer(JsonSerializer serializer)
			{
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Expected O, but got Unknown
				_serializer = serializer;
				if (serializer.prefix != null)
				{
					JToken? prefix = serializer.prefix;
					JObject val = (JObject)(object)((prefix is JObject) ? prefix : null);
					if (val == null)
					{
						throw new Exception("Incompatible prefix of type used " + ((object)_serializer).GetType().Name + " for JSON map/struct");
					}
					_result = val;
					serializer.prefix = null;
				}
				else
				{
					_result = new JObject();
				}
			}

			public StructSerializer field<F>(string name, SerializationContext ctx, Endec<F> endec, F value, bool mayOmit)
			{
				Endec<F> endec2 = endec;
				SerializationContext ctx2 = ctx;
				string name2 = name;
				F value2 = value;
				((RecursiveSerializer<JToken>)(object)_serializer).frame((FrameAction<JToken>)delegate(EncodedValue<JToken> encoded)
				{
					//IL_0042: Unknown result type (might be due to invalid IL or missing references)
					//IL_0047: Unknown result type (might be due to invalid IL or missing references)
					((Endec<JToken>)(object)endec2).encode<JToken>(ctx2.pushField(name2), (Serializer<JToken>)(object)_serializer, (JToken)value2);
					JToken val = encoded.require("struct field");
					if (mayOmit)
					{
						JTokenType type = val.Type;
						if (((object)(JTokenType)(ref type)).Equals((object)(JTokenType)10))
						{
							return;
						}
					}
					_result.Add(name2, val);
				});
				return (StructSerializer)(object)this;
			}

			public void end()
			{
				((RecursiveSerializer<JToken>)(object)_serializer).consume((JToken)(object)_result);
			}
		}

		private class JsonMapSerializer<V> : MapSerializer<V>, Endable, IDisposable
		{
			private readonly JsonSerializer _serializer;

			private readonly SerializationContext _ctx;

			private readonly Endec<V> _valueEndec;

			private readonly JObject _result;

			public JsonMapSerializer(JsonSerializer serializer, SerializationContext ctx, Endec<V> valueEndec)
			{
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Expected O, but got Unknown
				_serializer = serializer;
				_ctx = ctx;
				_valueEndec = valueEndec;
				if (serializer.prefix != null)
				{
					JToken? prefix = serializer.prefix;
					JObject val = (JObject)(object)((prefix is JObject) ? prefix : null);
					if (val == null)
					{
						throw new Exception("Incompatible prefix of type used " + ((object)_serializer).GetType().Name + " for JSON map/struct");
					}
					_result = val;
					serializer.prefix = null;
				}
				else
				{
					_result = new JObject();
				}
			}

			public void entry(string key, V value)
			{
				string key2 = key;
				V value2 = value;
				((RecursiveSerializer<JToken>)(object)_serializer).frame((FrameAction<JToken>)delegate(EncodedValue<JToken> encoded)
				{
					_valueEndec.encode<JToken>(_ctx.pushField(key2), (Serializer<JToken>)(object)_serializer, value2);
					_result.Add(key2, encoded.require("map value"));
				});
			}

			public void end()
			{
				((RecursiveSerializer<JToken>)(object)_serializer).consume((JToken)(object)_result);
			}
		}

		private class JsonSequenceSerializer<V> : SequenceSerializer<V>, Endable, IDisposable
		{
			private readonly JsonSerializer _serializer;

			private readonly SerializationContext _ctx;

			private readonly Endec<V> _valueEndec;

			private readonly JArray _result;

			public JsonSequenceSerializer(JsonSerializer serializer, SerializationContext ctx, Endec<V> valueEndec, int size)
			{
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Expected O, but got Unknown
				_serializer = serializer;
				_ctx = ctx;
				_valueEndec = valueEndec;
				if (serializer.prefix != null)
				{
					JToken? prefix = serializer.prefix;
					JArray val = (JArray)(object)((prefix is JArray) ? prefix : null);
					if (val == null)
					{
						throw new Exception("Incompatible prefix of type " + ((object)serializer.prefix).GetType().Name + " used for JSON sequence");
					}
					_result = val;
					serializer.prefix = null;
				}
				else
				{
					_result = new JArray();
				}
			}

			public void element(V element)
			{
				V element2 = element;
				((RecursiveSerializer<JToken>)(object)_serializer).frame((FrameAction<JToken>)delegate(EncodedValue<JToken> encoded)
				{
					_valueEndec.encode<JToken>(_ctx.pushIndex(((JContainer)_result).Count), (Serializer<JToken>)(object)_serializer, element2);
					_result.Add(encoded.require("sequence element"));
				});
			}

			public void end()
			{
				((RecursiveSerializer<JToken>)(object)_serializer).consume((JToken)(object)_result);
			}
		}

		internal JToken? prefix;

		protected JsonSerializer(JToken? prefix)
			: base((JToken)(object)JValue.CreateNull())
		{
			this.prefix = prefix;
		}

		public static JsonSerializer of()
		{
			return new JsonSerializer(null);
		}

		public SerializationContext setupContext(SerializationContext ctx)
		{
			return ctx.withAttributes((SerializationAttributeInstance[])(object)new SerializationAttributeInstance[1] { (SerializationAttributeInstance)SerializationAttributes.HUMAN_READABLE });
		}

		public override void writeByte(SerializationContext ctx, byte value)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			base.consume((JToken)new JValue((long)value));
		}

		public override void writeShort(SerializationContext ctx, short value)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			base.consume((JToken)new JValue((long)value));
		}

		public override void writeInt(SerializationContext ctx, int value)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			base.consume((JToken)new JValue((long)value));
		}

		public override void writeLong(SerializationContext ctx, long value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			base.consume((JToken)new JValue(value));
		}

		public override void writeFloat(SerializationContext ctx, float value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			base.consume((JToken)new JValue(value));
		}

		public override void writeDouble(SerializationContext ctx, double value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			base.consume((JToken)new JValue(value));
		}

		public override void writeVarInt(SerializationContext ctx, int value)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			base.consume((JToken)new JValue((long)value));
		}

		public override void writeVarLong(SerializationContext ctx, long value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			base.consume((JToken)new JValue(value));
		}

		public override void writeBoolean(SerializationContext ctx, bool value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			base.consume((JToken)new JValue(value));
		}

		public override void writeString(SerializationContext ctx, string value)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			base.consume((JToken)new JValue(value));
		}

		public override void writeBytes(SerializationContext ctx, byte[] bytes)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			JArray val = new JArray();
			for (int i = 0; i < bytes.Length; i++)
			{
				val.Add((JToken)new JValue((long)bytes[i]));
			}
			base.consume((JToken)(object)val);
		}

		public override void writeOptional<V>(SerializationContext ctx, Endec<V> endec, V? optional)
		{
			if (optional == null)
			{
				base.consume((JToken)(object)JValue.CreateNull());
			}
			else
			{
				((Endec<JToken>)(object)endec).encode<JToken>(ctx, (Serializer<JToken>)(object)this, (JToken)optional);
			}
		}

		public override SequenceSerializer<E> sequence<E>(SerializationContext ctx, Endec<E> elementEndec, int size)
		{
			return (SequenceSerializer<E>)(object)new JsonSequenceSerializer<E>(this, ctx, elementEndec, size);
		}

		public override MapSerializer<V> map<V>(SerializationContext ctx, Endec<V> valueEndec, int size)
		{
			return (MapSerializer<V>)(object)new JsonMapSerializer<V>(this, ctx, valueEndec);
		}

		public override StructSerializer structed()
		{
			return (StructSerializer)(object)new JsonStructSerializer(this);
		}
	}
	public class JsonUtils
	{
		private static readonly List<string> ALLOWED_JSON_PATTERNS = new List<string>(2) { "*.json", "*.json5" };

		public static string writeToString(JToken value)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			StringWriter stringWriter = new StringWriter();
			value.WriteTo((JsonWriter)new JsonTextWriter((TextWriter)stringWriter));
			return stringWriter.ToString();
		}

		public static JToken readFromString(string value)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			return JToken.ReadFrom((JsonReader)new JsonTextReader((TextReader)new StringReader(value)));
		}

		public static JToken readFromFile(string path)
		{
			return readFromString(File.ReadAllText(path));
		}

		public static JToken readFromStream(Stream value)
		{
			return readFromString(new StreamReader(value).ReadToEnd());
		}

		public static JToken readFromFileIfPresent(string path)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			if (!File.Exists(path))
			{
				return (JToken)new JObject();
			}
			return readFromString(File.ReadAllText(path));
		}

		public static T? parseFromFile<T>(string path) where T : EndecGetter<T>
		{
			return parseFromFile<T>(path, EndecGetter.Endec<T>());
		}

		public static T? parseFromFile<T>(string path, Endec<T> endec)
		{
			if (!File.Exists(path))
			{
				return default(T);
			}
			JToken val = readFromFile(path);
			return ((Endec<JToken>)(object)endec).decodeFully<JToken>((Func<JToken, Deserializer<JToken>>)JsonDeserializer.of, val);
		}

		public static T parseFromStream<T>(Stream stream) where T : EndecGetter<T>
		{
			return parseFromStream<T>(stream, EndecGetter.Endec<T>());
		}

		public static T parseFromStream<T>(Stream stream, Endec<T> endec)
		{
			JToken val = readFromStream(stream);
			return ((Endec<JToken>)(object)endec).decodeFully<JToken>((Func<JToken, Deserializer<JToken>>)JsonDeserializer.of, val);
		}

		public static T parseFromString<T>(string str, Endec<T> endec)
		{
			JToken val = readFromString(str);
			return ((Endec<JToken>)(object)endec).decodeFully<JToken>((Func<JToken, Deserializer<JToken>>)JsonDeserializer.of, val);
		}

		public static Dictionary<string, T> parseFiles<T>(string directory, Func<string, string> keyMaker, Action<string, Exception> onError) where T : EndecGetter<T>
		{
			return parseFiles<T>(directory, EndecGetter.Endec<T>(), keyMaker, onError);
		}

		public static Dictionary<string, T> parseFiles<T>(string directory, Endec<T> endec, Func<string, string> keyMaker, Action<string, Exception> onError)
		{
			string directory2 = directory;
			List<string> list = ALLOWED_JSON_PATTERNS.SelectMany((string pattern) => Directory.GetFiles(directory2, pattern)).ToList();
			Dictionary<string, T> dictionary = new Dictionary<string, T>();
			foreach (string item in list)
			{
				if (item != null && File.Exists(item))
				{
					try
					{
						T value = parseFromFile<T>(item, endec);
						dictionary[keyMaker(item)] = value;
					}
					catch (Exception arg)
					{
						onError(item, arg);
					}
				}
			}
			return dictionary;
		}
	}
}

StandardSocketsHttpHandler.dll

Decompiled a week ago
using System.Buffers.Text;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Security;
using System.Net.Sockets;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Authentication;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Tal Aloni")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.2.0.10")]
[assembly: AssemblyInformationalVersion("2.2.0.10")]
[assembly: AssemblyProduct("StandardSocketsHttpHandler")]
[assembly: AssemblyTitle("StandardSocketsHttpHandler")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/TalAloni/StandardSocketsHttpHandler")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.2.0.10")]
[assembly: TypeForwardedTo(typeof(SslClientAuthenticationOptions))]
[module: UnverifiableCode]
namespace System
{
	internal static class StringExtensions
	{
		internal static string SubstringTrim(this string value, int startIndex)
		{
			return value.SubstringTrim(startIndex, value.Length - startIndex);
		}

		internal static string SubstringTrim(this string value, int startIndex, int length)
		{
			if (length == 0)
			{
				return string.Empty;
			}
			int num = startIndex + length - 1;
			while (startIndex <= num && char.IsWhiteSpace(value[startIndex]))
			{
				startIndex++;
			}
			while (num >= startIndex && char.IsWhiteSpace(value[num]))
			{
				num--;
			}
			int num2 = num - startIndex + 1;
			if (num2 != 0)
			{
				if (num2 != value.Length)
				{
					return value.Substring(startIndex, num2);
				}
				return value;
			}
			return string.Empty;
		}
	}
	internal static class ByteArrayHelpers
	{
		internal static bool EqualsOrdinalAsciiIgnoreCase(string left, ReadOnlySpan<byte> right)
		{
			if (left.Length != right.Length)
			{
				return false;
			}
			for (int i = 0; i < left.Length; i++)
			{
				uint num = left[i];
				uint num2 = right[i];
				if (num - 97 <= 25)
				{
					num -= 32;
				}
				if (num2 - 97 <= 25)
				{
					num2 -= 32;
				}
				if (num != num2)
				{
					return false;
				}
			}
			return true;
		}
	}
	internal class RuntimeUtils
	{
		public static bool IsDotNetFramework()
		{
			return RuntimeInformation.FrameworkDescription.StartsWith(".NET Framework");
		}

		public static bool IsDotNetNative()
		{
			return RuntimeInformation.FrameworkDescription.StartsWith(".NET Native");
		}

		public static bool IsMono()
		{
			return RuntimeInformation.FrameworkDescription.StartsWith("Mono");
		}
	}
}
namespace System.Threading.Tasks
{
	internal static class TaskExtensions
	{
		public static bool IsCompletedSuccessfully(this Task task)
		{
			if (task.IsCompleted)
			{
				if (!task.IsFaulted)
				{
					return !task.IsCanceled;
				}
				return false;
			}
			return false;
		}
	}
	internal static class TaskToApm
	{
		private sealed class TaskWrapperAsyncResult : IAsyncResult
		{
			internal readonly Task Task;

			private readonly object _state;

			private readonly bool _completedSynchronously;

			object IAsyncResult.AsyncState => _state;

			bool IAsyncResult.CompletedSynchronously => _completedSynchronously;

			bool IAsyncResult.IsCompleted => Task.IsCompleted;

			WaitHandle IAsyncResult.AsyncWaitHandle => ((IAsyncResult)Task).AsyncWaitHandle;

			internal TaskWrapperAsyncResult(Task task, object state, bool completedSynchronously)
			{
				Task = task;
				_state = state;
				_completedSynchronously = completedSynchronously;
			}
		}

		public static IAsyncResult Begin(Task task, AsyncCallback callback, object state)
		{
			IAsyncResult asyncResult;
			if (task.IsCompleted)
			{
				asyncResult = new TaskWrapperAsyncResult(task, state, completedSynchronously: true);
				callback?.Invoke(asyncResult);
			}
			else
			{
				IAsyncResult asyncResult3;
				if (task.AsyncState != state)
				{
					IAsyncResult asyncResult2 = new TaskWrapperAsyncResult(task, state, completedSynchronously: false);
					asyncResult3 = asyncResult2;
				}
				else
				{
					IAsyncResult asyncResult2 = task;
					asyncResult3 = asyncResult2;
				}
				asyncResult = asyncResult3;
				if (callback != null)
				{
					InvokeCallbackWhenTaskCompletes(task, callback, asyncResult);
				}
			}
			return asyncResult;
		}

		public static void End(IAsyncResult asyncResult)
		{
			Task task = ((!(asyncResult is TaskWrapperAsyncResult taskWrapperAsyncResult)) ? (asyncResult as Task) : taskWrapperAsyncResult.Task);
			if (task == null)
			{
				throw new ArgumentNullException();
			}
			task.GetAwaiter().GetResult();
		}

		public static TResult End<TResult>(IAsyncResult asyncResult)
		{
			Task<TResult> task = ((!(asyncResult is TaskWrapperAsyncResult taskWrapperAsyncResult)) ? (asyncResult as Task<TResult>) : (taskWrapperAsyncResult.Task as Task<TResult>));
			if (task == null)
			{
				throw new ArgumentNullException();
			}
			return task.GetAwaiter().GetResult();
		}

		private static void InvokeCallbackWhenTaskCompletes(Task antecedent, AsyncCallback callback, IAsyncResult asyncResult)
		{
			antecedent.ConfigureAwait(continueOnCapturedContext: false).GetAwaiter().OnCompleted(delegate
			{
				callback(asyncResult);
			});
		}
	}
}
namespace System.Net
{
	internal static class HttpKnownHeaderNames
	{
		public const string Accept = "Accept";

		public const string AcceptCharset = "Accept-Charset";

		public const string AcceptEncoding = "Accept-Encoding";

		public const string AcceptLanguage = "Accept-Language";

		public const string AcceptPatch = "Accept-Patch";

		public const string AcceptRanges = "Accept-Ranges";

		public const string AccessControlAllowCredentials = "Access-Control-Allow-Credentials";

		public const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";

		public const string AccessControlAllowMethods = "Access-Control-Allow-Methods";

		public const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";

		public const string AccessControlExposeHeaders = "Access-Control-Expose-Headers";

		public const string AccessControlMaxAge = "Access-Control-Max-Age";

		public const string Age = "Age";

		public const string Allow = "Allow";

		public const string AltSvc = "Alt-Svc";

		public const string Authorization = "Authorization";

		public const string CacheControl = "Cache-Control";

		public const string Connection = "Connection";

		public const string ContentDisposition = "Content-Disposition";

		public const string ContentEncoding = "Content-Encoding";

		public const string ContentLanguage = "Content-Language";

		public const string ContentLength = "Content-Length";

		public const string ContentLocation = "Content-Location";

		public const string ContentMD5 = "Content-MD5";

		public const string ContentRange = "Content-Range";

		public const string ContentSecurityPolicy = "Content-Security-Policy";

		public const string ContentType = "Content-Type";

		public const string Cookie = "Cookie";

		public const string Cookie2 = "Cookie2";

		public const string Date = "Date";

		public const string ETag = "ETag";

		public const string Expect = "Expect";

		public const string Expires = "Expires";

		public const string From = "From";

		public const string Host = "Host";

		public const string IfMatch = "If-Match";

		public const string IfModifiedSince = "If-Modified-Since";

		public const string IfNoneMatch = "If-None-Match";

		public const string IfRange = "If-Range";

		public const string IfUnmodifiedSince = "If-Unmodified-Since";

		public const string KeepAlive = "Keep-Alive";

		public const string LastModified = "Last-Modified";

		public const string Link = "Link";

		public const string Location = "Location";

		public const string MaxForwards = "Max-Forwards";

		public const string Origin = "Origin";

		public const string P3P = "P3P";

		public const string Pragma = "Pragma";

		public const string ProxyAuthenticate = "Proxy-Authenticate";

		public const string ProxyAuthorization = "Proxy-Authorization";

		public const string ProxyConnection = "Proxy-Connection";

		public const string PublicKeyPins = "Public-Key-Pins";

		public const string Range = "Range";

		public const string Referer = "Referer";

		public const string RetryAfter = "Retry-After";

		public const string SecWebSocketAccept = "Sec-WebSocket-Accept";

		public const string SecWebSocketExtensions = "Sec-WebSocket-Extensions";

		public const string SecWebSocketKey = "Sec-WebSocket-Key";

		public const string SecWebSocketProtocol = "Sec-WebSocket-Protocol";

		public const string SecWebSocketVersion = "Sec-WebSocket-Version";

		public const string Server = "Server";

		public const string SetCookie = "Set-Cookie";

		public const string SetCookie2 = "Set-Cookie2";

		public const string StrictTransportSecurity = "Strict-Transport-Security";

		public const string TE = "TE";

		public const string TSV = "TSV";

		public const string Trailer = "Trailer";

		public const string TransferEncoding = "Transfer-Encoding";

		public const string Upgrade = "Upgrade";

		public const string UpgradeInsecureRequests = "Upgrade-Insecure-Requests";

		public const string UserAgent = "User-Agent";

		public const string Vary = "Vary";

		public const string Via = "Via";

		public const string WWWAuthenticate = "WWW-Authenticate";

		public const string Warning = "Warning";

		public const string XAspNetVersion = "X-AspNet-Version";

		public const string XContentDuration = "X-Content-Duration";

		public const string XContentTypeOptions = "X-Content-Type-Options";

		public const string XFrameOptions = "X-Frame-Options";

		public const string XMSEdgeRef = "X-MSEdge-Ref";

		public const string XPoweredBy = "X-Powered-By";

		public const string XRequestID = "X-Request-ID";

		public const string XUACompatible = "X-UA-Compatible";
	}
	internal static class HttpStatusDescription
	{
		internal static string Get(HttpStatusCode code)
		{
			return Get((int)code);
		}

		internal static string Get(int code)
		{
			return code switch
			{
				100 => "Continue", 
				101 => "Switching Protocols", 
				102 => "Processing", 
				103 => "Early Hints", 
				200 => "OK", 
				201 => "Created", 
				202 => "Accepted", 
				203 => "Non-Authoritative Information", 
				204 => "No Content", 
				205 => "Reset Content", 
				206 => "Partial Content", 
				207 => "Multi-Status", 
				208 => "Already Reported", 
				226 => "IM Used", 
				300 => "Multiple Choices", 
				301 => "Moved Permanently", 
				302 => "Found", 
				303 => "See Other", 
				304 => "Not Modified", 
				305 => "Use Proxy", 
				307 => "Temporary Redirect", 
				308 => "Permanent Redirect", 
				400 => "Bad Request", 
				401 => "Unauthorized", 
				402 => "Payment Required", 
				403 => "Forbidden", 
				404 => "Not Found", 
				405 => "Method Not Allowed", 
				406 => "Not Acceptable", 
				407 => "Proxy Authentication Required", 
				408 => "Request Timeout", 
				409 => "Conflict", 
				410 => "Gone", 
				411 => "Length Required", 
				412 => "Precondition Failed", 
				413 => "Request Entity Too Large", 
				414 => "Request-Uri Too Long", 
				415 => "Unsupported Media Type", 
				416 => "Requested Range Not Satisfiable", 
				417 => "Expectation Failed", 
				421 => "Misdirected Request", 
				422 => "Unprocessable Entity", 
				423 => "Locked", 
				424 => "Failed Dependency", 
				426 => "Upgrade Required", 
				428 => "Precondition Required", 
				429 => "Too Many Requests", 
				431 => "Request Header Fields Too Large", 
				451 => "Unavailable For Legal Reasons", 
				500 => "Internal Server Error", 
				501 => "Not Implemented", 
				502 => "Bad Gateway", 
				503 => "Service Unavailable", 
				504 => "Gateway Timeout", 
				505 => "Http Version Not Supported", 
				506 => "Variant Also Negotiates", 
				507 => "Insufficient Storage", 
				508 => "Loop Detected", 
				510 => "Not Extended", 
				511 => "Network Authentication Required", 
				_ => null, 
			};
		}
	}
	internal static class HttpVersionInternal
	{
		public static readonly Version Unknown = new Version(0, 0);

		public static readonly Version Version10 = new Version(1, 0);

		public static readonly Version Version11 = new Version(1, 1);

		public static readonly Version Version20 = new Version(2, 0);
	}
	[EventSource(Name = "Microsoft-System-Net-Http", LocalizationResources = "FxResources.System.Net.Http.SR")]
	internal sealed class NetEventSource : EventSource
	{
		public class Keywords
		{
			public const EventKeywords Default = (EventKeywords)1L;

			public const EventKeywords Debug = (EventKeywords)2L;

			public const EventKeywords EnterExit = (EventKeywords)4L;
		}

		private const int UriBaseAddressId = 17;

		private const int ContentNullId = 18;

		private const int ClientSendCompletedId = 19;

		private const int HeadersInvalidValueId = 20;

		private const int HandlerMessageId = 21;

		public static readonly System.Net.NetEventSource Log = new System.Net.NetEventSource();

		private const string MissingMember = "(?)";

		private const string NullInstance = "(null)";

		private const string StaticMethodObject = "(static)";

		private const string NoParameters = "";

		private const int MaxDumpSize = 1024;

		private const int EnterEventId = 1;

		private const int ExitEventId = 2;

		private const int AssociateEventId = 3;

		private const int InfoEventId = 4;

		private const int ErrorEventId = 5;

		private const int CriticalFailureEventId = 6;

		private const int DumpArrayEventId = 7;

		private const int EnumerateSecurityPackagesId = 8;

		private const int SspiPackageNotFoundId = 9;

		private const int AcquireDefaultCredentialId = 10;

		private const int AcquireCredentialsHandleId = 11;

		private const int InitializeSecurityContextId = 12;

		private const int SecurityContextInputBufferId = 13;

		private const int SecurityContextInputBuffersId = 14;

		private const int AcceptSecuritContextId = 15;

		private const int OperationReturnedSomethingId = 16;

		private const int NextAvailableEventId = 17;

		public new static bool IsEnabled => Log.IsEnabled();

		[NonEvent]
		public static void UriBaseAddress(object obj, Uri baseAddress)
		{
			if (IsEnabled)
			{
				Log.UriBaseAddress(baseAddress?.ToString(), IdOf(obj), GetHashCode(obj));
			}
		}

		[Event(17, Keywords = (EventKeywords)2L, Level = EventLevel.Informational)]
		private void UriBaseAddress(string uriBaseAddress, string objName, int objHash)
		{
			WriteEvent(17, uriBaseAddress, objName, objHash);
		}

		[NonEvent]
		public static void ContentNull(object obj)
		{
			if (IsEnabled)
			{
				Log.ContentNull(IdOf(obj), GetHashCode(obj));
			}
		}

		[Event(18, Keywords = (EventKeywords)2L, Level = EventLevel.Informational)]
		private void ContentNull(string objName, int objHash)
		{
			WriteEvent(18, objName, objHash);
		}

		[NonEvent]
		public static void ClientSendCompleted(HttpClient httpClient, HttpResponseMessage response, HttpRequestMessage request)
		{
			if (IsEnabled)
			{
				Log.ClientSendCompleted(response?.ToString(), GetHashCode(request), GetHashCode(response), GetHashCode(httpClient));
			}
		}

		[Event(19, Keywords = (EventKeywords)2L, Level = EventLevel.Verbose)]
		private void ClientSendCompleted(string responseString, int httpRequestMessageHash, int httpResponseMessageHash, int httpClientHash)
		{
			WriteEvent(19, responseString, httpRequestMessageHash, httpResponseMessageHash, httpClientHash);
		}

		[Event(20, Keywords = (EventKeywords)2L, Level = EventLevel.Verbose)]
		public void HeadersInvalidValue(string name, string rawValue)
		{
			WriteEvent(20, name, rawValue);
		}

		[Event(21, Keywords = (EventKeywords)2L, Level = EventLevel.Verbose)]
		public void HandlerMessage(int handlerId, int workerId, int requestId, string memberName, string message)
		{
			WriteEvent(21, handlerId, workerId, requestId, memberName, message);
		}

		[NonEvent]
		private unsafe void WriteEvent(int eventId, int arg1, int arg2, int arg3, string arg4, string arg5)
		{
			if (!IsEnabled())
			{
				return;
			}
			if (arg4 == null)
			{
				arg4 = "";
			}
			if (arg5 == null)
			{
				arg5 = "";
			}
			fixed (char* ptr2 = arg4)
			{
				fixed (char* ptr3 = arg5)
				{
					EventData* ptr = stackalloc EventData[5];
					*ptr = new EventData
					{
						DataPointer = (IntPtr)(&arg1),
						Size = 4
					};
					ptr[1] = new EventData
					{
						DataPointer = (IntPtr)(&arg2),
						Size = 4
					};
					ptr[2] = new EventData
					{
						DataPointer = (IntPtr)(&arg3),
						Size = 4
					};
					ptr[3] = new EventData
					{
						DataPointer = (IntPtr)ptr2,
						Size = (arg4.Length + 1) * 2
					};
					ptr[4] = new EventData
					{
						DataPointer = (IntPtr)ptr3,
						Size = (arg5.Length + 1) * 2
					};
					WriteEventCore(eventId, 5, ptr);
				}
			}
		}

		[NonEvent]
		public static void Enter(object thisOrContextObject, FormattableString formattableString = null, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.Enter(IdOf(thisOrContextObject), memberName, (formattableString != null) ? Format(formattableString) : "");
			}
		}

		[NonEvent]
		public static void Enter(object thisOrContextObject, object arg0, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.Enter(IdOf(thisOrContextObject), memberName, $"({Format(arg0)})");
			}
		}

		[NonEvent]
		public static void Enter(object thisOrContextObject, object arg0, object arg1, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.Enter(IdOf(thisOrContextObject), memberName, $"({Format(arg0)}, {Format(arg1)})");
			}
		}

		[NonEvent]
		public static void Enter(object thisOrContextObject, object arg0, object arg1, object arg2, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.Enter(IdOf(thisOrContextObject), memberName, $"({Format(arg0)}, {Format(arg1)}, {Format(arg2)})");
			}
		}

		[Event(1, Level = EventLevel.Informational, Keywords = (EventKeywords)4L)]
		private void Enter(string thisOrContextObject, string memberName, string parameters)
		{
			WriteEvent(1, thisOrContextObject, memberName ?? "(?)", parameters);
		}

		[NonEvent]
		public static void Exit(object thisOrContextObject, FormattableString formattableString = null, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.Exit(IdOf(thisOrContextObject), memberName, (formattableString != null) ? Format(formattableString) : "");
			}
		}

		[NonEvent]
		public static void Exit(object thisOrContextObject, object arg0, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.Exit(IdOf(thisOrContextObject), memberName, Format(arg0).ToString());
			}
		}

		[NonEvent]
		public static void Exit(object thisOrContextObject, object arg0, object arg1, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.Exit(IdOf(thisOrContextObject), memberName, $"{Format(arg0)}, {Format(arg1)}");
			}
		}

		[Event(2, Level = EventLevel.Informational, Keywords = (EventKeywords)4L)]
		private void Exit(string thisOrContextObject, string memberName, string result)
		{
			WriteEvent(2, thisOrContextObject, memberName ?? "(?)", result);
		}

		[NonEvent]
		public static void Info(object thisOrContextObject, FormattableString formattableString = null, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.Info(IdOf(thisOrContextObject), memberName, (formattableString != null) ? Format(formattableString) : "");
			}
		}

		[NonEvent]
		public static void Info(object thisOrContextObject, object message, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.Info(IdOf(thisOrContextObject), memberName, Format(message).ToString());
			}
		}

		[Event(4, Level = EventLevel.Informational, Keywords = (EventKeywords)1L)]
		private void Info(string thisOrContextObject, string memberName, string message)
		{
			WriteEvent(4, thisOrContextObject, memberName ?? "(?)", message);
		}

		[NonEvent]
		public static void Error(object thisOrContextObject, FormattableString formattableString, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.ErrorMessage(IdOf(thisOrContextObject), memberName, Format(formattableString));
			}
		}

		[NonEvent]
		public static void Error(object thisOrContextObject, object message, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.ErrorMessage(IdOf(thisOrContextObject), memberName, Format(message).ToString());
			}
		}

		[Event(5, Level = EventLevel.Warning, Keywords = (EventKeywords)1L)]
		private void ErrorMessage(string thisOrContextObject, string memberName, string message)
		{
			WriteEvent(5, thisOrContextObject, memberName ?? "(?)", message);
		}

		[NonEvent]
		public static void Fail(object thisOrContextObject, FormattableString formattableString, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.CriticalFailure(IdOf(thisOrContextObject), memberName, Format(formattableString));
			}
		}

		[NonEvent]
		public static void Fail(object thisOrContextObject, object message, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.CriticalFailure(IdOf(thisOrContextObject), memberName, Format(message).ToString());
			}
		}

		[Event(6, Level = EventLevel.Critical, Keywords = (EventKeywords)2L)]
		private void CriticalFailure(string thisOrContextObject, string memberName, string message)
		{
			WriteEvent(6, thisOrContextObject, memberName ?? "(?)", message);
		}

		[NonEvent]
		public static void DumpBuffer(object thisOrContextObject, byte[] buffer, [CallerMemberName] string memberName = null)
		{
			DumpBuffer(thisOrContextObject, buffer, 0, buffer.Length, memberName);
		}

		[NonEvent]
		public static void DumpBuffer(object thisOrContextObject, byte[] buffer, int offset, int count, [CallerMemberName] string memberName = null)
		{
			if (!IsEnabled)
			{
				return;
			}
			if (offset < 0 || offset > buffer.Length - count)
			{
				Fail(thisOrContextObject, FormattableStringFactory.Create("Invalid {0} Args. Length={1}, Offset={2}, Count={3}", "DumpBuffer", buffer.Length, offset, count), memberName);
				return;
			}
			count = Math.Min(count, 1024);
			byte[] array = buffer;
			if (offset != 0 || count != buffer.Length)
			{
				array = new byte[count];
				Buffer.BlockCopy(buffer, offset, array, 0, count);
			}
			Log.DumpBuffer(IdOf(thisOrContextObject), memberName, array);
		}

		[NonEvent]
		public unsafe static void DumpBuffer(object thisOrContextObject, IntPtr bufferPtr, int count, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				byte[] array = new byte[Math.Min(count, 1024)];
				fixed (byte* destination = array)
				{
					Buffer.MemoryCopy((void*)bufferPtr, destination, array.Length, array.Length);
				}
				Log.DumpBuffer(IdOf(thisOrContextObject), memberName, array);
			}
		}

		[Event(7, Level = EventLevel.Verbose, Keywords = (EventKeywords)2L)]
		private void DumpBuffer(string thisOrContextObject, string memberName, byte[] buffer)
		{
			WriteEvent(7, thisOrContextObject, memberName ?? "(?)", buffer);
		}

		[NonEvent]
		public static void Associate(object first, object second, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.Associate(IdOf(first), memberName, IdOf(first), IdOf(second));
			}
		}

		[NonEvent]
		public static void Associate(object thisOrContextObject, object first, object second, [CallerMemberName] string memberName = null)
		{
			if (IsEnabled)
			{
				Log.Associate(IdOf(thisOrContextObject), memberName, IdOf(first), IdOf(second));
			}
		}

		[Event(3, Level = EventLevel.Informational, Keywords = (EventKeywords)1L, Message = "[{2}]<-->[{3}]")]
		private void Associate(string thisOrContextObject, string memberName, string first, string second)
		{
			WriteEvent(3, thisOrContextObject, memberName ?? "(?)", first, second);
		}

		[Conditional("DEBUG_NETEVENTSOURCE_MISUSE")]
		private static void DebugValidateArg(object arg)
		{
			_ = IsEnabled;
		}

		[Conditional("DEBUG_NETEVENTSOURCE_MISUSE")]
		private static void DebugValidateArg(FormattableString arg)
		{
		}

		[NonEvent]
		public static string IdOf(object value)
		{
			if (value == null)
			{
				return "(null)";
			}
			return value.GetType().Name + "#" + GetHashCode(value);
		}

		[NonEvent]
		public static int GetHashCode(object value)
		{
			return value?.GetHashCode() ?? 0;
		}

		[NonEvent]
		public static object Format(object value)
		{
			if (value == null)
			{
				return "(null)";
			}
			string text = null;
			if (text != null)
			{
				return text;
			}
			if (value is Array array)
			{
				return $"{array.GetType().GetElementType()}[{((Array)value).Length}]";
			}
			if (value is ICollection collection)
			{
				return $"{collection.GetType().Name}({collection.Count})";
			}
			if (value is SafeHandle safeHandle)
			{
				return $"{safeHandle.GetType().Name}:{safeHandle.GetHashCode()}(0x{safeHandle.DangerousGetHandle():X})";
			}
			if (value is IntPtr)
			{
				return $"0x{value:X}";
			}
			string text2 = value.ToString();
			if (text2 == null || text2 == value.GetType().FullName)
			{
				return IdOf(value);
			}
			return value;
		}

		[NonEvent]
		private static string Format(FormattableString s)
		{
			switch (s.ArgumentCount)
			{
			case 0:
				return s.Format;
			case 1:
				return string.Format(s.Format, Format(s.GetArgument(0)));
			case 2:
				return string.Format(s.Format, Format(s.GetArgument(0)), Format(s.GetArgument(1)));
			case 3:
				return string.Format(s.Format, Format(s.GetArgument(0)), Format(s.GetArgument(1)), Format(s.GetArgument(2)));
			default:
			{
				object[] arguments = s.GetArguments();
				object[] array = new object[arguments.Length];
				for (int i = 0; i < arguments.Length; i++)
				{
					array[i] = Format(arguments[i]);
				}
				return string.Format(s.Format, array);
			}
			}
		}

		[NonEvent]
		private unsafe void WriteEvent(int eventId, string arg1, string arg2, string arg3, string arg4)
		{
			if (!IsEnabled())
			{
				return;
			}
			if (arg1 == null)
			{
				arg1 = "";
			}
			if (arg2 == null)
			{
				arg2 = "";
			}
			if (arg3 == null)
			{
				arg3 = "";
			}
			if (arg4 == null)
			{
				arg4 = "";
			}
			fixed (char* ptr2 = arg1)
			{
				fixed (char* ptr3 = arg2)
				{
					fixed (char* ptr4 = arg3)
					{
						fixed (char* ptr5 = arg4)
						{
							EventData* ptr = stackalloc EventData[4];
							*ptr = new EventData
							{
								DataPointer = (IntPtr)ptr2,
								Size = (arg1.Length + 1) * 2
							};
							ptr[1] = new EventData
							{
								DataPointer = (IntPtr)ptr3,
								Size = (arg2.Length + 1) * 2
							};
							ptr[2] = new EventData
							{
								DataPointer = (IntPtr)ptr4,
								Size = (arg3.Length + 1) * 2
							};
							ptr[3] = new EventData
							{
								DataPointer = (IntPtr)ptr5,
								Size = (arg4.Length + 1) * 2
							};
							WriteEventCore(eventId, 4, ptr);
						}
					}
				}
			}
		}

		[NonEvent]
		private unsafe void WriteEvent(int eventId, string arg1, string arg2, byte[] arg3)
		{
			if (!IsEnabled())
			{
				return;
			}
			if (arg1 == null)
			{
				arg1 = "";
			}
			if (arg2 == null)
			{
				arg2 = "";
			}
			if (arg3 == null)
			{
				arg3 = Array.Empty<byte>();
			}
			fixed (char* ptr2 = arg1)
			{
				fixed (char* ptr3 = arg2)
				{
					fixed (byte* ptr4 = arg3)
					{
						int size = arg3.Length;
						EventData* ptr = stackalloc EventData[4];
						*ptr = new EventData
						{
							DataPointer = (IntPtr)ptr2,
							Size = (arg1.Length + 1) * 2
						};
						ptr[1] = new EventData
						{
							DataPointer = (IntPtr)ptr3,
							Size = (arg2.Length + 1) * 2
						};
						ptr[2] = new EventData
						{
							DataPointer = (IntPtr)(&size),
							Size = 4
						};
						ptr[3] = new EventData
						{
							DataPointer = (IntPtr)ptr4,
							Size = size
						};
						WriteEventCore(eventId, 4, ptr);
					}
				}
			}
		}

		[NonEvent]
		private unsafe void WriteEvent(int eventId, string arg1, int arg2, int arg3, int arg4)
		{
			if (IsEnabled())
			{
				if (arg1 == null)
				{
					arg1 = "";
				}
				fixed (char* ptr2 = arg1)
				{
					EventData* ptr = stackalloc EventData[4];
					*ptr = new EventData
					{
						DataPointer = (IntPtr)ptr2,
						Size = (arg1.Length + 1) * 2
					};
					ptr[1] = new EventData
					{
						DataPointer = (IntPtr)(&arg2),
						Size = 4
					};
					ptr[2] = new EventData
					{
						DataPointer = (IntPtr)(&arg3),
						Size = 4
					};
					ptr[3] = new EventData
					{
						DataPointer = (IntPtr)(&arg4),
						Size = 4
					};
					WriteEventCore(eventId, 4, ptr);
				}
			}
		}

		[NonEvent]
		private unsafe void WriteEvent(int eventId, string arg1, int arg2, string arg3)
		{
			if (!IsEnabled())
			{
				return;
			}
			if (arg1 == null)
			{
				arg1 = "";
			}
			if (arg3 == null)
			{
				arg3 = "";
			}
			fixed (char* ptr2 = arg1)
			{
				fixed (char* ptr3 = arg3)
				{
					EventData* ptr = stackalloc EventData[3];
					*ptr = new EventData
					{
						DataPointer = (IntPtr)ptr2,
						Size = (arg1.Length + 1) * 2
					};
					ptr[1] = new EventData
					{
						DataPointer = (IntPtr)(&arg2),
						Size = 4
					};
					ptr[2] = new EventData
					{
						DataPointer = (IntPtr)ptr3,
						Size = (arg3.Length + 1) * 2
					};
					WriteEventCore(eventId, 3, ptr);
				}
			}
		}

		[NonEvent]
		private unsafe void WriteEvent(int eventId, string arg1, string arg2, int arg3)
		{
			if (!IsEnabled())
			{
				return;
			}
			if (arg1 == null)
			{
				arg1 = "";
			}
			if (arg2 == null)
			{
				arg2 = "";
			}
			fixed (char* ptr2 = arg1)
			{
				fixed (char* ptr3 = arg2)
				{
					EventData* ptr = stackalloc EventData[3];
					*ptr = new EventData
					{
						DataPointer = (IntPtr)ptr2,
						Size = (arg1.Length + 1) * 2
					};
					ptr[1] = new EventData
					{
						DataPointer = (IntPtr)ptr3,
						Size = (arg2.Length + 1) * 2
					};
					ptr[2] = new EventData
					{
						DataPointer = (IntPtr)(&arg3),
						Size = 4
					};
					WriteEventCore(eventId, 3, ptr);
				}
			}
		}

		[NonEvent]
		private unsafe void WriteEvent(int eventId, string arg1, string arg2, string arg3, int arg4)
		{
			if (!IsEnabled())
			{
				return;
			}
			if (arg1 == null)
			{
				arg1 = "";
			}
			if (arg2 == null)
			{
				arg2 = "";
			}
			if (arg3 == null)
			{
				arg3 = "";
			}
			fixed (char* ptr2 = arg1)
			{
				fixed (char* ptr3 = arg2)
				{
					fixed (char* ptr4 = arg3)
					{
						EventData* ptr = stackalloc EventData[4];
						*ptr = new EventData
						{
							DataPointer = (IntPtr)ptr2,
							Size = (arg1.Length + 1) * 2
						};
						ptr[1] = new EventData
						{
							DataPointer = (IntPtr)ptr3,
							Size = (arg2.Length + 1) * 2
						};
						ptr[2] = new EventData
						{
							DataPointer = (IntPtr)ptr4,
							Size = (arg3.Length + 1) * 2
						};
						ptr[3] = new EventData
						{
							DataPointer = (IntPtr)(&arg4),
							Size = 4
						};
						WriteEventCore(eventId, 4, ptr);
					}
				}
			}
		}
	}
	internal static class SecurityProtocol
	{
		public const SslProtocols DefaultSecurityProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13;

		public const SslProtocols SystemDefaultSecurityProtocols = SslProtocols.None;
	}
	internal static class UriScheme
	{
		public const string File = "file";

		public const string Ftp = "ftp";

		public const string Gopher = "gopher";

		public const string Http = "http";

		public const string Https = "https";

		public const string News = "news";

		public const string NetPipe = "net.pipe";

		public const string NetTcp = "net.tcp";

		public const string Nntp = "nntp";

		public const string Mailto = "mailto";

		public const string Ws = "ws";

		public const string Wss = "wss";

		public const string SchemeDelimiter = "://";
	}
}
namespace System.Net.Security
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	public class SR
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("System.Net.Http.Net.Security.SR", typeof(SR).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		public static string event_AttemptingRestartUsingCert => ResourceManager.GetString("event_AttemptingRestartUsingCert", resourceCulture);

		public static string event_CertificateFromDelegate => ResourceManager.GetString("event_CertificateFromDelegate", resourceCulture);

		public static string event_CertIsType2 => ResourceManager.GetString("event_CertIsType2", resourceCulture);

		public static string event_CertsAfterFiltering => ResourceManager.GetString("event_CertsAfterFiltering", resourceCulture);

		public static string event_EnumerateSecurityPackages => ResourceManager.GetString("event_EnumerateSecurityPackages", resourceCulture);

		public static string event_FindingMatchingCerts => ResourceManager.GetString("event_FindingMatchingCerts", resourceCulture);

		public static string event_FoundCertInStore => ResourceManager.GetString("event_FoundCertInStore", resourceCulture);

		public static string event_LocatingPrivateKey => ResourceManager.GetString("event_LocatingPrivateKey", resourceCulture);

		public static string event_LookForMatchingCerts => ResourceManager.GetString("event_LookForMatchingCerts", resourceCulture);

		public static string event_NoDelegateButClientCert => ResourceManager.GetString("event_NoDelegateButClientCert", resourceCulture);

		public static string event_NoDelegateNoClientCert => ResourceManager.GetString("event_NoDelegateNoClientCert", resourceCulture);

		public static string event_NoIssuersTryAllCerts => ResourceManager.GetString("event_NoIssuersTryAllCerts", resourceCulture);

		public static string event_NotFoundCertInStore => ResourceManager.GetString("event_NotFoundCertInStore", resourceCulture);

		public static string event_OperationReturnedSomething => ResourceManager.GetString("event_OperationReturnedSomething", resourceCulture);

		public static string event_RemoteCertDeclaredValid => ResourceManager.GetString("event_RemoteCertDeclaredValid", resourceCulture);

		public static string event_RemoteCertHasNoErrors => ResourceManager.GetString("event_RemoteCertHasNoErrors", resourceCulture);

		public static string event_RemoteCertificate => ResourceManager.GetString("event_RemoteCertificate", resourceCulture);

		public static string event_RemoteCertUserDeclaredInvalid => ResourceManager.GetString("event_RemoteCertUserDeclaredInvalid", resourceCulture);

		public static string event_SecurityContextInputBuffer => ResourceManager.GetString("event_SecurityContextInputBuffer", resourceCulture);

		public static string event_SecurityContextInputBuffers => ResourceManager.GetString("event_SecurityContextInputBuffers", resourceCulture);

		public static string event_SelectedCert => ResourceManager.GetString("event_SelectedCert", resourceCulture);

		public static string event_SspiPackageNotFound => ResourceManager.GetString("event_SspiPackageNotFound", resourceCulture);

		public static string event_SspiSelectedCipherSuite => ResourceManager.GetString("event_SspiSelectedCipherSuite", resourceCulture);

		public static string event_UsingCachedCredential => ResourceManager.GetString("event_UsingCachedCredential", resourceCulture);

		public static string net_allocate_ssl_context_failed => ResourceManager.GetString("net_allocate_ssl_context_failed", resourceCulture);

		public static string net_alpn_config_failed => ResourceManager.GetString("net_alpn_config_failed", resourceCulture);

		public static string net_alpn_failed => ResourceManager.GetString("net_alpn_failed", resourceCulture);

		public static string net_auth_alert => ResourceManager.GetString("net_auth_alert", resourceCulture);

		public static string net_auth_bad_client_creds => ResourceManager.GetString("net_auth_bad_client_creds", resourceCulture);

		public static string net_auth_bad_client_creds_or_target_mismatch => ResourceManager.GetString("net_auth_bad_client_creds_or_target_mismatch", resourceCulture);

		public static string net_auth_client_server => ResourceManager.GetString("net_auth_client_server", resourceCulture);

		public static string net_auth_context_expectation => ResourceManager.GetString("net_auth_context_expectation", resourceCulture);

		public static string net_auth_context_expectation_remote => ResourceManager.GetString("net_auth_context_expectation_remote", resourceCulture);

		public static string net_auth_eof => ResourceManager.GetString("net_auth_eof", resourceCulture);

		public static string net_auth_ignored_reauth => ResourceManager.GetString("net_auth_ignored_reauth", resourceCulture);

		public static string net_auth_message_not_encrypted => ResourceManager.GetString("net_auth_message_not_encrypted", resourceCulture);

		public static string net_auth_must_specify_extended_protection_scheme => ResourceManager.GetString("net_auth_must_specify_extended_protection_scheme", resourceCulture);

		public static string net_auth_noauth => ResourceManager.GetString("net_auth_noauth", resourceCulture);

		public static string net_auth_reauth => ResourceManager.GetString("net_auth_reauth", resourceCulture);

		public static string net_auth_SSPI => ResourceManager.GetString("net_auth_SSPI", resourceCulture);

		public static string net_auth_supported_impl_levels => ResourceManager.GetString("net_auth_supported_impl_levels", resourceCulture);

		public static string net_conflicting_options => ResourceManager.GetString("net_conflicting_options", resourceCulture);

		public static string net_context_buffer_too_small => ResourceManager.GetString("net_context_buffer_too_small", resourceCulture);

		public static string net_encryptionpolicy_notsupported => ResourceManager.GetString("net_encryptionpolicy_notsupported", resourceCulture);

		public static string net_frame_max_size => ResourceManager.GetString("net_frame_max_size", resourceCulture);

		public static string net_frame_read_io => ResourceManager.GetString("net_frame_read_io", resourceCulture);

		public static string net_frame_read_size => ResourceManager.GetString("net_frame_read_size", resourceCulture);

		public static string net_frame_size => ResourceManager.GetString("net_frame_size", resourceCulture);

		public static string net_generic_operation_failed => ResourceManager.GetString("net_generic_operation_failed", resourceCulture);

		public static string net_gssapi_operation_failed => ResourceManager.GetString("net_gssapi_operation_failed", resourceCulture);

		public static string net_gssapi_operation_failed_detailed => ResourceManager.GetString("net_gssapi_operation_failed_detailed", resourceCulture);

		public static string net_invalid_enum => ResourceManager.GetString("net_invalid_enum", resourceCulture);

		public static string net_io_async_result => ResourceManager.GetString("net_io_async_result", resourceCulture);

		public static string net_io_connectionclosed => ResourceManager.GetString("net_io_connectionclosed", resourceCulture);

		public static string net_io_decrypt => ResourceManager.GetString("net_io_decrypt", resourceCulture);

		public static string net_io_encrypt => ResourceManager.GetString("net_io_encrypt", resourceCulture);

		public static string net_io_eof => ResourceManager.GetString("net_io_eof", resourceCulture);

		public static string net_io_header_id => ResourceManager.GetString("net_io_header_id", resourceCulture);

		public static string net_io_invalidendcall => ResourceManager.GetString("net_io_invalidendcall", resourceCulture);

		public static string net_io_invalidnestedcall => ResourceManager.GetString("net_io_invalidnestedcall", resourceCulture);

		public static string net_io_must_be_rw_stream => ResourceManager.GetString("net_io_must_be_rw_stream", resourceCulture);

		public static string net_io_out_range => ResourceManager.GetString("net_io_out_range", resourceCulture);

		public static string net_io_read => ResourceManager.GetString("net_io_read", resourceCulture);

		public static string net_io_readfailure => ResourceManager.GetString("net_io_readfailure", resourceCulture);

		public static string net_io_write => ResourceManager.GetString("net_io_write", resourceCulture);

		public static string net_log_open_store_failed => ResourceManager.GetString("net_log_open_store_failed", resourceCulture);

		public static string net_log_operation_failed_with_error => ResourceManager.GetString("net_log_operation_failed_with_error", resourceCulture);

		public static string net_log_remote_cert_has_errors => ResourceManager.GetString("net_log_remote_cert_has_errors", resourceCulture);

		public static string net_log_remote_cert_name_mismatch => ResourceManager.GetString("net_log_remote_cert_name_mismatch", resourceCulture);

		public static string net_log_remote_cert_not_available => ResourceManager.GetString("net_log_remote_cert_not_available", resourceCulture);

		public static string net_MethodNotImplementedException => ResourceManager.GetString("net_MethodNotImplementedException", resourceCulture);

		public static string net_nego_channel_binding_not_supported => ResourceManager.GetString("net_nego_channel_binding_not_supported", resourceCulture);

		public static string net_nego_not_supported_empty_target_with_defaultcreds => ResourceManager.GetString("net_nego_not_supported_empty_target_with_defaultcreds", resourceCulture);

		public static string net_nego_protection_level_not_supported => ResourceManager.GetString("net_nego_protection_level_not_supported", resourceCulture);

		public static string net_nego_server_not_supported => ResourceManager.GetString("net_nego_server_not_supported", resourceCulture);

		public static string net_noseek => ResourceManager.GetString("net_noseek", resourceCulture);

		public static string net_ntlm_not_possible_default_cred => ResourceManager.GetString("net_ntlm_not_possible_default_cred", resourceCulture);

		public static string net_offset_plus_count => ResourceManager.GetString("net_offset_plus_count", resourceCulture);

		public static string net_security_sslprotocol_contiguous => ResourceManager.GetString("net_security_sslprotocol_contiguous", resourceCulture);

		public static string net_securitypackagesupport => ResourceManager.GetString("net_securitypackagesupport", resourceCulture);

		public static string net_securityprotocolnotsupported => ResourceManager.GetString("net_securityprotocolnotsupported", resourceCulture);

		public static string net_ssl_app_protocol_invalid => ResourceManager.GetString("net_ssl_app_protocol_invalid", resourceCulture);

		public static string net_ssl_app_protocols_invalid => ResourceManager.GetString("net_ssl_app_protocols_invalid", resourceCulture);

		public static string net_ssl_check_private_key_failed => ResourceManager.GetString("net_ssl_check_private_key_failed", resourceCulture);

		public static string net_ssl_decrypt_failed => ResourceManager.GetString("net_ssl_decrypt_failed", resourceCulture);

		public static string net_ssl_encrypt_failed => ResourceManager.GetString("net_ssl_encrypt_failed", resourceCulture);

		public static string net_ssl_encryptionpolicy_notsupported => ResourceManager.GetString("net_ssl_encryptionpolicy_notsupported", resourceCulture);

		public static string net_ssl_get_channel_binding_token_failed => ResourceManager.GetString("net_ssl_get_channel_binding_token_failed", resourceCulture);

		public static string net_ssl_get_connection_info_failed => ResourceManager.GetString("net_ssl_get_connection_info_failed", resourceCulture);

		public static string net_ssl_handshake_failed_error => ResourceManager.GetString("net_ssl_handshake_failed_error", resourceCulture);

		public static string net_ssl_invalid_certificate => ResourceManager.GetString("net_ssl_invalid_certificate", resourceCulture);

		public static string net_ssl_io_already_shutdown => ResourceManager.GetString("net_ssl_io_already_shutdown", resourceCulture);

		public static string net_ssl_io_cert_validation => ResourceManager.GetString("net_ssl_io_cert_validation", resourceCulture);

		public static string net_ssl_io_frame => ResourceManager.GetString("net_ssl_io_frame", resourceCulture);

		public static string net_ssl_io_no_server_cert => ResourceManager.GetString("net_ssl_io_no_server_cert", resourceCulture);

		public static string net_ssl_io_renego => ResourceManager.GetString("net_ssl_io_renego", resourceCulture);

		public static string net_ssl_read_bio_failed_error => ResourceManager.GetString("net_ssl_read_bio_failed_error", resourceCulture);

		public static string net_ssl_use_cert_failed => ResourceManager.GetString("net_ssl_use_cert_failed", resourceCulture);

		public static string net_ssl_use_private_key_failed => ResourceManager.GetString("net_ssl_use_private_key_failed", resourceCulture);

		public static string net_ssl_write_bio_failed_error => ResourceManager.GetString("net_ssl_write_bio_failed_error", resourceCulture);

		public static string net_ssl_x509Name_push_failed_error => ResourceManager.GetString("net_ssl_x509Name_push_failed_error", resourceCulture);

		public static string security_ExtendedProtectionPolicy_NoEmptyServiceNameCollection => ResourceManager.GetString("security_ExtendedProtectionPolicy_NoEmptyServiceNameCollection", resourceCulture);

		public static string security_ExtendedProtectionPolicy_UseDifferentConstructorForNever => ResourceManager.GetString("security_ExtendedProtectionPolicy_UseDifferentConstructorForNever", resourceCulture);

		public static string security_ServiceNameCollection_EmptyServiceName => ResourceManager.GetString("security_ServiceNameCollection_EmptyServiceName", resourceCulture);

		public static string SSPIInvalidHandleType => ResourceManager.GetString("SSPIInvalidHandleType", resourceCulture);

		internal SR()
		{
		}
	}
	internal static class SslClientAuthenticationOptionsExtensions
	{
		public static SslClientAuthenticationOptions ShallowClone(this SslClientAuthenticationOptions options)
		{
			return new SslClientAuthenticationOptions
			{
				AllowRenegotiation = options.AllowRenegotiation,
				ApplicationProtocols = options.ApplicationProtocols,
				CertificateRevocationCheckMode = options.CertificateRevocationCheckMode,
				ClientCertificates = options.ClientCertificates,
				EnabledSslProtocols = options.EnabledSslProtocols,
				EncryptionPolicy = options.EncryptionPolicy,
				LocalCertificateSelectionCallback = options.LocalCertificateSelectionCallback,
				RemoteCertificateValidationCallback = options.RemoteCertificateValidationCallback,
				TargetHost = options.TargetHost
			};
		}
	}
}
namespace System.Net.Http
{
	internal sealed class DecompressionHandler : StandardHttpMessageHandler
	{
		private abstract class DecompressedContent : HttpContent
		{
			private HttpContent _originalContent;

			private CancellationToken _cancellationToken;

			private bool _contentConsumed;

			public DecompressedContent(HttpContent originalContent)
			{
				_originalContent = originalContent;
				_contentConsumed = false;
				base.Headers.AddHeaders(originalContent.Headers);
				base.Headers.ContentLength = null;
				base.Headers.ContentEncoding.Clear();
				string text = null;
				foreach (string item in originalContent.Headers.ContentEncoding)
				{
					if (text != null)
					{
						base.Headers.ContentEncoding.Add(text);
					}
					text = item;
				}
			}

			public void SetDefaultCancellationToken(CancellationToken cancellationToken)
			{
				_cancellationToken = cancellationToken;
			}

			protected abstract Stream GetDecompressedStream(Stream originalStream);

			protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
			{
				return SerializeToStreamAsyncInternal(stream, context, _cancellationToken);
			}

			internal async Task SerializeToStreamAsyncInternal(Stream stream, TransportContext context, CancellationToken cancellationToken)
			{
				using Stream decompressedStream = await CreateContentReadStreamAsync().ConfigureAwait(continueOnCapturedContext: false);
				await decompressedStream.CopyToAsync(stream, 81920, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}

			protected override async Task<Stream> CreateContentReadStreamAsync()
			{
				if (_contentConsumed)
				{
					throw new InvalidOperationException(SR.net_http_content_stream_already_read);
				}
				_contentConsumed = true;
				return GetDecompressedStream(await _originalContent.ReadAsStreamAsync().ConfigureAwait(continueOnCapturedContext: false));
			}

			protected override bool TryComputeLength(out long length)
			{
				length = 0L;
				return false;
			}

			protected override void Dispose(bool disposing)
			{
				if (disposing)
				{
					_originalContent.Dispose();
				}
				base.Dispose(disposing);
			}
		}

		private sealed class GZipDecompressedContent : DecompressedContent
		{
			public GZipDecompressedContent(HttpContent originalContent)
				: base(originalContent)
			{
			}

			protected override Stream GetDecompressedStream(Stream originalStream)
			{
				return new GZipStream(originalStream, CompressionMode.Decompress);
			}
		}

		private sealed class DeflateDecompressedContent : DecompressedContent
		{
			public DeflateDecompressedContent(HttpContent originalContent)
				: base(originalContent)
			{
			}

			protected override Stream GetDecompressedStream(Stream originalStream)
			{
				return new DeflateStream(originalStream, CompressionMode.Decompress);
			}
		}

		private readonly StandardHttpMessageHandler _innerHandler;

		private readonly DecompressionMethods _decompressionMethods;

		private const string s_gzip = "gzip";

		private const string s_deflate = "deflate";

		private static readonly StringWithQualityHeaderValue s_gzipHeaderValue = new StringWithQualityHeaderValue("gzip");

		private static readonly StringWithQualityHeaderValue s_deflateHeaderValue = new StringWithQualityHeaderValue("deflate");

		internal bool GZipEnabled => (_decompressionMethods & DecompressionMethods.GZip) != 0;

		internal bool DeflateEnabled => (_decompressionMethods & DecompressionMethods.Deflate) != 0;

		public DecompressionHandler(DecompressionMethods decompressionMethods, StandardHttpMessageHandler innerHandler)
		{
			_decompressionMethods = decompressionMethods;
			_innerHandler = innerHandler;
		}

		protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
		{
			if (GZipEnabled)
			{
				request.Headers.AcceptEncoding.Add(s_gzipHeaderValue);
			}
			if (DeflateEnabled)
			{
				request.Headers.AcceptEncoding.Add(s_deflateHeaderValue);
			}
			HttpResponseMessage httpResponseMessage = await _innerHandler.SendRequestAsync(request, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			ICollection<string> contentEncoding = httpResponseMessage.Content.Headers.ContentEncoding;
			if (contentEncoding.Count > 0)
			{
				string text = null;
				foreach (string item in contentEncoding)
				{
					text = item;
				}
				if (GZipEnabled && text == "gzip")
				{
					httpResponseMessage.Content = new GZipDecompressedContent(httpResponseMessage.Content);
					((GZipDecompressedContent)httpResponseMessage.Content).SetDefaultCancellationToken(cancellationToken);
				}
				else if (DeflateEnabled && text == "deflate")
				{
					httpResponseMessage.Content = new DeflateDecompressedContent(httpResponseMessage.Content);
					((DeflateDecompressedContent)httpResponseMessage.Content).SetDefaultCancellationToken(cancellationToken);
				}
			}
			return httpResponseMessage;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				_innerHandler.Dispose();
			}
			base.Dispose(disposing);
		}
	}
	internal static class HttpContentHeadersExtensions
	{
		public static void AddHeaders(this HttpContentHeaders headers, HttpContentHeaders sourceHeaders)
		{
			foreach (KeyValuePair<string, IEnumerable<string>> sourceHeader in sourceHeaders)
			{
				headers.TryAddWithoutValidation(sourceHeader.Key, sourceHeader.Value);
			}
		}
	}
	internal static class HttpRequestMessageExtensions
	{
		public static bool HasHeaders(this HttpRequestMessage request)
		{
			bool flag = RuntimeUtils.IsDotNetFramework();
			bool flag2 = RuntimeUtils.IsMono();
			string name = ((flag || flag2) ? "headers" : "_headers");
			FieldInfo field = typeof(HttpRequestMessage).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
			if (field == null && flag)
			{
				name = "_headers";
				field = typeof(HttpRequestMessage).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
			}
			else if (field == null && RuntimeUtils.IsDotNetNative())
			{
				return true;
			}
			return (HttpRequestHeaders)field.GetValue(request) != null;
		}
	}
	internal static class HttpResponseMessageExtensions
	{
		internal static void SetVersionWithoutValidation(this HttpResponseMessage message, Version value)
		{
			message.Version = value;
		}

		internal static void SetStatusCodeWithoutValidation(this HttpResponseMessage message, HttpStatusCode value)
		{
			message.StatusCode = value;
		}

		internal static void SetReasonPhraseWithoutValidation(this HttpResponseMessage message, string value)
		{
			message.ReasonPhrase = value;
		}
	}
	internal static class HttpHandlerDefaults
	{
		public const int DefaultMaxAutomaticRedirections = 50;

		public const int DefaultMaxConnectionsPerServer = int.MaxValue;

		public const int DefaultMaxResponseDrainSize = 1048576;

		public static readonly TimeSpan DefaultResponseDrainTimeout = TimeSpan.FromSeconds(2.0);

		public const int DefaultMaxResponseHeadersLength = 64;

		public const DecompressionMethods DefaultAutomaticDecompression = DecompressionMethods.None;

		public const bool DefaultAutomaticRedirection = true;

		public const bool DefaultUseCookies = true;

		public const bool DefaultPreAuthenticate = false;

		public const ClientCertificateOption DefaultClientCertificateOption = ClientCertificateOption.Manual;

		public const bool DefaultUseProxy = true;

		public const bool DefaultUseDefaultCredentials = false;

		public const bool DefaultCheckCertificateRevocationList = false;

		public static readonly TimeSpan DefaultPooledConnectionLifetime = Timeout.InfiniteTimeSpan;

		public static readonly TimeSpan DefaultPooledConnectionIdleTimeout = TimeSpan.FromMinutes(2.0);

		public static readonly TimeSpan DefaultExpect100ContinueTimeout = TimeSpan.FromSeconds(1.0);

		public static readonly TimeSpan DefaultConnectTimeout = Timeout.InfiniteTimeSpan;
	}
	internal enum HttpParseResult
	{
		Parsed,
		NotParsed,
		InvalidFormat
	}
	internal static class HttpRuleParser
	{
		private static readonly bool[] s_tokenChars = CreateTokenChars();

		private const int maxNestedCount = 5;

		private static readonly string[] s_dateFormats = new string[15]
		{
			"ddd, d MMM yyyy H:m:s 'GMT'", "ddd, d MMM yyyy H:m:s", "d MMM yyyy H:m:s 'GMT'", "d MMM yyyy H:m:s", "ddd, d MMM yy H:m:s 'GMT'", "ddd, d MMM yy H:m:s", "d MMM yy H:m:s 'GMT'", "d MMM yy H:m:s", "dddd, d'-'MMM'-'yy H:m:s 'GMT'", "dddd, d'-'MMM'-'yy H:m:s",
			"ddd MMM d H:m:s yyyy", "ddd, d MMM yyyy H:m:s zzz", "ddd, d MMM yyyy H:m:s", "d MMM yyyy H:m:s zzz", "d MMM yyyy H:m:s"
		};

		internal const char CR = '\r';

		internal const char LF = '\n';

		internal const int MaxInt64Digits = 19;

		internal const int MaxInt32Digits = 10;

		internal static readonly Encoding DefaultHttpEncoding = Encoding.GetEncoding(28591);

		private static bool[] CreateTokenChars()
		{
			bool[] array = new bool[128];
			for (int i = 33; i < 127; i++)
			{
				array[i] = true;
			}
			array[40] = false;
			array[41] = false;
			array[60] = false;
			array[62] = false;
			array[64] = false;
			array[44] = false;
			array[59] = false;
			array[58] = false;
			array[92] = false;
			array[34] = false;
			array[47] = false;
			array[91] = false;
			array[93] = false;
			array[63] = false;
			array[61] = false;
			array[123] = false;
			array[125] = false;
			return array;
		}

		internal static bool IsTokenChar(char character)
		{
			if (character > '\u007f')
			{
				return false;
			}
			return s_tokenChars[(uint)character];
		}

		internal static int GetTokenLength(string input, int startIndex)
		{
			if (startIndex >= input.Length)
			{
				return 0;
			}
			for (int i = startIndex; i < input.Length; i++)
			{
				if (!IsTokenChar(input[i]))
				{
					return i - startIndex;
				}
			}
			return input.Length - startIndex;
		}

		internal static bool IsToken(string input)
		{
			for (int i = 0; i < input.Length; i++)
			{
				if (!IsTokenChar(input[i]))
				{
					return false;
				}
			}
			return true;
		}

		internal static bool IsToken(ReadOnlySpan<byte> input)
		{
			for (int i = 0; i < input.Length; i++)
			{
				if (!IsTokenChar((char)input[i]))
				{
					return false;
				}
			}
			return true;
		}

		internal static string GetTokenString(ReadOnlySpan<byte> input)
		{
			return Encoding.ASCII.GetString(input.ToArray());
		}

		internal static int GetWhitespaceLength(string input, int startIndex)
		{
			if (startIndex >= input.Length)
			{
				return 0;
			}
			int num = startIndex;
			while (num < input.Length)
			{
				switch (input[num])
				{
				case '\t':
				case ' ':
					num++;
					continue;
				case '\r':
					if (num + 2 < input.Length && input[num + 1] == '\n')
					{
						char c = input[num + 2];
						if (c == ' ' || c == '\t')
						{
							num += 3;
							continue;
						}
					}
					break;
				}
				return num - startIndex;
			}
			return input.Length - startIndex;
		}

		internal static bool ContainsInvalidNewLine(string value)
		{
			return ContainsInvalidNewLine(value, 0);
		}

		internal static bool ContainsInvalidNewLine(string value, int startIndex)
		{
			for (int i = startIndex; i < value.Length; i++)
			{
				if (value[i] != '\r')
				{
					continue;
				}
				int num = i + 1;
				if (num < value.Length && value[num] == '\n')
				{
					i = num + 1;
					if (i == value.Length)
					{
						return true;
					}
					char c = value[i];
					if (c != ' ' && c != '\t')
					{
						return true;
					}
				}
			}
			return false;
		}

		internal static int GetNumberLength(string input, int startIndex, bool allowDecimal)
		{
			int num = startIndex;
			bool flag = !allowDecimal;
			if (input[num] == '.')
			{
				return 0;
			}
			while (num < input.Length)
			{
				char c = input[num];
				if (c >= '0' && c <= '9')
				{
					num++;
					continue;
				}
				if (flag || c != '.')
				{
					break;
				}
				flag = true;
				num++;
			}
			return num - startIndex;
		}

		internal static int GetHostLength(string input, int startIndex, bool allowToken, out string host)
		{
			host = null;
			if (startIndex >= input.Length)
			{
				return 0;
			}
			int i = startIndex;
			bool flag;
			bool num;
			for (flag = true; i < input.Length; flag = num, i++)
			{
				char c = input[i];
				switch (c)
				{
				case '/':
					return 0;
				default:
					num = flag && IsTokenChar(c);
					continue;
				case '\t':
				case '\r':
				case ' ':
				case ',':
					break;
				}
				break;
			}
			int num2 = i - startIndex;
			if (num2 == 0)
			{
				return 0;
			}
			string text = input.Substring(startIndex, num2);
			if ((!allowToken || !flag) && !IsValidHostName(text))
			{
				return 0;
			}
			host = text;
			return num2;
		}

		internal static System.Net.Http.HttpParseResult GetCommentLength(string input, int startIndex, out int length)
		{
			int nestedCount = 0;
			return GetExpressionLength(input, startIndex, '(', ')', supportsNesting: true, ref nestedCount, out length);
		}

		internal static System.Net.Http.HttpParseResult GetQuotedStringLength(string input, int startIndex, out int length)
		{
			int nestedCount = 0;
			return GetExpressionLength(input, startIndex, '"', '"', supportsNesting: false, ref nestedCount, out length);
		}

		internal static System.Net.Http.HttpParseResult GetQuotedPairLength(string input, int startIndex, out int length)
		{
			length = 0;
			if (input[startIndex] != '\\')
			{
				return System.Net.Http.HttpParseResult.NotParsed;
			}
			if (startIndex + 2 > input.Length || input[startIndex + 1] > '\u007f')
			{
				return System.Net.Http.HttpParseResult.InvalidFormat;
			}
			length = 2;
			return System.Net.Http.HttpParseResult.Parsed;
		}

		internal static string DateToString(DateTimeOffset dateTime)
		{
			return dateTime.ToUniversalTime().ToString("r", CultureInfo.InvariantCulture);
		}

		internal static bool TryStringToDate(string input, out DateTimeOffset result)
		{
			if (DateTimeOffset.TryParseExact(input, s_dateFormats, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal, out result))
			{
				return true;
			}
			return false;
		}

		private static System.Net.Http.HttpParseResult GetExpressionLength(string input, int startIndex, char openChar, char closeChar, bool supportsNesting, ref int nestedCount, out int length)
		{
			length = 0;
			if (input[startIndex] != openChar)
			{
				return System.Net.Http.HttpParseResult.NotParsed;
			}
			int num = startIndex + 1;
			while (num < input.Length)
			{
				int length2 = 0;
				if (num + 2 < input.Length && GetQuotedPairLength(input, num, out length2) == System.Net.Http.HttpParseResult.Parsed)
				{
					num += length2;
					continue;
				}
				if (supportsNesting && input[num] == openChar)
				{
					nestedCount++;
					try
					{
						if (nestedCount > 5)
						{
							return System.Net.Http.HttpParseResult.InvalidFormat;
						}
						int length3 = 0;
						switch (GetExpressionLength(input, num, openChar, closeChar, supportsNesting, ref nestedCount, out length3))
						{
						case System.Net.Http.HttpParseResult.Parsed:
							num += length3;
							break;
						case System.Net.Http.HttpParseResult.InvalidFormat:
							return System.Net.Http.HttpParseResult.InvalidFormat;
						case System.Net.Http.HttpParseResult.NotParsed:
							break;
						}
					}
					finally
					{
						nestedCount--;
					}
				}
				if (input[num] == closeChar)
				{
					length = num - startIndex + 1;
					return System.Net.Http.HttpParseResult.Parsed;
				}
				num++;
			}
			return System.Net.Http.HttpParseResult.InvalidFormat;
		}

		private static bool IsValidHostName(string host)
		{
			Uri result;
			return Uri.TryCreate("http://u@" + host + "/", UriKind.Absolute, out result);
		}
	}
	internal static class HttpUtilities
	{
		internal static Version DefaultRequestVersion => HttpVersionInternal.Version20;

		internal static Version DefaultResponseVersion => HttpVersionInternal.Version11;

		internal static bool IsHttpUri(Uri uri)
		{
			return IsSupportedScheme(uri.Scheme);
		}

		internal static bool IsSupportedScheme(string scheme)
		{
			if (!IsSupportedNonSecureScheme(scheme))
			{
				return IsSupportedSecureScheme(scheme);
			}
			return true;
		}

		internal static bool IsSupportedNonSecureScheme(string scheme)
		{
			if (!string.Equals(scheme, "http", StringComparison.OrdinalIgnoreCase))
			{
				return IsNonSecureWebSocketScheme(scheme);
			}
			return true;
		}

		internal static bool IsSupportedSecureScheme(string scheme)
		{
			if (!string.Equals(scheme, "https", StringComparison.OrdinalIgnoreCase))
			{
				return IsSecureWebSocketScheme(scheme);
			}
			return true;
		}

		internal static bool IsNonSecureWebSocketScheme(string scheme)
		{
			return string.Equals(scheme, "ws", StringComparison.OrdinalIgnoreCase);
		}

		internal static bool IsSecureWebSocketScheme(string scheme)
		{
			return string.Equals(scheme, "wss", StringComparison.OrdinalIgnoreCase);
		}

		internal static Task ContinueWithStandard<T>(this Task<T> task, object state, Action<Task<T>, object> continuation)
		{
			return task.ContinueWith(continuation, state, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
		}
	}
	internal class AuthenticationHelper
	{
		private enum AuthenticationType
		{
			Basic,
			Digest,
			Ntlm,
			Negotiate
		}

		private readonly struct AuthenticationChallenge
		{
			public AuthenticationType AuthenticationType { get; }

			public string SchemeName { get; }

			public NetworkCredential Credential { get; }

			public string ChallengeData { get; }

			public AuthenticationChallenge(AuthenticationType authenticationType, string schemeName, NetworkCredential credential, string challenge)
			{
				AuthenticationType = authenticationType;
				SchemeName = schemeName;
				Credential = credential;
				ChallengeData = challenge;
			}
		}

		internal class DigestResponse
		{
			internal readonly Dictionary<string, string> Parameters = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

			internal const string NonceCount = "00000001";

			internal DigestResponse(string challenge)
			{
				if (!string.IsNullOrEmpty(challenge))
				{
					Parse(challenge);
				}
			}

			private static bool CharIsSpaceOrTab(char ch)
			{
				if (ch != ' ')
				{
					return ch == '\t';
				}
				return true;
			}

			private static bool MustValueBeQuoted(string key)
			{
				if (!key.Equals("realm", StringComparison.OrdinalIgnoreCase) && !key.Equals("nonce", StringComparison.OrdinalIgnoreCase) && !key.Equals("opaque", StringComparison.OrdinalIgnoreCase))
				{
					return key.Equals("qop", StringComparison.OrdinalIgnoreCase);
				}
				return true;
			}

			private string GetNextKey(string data, int currentIndex, out int parsedIndex)
			{
				while (currentIndex < data.Length && CharIsSpaceOrTab(data[currentIndex]))
				{
					currentIndex++;
				}
				int num = currentIndex;
				while (currentIndex < data.Length && data[currentIndex] != '=' && !CharIsSpaceOrTab(data[currentIndex]))
				{
					currentIndex++;
				}
				if (currentIndex == data.Length)
				{
					parsedIndex = currentIndex;
					return null;
				}
				int length = currentIndex - num;
				if (CharIsSpaceOrTab(data[currentIndex]))
				{
					while (currentIndex < data.Length && CharIsSpaceOrTab(data[currentIndex]))
					{
						currentIndex++;
					}
					if (currentIndex == data.Length || data[currentIndex] != '=')
					{
						parsedIndex = currentIndex;
						return null;
					}
				}
				while (currentIndex < data.Length && (CharIsSpaceOrTab(data[currentIndex]) || data[currentIndex] == '='))
				{
					currentIndex++;
				}
				parsedIndex = currentIndex;
				return data.Substring(num, length);
			}

			private string GetNextValue(string data, int currentIndex, bool expectQuotes, out int parsedIndex)
			{
				bool flag = false;
				if (data[currentIndex] == '"')
				{
					flag = true;
					currentIndex++;
				}
				if (expectQuotes && !flag)
				{
					parsedIndex = currentIndex;
					return null;
				}
				StringBuilder stringBuilder = StringBuilderCache.Acquire();
				while (currentIndex < data.Length && ((flag && data[currentIndex] != '"') || (!flag && data[currentIndex] != ',')))
				{
					stringBuilder.Append(data[currentIndex]);
					currentIndex++;
					if (currentIndex == data.Length || (!flag && CharIsSpaceOrTab(data[currentIndex])))
					{
						break;
					}
					if (flag && data[currentIndex] == '"' && data[currentIndex - 1] == '\\')
					{
						stringBuilder.Append(data[currentIndex]);
						currentIndex++;
					}
				}
				if (flag)
				{
					currentIndex++;
				}
				while (currentIndex < data.Length && CharIsSpaceOrTab(data[currentIndex]))
				{
					currentIndex++;
				}
				if (currentIndex == data.Length)
				{
					parsedIndex = currentIndex;
					return StringBuilderCache.GetStringAndRelease(stringBuilder);
				}
				if (data[currentIndex++] != ',')
				{
					parsedIndex = currentIndex;
					return null;
				}
				while (currentIndex < data.Length && CharIsSpaceOrTab(data[currentIndex]))
				{
					currentIndex++;
				}
				parsedIndex = currentIndex;
				return StringBuilderCache.GetStringAndRelease(stringBuilder);
			}

			private void Parse(string challenge)
			{
				int parsedIndex = 0;
				while (parsedIndex < challenge.Length)
				{
					string nextKey = GetNextKey(challenge, parsedIndex, out parsedIndex);
					if (!string.IsNullOrEmpty(nextKey) && parsedIndex < challenge.Length)
					{
						string nextValue = GetNextValue(challenge, parsedIndex, MustValueBeQuoted(nextKey), out parsedIndex);
						if (!string.IsNullOrEmpty(nextValue))
						{
							Parameters.Add(nextKey, nextValue);
							continue;
						}
						break;
					}
					break;
				}
			}
		}

		private const string BasicScheme = "Basic";

		private const string DigestScheme = "Digest";

		private const string NtlmScheme = "NTLM";

		private const string NegotiateScheme = "Negotiate";

		private const string Qop = "qop";

		private const string Auth = "auth";

		private const string AuthInt = "auth-int";

		private const string Nonce = "nonce";

		private const string NC = "nc";

		private const string Realm = "realm";

		private const string UserHash = "userhash";

		private const string Username = "username";

		private const string UsernameStar = "username*";

		private const string Algorithm = "algorithm";

		private const string Uri = "uri";

		private const string Sha256 = "SHA-256";

		private const string Md5 = "MD5";

		private const string Sha256Sess = "SHA-256-sess";

		private const string MD5Sess = "MD5-sess";

		private const string CNonce = "cnonce";

		private const string Opaque = "opaque";

		private const string Response = "response";

		private const string Stale = "stale";

		private static int[] s_alphaNumChooser = new int[3] { 48, 65, 97 };

		private static bool TryGetChallengeDataForScheme(string scheme, HttpHeaderValueCollection<AuthenticationHeaderValue> authenticationHeaderValues, out string challengeData)
		{
			foreach (AuthenticationHeaderValue authenticationHeaderValue in authenticationHeaderValues)
			{
				if (StringComparer.OrdinalIgnoreCase.Equals(scheme, authenticationHeaderValue.Scheme))
				{
					challengeData = authenticationHeaderValue.Parameter;
					return true;
				}
			}
			challengeData = null;
			return false;
		}

		internal static bool IsSessionAuthenticationChallenge(HttpResponseMessage response)
		{
			if (response.StatusCode != HttpStatusCode.Unauthorized)
			{
				return false;
			}
			foreach (AuthenticationHeaderValue responseAuthenticationHeaderValue in GetResponseAuthenticationHeaderValues(response, isProxyAuth: false))
			{
				if (StringComparer.OrdinalIgnoreCase.Equals("Negotiate", responseAuthenticationHeaderValue.Scheme) || StringComparer.OrdinalIgnoreCase.Equals("NTLM", responseAuthenticationHeaderValue.Scheme))
				{
					return true;
				}
			}
			return false;
		}

		private static bool TryGetValidAuthenticationChallengeForScheme(string scheme, AuthenticationType authenticationType, Uri uri, ICredentials credentials, HttpHeaderValueCollection<AuthenticationHeaderValue> authenticationHeaderValues, out AuthenticationChallenge challenge)
		{
			challenge = default(AuthenticationChallenge);
			if (!TryGetChallengeDataForScheme(scheme, authenticationHeaderValues, out var challengeData))
			{
				return false;
			}
			NetworkCredential credential = credentials.GetCredential(uri, scheme);
			if (credential == null)
			{
				return false;
			}
			challenge = new AuthenticationChallenge(authenticationType, scheme, credential, challengeData);
			return true;
		}

		private static bool TryGetAuthenticationChallenge(HttpResponseMessage response, bool isProxyAuth, Uri authUri, ICredentials credentials, out AuthenticationChallenge challenge)
		{
			if (!IsAuthenticationChallenge(response, isProxyAuth))
			{
				challenge = default(AuthenticationChallenge);
				return false;
			}
			HttpHeaderValueCollection<AuthenticationHeaderValue> responseAuthenticationHeaderValues = GetResponseAuthenticationHeaderValues(response, isProxyAuth);
			if (!TryGetValidAuthenticationChallengeForScheme("Negotiate", AuthenticationType.Negotiate, authUri, credentials, responseAuthenticationHeaderValues, out challenge) && !TryGetValidAuthenticationChallengeForScheme("NTLM", AuthenticationType.Ntlm, authUri, credentials, responseAuthenticationHeaderValues, out challenge) && !TryGetValidAuthenticationChallengeForScheme("Digest", AuthenticationType.Digest, authUri, credentials, responseAuthenticationHeaderValues, out challenge))
			{
				return TryGetValidAuthenticationChallengeForScheme("Basic", AuthenticationType.Basic, authUri, credentials, responseAuthenticationHeaderValues, out challenge);
			}
			return true;
		}

		private static bool TryGetRepeatedChallenge(HttpResponseMessage response, string scheme, bool isProxyAuth, out string challengeData)
		{
			challengeData = null;
			if (!IsAuthenticationChallenge(response, isProxyAuth))
			{
				return false;
			}
			if (!TryGetChallengeDataForScheme(scheme, GetResponseAuthenticationHeaderValues(response, isProxyAuth), out challengeData))
			{
				return false;
			}
			return true;
		}

		private static bool IsAuthenticationChallenge(HttpResponseMessage response, bool isProxyAuth)
		{
			if (!isProxyAuth)
			{
				return response.StatusCode == HttpStatusCode.Unauthorized;
			}
			return response.StatusCode == HttpStatusCode.ProxyAuthenticationRequired;
		}

		private static HttpHeaderValueCollection<AuthenticationHeaderValue> GetResponseAuthenticationHeaderValues(HttpResponseMessage response, bool isProxyAuth)
		{
			if (!isProxyAuth)
			{
				return response.Headers.WwwAuthenticate;
			}
			return response.Headers.ProxyAuthenticate;
		}

		private static void SetRequestAuthenticationHeaderValue(HttpRequestMessage request, AuthenticationHeaderValue headerValue, bool isProxyAuth)
		{
			if (isProxyAuth)
			{
				request.Headers.ProxyAuthorization = headerValue;
			}
			else
			{
				request.Headers.Authorization = headerValue;
			}
		}

		private static void SetBasicAuthToken(HttpRequestMessage request, NetworkCredential credential, bool isProxyAuth)
		{
			string s = ((!string.IsNullOrEmpty(credential.Domain)) ? (credential.Domain + "\\" + credential.UserName + ":" + credential.Password) : (credential.UserName + ":" + credential.Password));
			string parameter = Convert.ToBase64String(Encoding.UTF8.GetBytes(s));
			SetRequestAuthenticationHeaderValue(request, new AuthenticationHeaderValue("Basic", parameter), isProxyAuth);
		}

		private static async Task<bool> TrySetDigestAuthToken(HttpRequestMessage request, NetworkCredential credential, DigestResponse digestResponse, bool isProxyAuth)
		{
			string text = await GetDigestTokenForCredential(credential, request, digestResponse).ConfigureAwait(continueOnCapturedContext: false);
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			AuthenticationHeaderValue headerValue = new AuthenticationHeaderValue("Digest", text);
			SetRequestAuthenticationHeaderValue(request, headerValue, isProxyAuth);
			return true;
		}

		private static Task<HttpResponseMessage> InnerSendAsync(HttpRequestMessage request, bool isProxyAuth, bool doRequestAuth, System.Net.Http.HttpConnectionPool pool, CancellationToken cancellationToken)
		{
			if (!isProxyAuth)
			{
				return pool.SendWithProxyAuthAsync(request, doRequestAuth, cancellationToken);
			}
			return pool.SendWithRetryAsync(request, doRequestAuth, cancellationToken);
		}

		private static async Task<HttpResponseMessage> SendWithAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, bool preAuthenticate, bool isProxyAuth, bool doRequestAuth, System.Net.Http.HttpConnectionPool pool, CancellationToken cancellationToken)
		{
			bool performedBasicPreauth = false;
			if (preAuthenticate)
			{
				NetworkCredential credential;
				lock (pool.PreAuthCredentials)
				{
					credential = pool.PreAuthCredentials.GetCredential(authUri, "Basic");
				}
				if (credential != null)
				{
					SetBasicAuthToken(request, credential, isProxyAuth);
					performedBasicPreauth = true;
				}
			}
			HttpResponseMessage response = await InnerSendAsync(request, isProxyAuth, doRequestAuth, pool, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			if (TryGetAuthenticationChallenge(response, isProxyAuth, authUri, credentials, out var challenge))
			{
				switch (challenge.AuthenticationType)
				{
				case AuthenticationType.Digest:
				{
					DigestResponse digestResponse = new DigestResponse(challenge.ChallengeData);
					if (!(await TrySetDigestAuthToken(request, challenge.Credential, digestResponse, isProxyAuth).ConfigureAwait(continueOnCapturedContext: false)))
					{
						break;
					}
					response.Dispose();
					response = await InnerSendAsync(request, isProxyAuth, doRequestAuth, pool, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
					if (TryGetRepeatedChallenge(response, challenge.SchemeName, isProxyAuth, out var challengeData))
					{
						digestResponse = new DigestResponse(challengeData);
						bool flag = IsServerNonceStale(digestResponse);
						if (flag)
						{
							flag = await TrySetDigestAuthToken(request, challenge.Credential, digestResponse, isProxyAuth).ConfigureAwait(continueOnCapturedContext: false);
						}
						if (flag)
						{
							response.Dispose();
							response = await InnerSendAsync(request, isProxyAuth, doRequestAuth, pool, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
						}
					}
					break;
				}
				case AuthenticationType.Basic:
				{
					if (performedBasicPreauth)
					{
						break;
					}
					response.Dispose();
					SetBasicAuthToken(request, challenge.Credential, isProxyAuth);
					response = await InnerSendAsync(request, isProxyAuth, doRequestAuth, pool, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
					if (!preAuthenticate)
					{
						break;
					}
					HttpStatusCode statusCode = response.StatusCode;
					if (statusCode == HttpStatusCode.Unauthorized || statusCode == HttpStatusCode.ProxyAuthenticationRequired)
					{
						break;
					}
					lock (pool.PreAuthCredentials)
					{
						try
						{
							if (System.Net.NetEventSource.IsEnabled)
							{
								System.Net.NetEventSource.Info(pool.PreAuthCredentials, $"Adding Basic credential to cache, uri={authUri}, username={challenge.Credential.UserName}", "SendWithAuthAsync");
							}
							pool.PreAuthCredentials.Add(authUri, "Basic", challenge.Credential);
						}
						catch (ArgumentException)
						{
							if (System.Net.NetEventSource.IsEnabled)
							{
								System.Net.NetEventSource.Info(pool.PreAuthCredentials, $"Basic credential present in cache, uri={authUri}, username={challenge.Credential.UserName}", "SendWithAuthAsync");
							}
						}
					}
					break;
				}
				}
			}
			return response;
		}

		public static Task<HttpResponseMessage> SendWithProxyAuthAsync(HttpRequestMessage request, Uri proxyUri, ICredentials proxyCredentials, bool doRequestAuth, System.Net.Http.HttpConnectionPool pool, CancellationToken cancellationToken)
		{
			return SendWithAuthAsync(request, proxyUri, proxyCredentials, preAuthenticate: false, isProxyAuth: true, doRequestAuth, pool, cancellationToken);
		}

		public static Task<HttpResponseMessage> SendWithRequestAuthAsync(HttpRequestMessage request, ICredentials credentials, bool preAuthenticate, System.Net.Http.HttpConnectionPool pool, CancellationToken cancellationToken)
		{
			return SendWithAuthAsync(request, request.RequestUri, credentials, preAuthenticate, isProxyAuth: false, doRequestAuth: true, pool, cancellationToken);
		}

		public static async Task<string> GetDigestTokenForCredential(NetworkCredential credential, HttpRequestMessage request, DigestResponse digestResponse)
		{
			StringBuilder sb = StringBuilderCache.Acquire();
			if (digestResponse.Parameters.TryGetValue("algorithm", out var algorithm))
			{
				if (!algorithm.Equals("SHA-256", StringComparison.OrdinalIgnoreCase) && !algorithm.Equals("MD5", StringComparison.OrdinalIgnoreCase) && !algorithm.Equals("SHA-256-sess", StringComparison.OrdinalIgnoreCase) && !algorithm.Equals("MD5-sess", StringComparison.OrdinalIgnoreCase))
				{
					if (System.Net.NetEventSource.IsEnabled)
					{
						System.Net.NetEventSource.Error(digestResponse, "Algorithm not supported: {algorithm}", "GetDigestTokenForCredential");
					}
					return null;
				}
			}
			else
			{
				algorithm = "MD5";
			}
			if (!digestResponse.Parameters.TryGetValue("nonce", out var nonce))
			{
				if (System.Net.NetEventSource.IsEnabled)
				{
					System.Net.NetEventSource.Error(digestResponse, "Nonce missing", "GetDigestTokenForCredential");
				}
				return null;
			}
			digestResponse.Parameters.TryGetValue("opaque", out var opaque);
			if (!digestResponse.Parameters.TryGetValue("realm", out var value))
			{
				if (System.Net.NetEventSource.IsEnabled)
				{
					System.Net.NetEventSource.Error(digestResponse, "Realm missing", "GetDigestTokenForCredential");
				}
				return null;
			}
			string output;
			if (digestResponse.Parameters.TryGetValue("userhash", out var value2) && value2 == "true")
			{
				sb.AppendKeyValue("username", ComputeHash(credential.UserName + ":" + value, algorithm));
				sb.AppendKeyValue("userhash", value2, includeQuotes: false);
			}
			else if (System.Net.Http.Headers.HeaderUtilities.IsInputEncoded5987(credential.UserName, out output))
			{
				sb.AppendKeyValue("username*", output, includeQuotes: false);
			}
			else
			{
				sb.AppendKeyValue("username", credential.UserName);
			}
			if (value != string.Empty)
			{
				sb.AppendKeyValue("realm", value);
			}
			sb.AppendKeyValue("nonce", nonce);
			sb.AppendKeyValue("uri", request.RequestUri.PathAndQuery);
			string qop = "auth";
			if (digestResponse.Parameters.ContainsKey("qop"))
			{
				int num = digestResponse.Parameters["qop"].IndexOf("auth-int");
				if (num != -1 && digestResponse.Parameters["qop"].IndexOf("auth") == num && digestResponse.Parameters["qop"].IndexOf("auth", num + "auth-int".Length) == -1)
				{
					qop = "auth-int";
				}
			}
			string cnonce = GetRandomAlphaNumericString();
			string a1 = credential.UserName + ":" + value + ":" + credential.Password;
			if (algorithm.EndsWith("sess", StringComparison.OrdinalIgnoreCase))
			{
				a1 = ComputeHash(a1, algorithm) + ":" + nonce + ":" + cnonce;
			}
			string a2 = request.Method.Method + ":" + request.RequestUri.PathAndQuery;
			if (qop == "auth-int")
			{
				string text = ((request.Content != null) ? (await request.Content.ReadAsStringAsync().ConfigureAwait(continueOnCapturedContext: false)) : string.Empty);
				string data = text;
				a2 = a2 + ":" + ComputeHash(data, algorithm);
			}
			string value3 = ComputeHash(ComputeHash(a1, algorithm) + ":" + nonce + ":00000001:" + cnonce + ":" + qop + ":" + ComputeHash(a2, algorithm), algorithm);
			sb.AppendKeyValue("response", value3);
			sb.AppendKeyValue("algorithm", algorithm, includeQuotes: false);
			if (opaque != null)
			{
				sb.AppendKeyValue("opaque", opaque);
			}
			sb.AppendKeyValue("qop", qop, includeQuotes: false);
			sb.AppendKeyValue("nc", "00000001", includeQuotes: false);
			sb.AppendKeyValue("cnonce", cnonce, includeQuotes: true, includeComma: false);
			return StringBuilderCache.GetStringAndRelease(sb);
		}

		public static bool IsServerNonceStale(DigestResponse digestResponse)
		{
			string value = null;
			if (digestResponse.Parameters.TryGetValue("stale", out value))
			{
				return value == "true";
			}
			return false;
		}

		private static string GetRandomAlphaNumericString()
		{
			byte[] array = new byte[32];
			RandomNumberGenerator.Create().GetBytes(array);
			StringBuilder stringBuilder = StringBuilderCache.Acquire();
			int num = 0;
			while (num < array.Length)
			{
				int num2 = array[num++] % 3;
				int num3 = array[num++] % ((num2 == 0) ? 10 : 26);
				stringBuilder.Append((char)(s_alphaNumChooser[num2] + num3));
			}
			return StringBuilderCache.GetStringAndRelease(stringBuilder);
		}

		private static string ComputeHash(string data, string algorithm)
		{
			using HashAlgorithm hashAlgorithm = (algorithm.StartsWith("SHA-256", StringComparison.OrdinalIgnoreCase) ? ((HashAlgorithm)SHA256.Create()) : ((HashAlgorithm)MD5.Create()));
			Span<byte> span = stackalloc byte[hashAlgorithm.HashSize / 8];
			span = hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(data));
			StringBuilder stringBuilder = StringBuilderCache.Acquire(span.Length * 2);
			for (int i = 0; i < span.Length; i++)
			{
				stringBuilder.Append(span[i].ToString("x2"));
			}
			return StringBuilderCache.GetStringAndRelease(stringBuilder);
		}

		private static Task<HttpResponseMessage> InnerSendAsync(HttpRequestMessage request, bool isProxyAuth, System.Net.Http.HttpConnectionPool pool, System.Net.Http.HttpConnection connection, CancellationToken cancellationToken)
		{
			if (!isProxyAuth)
			{
				return pool.SendWithNtProxyAuthAsync(connection, request, cancellationToken);
			}
			return connection.SendAsyncCore(request, cancellationToken);
		}

		private static bool ProxySupportsConnectionAuth(HttpResponseMessage response)
		{
			if (!response.Headers.TryGetValues(System.Net.Http.Headers.KnownHeaders.ProxySupport.Descriptor.Name, out IEnumerable<string> values))
			{
				return false;
			}
			foreach (string item in values)
			{
				if (item == "Session-Based-Authentication")
				{
					return true;
				}
			}
			return false;
		}

		private static async Task<HttpResponseMessage> SendWithNtAuthAsync(HttpRequestMessage request, Uri authUri, ICredentials credentials, bool isProxyAuth, System.Net.Http.HttpConnection connection, System.Net.Http.HttpConnectionPool connectionPool, CancellationToken cancellationToken)
		{
			HttpResponseMessage httpResponseMessage = await InnerSendAsync(request, isProxyAuth, connectionPool, connection, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			if (!isProxyAuth && connection.Kind == System.Net.Http.HttpConnectionKind.Proxy && !ProxySupportsConnectionAuth(httpResponseMessage))
			{
				if (System.Net.NetEventSource.IsEnabled)
				{
					System.Net.NetEventSource.Error(connection, $"Proxy doesn't support connection-based auth, uri={authUri}", "SendWithNtAuthAsync");
				}
				return httpResponseMessage;
			}
			if (TryGetAuthenticationChallenge(httpResponseMessage, isProxyAuth, authUri, credentials, out var challenge) && (challenge.AuthenticationType == AuthenticationType.Negotiate || challenge.AuthenticationType == AuthenticationType.Ntlm))
			{
				throw new NotImplementedException("Windows Authentication is not implemented");
			}
			return httpResponseMessage;
		}

		public static Task<HttpResponseMessage> SendWithNtProxyAuthAsync(HttpRequestMessage request, Uri proxyUri, ICredentials proxyCredentials, System.Net.Http.HttpConnection connection, System.Net.Http.HttpConnectionPool connectionPool, CancellationToken cancellationToken)
		{
			return SendWithNtAuthAsync(request, proxyUri, proxyCredentials, isProxyAuth: true, connection, connectionPool, cancellationToken);
		}

		public static Task<HttpResponseMessage> SendWithNtConnectionAuthAsync(HttpRequestMessage request, ICredentials credentials, System.Net.Http.HttpConnection connection, System.Net.Http.HttpConnectionPool connectionPool, CancellationToken cancellationToken)
		{
			return SendWithNtAuthAsync(request, request.RequestUri, credentials, isProxyAuth: false, connection, connectionPool, cancellationToken);
		}
	}
	internal static class StringBuilderExtensions
	{
		public static void AppendKeyValue(this StringBuilder sb, string key, string value, bool includeQuotes = true, bool includeComma = true)
		{
			sb.Append(key);
			sb.Append('=');
			if (includeQuotes)
			{
				sb.Append('"');
			}
			sb.Append(value);
			if (includeQuotes)
			{
				sb.Append('"');
			}
			if (includeComma)
			{
				sb.Append(',');
				sb.Append(' ');
			}
		}
	}
	internal static class CancellationHelper
	{
		private static readonly string s_cancellationMessage = new OperationCanceledException().Message;

		internal static bool ShouldWrapInOperationCanceledException(Exception exception, CancellationToken cancellationToken)
		{
			if (!(exception is OperationCanceledException))
			{
				return cancellationToken.IsCancellationRequested;
			}
			return false;
		}

		internal static Exception CreateOperationCanceledException(Exception innerException, CancellationToken cancellationToken)
		{
			return new TaskCanceledException(s_cancellationMessage, innerException, cancellationToken);
		}

		private static void ThrowOperationCanceledException(Exception innerException, CancellationToken cancellationToken)
		{
			throw CreateOperationCanceledException(innerException, cancellationToken);
		}

		internal static void ThrowIfCancellationRequested(CancellationToken cancellationToken)
		{
			if (cancellationToken.IsCancellationRequested)
			{
				ThrowOperationCanceledException(null, cancellationToken);
			}
		}
	}
	internal class HttpConnection : IDisposable
	{
		private sealed class ChunkedEncodingReadStream : HttpContentReadStream
		{
			private enum ParsingState : byte
			{
				ExpectChunkHeader,
				ExpectChunkData,
				ExpectChunkTerminator,
				ConsumeTrailers,
				Done
			}

			private const int MaxChunkBytesAllowed = 16384;

			private const int MaxTrailingHeaderLength = 16384;

			private ulong _chunkBytesRemaining;

			private ParsingState _state;

			public override bool NeedsDrain => _connection != null;

			public ChunkedEncodingReadStream(System.Net.Http.HttpConnection connection)
				: base(connection)
			{
			}

			public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
			{
				System.Net.Http.HttpContentStream.ValidateBufferArgs(buffer, offset, count);
				return ReadAsyncInternal(new Memory<byte>(buffer, offset, count), cancellationToken);
			}

			private Task<int> ReadAsyncInternal(Memory<byte> buffer, CancellationToken cancellationToken)
			{
				if (cancellationToken.IsCancellationRequested)
				{
					return Task.FromCanceled<int>(cancellationToken);
				}
				if (_connection == null || buffer.Length == 0)
				{
					return Task.FromResult(0);
				}
				int num = ReadChunksFromConnectionBuffer(buffer.Span, default(CancellationTokenRegistration), cancellationToken);
				if (num > 0)
				{
					return Task.FromResult(num);
				}
				if (_connection == null)
				{
					return Task.FromResult(0);
				}
				return ReadAsyncCore(buffer, cancellationToken);
			}

			private async Task<int> ReadAsyncCore(Memory<byte> buffer, CancellationToken cancellationToken)
			{
				CancellationTokenRegistration ctr = _connection.RegisterCancellation(cancellationToken);
				try
				{
					int num2;
					do
					{
						if (_connection == null)
						{
							return 0;
						}
						if (_state == ParsingState.ExpectChunkData && buffer.Length >= _connection.ReadBufferSize && _chunkBytesRemaining >= (ulong)_connection.ReadBufferSize)
						{
							int num = await _connection.ReadAsync(buffer.Slice(0, (int)Math.Min((ulong)buffer.Length, _chunkBytesRemaining))).ConfigureAwait(continueOnCapturedContext: false);
							if (num == 0)
							{
								throw new IOException(SR.net_http_invalid_response);
							}
							_chunkBytesRemaining -= (ulong)num;
							if (_chunkBytesRemaining == 0L)
							{
								_state = ParsingState.ExpectChunkTerminator;
							}
							return num;
						}
						await _connection.FillAsync().ConfigureAwait(continueOnCapturedContext: false);
						num2 = ReadChunksFromConnectionBuffer(buffer.Span, ctr, cancellationToken);
					}
					while (num2 <= 0);
					return num2;
				}
				catch (Exception ex) when (System.Net.Http.CancellationHelper.ShouldWrapInOperationCanceledException(ex, cancellationToken))
				{
					throw System.Net.Http.CancellationHelper.CreateOperationCanceledException(ex, cancellationToken);
				}
				finally
				{
					ctr.Dispose();
				}
			}

			public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
			{
				System.Net.Http.HttpContentStream.ValidateCopyToArgs(this, destination, bufferSize);
				if (!cancellationToken.IsCancellationRequested)
				{
					if (_connection != null)
					{
						return CopyToAsyncCore(destination, cancellationToken);
					}
					return Task.CompletedTask;
				}
				return Task.FromCanceled(cancellationToken);
			}

			private async Task CopyToAsyncCore(Stream destination, CancellationToken cancellationToken)
			{
				CancellationTokenRegistration ctr = _connection.RegisterCancellation(cancellationToken);
				try
				{
					while (true)
					{
						ReadOnlyMemory<byte> buffer = ReadChunkFromConnectionBuffer(int.MaxValue, ctr, cancellationToken);
						if (buffer.Length != 0)
						{
							await destination.WriteAsync(buffer, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
							continue;
						}
						if (_connection == null)
						{
							break;
						}
						await _connection.FillAsync().ConfigureAwait(continueOnCapturedContext: false);
					}
				}
				catch (Exception ex) when (System.Net.Http.CancellationHelper.ShouldWrapInOperationCanceledException(ex, cancellationToken))
				{
					throw System.Net.Http.CancellationHelper.CreateOperationCanceledException(ex, cancellationToken);
				}
				finally
				{
					ctr.Dispose();
				}
			}

			private int ReadChunksFromConnectionBuffer(Span<byte> buffer, CancellationTokenRegistration cancellationRegistration, CancellationToken cancellationToken)
			{
				int num = 0;
				while (buffer.Length > 0)
				{
					ReadOnlyMemory<byte> readOnlyMemory = ReadChunkFromConnectionBuffer(buffer.Length, cancellationRegistration, cancellationToken);
					if (readOnlyMemory.Length == 0)
					{
						break;
					}
					num += readOnlyMemory.Length;
					readOnlyMemory.Span.CopyTo(buffer);
					buffer = buffer.Slice(readOnlyMemory.Length);
				}
				return num;
			}

			private ReadOnlyMemory<byte> ReadChunkFromConnectionBuffer(int maxBytesToRead, CancellationTokenRegistration cancellationRegistration, CancellationToken cancellationToken = default(CancellationToken))
			{
				try
				{
					ReadOnlySpan<byte> line;
					switch (_state)
					{
					case ParsingState.ExpectChunkHeader:
					{
						_connection._allowedReadLineBytes = 16384;
						if (!_connection.TryReadNextLine(out line))
						{
							return default(ReadOnlyMemory<byte>);
						}
						if (!Utf8Parser.TryParse(line, out ulong value, out int bytesConsumed, 'X'))
						{
							throw new IOException(SR.net_http_invalid_response);
						}
						_chunkBytesRemaining = value;
						if (bytesConsumed != line.Length)
						{
							ValidateChunkExtension(line.Slice(bytesConsumed));
						}
						if (value != 0)
						{
							_state = ParsingState.ExpectChunkData;
							goto case ParsingState.ExpectChunkData;
						}
						_state = ParsingState.ConsumeTrailers;
						goto case ParsingState.ConsumeTrailers;
					}
					case ParsingState.ExpectChunkData:
					{
						ReadOnlyMemory<byte> remainingBuffer = _connection.RemainingBuffer;
						if (remainingBuffer.Length == 0)
						{
							return default(ReadOnlyMemory<byte>);
						}
						int num = Math.Min(maxBytesToRead, (int)Math.Min((ulong)remainingBuffer.Length, _chunkBytesRemaining));
						_connection.ConsumeFromRemainingBuffer(num);
						_chunkBytesRemaining -= (ulong)num;
						if (_chunkBytesRemaining == 0L)
						{
							_state = ParsingState.ExpectChunkTerminator;
						}
						return remainingBuffer.Slice(0, num);
					}
					case ParsingState.ExpectChunkTerminator:
						_connection._allowedReadLineBytes = 16384;
						if (!_connection.TryReadNextLine(out line))
						{
							return default(ReadOnlyMemory<byte>);
						}
						if (line.Length != 0)
						{
							ThrowInvalidHttpResponse();
						}
						_state = ParsingState.ExpectChunkHeader;
						goto case ParsingState.ExpectChunkHeader;
					case ParsingState.ConsumeTrailers:
						while (true)
						{
							_connection._allowedReadLineBytes = 16384;
							if (!_connection.TryReadNextLine(out line))
							{
								break;
							}
							if (line.IsEmpty)
							{
								cancellationRegistration.Dispose();
								System.Net.Http.CancellationHelper.ThrowIfCancellationRequested(cancellationToken);
								_state = ParsingState.Done;
								_connection.CompleteResponse();
								_connection = null;
								break;
							}
						}
						return default(ReadOnlyMemory<byte>);
					default:
						if (System.Net.NetEventSource.IsEnabled)
						{
							System.Net.NetEventSource.Error(this, $"Unexpected state: {_state}", "ReadChunkFromConnectionBuffer");
						}
						return default(ReadOnlyMemory<byte>);
					}
				}
				catch (Exception)
				{
					_connection.Dispose();
					_connection = null;
					throw;
				}
			}

			private static void ValidateChunkExtension(ReadOnlySpan<byte> lineAfterChunkSize)
			{
				for (int i = 0; i < lineAfterChunkSize.Length; i++)
				{
					switch (lineAfterChunkSize[i])
					{
					case 9:
					case 32:
						continue;
					case 59:
						return;
					}
					throw new IOException(SR.net_http_invalid_response);
				}
			}

			public override async Task<bool> DrainAsync(int maxDrainBytes)
			{
				CancellationTokenSource cts = null;
				CancellationTokenRegistration ctr = default(CancellationTokenRegistration);
				try
				{
					int drainedBytes = 0;
					while (true)
					{
						drainedBytes += _connection.RemainingBuffer.Length;
						while (ReadChunkFromConnectionBuffer(int.MaxValue, ctr).Length != 0)
						{
						}
						if (_connection == null)
						{
							return true;
						}
						if (drainedBytes >= maxDrainBytes)
						{
							break;
						}
						if (cts == null)
						{
							TimeSpan maxResponseDrainTime = _connection._pool.Settings._maxResponseDrainTime;
							if (maxResponseDrainTime != Timeout.InfiniteTimeSpan)
							{
								cts = new CancellationTokenSource((int)maxResponseDrainTime.TotalMilliseconds);
								ctr = cts.Token.Register(delegate(object s)
								{
									((System.Net.Http.HttpConnection)s).Dispose();
								}, _connection);
							}
						}
						await _connection.FillAsync().ConfigureAwait(continueOnCapturedContext: false);
					}
					return false;
				}
				finally
				{
					ctr.Dispose();
					cts?.Dispose();
				}
			}
		}

		private sealed class ChunkedEncodingWriteStream : HttpContentWriteStream
		{
			private static readonly byte[] s_finalChunkBytes = new byte[5] { 48, 13, 10, 13, 10 };

			public ChunkedEncodingWriteStream(System.Net.Http.HttpConnection connection)
				: base(connection)
			{
			}

			public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken ignored)
			{
				return WriteAsyncInternal(new ReadOnlyMemory<byte>(buffer, offset, count), ignored);
			}

			private Task WriteAsyncInternal(ReadOnlyMemory<byte> buffer, CancellationToken ignored)
			{
				if (buffer.Length != 0)
				{
					return WriteChunkAsync(buffer);
				}
				return _connection.FlushAsync();
			}

			private async Task WriteChunkAsync(ReadOnlyMemory<byte> buffer)
			{
				await _connection.WriteHexInt32Async(buffer.Length).ConfigureAwait(continueOnCapturedContext: false);
				await _connection.WriteTwoBytesAsync(13, 10).ConfigureAwait(continueOnCapturedContext: false);
				await _connection.WriteAsync(buffer).ConfigureAwait(continueOnCapturedContext: false);
				await _connection.WriteTwoBytesAsync(13, 10).ConfigureAwait(continueOnCapturedContext: false);
			}

			public override async Task FinishAsync()
			{
				await _connection.WriteBytesAsync(s_finalChunkBytes).ConfigureAwait(continueOnCapturedContext: false);
				_connection = null;
			}
		}

		private sealed class ConnectionCloseReadStream : HttpContentReadStream
		{
			public ConnectionCloseReadStream(System.Net.Http.HttpConnection connection)
				: base(connection)
			{
			}

			public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
			{
				System.Net.Http.HttpContentStream.ValidateBufferArgs(buffer, offset, count);
				return ReadAsyncInternal(new Memory<byte>(buffer, offset, count), cancellationToken);
			}

			private async Task<int> ReadAsyncInternal(Memory<byte> buffer, CancellationToken cancellationToken)
			{
				System.Net.Http.CancellationHelper.ThrowIfCancellationRequested(cancellationToken);
				if (_connection == null || buffer.Length == 0)
				{
					return 0;
				}
				Task<int> task = _connection.ReadAsync(buffer);
				int num;
				if (task.IsCompletedSuccessfully())
				{
					num = task.Result;
				}
				else
				{
					CancellationTokenRegistration ctr = _connection.RegisterCancellation(cancellationToken);
					try
					{
						num = await task.ConfigureAwait(continueOnCapturedContext: false);
					}
					catch (Exception ex) when (System.Net.Http.CancellationHelper.ShouldWrapInOperationCanceledException(ex, cancellationToken))
					{
						throw System.Net.Http.CancellationHelper.CreateOperationCanceledException(ex, cancellationToken);
					}
					finally
					{
						ctr.Dispose();
					}