Decompiled source of EverScapeMMORPG v1.2.4

config/ServerCharacters-master/ServerCharacters/Libs/ServerSync.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ServerSync")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ServerSync")]
[assembly: AssemblyCopyright("Copyright ยฉ 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("E16C3332-50B4-4DA6-9E8A-A590C4E5CD49")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 ServerSync
{
	[PublicAPI]
	public abstract class OwnConfigEntryBase
	{
		public object? LocalBaseValue;

		public bool SynchronizedConfig = true;

		public abstract ConfigEntryBase BaseConfig { get; }
	}
	[PublicAPI]
	public class SyncedConfigEntry<T> : OwnConfigEntryBase
	{
		public readonly ConfigEntry<T> SourceConfig;

		public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig;

		public T Value
		{
			get
			{
				return SourceConfig.Value;
			}
			set
			{
				SourceConfig.Value = value;
			}
		}

		public SyncedConfigEntry(ConfigEntry<T> sourceConfig)
		{
			SourceConfig = sourceConfig;
		}

		public void AssignLocalValue(T value)
		{
			if (LocalBaseValue == null)
			{
				Value = value;
			}
			else
			{
				LocalBaseValue = value;
			}
		}
	}
	public abstract class CustomSyncedValueBase
	{
		public object? LocalBaseValue;

		public readonly string Identifier;

		public readonly Type Type;

		private object? boxedValue;

		protected bool localIsOwner;

		public readonly int Priority;

		public object? BoxedValue
		{
			get
			{
				return boxedValue;
			}
			set
			{
				boxedValue = value;
				this.ValueChanged?.Invoke();
			}
		}

		public event Action? ValueChanged;

		protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority)
		{
			Priority = priority;
			Identifier = identifier;
			Type = type;
			configSync.AddCustomValue(this);
			localIsOwner = configSync.IsSourceOfTruth;
			configSync.SourceOfTruthChanged += delegate(bool truth)
			{
				localIsOwner = truth;
			};
		}
	}
	[PublicAPI]
	public sealed class CustomSyncedValue<T> : CustomSyncedValueBase
	{
		public T Value
		{
			get
			{
				return (T)base.BoxedValue;
			}
			set
			{
				base.BoxedValue = value;
			}
		}

		public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0)
			: base(configSync, identifier, typeof(T), priority)
		{
			Value = value;
		}

		public void AssignLocalValue(T value)
		{
			if (localIsOwner)
			{
				Value = value;
			}
			else
			{
				LocalBaseValue = value;
			}
		}
	}
	internal class ConfigurationManagerAttributes
	{
		[UsedImplicitly]
		public bool? ReadOnly = false;
	}
	[PublicAPI]
	public class ConfigSync
	{
		[HarmonyPatch(typeof(ZRpc), "HandlePackage")]
		private static class SnatchCurrentlyHandlingRPC
		{
			public static ZRpc? currentRpc;

			[HarmonyPrefix]
			private static void Prefix(ZRpc __instance)
			{
				currentRpc = __instance;
			}
		}

		[HarmonyPatch(typeof(ZNet), "Awake")]
		internal static class RegisterRPCPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ZNet __instance)
			{
				isServer = __instance.IsServer();
				foreach (ConfigSync configSync2 in configSyncs)
				{
					ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync);
					if (isServer)
					{
						configSync2.InitialSyncDone = true;
						Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections"));
					}
				}
				if (isServer)
				{
					((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges());
				}
				static void SendAdmin(List<ZNetPeer> peers, bool isAdmin)
				{
					ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1]
					{
						new PackageEntry
						{
							section = "Internal",
							key = "lockexempt",
							type = typeof(bool),
							value = isAdmin
						}
					});
					ConfigSync configSync = configSyncs.First();
					if (configSync != null)
					{
						((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package));
					}
				}
				static IEnumerator WatchAdminListChanges()
				{
					MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
					SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
					List<string> CurrentList = new List<string>(adminList.GetList());
					while (true)
					{
						yield return (object)new WaitForSeconds(30f);
						if (!adminList.GetList().SequenceEqual(CurrentList))
						{
							CurrentList = new List<string>(adminList.GetList());
							List<ZNetPeer> adminPeer = ZNet.instance.GetPeers().Where(delegate(ZNetPeer p)
							{
								string hostName = p.m_rpc.GetSocket().GetHostName();
								return ((object)listContainsId == null) ? adminList.Contains(hostName) : ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName }));
							}).ToList();
							List<ZNetPeer> nonAdminPeer = ZNet.instance.GetPeers().Except(adminPeer).ToList();
							SendAdmin(nonAdminPeer, isAdmin: false);
							SendAdmin(adminPeer, isAdmin: true);
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		private static class RegisterClientRPCPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ZNet __instance, ZNetPeer peer)
			{
				if (__instance.IsServer())
				{
					return;
				}
				foreach (ConfigSync configSync in configSyncs)
				{
					peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync);
				}
			}
		}

		private class ParsedConfigs
		{
			public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>();

			public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>();
		}

		[HarmonyPatch(typeof(ZNet), "Shutdown")]
		private class ResetConfigsOnShutdown
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				ProcessingServerUpdate = true;
				foreach (ConfigSync configSync in configSyncs)
				{
					configSync.resetConfigsFromServer();
					configSync.IsSourceOfTruth = true;
					configSync.InitialSyncDone = false;
				}
				ProcessingServerUpdate = false;
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		private class SendConfigsAfterLogin
		{
			private class BufferingSocket : ISocket
			{
				public volatile bool finished = false;

				public volatile int versionMatchQueued = -1;

				public readonly List<ZPackage> Package = new List<ZPackage>();

				public readonly ISocket Original;

				public BufferingSocket(ISocket original)
				{
					Original = original;
				}

				public bool IsConnected()
				{
					return Original.IsConnected();
				}

				public ZPackage Recv()
				{
					return Original.Recv();
				}

				public int GetSendQueueSize()
				{
					return Original.GetSendQueueSize();
				}

				public int GetCurrentSendRate()
				{
					return Original.GetCurrentSendRate();
				}

				public bool IsHost()
				{
					return Original.IsHost();
				}

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

				public bool GotNewData()
				{
					return Original.GotNewData();
				}

				public void Close()
				{
					Original.Close();
				}

				public string GetEndPointString()
				{
					return Original.GetEndPointString();
				}

				public void GetAndResetStats(out int totalSent, out int totalRecv)
				{
					Original.GetAndResetStats(ref totalSent, ref totalRecv);
				}

				public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec)
				{
					Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec);
				}

				public ISocket Accept()
				{
					return Original.Accept();
				}

				public int GetHostPort()
				{
					return Original.GetHostPort();
				}

				public bool Flush()
				{
					return Original.Flush();
				}

				public string GetHostName()
				{
					return Original.GetHostName();
				}

				public void VersionMatch()
				{
					if (finished)
					{
						Original.VersionMatch();
					}
					else
					{
						versionMatchQueued = Package.Count;
					}
				}

				public void Send(ZPackage pkg)
				{
					//IL_0057: Unknown result type (might be due to invalid IL or missing references)
					//IL_005d: Expected O, but got Unknown
					int pos = pkg.GetPos();
					pkg.SetPos(0);
					int num = pkg.ReadInt();
					if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished)
					{
						ZPackage val = new ZPackage(pkg.GetArray());
						val.SetPos(pos);
						Package.Add(val);
					}
					else
					{
						pkg.SetPos(pos);
						Original.Send(pkg);
					}
				}
			}

			[HarmonyPriority(800)]
			[HarmonyPrefix]
			private static void Prefix(ref Dictionary<Assembly, BufferingSocket>? __state, ZNet __instance, ZRpc rpc)
			{
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Invalid comparison between Unknown and I4
				if (__instance.IsServer())
				{
					BufferingSocket value = new BufferingSocket(rpc.GetSocket());
					AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, value);
					object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc });
					ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
					if (val != null && (int)ZNet.m_onlineBackend > 0)
					{
						AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, value);
					}
					if (__state == null)
					{
						__state = new Dictionary<Assembly, BufferingSocket>();
					}
					__state[Assembly.GetExecutingAssembly()] = value;
				}
			}

			[HarmonyPostfix]
			private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc)
			{
				ZRpc rpc2 = rpc;
				ZNet __instance2 = __instance;
				Dictionary<Assembly, BufferingSocket> __state2 = __state;
				ZNetPeer peer;
				if (__instance2.IsServer())
				{
					object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 });
					peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
					if (peer == null)
					{
						SendBufferedData();
					}
					else
					{
						((MonoBehaviour)__instance2).StartCoroutine(sendAsync());
					}
				}
				void SendBufferedData()
				{
					if (rpc2.GetSocket() is BufferingSocket bufferingSocket)
					{
						AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc2, bufferingSocket.Original);
						object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance2, new object[1] { rpc2 });
						ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null);
						if (val != null)
						{
							AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original);
						}
					}
					BufferingSocket bufferingSocket2 = __state2[Assembly.GetExecutingAssembly()];
					bufferingSocket2.finished = true;
					for (int i = 0; i < bufferingSocket2.Package.Count; i++)
					{
						if (i == bufferingSocket2.versionMatchQueued)
						{
							bufferingSocket2.Original.VersionMatch();
						}
						bufferingSocket2.Original.Send(bufferingSocket2.Package[i]);
					}
					if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued)
					{
						bufferingSocket2.Original.VersionMatch();
					}
				}
				IEnumerator sendAsync()
				{
					foreach (ConfigSync configSync in configSyncs)
					{
						List<PackageEntry> entries = new List<PackageEntry>();
						if (configSync.CurrentVersion != null)
						{
							entries.Add(new PackageEntry
							{
								section = "Internal",
								key = "serverversion",
								type = typeof(string),
								value = configSync.CurrentVersion
							});
						}
						MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
						SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
						entries.Add(new PackageEntry
						{
							section = "Internal",
							key = "lockexempt",
							type = typeof(bool),
							value = (((object)listContainsId == null) ? ((object)adminList.Contains(rpc2.GetSocket().GetHostName())) : listContainsId.Invoke(ZNet.instance, new object[2]
							{
								adminList,
								rpc2.GetSocket().GetHostName()
							}))
						});
						ZPackage package = ConfigsToPackage(configSync.allConfigs.Select((OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, entries, partial: false);
						yield return ((MonoBehaviour)__instance2).StartCoroutine(configSync.sendZPackage(new List<ZNetPeer> { peer }, package));
					}
					SendBufferedData();
				}
			}
		}

		private class PackageEntry
		{
			public string section = null;

			public string key = null;

			public Type type = null;

			public object? value;
		}

		[HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")]
		private static class PreventSavingServerInfo
		{
			[HarmonyPrefix]
			private static bool Prefix(ConfigEntryBase __instance, ref string __result)
			{
				OwnConfigEntryBase ownConfigEntryBase = configData(__instance);
				if (ownConfigEntryBase == null || isWritableConfig(ownConfigEntryBase))
				{
					return true;
				}
				__result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType);
				return false;
			}
		}

		[HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")]
		private static class PreventConfigRereadChangingValues
		{
			[HarmonyPrefix]
			private static bool Prefix(ConfigEntryBase __instance, string value)
			{
				OwnConfigEntryBase ownConfigEntryBase = configData(__instance);
				if (ownConfigEntryBase == null || ownConfigEntryBase.LocalBaseValue == null)
				{
					return true;
				}
				try
				{
					ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType);
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)$"Config value of setting \"{__instance.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}");
				}
				return false;
			}
		}

		private class InvalidDeserializationTypeException : Exception
		{
			public string expected = null;

			public string received = null;

			public string field = "";
		}

		public static bool ProcessingServerUpdate;

		public readonly string Name;

		public string? DisplayName;

		public string? CurrentVersion;

		public string? MinimumRequiredVersion;

		public bool ModRequired = false;

		private bool? forceConfigLocking;

		private bool isSourceOfTruth = true;

		private static readonly HashSet<ConfigSync> configSyncs;

		private readonly HashSet<OwnConfigEntryBase> allConfigs = new HashSet<OwnConfigEntryBase>();

		private HashSet<CustomSyncedValueBase> allCustomValues = new HashSet<CustomSyncedValueBase>();

		private static bool isServer;

		private static bool lockExempt;

		private OwnConfigEntryBase? lockedConfig = null;

		private const byte PARTIAL_CONFIGS = 1;

		private const byte FRAGMENTED_CONFIG = 2;

		private const byte COMPRESSED_CONFIG = 4;

		private readonly Dictionary<string, SortedDictionary<int, byte[]>> configValueCache = new Dictionary<string, SortedDictionary<int, byte[]>>();

		private readonly List<KeyValuePair<long, string>> cacheExpirations = new List<KeyValuePair<long, string>>();

		private static long packageCounter;

		public bool IsLocked
		{
			get
			{
				bool? flag = forceConfigLocking;
				bool num;
				if (!flag.HasValue)
				{
					if (lockedConfig == null)
					{
						goto IL_0052;
					}
					num = ((IConvertible)lockedConfig.BaseConfig.BoxedValue).ToInt32(CultureInfo.InvariantCulture) != 0;
				}
				else
				{
					num = flag.GetValueOrDefault();
				}
				if (!num)
				{
					goto IL_0052;
				}
				int result = ((!lockExempt) ? 1 : 0);
				goto IL_0053;
				IL_0053:
				return (byte)result != 0;
				IL_0052:
				result = 0;
				goto IL_0053;
			}
			set
			{
				forceConfigLocking = value;
			}
		}

		public bool IsAdmin => lockExempt || isSourceOfTruth;

		public bool IsSourceOfTruth
		{
			get
			{
				return isSourceOfTruth;
			}
			private set
			{
				if (value != isSourceOfTruth)
				{
					isSourceOfTruth = value;
					this.SourceOfTruthChanged?.Invoke(value);
				}
			}
		}

		public bool InitialSyncDone { get; private set; } = false;


		public event Action<bool>? SourceOfTruthChanged;

		private event Action? lockedConfigChanged;

		static ConfigSync()
		{
			ProcessingServerUpdate = false;
			configSyncs = new HashSet<ConfigSync>();
			lockExempt = false;
			packageCounter = 0L;
			RuntimeHelpers.RunClassConstructor(typeof(VersionCheck).TypeHandle);
		}

		public ConfigSync(string name)
		{
			Name = name;
			configSyncs.Add(this);
			new VersionCheck(this);
		}

		public SyncedConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry)
		{
			ConfigEntry<T> configEntry2 = configEntry;
			OwnConfigEntryBase ownConfigEntryBase = configData((ConfigEntryBase)(object)configEntry2);
			SyncedConfigEntry<T> syncedEntry = ownConfigEntryBase as SyncedConfigEntry<T>;
			if (syncedEntry == null)
			{
				syncedEntry = new SyncedConfigEntry<T>(configEntry2);
				AccessTools.DeclaredField(typeof(ConfigDescription), "<Tags>k__BackingField").SetValue(((ConfigEntryBase)configEntry2).Description, new object[1]
				{
					new ConfigurationManagerAttributes()
				}.Concat(((ConfigEntryBase)configEntry2).Description.Tags ?? Array.Empty<object>()).Concat(new SyncedConfigEntry<T>[1] { syncedEntry }).ToArray());
				configEntry2.SettingChanged += delegate
				{
					if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig)
					{
						Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)configEntry2);
					}
				};
				allConfigs.Add(syncedEntry);
			}
			return syncedEntry;
		}

		public SyncedConfigEntry<T> AddLockingConfigEntry<T>(ConfigEntry<T> lockingConfig) where T : IConvertible
		{
			if (lockedConfig != null)
			{
				throw new Exception("Cannot initialize locking ConfigEntry twice");
			}
			lockedConfig = AddConfigEntry<T>(lockingConfig);
			lockingConfig.SettingChanged += delegate
			{
				this.lockedConfigChanged?.Invoke();
			};
			return (SyncedConfigEntry<T>)lockedConfig;
		}

		internal void AddCustomValue(CustomSyncedValueBase customValue)
		{
			CustomSyncedValueBase customValue2 = customValue;
			if (allCustomValues.Select((CustomSyncedValueBase v) => v.Identifier).Concat(new string[1] { "serverversion" }).Contains(customValue2.Identifier))
			{
				throw new Exception("Cannot have multiple settings with the same name or with a reserved name (serverversion)");
			}
			allCustomValues.Add(customValue2);
			allCustomValues = new HashSet<CustomSyncedValueBase>(allCustomValues.OrderByDescending((CustomSyncedValueBase v) => v.Priority));
			customValue2.ValueChanged += delegate
			{
				if (!ProcessingServerUpdate)
				{
					Broadcast(ZRoutedRpc.Everybody, customValue2);
				}
			};
		}

		private void RPC_FromServerConfigSync(ZRpc rpc, ZPackage package)
		{
			lockedConfigChanged += serverLockedSettingChanged;
			IsSourceOfTruth = false;
			if (HandleConfigSyncRPC(0L, package, clientUpdate: false))
			{
				InitialSyncDone = true;
			}
		}

		private void RPC_FromOtherClientConfigSync(long sender, ZPackage package)
		{
			HandleConfigSyncRPC(sender, package, clientUpdate: true);
		}

		private bool HandleConfigSyncRPC(long sender, ZPackage package, bool clientUpdate)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Expected O, but got Unknown
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			try
			{
				if (isServer && IsLocked)
				{
					ZRpc? currentRpc = SnatchCurrentlyHandlingRPC.currentRpc;
					object obj;
					if (currentRpc == null)
					{
						obj = null;
					}
					else
					{
						ISocket socket = currentRpc.GetSocket();
						obj = ((socket != null) ? socket.GetHostName() : null);
					}
					string text = (string)obj;
					if (text != null)
					{
						MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
						SyncedList val = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
						if (!(((object)methodInfo == null) ? val.Contains(text) : ((bool)methodInfo.Invoke(ZNet.instance, new object[2] { val, text }))))
						{
							return false;
						}
					}
				}
				cacheExpirations.RemoveAll(delegate(KeyValuePair<long, string> kv)
				{
					if (kv.Key < DateTimeOffset.Now.Ticks)
					{
						configValueCache.Remove(kv.Value);
						return true;
					}
					return false;
				});
				byte b = package.ReadByte();
				if ((b & 2u) != 0)
				{
					long num = package.ReadLong();
					string text2 = sender.ToString() + num;
					if (!configValueCache.TryGetValue(text2, out SortedDictionary<int, byte[]> value))
					{
						value = new SortedDictionary<int, byte[]>();
						configValueCache[text2] = value;
						cacheExpirations.Add(new KeyValuePair<long, string>(DateTimeOffset.Now.AddSeconds(60.0).Ticks, text2));
					}
					int key = package.ReadInt();
					int num2 = package.ReadInt();
					value.Add(key, package.ReadByteArray());
					if (value.Count < num2)
					{
						return false;
					}
					configValueCache.Remove(text2);
					package = new ZPackage(value.Values.SelectMany((byte[] a) => a).ToArray());
					b = package.ReadByte();
				}
				ProcessingServerUpdate = true;
				if ((b & 4u) != 0)
				{
					byte[] buffer = package.ReadByteArray();
					MemoryStream stream = new MemoryStream(buffer);
					MemoryStream memoryStream = new MemoryStream();
					using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress))
					{
						deflateStream.CopyTo(memoryStream);
					}
					package = new ZPackage(memoryStream.ToArray());
					b = package.ReadByte();
				}
				if ((b & 1) == 0)
				{
					resetConfigsFromServer();
				}
				ParsedConfigs parsedConfigs = ReadConfigsFromPackage(package);
				ConfigFile val2 = null;
				bool saveOnConfigSet = false;
				foreach (KeyValuePair<OwnConfigEntryBase, object> configValue in parsedConfigs.configValues)
				{
					if (!isServer && configValue.Key.LocalBaseValue == null)
					{
						configValue.Key.LocalBaseValue = configValue.Key.BaseConfig.BoxedValue;
					}
					if (val2 == null)
					{
						val2 = configValue.Key.BaseConfig.ConfigFile;
						saveOnConfigSet = val2.SaveOnConfigSet;
						val2.SaveOnConfigSet = false;
					}
					configValue.Key.BaseConfig.BoxedValue = configValue.Value;
				}
				if (val2 != null)
				{
					val2.SaveOnConfigSet = saveOnConfigSet;
				}
				foreach (KeyValuePair<CustomSyncedValueBase, object> customValue in parsedConfigs.customValues)
				{
					if (!isServer)
					{
						CustomSyncedValueBase key2 = customValue.Key;
						if (key2.LocalBaseValue == null)
						{
							key2.LocalBaseValue = customValue.Key.BoxedValue;
						}
					}
					customValue.Key.BoxedValue = customValue.Value;
				}
				Debug.Log((object)string.Format("Received {0} configs and {1} custom values from {2} for mod {3}", parsedConfigs.configValues.Count, parsedConfigs.customValues.Count, (isServer || clientUpdate) ? $"client {sender}" : "the server", DisplayName ?? Name));
				if (!isServer)
				{
					serverLockedSettingChanged();
				}
				return true;
			}
			finally
			{
				ProcessingServerUpdate = false;
			}
		}

		private ParsedConfigs ReadConfigsFromPackage(ZPackage package)
		{
			ParsedConfigs parsedConfigs = new ParsedConfigs();
			Dictionary<string, OwnConfigEntryBase> dictionary = allConfigs.Where((OwnConfigEntryBase c) => c.SynchronizedConfig).ToDictionary((OwnConfigEntryBase c) => c.BaseConfig.Definition.Section + "_" + c.BaseConfig.Definition.Key, (OwnConfigEntryBase c) => c);
			Dictionary<string, CustomSyncedValueBase> dictionary2 = allCustomValues.ToDictionary((CustomSyncedValueBase c) => c.Identifier, (CustomSyncedValueBase c) => c);
			int num = package.ReadInt();
			for (int i = 0; i < num; i++)
			{
				string text = package.ReadString();
				string text2 = package.ReadString();
				string text3 = package.ReadString();
				Type type = Type.GetType(text3);
				if (text3 == "" || type != null)
				{
					object obj;
					try
					{
						obj = ((text3 == "") ? null : ReadValueWithTypeFromZPackage(package, type));
					}
					catch (InvalidDeserializationTypeException ex)
					{
						Debug.LogWarning((object)("Got unexpected struct internal type " + ex.received + " for field " + ex.field + " struct " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + ex.expected));
						continue;
					}
					OwnConfigEntryBase value2;
					if (text == "Internal")
					{
						CustomSyncedValueBase value;
						if (text2 == "serverversion")
						{
							if (obj?.ToString() != CurrentVersion)
							{
								Debug.LogWarning((object)("Received server version is not equal: server version = " + (obj?.ToString() ?? "null") + "; local version = " + (CurrentVersion ?? "unknown")));
							}
						}
						else if (text2 == "lockexempt")
						{
							if (obj is bool flag)
							{
								lockExempt = flag;
							}
						}
						else if (dictionary2.TryGetValue(text2, out value))
						{
							if ((text3 == "" && (!value.Type.IsValueType || Nullable.GetUnderlyingType(value.Type) != null)) || GetZPackageTypeString(value.Type) == text3)
							{
								parsedConfigs.customValues[value] = obj;
								continue;
							}
							Debug.LogWarning((object)("Got unexpected type " + text3 + " for internal value " + text2 + " for mod " + (DisplayName ?? Name) + ", expecting " + value.Type.AssemblyQualifiedName));
						}
					}
					else if (dictionary.TryGetValue(text + "_" + text2, out value2))
					{
						Type type2 = configType(value2.BaseConfig);
						if ((text3 == "" && (!type2.IsValueType || Nullable.GetUnderlyingType(type2) != null)) || GetZPackageTypeString(type2) == text3)
						{
							parsedConfigs.configValues[value2] = obj;
							continue;
						}
						Debug.LogWarning((object)("Got unexpected type " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + type2.AssemblyQualifiedName));
					}
					else
					{
						Debug.LogWarning((object)("Received unknown config entry " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ". This may happen if client and server versions of the mod do not match."));
					}
					continue;
				}
				Debug.LogWarning((object)("Got invalid type " + text3 + ", abort reading of received configs"));
				return new ParsedConfigs();
			}
			return parsedConfigs;
		}

		private static bool isWritableConfig(OwnConfigEntryBase config)
		{
			OwnConfigEntryBase config2 = config;
			ConfigSync configSync = configSyncs.FirstOrDefault((ConfigSync cs) => cs.allConfigs.Contains(config2));
			if (configSync == null)
			{
				return true;
			}
			return configSync.IsSourceOfTruth || !config2.SynchronizedConfig || config2.LocalBaseValue == null || (!configSync.IsLocked && (config2 != configSync.lockedConfig || lockExempt));
		}

		private void serverLockedSettingChanged()
		{
			foreach (OwnConfigEntryBase allConfig in allConfigs)
			{
				configAttribute<ConfigurationManagerAttributes>(allConfig.BaseConfig).ReadOnly = !isWritableConfig(allConfig);
			}
		}

		private void resetConfigsFromServer()
		{
			ConfigFile val = null;
			bool saveOnConfigSet = false;
			foreach (OwnConfigEntryBase item in allConfigs.Where((OwnConfigEntryBase config) => config.LocalBaseValue != null))
			{
				if (val == null)
				{
					val = item.BaseConfig.ConfigFile;
					saveOnConfigSet = val.SaveOnConfigSet;
					val.SaveOnConfigSet = false;
				}
				item.BaseConfig.BoxedValue = item.LocalBaseValue;
				item.LocalBaseValue = null;
			}
			if (val != null)
			{
				val.SaveOnConfigSet = saveOnConfigSet;
			}
			foreach (CustomSyncedValueBase item2 in allCustomValues.Where((CustomSyncedValueBase config) => config.LocalBaseValue != null))
			{
				item2.BoxedValue = item2.LocalBaseValue;
				item2.LocalBaseValue = null;
			}
			lockedConfigChanged -= serverLockedSettingChanged;
			serverLockedSettingChanged();
		}

		private IEnumerator<bool> distributeConfigToPeers(ZNetPeer peer, ZPackage package)
		{
			ZNetPeer peer2 = peer;
			ZRoutedRpc rpc = ZRoutedRpc.instance;
			if (rpc == null)
			{
				yield break;
			}
			byte[] data = package.GetArray();
			if (data != null && data.LongLength > 250000)
			{
				int fragments = (int)(1 + (data.LongLength - 1) / 250000);
				long packageIdentifier = ++packageCounter;
				int fragment = 0;
				while (fragment < fragments)
				{
					foreach (bool item in waitForQueue())
					{
						yield return item;
					}
					if (peer2.m_socket.IsConnected())
					{
						ZPackage fragmentedPackage = new ZPackage();
						fragmentedPackage.Write((byte)2);
						fragmentedPackage.Write(packageIdentifier);
						fragmentedPackage.Write(fragment);
						fragmentedPackage.Write(fragments);
						fragmentedPackage.Write(data.Skip(250000 * fragment).Take(250000).ToArray());
						SendPackage(fragmentedPackage);
						if (fragment != fragments - 1)
						{
							yield return true;
						}
						int num = fragment + 1;
						fragment = num;
						continue;
					}
					break;
				}
				yield break;
			}
			foreach (bool item2 in waitForQueue())
			{
				yield return item2;
			}
			SendPackage(package);
			void SendPackage(ZPackage pkg)
			{
				string text = Name + " ConfigSync";
				if (isServer)
				{
					peer2.m_rpc.Invoke(text, new object[1] { pkg });
				}
				else
				{
					rpc.InvokeRoutedRPC(peer2.m_server ? 0 : peer2.m_uid, text, new object[1] { pkg });
				}
			}
			IEnumerable<bool> waitForQueue()
			{
				float timeout = Time.time + 30f;
				while (peer2.m_socket.GetSendQueueSize() > 20000)
				{
					if (Time.time > timeout)
					{
						Debug.Log((object)$"Disconnecting {peer2.m_uid} after 30 seconds config sending timeout");
						peer2.m_rpc.Invoke("Error", new object[1] { (object)(ConnectionStatus)5 });
						ZNet.instance.Disconnect(peer2);
						break;
					}
					yield return false;
				}
			}
		}

		private IEnumerator sendZPackage(long target, ZPackage package)
		{
			if (!Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return Enumerable.Empty<object>().GetEnumerator();
			}
			List<ZNetPeer> list = (List<ZNetPeer>)AccessTools.DeclaredField(typeof(ZRoutedRpc), "m_peers").GetValue(ZRoutedRpc.instance);
			if (target != ZRoutedRpc.Everybody)
			{
				list = list.Where((ZNetPeer p) => p.m_uid == target).ToList();
			}
			return sendZPackage(list, package);
		}

		private IEnumerator sendZPackage(List<ZNetPeer> peers, ZPackage package)
		{
			ZPackage package2 = package;
			if (!Object.op_Implicit((Object)(object)ZNet.instance))
			{
				yield break;
			}
			byte[] rawData = package2.GetArray();
			if (rawData != null && rawData.LongLength > 10000)
			{
				ZPackage compressedPackage = new ZPackage();
				compressedPackage.Write((byte)4);
				MemoryStream output = new MemoryStream();
				using (DeflateStream deflateStream = new DeflateStream(output, CompressionLevel.Optimal))
				{
					deflateStream.Write(rawData, 0, rawData.Length);
				}
				compressedPackage.Write(output.ToArray());
				package2 = compressedPackage;
			}
			List<IEnumerator<bool>> writers = (from peer in peers
				where peer.IsReady()
				select peer into p
				select distributeConfigToPeers(p, package2)).ToList();
			writers.RemoveAll((IEnumerator<bool> writer) => !writer.MoveNext());
			while (writers.Count > 0)
			{
				yield return null;
				writers.RemoveAll((IEnumerator<bool> writer) => !writer.MoveNext());
			}
		}

		private void Broadcast(long target, params ConfigEntryBase[] configs)
		{
			if (!IsLocked || isServer)
			{
				ZPackage package = ConfigsToPackage(configs);
				ZNet instance = ZNet.instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package));
				}
			}
		}

		private void Broadcast(long target, params CustomSyncedValueBase[] customValues)
		{
			if (!IsLocked || isServer)
			{
				ZPackage package = ConfigsToPackage(null, customValues);
				ZNet instance = ZNet.instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package));
				}
			}
		}

		private static OwnConfigEntryBase? configData(ConfigEntryBase config)
		{
			return config.Description.Tags?.OfType<OwnConfigEntryBase>().SingleOrDefault();
		}

		public static SyncedConfigEntry<T>? ConfigData<T>(ConfigEntry<T> config)
		{
			return ((ConfigEntryBase)config).Description.Tags?.OfType<SyncedConfigEntry<T>>().SingleOrDefault();
		}

		private static T configAttribute<T>(ConfigEntryBase config)
		{
			return config.Description.Tags.OfType<T>().First();
		}

		private static Type configType(ConfigEntryBase config)
		{
			return configType(config.SettingType);
		}

		private static Type configType(Type type)
		{
			return type.IsEnum ? Enum.GetUnderlyingType(type) : type;
		}

		private static ZPackage ConfigsToPackage(IEnumerable<ConfigEntryBase>? configs = null, IEnumerable<CustomSyncedValueBase>? customValues = null, IEnumerable<PackageEntry>? packageEntries = null, bool partial = true)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			List<ConfigEntryBase> list = configs?.Where((ConfigEntryBase config) => configData(config).SynchronizedConfig).ToList() ?? new List<ConfigEntryBase>();
			List<CustomSyncedValueBase> list2 = customValues?.ToList() ?? new List<CustomSyncedValueBase>();
			ZPackage val = new ZPackage();
			val.Write((byte)(partial ? 1 : 0));
			val.Write(list.Count + list2.Count + (packageEntries?.Count() ?? 0));
			foreach (PackageEntry item in packageEntries ?? Array.Empty<PackageEntry>())
			{
				AddEntryToPackage(val, item);
			}
			foreach (CustomSyncedValueBase item2 in list2)
			{
				AddEntryToPackage(val, new PackageEntry
				{
					section = "Internal",
					key = item2.Identifier,
					type = item2.Type,
					value = item2.BoxedValue
				});
			}
			foreach (ConfigEntryBase item3 in list)
			{
				AddEntryToPackage(val, new PackageEntry
				{
					section = item3.Definition.Section,
					key = item3.Definition.Key,
					type = configType(item3),
					value = item3.BoxedValue
				});
			}
			return val;
		}

		private static void AddEntryToPackage(ZPackage package, PackageEntry entry)
		{
			package.Write(entry.section);
			package.Write(entry.key);
			package.Write((entry.value == null) ? "" : GetZPackageTypeString(entry.type));
			AddValueToZPackage(package, entry.value);
		}

		private static string GetZPackageTypeString(Type type)
		{
			return type.AssemblyQualifiedName;
		}

		private static void AddValueToZPackage(ZPackage package, object? value)
		{
			Type type = value?.GetType();
			if (value is Enum)
			{
				value = ((IConvertible)value).ToType(Enum.GetUnderlyingType(value.GetType()), CultureInfo.InvariantCulture);
			}
			else
			{
				if (value is ICollection collection)
				{
					package.Write(collection.Count);
					{
						foreach (object item in collection)
						{
							AddValueToZPackage(package, item);
						}
						return;
					}
				}
				if ((object)type != null && type.IsValueType && !type.IsPrimitive)
				{
					FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					package.Write(fields.Length);
					FieldInfo[] array = fields;
					foreach (FieldInfo fieldInfo in array)
					{
						package.Write(GetZPackageTypeString(fieldInfo.FieldType));
						AddValueToZPackage(package, fieldInfo.GetValue(value));
					}
					return;
				}
			}
			ZRpc.Serialize(new object[1] { value }, ref package);
		}

		private static object ReadValueWithTypeFromZPackage(ZPackage package, Type type)
		{
			if ((object)type != null && type.IsValueType && !type.IsPrimitive && !type.IsEnum)
			{
				FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				int num = package.ReadInt();
				if (num != fields.Length)
				{
					throw new InvalidDeserializationTypeException
					{
						received = $"(field count: {num})",
						expected = $"(field count: {fields.Length})"
					};
				}
				object uninitializedObject = FormatterServices.GetUninitializedObject(type);
				FieldInfo[] array = fields;
				foreach (FieldInfo fieldInfo in array)
				{
					string text = package.ReadString();
					if (text != GetZPackageTypeString(fieldInfo.FieldType))
					{
						throw new InvalidDeserializationTypeException
						{
							received = text,
							expected = GetZPackageTypeString(fieldInfo.FieldType),
							field = fieldInfo.Name
						};
					}
					fieldInfo.SetValue(uninitializedObject, ReadValueWithTypeFromZPackage(package, fieldInfo.FieldType));
				}
				return uninitializedObject;
			}
			if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >))
			{
				int num2 = package.ReadInt();
				IDictionary dictionary = (IDictionary)Activator.CreateInstance(type);
				Type type2 = typeof(KeyValuePair<, >).MakeGenericType(type.GenericTypeArguments);
				FieldInfo field = type2.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic);
				FieldInfo field2 = type2.GetField("value", BindingFlags.Instance | BindingFlags.NonPublic);
				for (int j = 0; j < num2; j++)
				{
					object obj = ReadValueWithTypeFromZPackage(package, type2);
					dictionary.Add(field.GetValue(obj), field2.GetValue(obj));
				}
				return dictionary;
			}
			if (type != typeof(List<string>) && type.IsGenericType)
			{
				Type type3 = typeof(ICollection<>).MakeGenericType(type.GenericTypeArguments[0]);
				if ((object)type3 != null && type3.IsAssignableFrom(type))
				{
					int num3 = package.ReadInt();
					object obj2 = Activator.CreateInstance(type);
					MethodInfo method = type3.GetMethod("Add");
					for (int k = 0; k < num3; k++)
					{
						method.Invoke(obj2, new object[1] { ReadValueWithTypeFromZPackage(package, type.GenericTypeArguments[0]) });
					}
					return obj2;
				}
			}
			ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo));
			AccessTools.DeclaredField(typeof(ParameterInfo), "ClassImpl").SetValue(parameterInfo, type);
			List<object> source = new List<object>();
			ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, package, ref source);
			return source.First();
		}
	}
	[PublicAPI]
	[HarmonyPatch]
	public class VersionCheck
	{
		private static readonly HashSet<VersionCheck> versionChecks;

		private static readonly Dictionary<string, string> notProcessedNames;

		public string Name;

		private string? displayName;

		private string? currentVersion;

		private string? minimumRequiredVersion;

		public bool ModRequired = true;

		private string? ReceivedCurrentVersion;

		private string? ReceivedMinimumRequiredVersion;

		private readonly List<ZRpc> ValidatedClients = new List<ZRpc>();

		private ConfigSync? ConfigSync;

		public string DisplayName
		{
			get
			{
				return displayName ?? Name;
			}
			set
			{
				displayName = value;
			}
		}

		public string CurrentVersion
		{
			get
			{
				return currentVersion ?? "0.0.0";
			}
			set
			{
				currentVersion = value;
			}
		}

		public string MinimumRequiredVersion
		{
			get
			{
				return minimumRequiredVersion ?? (ModRequired ? CurrentVersion : "0.0.0");
			}
			set
			{
				minimumRequiredVersion = value;
			}
		}

		private static void PatchServerSync()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			Patches patchInfo = PatchProcessor.GetPatchInfo((MethodBase)AccessTools.DeclaredMethod(typeof(ZNet), "Awake", (Type[])null, (Type[])null));
			if (patchInfo != null && patchInfo.Postfixes.Count((Patch p) => p.PatchMethod.DeclaringType == typeof(ConfigSync.RegisterRPCPatch)) > 0)
			{
				return;
			}
			Harmony val = new Harmony("org.bepinex.helpers.ServerSync");
			foreach (Type item in from t in typeof(ConfigSync).GetNestedTypes(BindingFlags.NonPublic).Concat(new Type[1] { typeof(VersionCheck) })
				where t.IsClass
				select t)
			{
				val.PatchAll(item);
			}
		}

		static VersionCheck()
		{
			versionChecks = new HashSet<VersionCheck>();
			notProcessedNames = new Dictionary<string, string>();
			typeof(ThreadingHelper).GetMethod("StartSyncInvoke").Invoke(ThreadingHelper.Instance, new object[1]
			{
				new Action(PatchServerSync)
			});
		}

		public VersionCheck(string name)
		{
			Name = name;
			ModRequired = true;
			versionChecks.Add(this);
		}

		public VersionCheck(ConfigSync configSync)
		{
			ConfigSync = configSync;
			Name = ConfigSync.Name;
			versionChecks.Add(this);
		}

		public void Initialize()
		{
			ReceivedCurrentVersion = null;
			ReceivedMinimumRequiredVersion = null;
			if (ConfigSync != null)
			{
				Name = ConfigSync.Name;
				DisplayName = ConfigSync.DisplayName;
				CurrentVersion = ConfigSync.CurrentVersion;
				MinimumRequiredVersion = ConfigSync.MinimumRequiredVersion;
				ModRequired = ConfigSync.ModRequired;
			}
		}

		private bool IsVersionOk()
		{
			if (ReceivedMinimumRequiredVersion == null || ReceivedCurrentVersion == null)
			{
				return !ModRequired;
			}
			bool flag = new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion);
			bool flag2 = new Version(ReceivedCurrentVersion) >= new Version(MinimumRequiredVersion);
			return flag && flag2;
		}

		private string ErrorClient()
		{
			if (ReceivedMinimumRequiredVersion == null)
			{
				return DisplayName + " is not installed on the server.";
			}
			return (new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion)) ? (DisplayName + " may not be higher than version " + ReceivedCurrentVersion + ". You have version " + CurrentVersion + ".") : (DisplayName + " needs to be at least version " + ReceivedMinimumRequiredVersion + ". You have version " + CurrentVersion + ".");
		}

		private string ErrorServer(ZRpc rpc)
		{
			return "Disconnect: The client (" + rpc.GetSocket().GetHostName() + ") doesn't have the correct " + DisplayName + " version " + MinimumRequiredVersion;
		}

		private string Error(ZRpc? rpc = null)
		{
			return (rpc == null) ? ErrorClient() : ErrorServer(rpc);
		}

		private static VersionCheck[] GetFailedClient()
		{
			return versionChecks.Where((VersionCheck check) => !check.IsVersionOk()).ToArray();
		}

		private static VersionCheck[] GetFailedServer(ZRpc rpc)
		{
			ZRpc rpc2 = rpc;
			return versionChecks.Where((VersionCheck check) => check.ModRequired && !check.ValidatedClients.Contains(rpc2)).ToArray();
		}

		private static void Logout()
		{
			Game.instance.Logout(true, true);
			AccessTools.DeclaredField(typeof(ZNet), "m_connectionStatus").SetValue(null, (object)(ConnectionStatus)3);
		}

		private static void DisconnectClient(ZRpc rpc)
		{
			rpc.Invoke("Error", new object[1] { 3 });
		}

		private static void CheckVersion(ZRpc rpc, ZPackage pkg)
		{
			CheckVersion(rpc, pkg, null);
		}

		private static void CheckVersion(ZRpc rpc, ZPackage pkg, Action<ZRpc, ZPackage>? original)
		{
			string text = pkg.ReadString();
			string text2 = pkg.ReadString();
			string text3 = pkg.ReadString();
			bool flag = false;
			foreach (VersionCheck versionCheck in versionChecks)
			{
				if (!(text != versionCheck.Name))
				{
					Debug.Log((object)("Received " + versionCheck.DisplayName + " version " + text3 + " and minimum version " + text2 + " from the " + (ZNet.instance.IsServer() ? "client" : "server") + "."));
					versionCheck.ReceivedMinimumRequiredVersion = text2;
					versionCheck.ReceivedCurrentVersion = text3;
					if (ZNet.instance.IsServer() && versionCheck.IsVersionOk())
					{
						versionCheck.ValidatedClients.Add(rpc);
					}
					flag = true;
				}
			}
			if (flag)
			{
				return;
			}
			pkg.SetPos(0);
			if (original != null)
			{
				original(rpc, pkg);
				if (pkg.GetPos() == 0)
				{
					notProcessedNames.Add(text, text3);
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		[HarmonyPrefix]
		private static bool RPC_PeerInfo(ZRpc rpc, ZNet __instance)
		{
			VersionCheck[] array = (__instance.IsServer() ? GetFailedServer(rpc) : GetFailedClient());
			if (array.Length == 0)
			{
				return true;
			}
			VersionCheck[] array2 = array;
			foreach (VersionCheck versionCheck in array2)
			{
				Debug.LogWarning((object)versionCheck.Error(rpc));
			}
			if (__instance.IsServer())
			{
				DisconnectClient(rpc);
			}
			else
			{
				Logout();
			}
			return false;
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		[HarmonyPrefix]
		private static void RegisterAndCheckVersion(ZNetPeer peer, ZNet __instance)
		{
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Expected O, but got Unknown
			notProcessedNames.Clear();
			IDictionary dictionary = (IDictionary)typeof(ZRpc).GetField("m_functions", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(peer.m_rpc);
			if (dictionary.Contains(StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck")))
			{
				object obj = dictionary[StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck")];
				Action<ZRpc, ZPackage> action = (Action<ZRpc, ZPackage>)obj.GetType().GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj);
				peer.m_rpc.Register<ZPackage>("ServerSync VersionCheck", (Action<ZRpc, ZPackage>)delegate(ZRpc rpc, ZPackage pkg)
				{
					CheckVersion(rpc, pkg, action);
				});
			}
			else
			{
				peer.m_rpc.Register<ZPackage>("ServerSync VersionCheck", (Action<ZRpc, ZPackage>)CheckVersion);
			}
			foreach (VersionCheck versionCheck in versionChecks)
			{
				versionCheck.Initialize();
				if (versionCheck.ModRequired || __instance.IsServer())
				{
					Debug.Log((object)("Sending " + versionCheck.DisplayName + " version " + versionCheck.CurrentVersion + " and minimum version " + versionCheck.MinimumRequiredVersion + " to the " + (__instance.IsServer() ? "client" : "server") + "."));
					ZPackage val = new ZPackage();
					val.Write(versionCheck.Name);
					val.Write(versionCheck.MinimumRequiredVersion);
					val.Write(versionCheck.CurrentVersion);
					peer.m_rpc.Invoke("ServerSync VersionCheck", new object[1] { val });
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "Disconnect")]
		[HarmonyPrefix]
		private static void RemoveDisconnected(ZNetPeer peer, ZNet __instance)
		{
			if (!__instance.IsServer())
			{
				return;
			}
			foreach (VersionCheck versionCheck in versionChecks)
			{
				versionCheck.ValidatedClients.Remove(peer.m_rpc);
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
		[HarmonyPostfix]
		private static void ShowConnectionError(FejdStartup __instance)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.m_connectionFailedPanel.activeSelf || (int)ZNet.GetConnectionStatus() != 3)
			{
				return;
			}
			bool flag = false;
			VersionCheck[] failedClient = GetFailedClient();
			if (failedClient.Length != 0)
			{
				string text = string.Join("\n", failedClient.Select((VersionCheck check) => check.Error()));
				TMP_Text connectionFailedError = __instance.m_connectionFailedError;
				connectionFailedError.text = connectionFailedError.text + "\n" + text;
				flag = true;
			}
			foreach (KeyValuePair<string, string> item in notProcessedNames.OrderBy<KeyValuePair<string, string>, string>((KeyValuePair<string, string> kv) => kv.Key))
			{
				if (!__instance.m_connectionFailedError.text.Contains(item.Key))
				{
					TMP_Text connectionFailedError2 = __instance.m_connectionFailedError;
					connectionFailedError2.text = connectionFailedError2.text + "\nServer expects you to have " + item.Key + " (Version: " + item.Value + ") installed.";
					flag = true;
				}
			}
			if (flag)
			{
				RectTransform component = ((Component)__instance.m_connectionFailedPanel.transform.Find("Image")).GetComponent<RectTransform>();
				Vector2 sizeDelta = component.sizeDelta;
				sizeDelta.x = 675f;
				component.sizeDelta = sizeDelta;
				__instance.m_connectionFailedError.ForceMeshUpdate(false, false);
				float num = __instance.m_connectionFailedError.renderedHeight + 105f;
				RectTransform component2 = ((Component)((Component)component).transform.Find("ButtonOk")).GetComponent<RectTransform>();
				component2.anchoredPosition = new Vector2(component2.anchoredPosition.x, component2.anchoredPosition.y - (num - component.sizeDelta.y) / 2f);
				sizeDelta = component.sizeDelta;
				sizeDelta.y = num;
				component.sizeDelta = sizeDelta;
			}
		}
	}
}

config/ServerCharacters-master/ServerCharacters/Libs/System.Buffers.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using FxResources.System.Buffers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Buffers")]
[assembly: AssemblyDescription("System.Buffers")]
[assembly: AssemblyDefaultAlias("System.Buffers")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoftยฎ .NET Framework")]
[assembly: AssemblyCopyright("ยฉ Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.28619.01")]
[assembly: AssemblyInformationalVersion("4.6.28619.01 @BuiltBy: dlab14-DDVSOWINAGE069 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/corefx/tree/7601f4f6225089ffb291dc7d58293c7bbf5c5d4f")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.3.0")]
[module: UnverifiableCode]
namespace FxResources.System.Buffers
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));

		internal static Type ResourceType { get; } = typeof(SR);


		internal static string ArgumentException_BufferNotFromPool => GetResourceString("ArgumentException_BufferNotFromPool", null);

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

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

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}
	}
}
namespace System.Buffers
{
	public abstract class ArrayPool<T>
	{
		private static ArrayPool<T> s_sharedInstance;

		public static ArrayPool<T> Shared
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return Volatile.Read(ref s_sharedInstance) ?? EnsureSharedCreated();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ArrayPool<T> EnsureSharedCreated()
		{
			Interlocked.CompareExchange(ref s_sharedInstance, Create(), null);
			return s_sharedInstance;
		}

		public static ArrayPool<T> Create()
		{
			return new DefaultArrayPool<T>();
		}

		public static ArrayPool<T> Create(int maxArrayLength, int maxArraysPerBucket)
		{
			return new DefaultArrayPool<T>(maxArrayLength, maxArraysPerBucket);
		}

		public abstract T[] Rent(int minimumLength);

		public abstract void Return(T[] array, bool clearArray = false);
	}
	[EventSource(Name = "System.Buffers.ArrayPoolEventSource")]
	internal sealed class ArrayPoolEventSource : EventSource
	{
		internal enum BufferAllocatedReason
		{
			Pooled,
			OverMaximumSize,
			PoolExhausted
		}

		internal static readonly System.Buffers.ArrayPoolEventSource Log = new System.Buffers.ArrayPoolEventSource();

		[Event(1, Level = EventLevel.Verbose)]
		internal unsafe void BufferRented(int bufferId, int bufferSize, int poolId, int bucketId)
		{
			EventData* ptr = stackalloc EventData[4];
			*ptr = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			WriteEventCore(1, 4, ptr);
		}

		[Event(2, Level = EventLevel.Informational)]
		internal unsafe void BufferAllocated(int bufferId, int bufferSize, int poolId, int bucketId, BufferAllocatedReason reason)
		{
			EventData* ptr = stackalloc EventData[5];
			*ptr = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			ptr[4] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&reason)
			};
			WriteEventCore(2, 5, ptr);
		}

		[Event(3, Level = EventLevel.Verbose)]
		internal void BufferReturned(int bufferId, int bufferSize, int poolId)
		{
			WriteEvent(3, bufferId, bufferSize, poolId);
		}
	}
	internal sealed class DefaultArrayPool<T> : ArrayPool<T>
	{
		private sealed class Bucket
		{
			internal readonly int _bufferLength;

			private readonly T[][] _buffers;

			private readonly int _poolId;

			private SpinLock _lock;

			private int _index;

			internal int Id => GetHashCode();

			internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
			{
				_lock = new SpinLock(Debugger.IsAttached);
				_buffers = new T[numberOfBuffers][];
				_bufferLength = bufferLength;
				_poolId = poolId;
			}

			internal T[] Rent()
			{
				T[][] buffers = _buffers;
				T[] array = null;
				bool lockTaken = false;
				bool flag = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index < buffers.Length)
					{
						array = buffers[_index];
						buffers[_index++] = null;
						flag = array == null;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
				if (flag)
				{
					array = new T[_bufferLength];
					System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
					if (log.IsEnabled())
					{
						log.BufferAllocated(array.GetHashCode(), _bufferLength, _poolId, Id, System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.Pooled);
					}
				}
				return array;
			}

			internal void Return(T[] array)
			{
				if (array.Length != _bufferLength)
				{
					throw new ArgumentException(System.SR.ArgumentException_BufferNotFromPool, "array");
				}
				bool lockTaken = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index != 0)
					{
						_buffers[--_index] = array;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
			}
		}

		private const int DefaultMaxArrayLength = 1048576;

		private const int DefaultMaxNumberOfArraysPerBucket = 50;

		private static T[] s_emptyArray;

		private readonly Bucket[] _buckets;

		private int Id => GetHashCode();

		internal DefaultArrayPool()
			: this(1048576, 50)
		{
		}

		internal DefaultArrayPool(int maxArrayLength, int maxArraysPerBucket)
		{
			if (maxArrayLength <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArrayLength");
			}
			if (maxArraysPerBucket <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArraysPerBucket");
			}
			if (maxArrayLength > 1073741824)
			{
				maxArrayLength = 1073741824;
			}
			else if (maxArrayLength < 16)
			{
				maxArrayLength = 16;
			}
			int id = Id;
			int num = System.Buffers.Utilities.SelectBucketIndex(maxArrayLength);
			Bucket[] array = new Bucket[num + 1];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new Bucket(System.Buffers.Utilities.GetMaxSizeForBucket(i), maxArraysPerBucket, id);
			}
			_buckets = array;
		}

		public override T[] Rent(int minimumLength)
		{
			if (minimumLength < 0)
			{
				throw new ArgumentOutOfRangeException("minimumLength");
			}
			if (minimumLength == 0)
			{
				return s_emptyArray ?? (s_emptyArray = new T[0]);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			T[] array = null;
			int num = System.Buffers.Utilities.SelectBucketIndex(minimumLength);
			if (num < _buckets.Length)
			{
				int num2 = num;
				do
				{
					array = _buckets[num2].Rent();
					if (array != null)
					{
						if (log.IsEnabled())
						{
							log.BufferRented(array.GetHashCode(), array.Length, Id, _buckets[num2].Id);
						}
						return array;
					}
				}
				while (++num2 < _buckets.Length && num2 != num + 2);
				array = new T[_buckets[num]._bufferLength];
			}
			else
			{
				array = new T[minimumLength];
			}
			if (log.IsEnabled())
			{
				int hashCode = array.GetHashCode();
				int bucketId = -1;
				log.BufferRented(hashCode, array.Length, Id, bucketId);
				log.BufferAllocated(hashCode, array.Length, Id, bucketId, (num >= _buckets.Length) ? System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.OverMaximumSize : System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.PoolExhausted);
			}
			return array;
		}

		public override void Return(T[] array, bool clearArray = false)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (array.Length == 0)
			{
				return;
			}
			int num = System.Buffers.Utilities.SelectBucketIndex(array.Length);
			if (num < _buckets.Length)
			{
				if (clearArray)
				{
					Array.Clear(array, 0, array.Length);
				}
				_buckets[num].Return(array);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			if (log.IsEnabled())
			{
				log.BufferReturned(array.GetHashCode(), array.Length, Id);
			}
		}
	}
	internal static class Utilities
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int SelectBucketIndex(int bufferSize)
		{
			uint num = (uint)(bufferSize - 1) >> 4;
			int num2 = 0;
			if (num > 65535)
			{
				num >>= 16;
				num2 = 16;
			}
			if (num > 255)
			{
				num >>= 8;
				num2 += 8;
			}
			if (num > 15)
			{
				num >>= 4;
				num2 += 4;
			}
			if (num > 3)
			{
				num >>= 2;
				num2 += 2;
			}
			if (num > 1)
			{
				num >>= 1;
				num2++;
			}
			return num2 + (int)num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int GetMaxSizeForBucket(int binIndex)
		{
			return 16 << binIndex;
		}
	}
}

config/ServerCharacters-master/ServerCharacters/Libs/System.Collections.Immutable.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading;
using FxResources.System.Collections.Immutable;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("System.Collections.Immutable.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b86c4cb78549b34bab61a3b1800e23bfeb5b3ec390074041536a7e3cbd97f5f04cf0f857155a8928eaa29ebfd11cfbbad3ba70efea7bda3226c6a8d370a4cd303f714486b6ebc225985a638471e6ef571cc92a4613c00b8fa65d61ccee0cbe5f36330c9a01f4183559f1bef24cc2917c6d913e3a541333a1d05d9bed22b38cb")]
[assembly: AssemblyDefaultAlias("System.Collections.Immutable")]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("ยฉ Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("System.Collections.Immutable")]
[assembly: AssemblyFileVersion("4.700.20.21406")]
[assembly: AssemblyInformationalVersion("3.1.4+c4164928b270ee2369808ab347d33423ef765216")]
[assembly: AssemblyProduct("Microsoftยฎ .NET Core")]
[assembly: AssemblyTitle("System.Collections.Immutable")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyVersion("1.2.5.0")]
[module: System.Runtime.CompilerServices.NullablePublicOnly(true)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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.Module | 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 NullablePublicOnlyAttribute : Attribute
	{
		public readonly bool IncludesInternals;

		public NullablePublicOnlyAttribute(bool P_0)
		{
			IncludesInternals = P_0;
		}
	}
}
namespace FxResources.System.Collections.Immutable
{
	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 Arg_KeyNotFoundWithKey => GetResourceString("Arg_KeyNotFoundWithKey");

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

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

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

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

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

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

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

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

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

		[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);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}

		internal static string Format(string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(provider, resourceFormat, p1);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(provider, resourceFormat, p1, p2);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2, object? p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(provider, resourceFormat, p1, p2, p3);
		}

		internal static string Format(IFormatProvider? provider, string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class NonVersionableAttribute : Attribute
	{
	}
}
namespace System.Linq
{
	public static class ImmutableArrayExtensions
	{
		public static IEnumerable<TResult> Select<T, TResult>(this ImmutableArray<T> immutableArray, Func<T, TResult> selector)
		{
			immutableArray.ThrowNullRefIfNotInitialized();
			return immutableArray.array.Select(selector);
		}

		public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this ImmutableArray<TSource> immutableArray, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
		{
			immutableArray.ThrowNullRefIfNotInitialized();
			if (collectionSelector == null || resultSelector == null)
			{
				return Enumerable.SelectMany(immutableArray, collectionSelector, resultSelector);
			}
			if (immutableArray.Length != 0)
			{
				return immutableArray.SelectManyIterator(collectionSelector, resultSelector);
			}
			return Enumerable.Empty<TResult>();
		}

		public static IEnumerable<T> Where<T>(this ImmutableArray<T> immutableArray, Func<T, bool> predicate)
		{
			immutableArray.ThrowNullRefIfNotInitialized();
			return immutableArray.array.Where(predicate);
		}

		public static bool Any<T>(this ImmutableArray<T> immutableArray)
		{
			return immutableArray.Length > 0;
		}

		public static bool Any<T>(this ImmutableArray<T> immutableArray, Func<T, bool> predicate)
		{
			immutableArray.ThrowNullRefIfNotInitialized();
			Requires.NotNull(predicate, "predicate");
			T[] array = immutableArray.array;
			foreach (T arg in array)
			{
				if (predicate(arg))
				{
					return true;
				}
			}
			return false;
		}

		public static bool All<T>(this ImmutableArray<T> immutableArray, Func<T, bool> predicate)
		{
			immutableArray.ThrowNullRefIfNotInitialized();
			Requires.NotNull(predicate, "predicate");
			T[] array = immutableArray.array;
			foreach (T arg in array)
			{
				if (!predicate(arg))
				{
					return false;
				}
			}
			return true;
		}

		public static bool SequenceEqual<TDerived, TBase>(this ImmutableArray<TBase> immutableArray, ImmutableArray<TDerived> items, IEqualityComparer<TBase> comparer = null) where TDerived : TBase
		{
			immutableArray.ThrowNullRefIfNotInitialized();
			items.ThrowNullRefIfNotInitialized();
			if (immutableArray.array == items.array)
			{
				return true;
			}
			if (immutableArray.Length != items.Length)
			{
				return false;
			}
			if (comparer == null)
			{
				comparer = EqualityComparer<TBase>.Default;
			}
			for (int i = 0; i < immutableArray.Length; i++)
			{
				if (!comparer.Equals(immutableArray.array[i], (TBase)(object)items.array[i]))
				{
					return false;
				}
			}
			return true;
		}

		public static bool SequenceEqual<TDerived, TBase>(this ImmutableArray<TBase> immutableArray, IEnumerable<TDerived> items, IEqualityComparer<TBase> comparer = null) where TDerived : TBase
		{
			Requires.NotNull(items, "items");
			if (comparer == null)
			{
				comparer = EqualityComparer<TBase>.Default;
			}
			int num = 0;
			int length = immutableArray.Length;
			foreach (TDerived item in items)
			{
				if (num == length)
				{
					return false;
				}
				if (!comparer.Equals(immutableArray[num], (TBase)(object)item))
				{
					return false;
				}
				num++;
			}
			return num == length;
		}

		public static bool SequenceEqual<TDerived, TBase>(this ImmutableArray<TBase> immutableArray, ImmutableArray<TDerived> items, Func<TBase, TBase, bool> predicate) where TDerived : TBase
		{
			Requires.NotNull(predicate, "predicate");
			immutableArray.ThrowNullRefIfNotInitialized();
			items.ThrowNullRefIfNotInitialized();
			if (immutableArray.array == items.array)
			{
				return true;
			}
			if (immutableArray.Length != items.Length)
			{
				return false;
			}
			int i = 0;
			for (int length = immutableArray.Length; i < length; i++)
			{
				if (!predicate(immutableArray[i], (TBase)(object)items[i]))
				{
					return false;
				}
			}
			return true;
		}

		public static T Aggregate<T>(this ImmutableArray<T> immutableArray, Func<T, T, T> func)
		{
			Requires.NotNull(func, "func");
			if (immutableArray.Length == 0)
			{
				return default(T);
			}
			T val = immutableArray[0];
			int i = 1;
			for (int length = immutableArray.Length; i < length; i++)
			{
				val = func(val, immutableArray[i]);
			}
			return val;
		}

		public static TAccumulate Aggregate<TAccumulate, T>(this ImmutableArray<T> immutableArray, TAccumulate seed, Func<TAccumulate, T, TAccumulate> func)
		{
			Requires.NotNull(func, "func");
			TAccumulate val = seed;
			T[] array = immutableArray.array;
			foreach (T arg in array)
			{
				val = func(val, arg);
			}
			return val;
		}

		public static TResult Aggregate<TAccumulate, TResult, T>(this ImmutableArray<T> immutableArray, TAccumulate seed, Func<TAccumulate, T, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)
		{
			Requires.NotNull(resultSelector, "resultSelector");
			return resultSelector(immutableArray.Aggregate(seed, func));
		}

		public static T ElementAt<T>(this ImmutableArray<T> immutableArray, int index)
		{
			return immutableArray[index];
		}

		public static T ElementAtOrDefault<T>(this ImmutableArray<T> immutableArray, int index)
		{
			if (index < 0 || index >= immutableArray.Length)
			{
				return default(T);
			}
			return immutableArray[index];
		}

		public static T First<T>(this ImmutableArray<T> immutableArray, Func<T, bool> predicate)
		{
			Requires.NotNull(predicate, "predicate");
			T[] array = immutableArray.array;
			foreach (T val in array)
			{
				if (predicate(val))
				{
					return val;
				}
			}
			return Enumerable.Empty<T>().First();
		}

		public static T First<T>(this ImmutableArray<T> immutableArray)
		{
			if (immutableArray.Length <= 0)
			{
				return immutableArray.array.First();
			}
			return immutableArray[0];
		}

		public static T FirstOrDefault<T>(this ImmutableArray<T> immutableArray)
		{
			if (immutableArray.array.Length == 0)
			{
				return default(T);
			}
			return immutableArray.array[0];
		}

		public static T FirstOrDefault<T>(this ImmutableArray<T> immutableArray, Func<T, bool> predicate)
		{
			Requires.NotNull(predicate, "predicate");
			T[] array = immutableArray.array;
			foreach (T val in array)
			{
				if (predicate(val))
				{
					return val;
				}
			}
			return default(T);
		}

		public static T Last<T>(this ImmutableArray<T> immutableArray)
		{
			if (immutableArray.Length <= 0)
			{
				return immutableArray.array.Last();
			}
			return immutableArray[immutableArray.Length - 1];
		}

		public static T Last<T>(this ImmutableArray<T> immutableArray, Func<T, bool> predicate)
		{
			Requires.NotNull(predicate, "predicate");
			for (int num = immutableArray.Length - 1; num >= 0; num--)
			{
				if (predicate(immutableArray[num]))
				{
					return immutableArray[num];
				}
			}
			return Enumerable.Empty<T>().Last();
		}

		public static T LastOrDefault<T>(this ImmutableArray<T> immutableArray)
		{
			immutableArray.ThrowNullRefIfNotInitialized();
			return immutableArray.array.LastOrDefault();
		}

		public static T LastOrDefault<T>(this ImmutableArray<T> immutableArray, Func<T, bool> predicate)
		{
			Requires.NotNull(predicate, "predicate");
			for (int num = immutableArray.Length - 1; num >= 0; num--)
			{
				if (predicate(immutableArray[num]))
				{
					return immutableArray[num];
				}
			}
			return default(T);
		}

		public static T Single<T>(this ImmutableArray<T> immutableArray)
		{
			immutableArray.ThrowNullRefIfNotInitialized();
			return immutableArray.array.Single();
		}

		public static T Single<T>(this ImmutableArray<T> immutableArray, Func<T, bool> predicate)
		{
			Requires.NotNull(predicate, "predicate");
			bool flag = true;
			T result = default(T);
			T[] array = immutableArray.array;
			foreach (T val in array)
			{
				if (predicate(val))
				{
					if (!flag)
					{
						ImmutableArray.TwoElementArray.Single();
					}
					flag = false;
					result = val;
				}
			}
			if (flag)
			{
				Enumerable.Empty<T>().Single();
			}
			return result;
		}

		public static T SingleOrDefault<T>(this ImmutableArray<T> immutableArray)
		{
			immutableArray.ThrowNullRefIfNotInitialized();
			return immutableArray.array.SingleOrDefault();
		}

		public static T SingleOrDefault<T>(this ImmutableArray<T> immutableArray, Func<T, bool> predicate)
		{
			Requires.NotNull(predicate, "predicate");
			bool flag = true;
			T result = default(T);
			T[] array = immutableArray.array;
			foreach (T val in array)
			{
				if (predicate(val))
				{
					if (!flag)
					{
						ImmutableArray.TwoElementArray.Single();
					}
					flag = false;
					result = val;
				}
			}
			return result;
		}

		public static Dictionary<TKey, T> ToDictionary<TKey, T>(this ImmutableArray<T> immutableArray, Func<T, TKey> keySelector)
		{
			return immutableArray.ToDictionary(keySelector, EqualityComparer<TKey>.Default);
		}

		public static Dictionary<TKey, TElement> ToDictionary<TKey, TElement, T>(this ImmutableArray<T> immutableArray, Func<T, TKey> keySelector, Func<T, TElement> elementSelector)
		{
			return immutableArray.ToDictionary(keySelector, elementSelector, EqualityComparer<TKey>.Default);
		}

		public static Dictionary<TKey, T> ToDictionary<TKey, T>(this ImmutableArray<T> immutableArray, Func<T, TKey> keySelector, IEqualityComparer<TKey> comparer)
		{
			Requires.NotNull(keySelector, "keySelector");
			Dictionary<TKey, T> dictionary = new Dictionary<TKey, T>(immutableArray.Length, comparer);
			ImmutableArray<T>.Enumerator enumerator = immutableArray.GetEnumerator();
			while (enumerator.MoveNext())
			{
				T current = enumerator.Current;
				dictionary.Add(keySelector(current), current);
			}
			return dictionary;
		}

		public static Dictionary<TKey, TElement> ToDictionary<TKey, TElement, T>(this ImmutableArray<T> immutableArray, Func<T, TKey> keySelector, Func<T, TElement> elementSelector, IEqualityComparer<TKey> comparer)
		{
			Requires.NotNull(keySelector, "keySelector");
			Requires.NotNull(elementSelector, "elementSelector");
			Dictionary<TKey, TElement> dictionary = new Dictionary<TKey, TElement>(immutableArray.Length, comparer);
			T[] array = immutableArray.array;
			foreach (T arg in array)
			{
				dictionary.Add(keySelector(arg), elementSelector(arg));
			}
			return dictionary;
		}

		public static T[] ToArray<T>(this ImmutableArray<T> immutableArray)
		{
			immutableArray.ThrowNullRefIfNotInitialized();
			if (immutableArray.array.Length == 0)
			{
				return ImmutableArray<T>.Empty.array;
			}
			return (T[])immutableArray.array.Clone();
		}

		public static T First<T>(this ImmutableArray<T>.Builder builder)
		{
			Requires.NotNull(builder, "builder");
			if (!builder.Any())
			{
				throw new InvalidOperationException();
			}
			return builder[0];
		}

		public static T FirstOrDefault<T>(this ImmutableArray<T>.Builder builder)
		{
			Requires.NotNull(builder, "builder");
			if (!builder.Any())
			{
				return default(T);
			}
			return builder[0];
		}

		public static T Last<T>(this ImmutableArray<T>.Builder builder)
		{
			Requires.NotNull(builder, "builder");
			if (!builder.Any())
			{
				throw new InvalidOperationException();
			}
			return builder[builder.Count - 1];
		}

		public static T LastOrDefault<T>(this ImmutableArray<T>.Builder builder)
		{
			Requires.NotNull(builder, "builder");
			if (!builder.Any())
			{
				return default(T);
			}
			return builder[builder.Count - 1];
		}

		public static bool Any<T>(this ImmutableArray<T>.Builder builder)
		{
			Requires.NotNull(builder, "builder");
			return builder.Count > 0;
		}

		private static IEnumerable<TResult> SelectManyIterator<TSource, TCollection, TResult>(this ImmutableArray<TSource> immutableArray, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
		{
			TSource[] array = immutableArray.array;
			foreach (TSource item in array)
			{
				foreach (TCollection item2 in collectionSelector(item))
				{
					yield return resultSelector(item, item2);
				}
			}
		}
	}
}
namespace System.Collections.Immutable
{
	internal static class AllocFreeConcurrentStack<T>
	{
		private const int MaxSize = 35;

		private static readonly Type s_typeOfT = typeof(T);

		private static Stack<RefAsValueType<T>> ThreadLocalStack
		{
			get
			{
				Dictionary<Type, object> dictionary = AllocFreeConcurrentStack.t_stacks;
				if (dictionary == null)
				{
					dictionary = (AllocFreeConcurrentStack.t_stacks = new Dictionary<Type, object>());
				}
				if (!dictionary.TryGetValue(s_typeOfT, out var value))
				{
					value = new Stack<RefAsValueType<T>>(35);
					dictionary.Add(s_typeOfT, value);
				}
				return (Stack<RefAsValueType<T>>)value;
			}
		}

		public static void TryAdd(T item)
		{
			Stack<RefAsValueType<T>> threadLocalStack = ThreadLocalStack;
			if (threadLocalStack.Count < 35)
			{
				threadLocalStack.Push(new RefAsValueType<T>(item));
			}
		}

		public static bool TryTake(out T item)
		{
			Stack<RefAsValueType<T>> threadLocalStack = ThreadLocalStack;
			if (threadLocalStack != null && threadLocalStack.Count > 0)
			{
				item = threadLocalStack.Pop().Value;
				return true;
			}
			item = default(T);
			return false;
		}
	}
	internal static class AllocFreeConcurrentStack
	{
		[ThreadStatic]
		internal static Dictionary<Type, object> t_stacks;
	}
	internal sealed class DictionaryEnumerator<TKey, TValue> : IDictionaryEnumerator, IEnumerator
	{
		private readonly IEnumerator<KeyValuePair<TKey, TValue>> _inner;

		public DictionaryEntry Entry => new DictionaryEntry(_inner.Current.Key, _inner.Current.Value);

		public object Key => _inner.Current.Key;

		public object Value => _inner.Current.Value;

		public object Current => Entry;

		internal DictionaryEnumerator(IEnumerator<KeyValuePair<TKey, TValue>> inner)
		{
			Requires.NotNull(inner, "inner");
			_inner = inner;
		}

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

		public void Reset()
		{
			_inner.Reset();
		}
	}
	internal struct DisposableEnumeratorAdapter<T, TEnumerator> : IDisposable where TEnumerator : struct, IEnumerator<T>
	{
		private readonly IEnumerator<T> _enumeratorObject;

		private TEnumerator _enumeratorStruct;

		public T Current
		{
			get
			{
				if (_enumeratorObject == null)
				{
					return _enumeratorStruct.Current;
				}
				return _enumeratorObject.Current;
			}
		}

		internal DisposableEnumeratorAdapter(TEnumerator enumerator)
		{
			_enumeratorStruct = enumerator;
			_enumeratorObject = null;
		}

		internal DisposableEnumeratorAdapter(IEnumerator<T> enumerator)
		{
			_enumeratorStruct = default(TEnumerator);
			_enumeratorObject = enumerator;
		}

		public bool MoveNext()
		{
			if (_enumeratorObject == null)
			{
				return _enumeratorStruct.MoveNext();
			}
			return _enumeratorObject.MoveNext();
		}

		public void Dispose()
		{
			if (_enumeratorObject != null)
			{
				_enumeratorObject.Dispose();
			}
			else
			{
				_enumeratorStruct.Dispose();
			}
		}

		public DisposableEnumeratorAdapter<T, TEnumerator> GetEnumerator()
		{
			return this;
		}
	}
	internal interface IBinaryTree
	{
		int Height { get; }

		bool IsEmpty { get; }

		int Count { get; }

		IBinaryTree Left { get; }

		IBinaryTree Right { get; }
	}
	internal interface IBinaryTree<out T> : IBinaryTree
	{
		T Value { get; }

		new IBinaryTree<T> Left { get; }

		new IBinaryTree<T> Right { get; }
	}
	internal interface IImmutableArray
	{
		Array Array { get; }
	}
	public interface IImmutableDictionary<TKey, TValue> : IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable
	{
		IImmutableDictionary<TKey, TValue> Clear();

		IImmutableDictionary<TKey, TValue> Add(TKey key, TValue value);

		IImmutableDictionary<TKey, TValue> AddRange(IEnumerable<KeyValuePair<TKey, TValue>> pairs);

		IImmutableDictionary<TKey, TValue> SetItem(TKey key, TValue value);

		IImmutableDictionary<TKey, TValue> SetItems(IEnumerable<KeyValuePair<TKey, TValue>> items);

		IImmutableDictionary<TKey, TValue> RemoveRange(IEnumerable<TKey> keys);

		IImmutableDictionary<TKey, TValue> Remove(TKey key);

		bool Contains(KeyValuePair<TKey, TValue> pair);

		bool TryGetKey(TKey equalKey, out TKey actualKey);
	}
	internal interface IImmutableDictionaryInternal<TKey, TValue>
	{
		bool ContainsValue(TValue value);
	}
	public interface IImmutableList<T> : IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable
	{
		IImmutableList<T> Clear();

		int IndexOf(T item, int index, int count, IEqualityComparer<T> equalityComparer);

		int LastIndexOf(T item, int index, int count, IEqualityComparer<T> equalityComparer);

		IImmutableList<T> Add(T value);

		IImmutableList<T> AddRange(IEnumerable<T> items);

		IImmutableList<T> Insert(int index, T element);

		IImmutableList<T> InsertRange(int index, IEnumerable<T> items);

		IImmutableList<T> Remove(T value, IEqualityComparer<T> equalityComparer);

		IImmutableList<T> RemoveAll(Predicate<T> match);

		IImmutableList<T> RemoveRange(IEnumerable<T> items, IEqualityComparer<T> equalityComparer);

		IImmutableList<T> RemoveRange(int index, int count);

		IImmutableList<T> RemoveAt(int index);

		IImmutableList<T> SetItem(int index, T value);

		IImmutableList<T> Replace(T oldValue, T newValue, IEqualityComparer<T> equalityComparer);
	}
	internal interface IImmutableListQueries<T> : IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable
	{
		ImmutableList<TOutput> ConvertAll<TOutput>(Func<T, TOutput> converter);

		void ForEach(Action<T> action);

		ImmutableList<T> GetRange(int index, int count);

		void CopyTo(T[] array);

		void CopyTo(T[] array, int arrayIndex);

		void CopyTo(int index, T[] array, int arrayIndex, int count);

		bool Exists(Predicate<T> match);

		T Find(Predicate<T> match);

		ImmutableList<T> FindAll(Predicate<T> match);

		int FindIndex(Predicate<T> match);

		int FindIndex(int startIndex, Predicate<T> match);

		int FindIndex(int startIndex, int count, Predicate<T> match);

		T FindLast(Predicate<T> match);

		int FindLastIndex(Predicate<T> match);

		int FindLastIndex(int startIndex, Predicate<T> match);

		int FindLastIndex(int startIndex, int count, Predicate<T> match);

		bool TrueForAll(Predicate<T> match);

		int BinarySearch(T item);

		int BinarySearch(T item, IComparer<T> comparer);

		int BinarySearch(int index, int count, T item, IComparer<T> comparer);
	}
	public interface IImmutableQueue<T> : IEnumerable<T>, IEnumerable
	{
		bool IsEmpty { get; }

		IImmutableQueue<T> Clear();

		T Peek();

		IImmutableQueue<T> Enqueue(T value);

		IImmutableQueue<T> Dequeue();
	}
	public interface IImmutableSet<T> : IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable
	{
		IImmutableSet<T> Clear();

		bool Contains(T value);

		IImmutableSet<T> Add(T value);

		IImmutableSet<T> Remove(T value);

		bool TryGetValue(T equalValue, out T actualValue);

		IImmutableSet<T> Intersect(IEnumerable<T> other);

		IImmutableSet<T> Except(IEnumerable<T> other);

		IImmutableSet<T> SymmetricExcept(IEnumerable<T> other);

		IImmutableSet<T> Union(IEnumerable<T> other);

		bool SetEquals(IEnumerable<T> other);

		bool IsProperSubsetOf(IEnumerable<T> other);

		bool IsProperSupersetOf(IEnumerable<T> other);

		bool IsSubsetOf(IEnumerable<T> other);

		bool IsSupersetOf(IEnumerable<T> other);

		bool Overlaps(IEnumerable<T> other);
	}
	public interface IImmutableStack<T> : IEnumerable<T>, IEnumerable
	{
		bool IsEmpty { get; }

		IImmutableStack<T> Clear();

		IImmutableStack<T> Push(T value);

		IImmutableStack<T> Pop();

		T Peek();
	}
	[DebuggerDisplay("Count = {Count}")]
	[DebuggerTypeProxy(typeof(ImmutableEnumerableDebuggerProxy<>))]
	public sealed class ImmutableHashSet<T> : IImmutableSet<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable, IHashKeyCollection<T>, ICollection<T>, ISet<T>, ICollection, IStrongEnumerable<T, ImmutableHashSet<T>.Enumerator>
	{
		private class HashBucketByValueEqualityComparer : IEqualityComparer<HashBucket>
		{
			private static readonly IEqualityComparer<HashBucket> s_defaultInstance = new HashBucketByValueEqualityComparer(EqualityComparer<T>.Default);

			private readonly IEqualityComparer<T> _valueComparer;

			internal static IEqualityComparer<HashBucket> DefaultInstance => s_defaultInstance;

			internal HashBucketByValueEqualityComparer(IEqualityComparer<T> valueComparer)
			{
				Requires.NotNull(valueComparer, "valueComparer");
				_valueComparer = valueComparer;
			}

			public bool Equals(HashBucket x, HashBucket y)
			{
				return x.EqualsByValue(y, _valueComparer);
			}

			public int GetHashCode(HashBucket obj)
			{
				throw new NotSupportedException();
			}
		}

		private class HashBucketByRefEqualityComparer : IEqualityComparer<HashBucket>
		{
			private static readonly IEqualityComparer<HashBucket> s_defaultInstance = new HashBucketByRefEqualityComparer();

			internal static IEqualityComparer<HashBucket> DefaultInstance => s_defaultInstance;

			private HashBucketByRefEqualityComparer()
			{
			}

			public bool Equals(HashBucket x, HashBucket y)
			{
				return x.EqualsByRef(y);
			}

			public int GetHashCode(HashBucket obj)
			{
				throw new NotSupportedException();
			}
		}

		[DebuggerDisplay("Count = {Count}")]
		public sealed class Builder : IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable, ISet<T>, ICollection<T>
		{
			private SortedInt32KeyNode<HashBucket> _root = SortedInt32KeyNode<HashBucket>.EmptyNode;

			private IEqualityComparer<T> _equalityComparer;

			private IEqualityComparer<HashBucket> _hashBucketEqualityComparer;

			private int _count;

			private ImmutableHashSet<T> _immutable;

			private int _version;

			public int Count => _count;

			bool ICollection<T>.IsReadOnly => false;

			public IEqualityComparer<T> KeyComparer
			{
				get
				{
					return _equalityComparer;
				}
				set
				{
					Requires.NotNull(value, "value");
					if (value != _equalityComparer)
					{
						MutationResult mutationResult = ImmutableHashSet<T>.Union((IEnumerable<T>)this, new MutationInput(SortedInt32KeyNode<HashBucket>.EmptyNode, value, _hashBucketEqualityComparer, 0));
						_immutable = null;
						_equalityComparer = value;
						Root = mutationResult.Root;
						_count = mutationResult.Count;
					}
				}
			}

			internal int Version => _version;

			private MutationInput Origin => new MutationInput(Root, _equalityComparer, _hashBucketEqualityComparer, _count);

			private SortedInt32KeyNode<HashBucket> Root
			{
				get
				{
					return _root;
				}
				set
				{
					_version++;
					if (_root != value)
					{
						_root = value;
						_immutable = null;
					}
				}
			}

			internal Builder(ImmutableHashSet<T> set)
			{
				Requires.NotNull(set, "set");
				_root = set._root;
				_count = set._count;
				_equalityComparer = set._equalityComparer;
				_hashBucketEqualityComparer = set._hashBucketEqualityComparer;
				_immutable = set;
			}

			public Enumerator GetEnumerator()
			{
				return new Enumerator(_root, this);
			}

			public ImmutableHashSet<T> ToImmutable()
			{
				if (_immutable == null)
				{
					_immutable = ImmutableHashSet<T>.Wrap(_root, _equalityComparer, _count);
				}
				return _immutable;
			}

			public bool Add(T item)
			{
				MutationResult result = ImmutableHashSet<T>.Add(item, Origin);
				Apply(result);
				return result.Count != 0;
			}

			public bool Remove(T item)
			{
				MutationResult result = ImmutableHashSet<T>.Remove(item, Origin);
				Apply(result);
				return result.Count != 0;
			}

			public bool Contains(T item)
			{
				return ImmutableHashSet<T>.Contains(item, Origin);
			}

			public void Clear()
			{
				_count = 0;
				Root = SortedInt32KeyNode<HashBucket>.EmptyNode;
			}

			public void ExceptWith(IEnumerable<T> other)
			{
				MutationResult result = ImmutableHashSet<T>.Except(other, _equalityComparer, _hashBucketEqualityComparer, _root);
				Apply(result);
			}

			public void IntersectWith(IEnumerable<T> other)
			{
				MutationResult result = ImmutableHashSet<T>.Intersect(other, Origin);
				Apply(result);
			}

			public bool IsProperSubsetOf(IEnumerable<T> other)
			{
				return ImmutableHashSet<T>.IsProperSubsetOf(other, Origin);
			}

			public bool IsProperSupersetOf(IEnumerable<T> other)
			{
				return ImmutableHashSet<T>.IsProperSupersetOf(other, Origin);
			}

			public bool IsSubsetOf(IEnumerable<T> other)
			{
				return ImmutableHashSet<T>.IsSubsetOf(other, Origin);
			}

			public bool IsSupersetOf(IEnumerable<T> other)
			{
				return ImmutableHashSet<T>.IsSupersetOf(other, Origin);
			}

			public bool Overlaps(IEnumerable<T> other)
			{
				return ImmutableHashSet<T>.Overlaps(other, Origin);
			}

			public bool SetEquals(IEnumerable<T> other)
			{
				if (this == other)
				{
					return true;
				}
				return ImmutableHashSet<T>.SetEquals(other, Origin);
			}

			public void SymmetricExceptWith(IEnumerable<T> other)
			{
				MutationResult result = ImmutableHashSet<T>.SymmetricExcept(other, Origin);
				Apply(result);
			}

			public void UnionWith(IEnumerable<T> other)
			{
				MutationResult result = ImmutableHashSet<T>.Union(other, Origin);
				Apply(result);
			}

			void ICollection<T>.Add(T item)
			{
				Add(item);
			}

			void ICollection<T>.CopyTo(T[] array, int arrayIndex)
			{
				Requires.NotNull(array, "array");
				Requires.Range(arrayIndex >= 0, "arrayIndex");
				Requires.Range(array.Length >= arrayIndex + Count, "arrayIndex");
				using Enumerator enumerator = GetEnumerator();
				while (enumerator.MoveNext())
				{
					T current = enumerator.Current;
					array[arrayIndex++] = current;
				}
			}

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

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

			private void Apply(MutationResult result)
			{
				Root = result.Root;
				if (result.CountType == CountType.Adjustment)
				{
					_count += result.Count;
				}
				else
				{
					_count = result.Count;
				}
			}
		}

		public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator, IStrongEnumerator<T>
		{
			private readonly Builder _builder;

			private SortedInt32KeyNode<HashBucket>.Enumerator _mapEnumerator;

			private HashBucket.Enumerator _bucketEnumerator;

			private int _enumeratingBuilderVersion;

			public T Current
			{
				get
				{
					_mapEnumerator.ThrowIfDisposed();
					return _bucketEnumerator.Current;
				}
			}

			object IEnumerator.Current => Current;

			internal Enumerator(SortedInt32KeyNode<HashBucket> root, Builder builder = null)
			{
				_builder = builder;
				_mapEnumerator = new SortedInt32KeyNode<HashBucket>.Enumerator(root);
				_bucketEnumerator = default(HashBucket.Enumerator);
				_enumeratingBuilderVersion = builder?.Version ?? (-1);
			}

			public bool MoveNext()
			{
				ThrowIfChanged();
				if (_bucketEnumerator.MoveNext())
				{
					return true;
				}
				if (_mapEnumerator.MoveNext())
				{
					_bucketEnumerator = new HashBucket.Enumerator(_mapEnumerator.Current.Value);
					return _bucketEnumerator.MoveNext();
				}
				return false;
			}

			public void Reset()
			{
				_enumeratingBuilderVersion = ((_builder != null) ? _builder.Version : (-1));
				_mapEnumerator.Reset();
				_bucketEnumerator.Dispose();
				_bucketEnumerator = default(HashBucket.Enumerator);
			}

			public void Dispose()
			{
				_mapEnumerator.Dispose();
				_bucketEnumerator.Dispose();
			}

			private void ThrowIfChanged()
			{
				if (_builder != null && _builder.Version != _enumeratingBuilderVersion)
				{
					throw new InvalidOperationException(System.SR.CollectionModifiedDuringEnumeration);
				}
			}
		}

		internal enum OperationResult
		{
			SizeChanged,
			NoChangeRequired
		}

		internal readonly struct HashBucket
		{
			internal struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
			{
				private enum Position
				{
					BeforeFirst,
					First,
					Additional,
					End
				}

				private readonly HashBucket _bucket;

				private bool _disposed;

				private Position _currentPosition;

				private ImmutableList<T>.Enumerator _additionalEnumerator;

				object IEnumerator.Current => Current;

				public T Current
				{
					get
					{
						ThrowIfDisposed();
						return _currentPosition switch
						{
							Position.First => _bucket._firstValue, 
							Position.Additional => _additionalEnumerator.Current, 
							_ => throw new InvalidOperationException(), 
						};
					}
				}

				internal Enumerator(HashBucket bucket)
				{
					_disposed = false;
					_bucket = bucket;
					_currentPosition = Position.BeforeFirst;
					_additionalEnumerator = default(ImmutableList<T>.Enumerator);
				}

				public bool MoveNext()
				{
					ThrowIfDisposed();
					if (_bucket.IsEmpty)
					{
						_currentPosition = Position.End;
						return false;
					}
					switch (_currentPosition)
					{
					case Position.BeforeFirst:
						_currentPosition = Position.First;
						return true;
					case Position.First:
						if (_bucket._additionalElements.IsEmpty)
						{
							_currentPosition = Position.End;
							return false;
						}
						_currentPosition = Position.Additional;
						_additionalEnumerator = new ImmutableList<T>.Enumerator(_bucket._additionalElements);
						return _additionalEnumerator.MoveNext();
					case Position.Additional:
						return _additionalEnumerator.MoveNext();
					case Position.End:
						return false;
					default:
						throw new InvalidOperationException();
					}
				}

				public void Reset()
				{
					ThrowIfDisposed();
					_additionalEnumerator.Dispose();
					_currentPosition = Position.BeforeFirst;
				}

				public void Dispose()
				{
					_disposed = true;
					_additionalEnumerator.Dispose();
				}

				private void ThrowIfDisposed()
				{
					if (_disposed)
					{
						Requires.FailObjectDisposed(this);
					}
				}
			}

			private readonly T _firstValue;

			private readonly ImmutableList<T>.Node _additionalElements;

			internal bool IsEmpty => _additionalElements == null;

			private HashBucket(T firstElement, ImmutableList<T>.Node additionalElements = null)
			{
				_firstValue = firstElement;
				_additionalElements = additionalElements ?? ImmutableList<T>.Node.EmptyNode;
			}

			public Enumerator GetEnumerator()
			{
				return new Enumerator(this);
			}

			public override bool Equals(object obj)
			{
				throw new NotSupportedException();
			}

			public override int GetHashCode()
			{
				throw new NotSupportedException();
			}

			internal bool EqualsByRef(HashBucket other)
			{
				if ((object)_firstValue == (object)other._firstValue)
				{
					return _additionalElements == other._additionalElements;
				}
				return false;
			}

			internal bool EqualsByValue(HashBucket other, IEqualityComparer<T> valueComparer)
			{
				if (valueComparer.Equals(_firstValue, other._firstValue))
				{
					return _additionalElements == other._additionalElements;
				}
				return false;
			}

			internal HashBucket Add(T value, IEqualityComparer<T> valueComparer, out OperationResult result)
			{
				if (IsEmpty)
				{
					result = OperationResult.SizeChanged;
					return new HashBucket(value);
				}
				if (valueComparer.Equals(value, _firstValue) || _additionalElements.IndexOf(value, valueComparer) >= 0)
				{
					result = OperationResult.NoChangeRequired;
					return this;
				}
				result = OperationResult.SizeChanged;
				return new HashBucket(_firstValue, _additionalElements.Add(value));
			}

			internal bool Contains(T value, IEqualityComparer<T> valueComparer)
			{
				if (IsEmpty)
				{
					return false;
				}
				if (!valueComparer.Equals(value, _firstValue))
				{
					return _additionalElements.IndexOf(value, valueComparer) >= 0;
				}
				return true;
			}

			internal bool TryExchange(T value, IEqualityComparer<T> valueComparer, out T existingValue)
			{
				if (!IsEmpty)
				{
					if (valueComparer.Equals(value, _firstValue))
					{
						existingValue = _firstValue;
						return true;
					}
					int num = _additionalElements.IndexOf(value, valueComparer);
					if (num >= 0)
					{
						existingValue = _additionalElements.ItemRef(num);
						return true;
					}
				}
				existingValue = value;
				return false;
			}

			internal HashBucket Remove(T value, IEqualityComparer<T> equalityComparer, out OperationResult result)
			{
				if (IsEmpty)
				{
					result = OperationResult.NoChangeRequired;
					return this;
				}
				if (equalityComparer.Equals(_firstValue, value))
				{
					if (_additionalElements.IsEmpty)
					{
						result = OperationResult.SizeChanged;
						return default(HashBucket);
					}
					int count = _additionalElements.Left.Count;
					result = OperationResult.SizeChanged;
					return new HashBucket(_additionalElements.Key, _additionalElements.RemoveAt(count));
				}
				int num = _additionalElements.IndexOf(value, equalityComparer);
				if (num < 0)
				{
					result = OperationResult.NoChangeRequired;
					return this;
				}
				result = OperationResult.SizeChanged;
				return new HashBucket(_firstValue, _additionalElements.RemoveAt(num));
			}

			internal void Freeze()
			{
				if (_additionalElements != null)
				{
					_additionalElements.Freeze();
				}
			}
		}

		private readonly struct MutationInput
		{
			private readonly SortedInt32KeyNode<HashBucket> _root;

			private readonly IEqualityComparer<T> _equalityComparer;

			private readonly int _count;

			private readonly IEqualityComparer<HashBucket> _hashBucketEqualityComparer;

			internal SortedInt32KeyNode<HashBucket> Root => _root;

			internal IEqualityComparer<T> EqualityComparer => _equalityComparer;

			internal int Count => _count;

			internal IEqualityComparer<HashBucket> HashBucketEqualityComparer => _hashBucketEqualityComparer;

			internal MutationInput(ImmutableHashSet<T> set)
			{
				Requires.NotNull(set, "set");
				_root = set._root;
				_equalityComparer = set._equalityComparer;
				_count = set._count;
				_hashBucketEqualityComparer = set._hashBucketEqualityComparer;
			}

			internal MutationInput(SortedInt32KeyNode<HashBucket> root, IEqualityComparer<T> equalityComparer, IEqualityComparer<HashBucket> hashBucketEqualityComparer, int count)
			{
				Requires.NotNull(root, "root");
				Requires.NotNull(equalityComparer, "equalityComparer");
				Requires.Range(count >= 0, "count");
				Requires.NotNull(hashBucketEqualityComparer, "hashBucketEqualityComparer");
				_root = root;
				_equalityComparer = equalityComparer;
				_count = count;
				_hashBucketEqualityComparer = hashBucketEqualityComparer;
			}
		}

		private enum CountType
		{
			Adjustment,
			FinalValue
		}

		private readonly struct MutationResult
		{
			private readonly SortedInt32KeyNode<HashBucket> _root;

			private readonly int _count;

			private readonly CountType _countType;

			internal SortedInt32KeyNode<HashBucket> Root => _root;

			internal int Count => _count;

			internal CountType CountType => _countType;

			internal MutationResult(SortedInt32KeyNode<HashBucket> root, int count, CountType countType = CountType.Adjustment)
			{
				Requires.NotNull(root, "root");
				_root = root;
				_count = count;
				_countType = countType;
			}

			internal ImmutableHashSet<T> Finalize(ImmutableHashSet<T> priorSet)
			{
				Requires.NotNull(priorSet, "priorSet");
				int num = Count;
				if (CountType == CountType.Adjustment)
				{
					num += priorSet._count;
				}
				return priorSet.Wrap(Root, num);
			}
		}

		private readonly struct NodeEnumerable : IEnumerable<T>, IEnumerable
		{
			private readonly SortedInt32KeyNode<HashBucket> _root;

			internal NodeEnumerable(SortedInt32KeyNode<HashBucket> root)
			{
				Requires.NotNull(root, "root");
				_root = root;
			}

			public Enumerator GetEnumerator()
			{
				return new Enumerator(_root);
			}

			[ExcludeFromCodeCoverage]
			IEnumerator<T> IEnumerable<T>.GetEnumerator()
			{
				return GetEnumerator();
			}

			[ExcludeFromCodeCoverage]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return GetEnumerator();
			}
		}

		public static readonly ImmutableHashSet<T> Empty = new ImmutableHashSet<T>(SortedInt32KeyNode<HashBucket>.EmptyNode, EqualityComparer<T>.Default, 0);

		private static readonly Action<KeyValuePair<int, HashBucket>> s_FreezeBucketAction = delegate(KeyValuePair<int, HashBucket> kv)
		{
			kv.Value.Freeze();
		};

		private readonly IEqualityComparer<T> _equalityComparer;

		private readonly int _count;

		private readonly SortedInt32KeyNode<HashBucket> _root;

		private readonly IEqualityComparer<HashBucket> _hashBucketEqualityComparer;

		public int Count => _count;

		public bool IsEmpty => Count == 0;

		public IEqualityComparer<T> KeyComparer => _equalityComparer;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		object ICollection.SyncRoot => this;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		bool ICollection.IsSynchronized => true;

		internal IBinaryTree Root => _root;

		private MutationInput Origin => new MutationInput(this);

		bool ICollection<T>.IsReadOnly => true;

		internal ImmutableHashSet(IEqualityComparer<T> equalityComparer)
			: this(SortedInt32KeyNode<HashBucket>.EmptyNode, equalityComparer, 0)
		{
		}

		private ImmutableHashSet(SortedInt32KeyNode<HashBucket> root, IEqualityComparer<T> equalityComparer, int count)
		{
			Requires.NotNull(root, "root");
			Requires.NotNull(equalityComparer, "equalityComparer");
			root.Freeze(s_FreezeBucketAction);
			_root = root;
			_count = count;
			_equalityComparer = equalityComparer;
			_hashBucketEqualityComparer = GetHashBucketEqualityComparer(equalityComparer);
		}

		public ImmutableHashSet<T> Clear()
		{
			if (!IsEmpty)
			{
				return Empty.WithComparer(_equalityComparer);
			}
			return this;
		}

		[ExcludeFromCodeCoverage]
		IImmutableSet<T> IImmutableSet<T>.Clear()
		{
			return Clear();
		}

		public Builder ToBuilder()
		{
			return new Builder(this);
		}

		public ImmutableHashSet<T> Add(T item)
		{
			return Add(item, Origin).Finalize(this);
		}

		public ImmutableHashSet<T> Remove(T item)
		{
			return Remove(item, Origin).Finalize(this);
		}

		public bool TryGetValue(T equalValue, out T actualValue)
		{
			int hashCode = _equalityComparer.GetHashCode(equalValue);
			if (_root.TryGetValue(hashCode, out var value))
			{
				return value.TryExchange(equalValue, _equalityComparer, out actualValue);
			}
			actualValue = equalValue;
			return false;
		}

		public ImmutableHashSet<T> Union(IEnumerable<T> other)
		{
			Requires.NotNull(other, "other");
			return Union(other, avoidWithComparer: false);
		}

		public ImmutableHashSet<T> Intersect(IEnumerable<T> other)
		{
			Requires.NotNull(other, "other");
			return Intersect(other, Origin).Finalize(this);
		}

		public ImmutableHashSet<T> Except(IEnumerable<T> other)
		{
			Requires.NotNull(other, "other");
			return Except(other, _equalityComparer, _hashBucketEqualityComparer, _root).Finalize(this);
		}

		public ImmutableHashSet<T> SymmetricExcept(IEnumerable<T> other)
		{
			Requires.NotNull(other, "other");
			return SymmetricExcept(other, Origin).Finalize(this);
		}

		public bool SetEquals(IEnumerable<T> other)
		{
			Requires.NotNull(other, "other");
			if (this == other)
			{
				return true;
			}
			return SetEquals(other, Origin);
		}

		public bool IsProperSubsetOf(IEnumerable<T> other)
		{
			Requires.NotNull(other, "other");
			return IsProperSubsetOf(other, Origin);
		}

		public bool IsProperSupersetOf(IEnumerable<T> other)
		{
			Requires.NotNull(other, "other");
			return IsProperSupersetOf(other, Origin);
		}

		public bool IsSubsetOf(IEnumerable<T> other)
		{
			Requires.NotNull(other, "other");
			return IsSubsetOf(other, Origin);
		}

		public bool IsSupersetOf(IEnumerable<T> other)
		{
			Requires.NotNull(other, "other");
			return IsSupersetOf(other, Origin);
		}

		public bool Overlaps(IEnumerable<T> other)
		{
			Requires.NotNull(other, "other");
			return Overlaps(other, Origin);
		}

		[ExcludeFromCodeCoverage]
		IImmutableSet<T> IImmutableSet<T>.Add(T item)
		{
			return Add(item);
		}

		[ExcludeFromCodeCoverage]
		IImmutableSet<T> IImmutableSet<T>.Remove(T item)
		{
			return Remove(item);
		}

		[ExcludeFromCodeCoverage]
		IImmutableSet<T> IImmutableSet<T>.Union(IEnumerable<T> other)
		{
			return Union(other);
		}

		[ExcludeFromCodeCoverage]
		IImmutableSet<T> IImmutableSet<T>.Intersect(IEnumerable<T> other)
		{
			return Intersect(other);
		}

		[ExcludeFromCodeCoverage]
		IImmutableSet<T> IImmutableSet<T>.Except(IEnumerable<T> other)
		{
			return Except(other);
		}

		[ExcludeFromCodeCoverage]
		IImmutableSet<T> IImmutableSet<T>.SymmetricExcept(IEnumerable<T> other)
		{
			return SymmetricExcept(other);
		}

		public bool Contains(T item)
		{
			return Contains(item, Origin);
		}

		public ImmutableHashSet<T> WithComparer(IEqualityComparer<T> equalityComparer)
		{
			if (equalityComparer == null)
			{
				equalityComparer = EqualityComparer<T>.Default;
			}
			if (equalityComparer == _equalityComparer)
			{
				return this;
			}
			ImmutableHashSet<T> immutableHashSet = new ImmutableHashSet<T>(equalityComparer);
			return immutableHashSet.Union(this, avoidWithComparer: true);
		}

		bool ISet<T>.Add(T item)
		{
			throw new NotSupportedException();
		}

		void ISet<T>.ExceptWith(IEnumerable<T> other)
		{
			throw new NotSupportedException();
		}

		void ISet<T>.IntersectWith(IEnumerable<T> other)
		{
			throw new NotSupportedException();
		}

		void ISet<T>.SymmetricExceptWith(IEnumerable<T> other)
		{
			throw new NotSupportedException();
		}

		void ISet<T>.UnionWith(IEnumerable<T> other)
		{
			throw new NotSupportedException();
		}

		void ICollection<T>.CopyTo(T[] array, int arrayIndex)
		{
			Requires.NotNull(array, "array");
			Requires.Range(arrayIndex >= 0, "arrayIndex");
			Requires.Range(array.Length >= arrayIndex + Count, "arrayIndex");
			using Enumerator enumerator = GetEnumerator();
			while (enumerator.MoveNext())
			{
				T current = enumerator.Current;
				array[arrayIndex++] = current;
			}
		}

		void ICollection<T>.Add(T item)
		{
			throw new NotSupportedException();
		}

		void ICollection<T>.Clear()
		{
			throw new NotSupportedException();
		}

		bool ICollection<T>.Remove(T item)
		{
			throw new NotSupportedException();
		}

		void ICollection.CopyTo(Array array, int arrayIndex)
		{
			Requires.NotNull(array, "array");
			Requires.Range(arrayIndex >= 0, "arrayIndex");
			Requires.Range(array.Length >= arrayIndex + Count, "arrayIndex");
			using Enumerator enumerator = GetEnumerator();
			while (enumerator.MoveNext())
			{
				T current = enumerator.Current;
				array.SetValue(current, arrayIndex++);
			}
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(_root);
		}

		IEnumerator<T> IEnumerable<T>.GetEnumerator()
		{
			if (!IsEmpty)
			{
				return GetEnumerator();
			}
			return Enumerable.Empty<T>().GetEnumerator();
		}

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

		private static bool IsSupersetOf(IEnumerable<T> other, MutationInput origin)
		{
			Requires.NotNull(other, "other");
			foreach (T item in other.GetEnumerableDisposable<T, Enumerator>())
			{
				if (!Contains(item, origin))
				{
					return false;
				}
			}
			return true;
		}

		private static MutationResult Add(T item, MutationInput origin)
		{
			int hashCode = origin.EqualityComparer.GetHashCode(item);
			OperationResult result;
			HashBucket newBucket = origin.Root.GetValueOrDefault(hashCode).Add(item, origin.EqualityComparer, out result);
			if (result == OperationResult.NoChangeRequired)
			{
				return new MutationResult(origin.Root, 0);
			}
			SortedInt32KeyNode<HashBucket> root = UpdateRoot(origin.Root, hashCode, origin.HashBucketEqualityComparer, newBucket);
			return new MutationResult(root, 1);
		}

		private static MutationResult Remove(T item, MutationInput origin)
		{
			OperationResult result = OperationResult.NoChangeRequired;
			int hashCode = origin.EqualityComparer.GetHashCode(item);
			SortedInt32KeyNode<HashBucket> root = origin.Root;
			if (origin.Root.TryGetValue(hashCode, out var value))
			{
				HashBucket newBucket = value.Remove(item, origin.EqualityComparer, out result);
				if (result == OperationResult.NoChangeRequired)
				{
					return new MutationResult(origin.Root, 0);
				}
				root = UpdateRoot(origin.Root, hashCode, origin.HashBucketEqualityComparer, newBucket);
			}
			return new MutationResult(root, (result == OperationResult.SizeChanged) ? (-1) : 0);
		}

		private static bool Contains(T item, MutationInput origin)
		{
			int hashCode = origin.EqualityComparer.GetHashCode(item);
			if (origin.Root.TryGetValue(hashCode, out var value))
			{
				return value.Contains(item, origin.EqualityComparer);
			}
			return false;
		}

		private static MutationResult Union(IEnumerable<T> other, MutationInput origin)
		{
			Requires.NotNull(other, "other");
			int num = 0;
			SortedInt32KeyNode<HashBucket> sortedInt32KeyNode = origin.Root;
			foreach (T item in other.GetEnumerableDisposable<T, Enumerator>())
			{
				int hashCode = origin.EqualityComparer.GetHashCode(item);
				OperationResult result;
				HashBucket newBucket = sortedInt32KeyNode.GetValueOrDefault(hashCode).Add(item, origin.EqualityComparer, out result);
				if (result == OperationResult.SizeChanged)
				{
					sortedInt32KeyNode = UpdateRoot(sortedInt32KeyNode, hashCode, origin.HashBucketEqualityComparer, newBucket);
					num++;
				}
			}
			return new MutationResult(sortedInt32KeyNode, num);
		}

		private static bool Overlaps(IEnumerable<T> other, MutationInput origin)
		{
			Requires.NotNull(other, "other");
			if (origin.Root.IsEmpty)
			{
				return false;
			}
			foreach (T item in other.GetEnumerableDisposable<T, Enumerator>())
			{
				if (Contains(item, origin))
				{
					return true;
				}
			}
			return false;
		}

		private static bool SetEquals(IEnumerable<T> other, MutationInput origin)
		{
			Requires.NotNull(other, "other");
			HashSet<T> hashSet = new HashSet<T>(other, origin.EqualityComparer);
			if (origin.Count != hashSet.Count)
			{
				return false;
			}
			foreach (T item in hashSet)
			{
				if (!Contains(item, origin))
				{
					return false;
				}
			}
			return true;
		}

		private static SortedInt32KeyNode<HashBucket> UpdateRoot(SortedInt32KeyNode<HashBucket> root, int hashCode, IEqualityComparer<HashBucket> hashBucketEqualityComparer, HashBucket newBucket)
		{
			bool mutated;
			if (newBucket.IsEmpty)
			{
				return root.Remove(hashCode, out mutated);
			}
			bool replacedExistingValue;
			return root.SetItem(hashCode, newBucket, hashBucketEqualityComparer, out replacedExistingValue, out mutated);
		}

		private static MutationResult Intersect(IEnumerable<T> other, MutationInput origin)
		{
			Requires.NotNull(other, "other");
			SortedInt32KeyNode<HashBucket> root = SortedInt32KeyNode<HashBucket>.EmptyNode;
			int num = 0;
			foreach (T item in other.GetEnumerableDisposable<T, Enumerator>())
			{
				if (Contains(item, origin))
				{
					MutationResult mutationResult = Add(item, new MutationInput(root, origin.EqualityComparer, origin.HashBucketEqualityComparer, num));
					root = mutationResult.Root;
					num += mutationResult.Count;
				}
			}
			return new MutationResult(root, num, CountType.FinalValue);
		}

		private static MutationResult Except(IEnumerable<T> other, IEqualityComparer<T> equalityComparer, IEqualityComparer<HashBucket> hashBucketEqualityComparer, SortedInt32KeyNode<HashBucket> root)
		{
			Requires.NotNull(other, "other");
			Requires.NotNull(equalityComparer, "equalityComparer");
			Requires.NotNull(root, "root");
			int num = 0;
			SortedInt32KeyNode<HashBucket> sortedInt32KeyNode = root;
			foreach (T item in other.GetEnumerableDisposable<T, Enumerator>())
			{
				int hashCode = equalityComparer.GetHashCode(item);
				if (sortedInt32KeyNode.TryGetValue(hashCode, out var value))
				{
					OperationResult result;
					HashBucket newBucket = value.Remove(item, equalityComparer, out result);
					if (result == OperationResult.SizeChanged)
					{
						num--;
						sortedInt32KeyNode = UpdateRoot(sortedInt32KeyNode, hashCode, hashBucketEqualityComparer, newBucket);
					}
				}
			}
			return new MutationResult(sortedInt32KeyNode, num);
		}

		private static MutationResult SymmetricExcept(IEnumerable<T> other, MutationInput origin)
		{
			Requires.NotNull(other, "other");
			ImmutableHashSet<T> immutableHashSet = ImmutableHashSet.CreateRange(origin.EqualityComparer, other);
			int num = 0;
			SortedInt32KeyNode<HashBucket> root = SortedInt32KeyNode<HashBucket>.EmptyNode;
			foreach (T item in new NodeEnumerable(origin.Root))
			{
				if (!immutableHashSet.Contains(item))
				{
					MutationResult mutationResult = Add(item, new MutationInput(root, origin.EqualityComparer, origin.HashBucketEqualityComparer, num));
					root = mutationResult.Root;
					num += mutationResult.Count;
				}
			}
			foreach (T item2 in immutableHashSet)
			{
				if (!Contains(item2, origin))
				{
					MutationResult mutationResult2 = Add(item2, new MutationInput(root, origin.EqualityComparer, origin.HashBucketEqualityComparer, num));
					root = mutationResult2.Root;
					num += mutationResult2.Count;
				}
			}
			return new MutationResult(root, num, CountType.FinalValue);
		}

		private static bool IsProperSubsetOf(IEnumerable<T> other, MutationInput origin)
		{
			Requires.NotNull(other, "other");
			if (origin.Root.IsEmpty)
			{
				return other.Any();
			}
			HashSet<T> hashSet = new HashSet<T>(other, origin.EqualityComparer);
			if (origin.Count >= hashSet.Count)
			{
				return false;
			}
			int num = 0;
			bool flag = false;
			foreach (T item in hashSet)
			{
				if (Contains(item, origin))
				{
					num++;
				}
				else
				{
					flag = true;
				}
				if (num == origin.Count && flag)
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsProperSupersetOf(IEnumerable<T> other, MutationInput origin)
		{
			Requires.NotNull(other, "other");
			if (origin.Root.IsEmpty)
			{
				return false;
			}
			int num = 0;
			foreach (T item in other.GetEnumerableDisposable<T, Enumerator>())
			{
				num++;
				if (!Contains(item, origin))
				{
					return false;
				}
			}
			return origin.Count > num;
		}

		private static bool IsSubsetOf(IEnumerable<T> other, MutationInput origin)
		{
			Requires.NotNull(other, "other");
			if (origin.Root.IsEmpty)
			{
				return true;
			}
			HashSet<T> hashSet = new HashSet<T>(other, origin.EqualityComparer);
			int num = 0;
			foreach (T item in hashSet)
			{
				if (Contains(item, origin))
				{
					num++;
				}
			}
			return num == origin.Count;
		}

		private static ImmutableHashSet<T> Wrap(SortedInt32KeyNode<HashBucket> root, IEqualityComparer<T> equalityComparer, int count)
		{
			Requires.NotNull(root, "root");
			Requires.NotNull(equalityComparer, "equalityComparer");
			Requires.Range(count >= 0, "count");
			return new ImmutableHashSet<T>(root, equalityComparer, count);
		}

		private static IEqualityComparer<HashBucket> GetHashBucketEqualityComparer(IEqualityComparer<T> valueComparer)
		{
			if (!ImmutableExtensions.IsValueType<T>())
			{
				return HashBucketByRefEqualityComparer.DefaultInstance;
			}
			if (valueComparer == EqualityComparer<T>.Default)
			{
				return HashBucketByValueEqualityComparer.DefaultInstance;
			}
			return new HashBucketByValueEqualityComparer(valueComparer);
		}

		private ImmutableHashSet<T> Wrap(SortedInt32KeyNode<HashBucket> root, int adjustedCountIfDifferentRoot)
		{
			if (root == _root)
			{
				return this;
			}
			return new ImmutableHashSet<T>(root, _equalityComparer, adjustedCountIfDifferentRoot);
		}

		private ImmutableHashSet<T> Union(IEnumerable<T> items, bool avoidWithComparer)
		{
			Requires.NotNull(items, "items");
			if (IsEmpty && !avoidWithComparer && items is ImmutableHashSet<T> immutableHashSet)
			{
				return immutableHashSet.WithComparer(KeyComparer);
			}
			return Union(items, Origin).Finalize(this);
		}
	}
	internal interface IStrongEnumerable<out T, TEnumerator> where TEnumerator : struct, IStrongEnumerator<T>
	{
		TEnumerator GetEnumerator();
	}
	internal interface IStrongEnumerator<T>
	{
		T Current { get; }

		bool MoveNext();
	}
	internal interface IOrderedCollection<out T> : IEnumerable<T>, IEnumerable
	{
		int Count { get; }

		T this[int index] { get; }
	}
	public static class ImmutableArray
	{
		internal static readonly byte[] TwoElementArray = new byte[2];

		public static ImmutableArray<T> Create<T>()
		{
			return ImmutableArray<T>.Empty;
		}

		public static ImmutableArray<T> Create<T>(T item)
		{
			T[] items = new T[1] { item };
			return new ImmutableArray<T>(items);
		}

		public static ImmutableArray<T> Create<T>(T item1, T item2)
		{
			T[] items = new T[2] { item1, item2 };
			return new ImmutableArray<T>(items);
		}

		public static ImmutableArray<T> Create<T>(T item1, T item2, T item3)
		{
			T[] items = new T[3] { item1, item2, item3 };
			return new ImmutableArray<T>(items);
		}

		public static ImmutableArray<T> Create<T>(T item1, T item2, T item3, T item4)
		{
			T[] items = new T[4] { item1, item2, item3, item4 };
			return new ImmutableArray<T>(items);
		}

		public static ImmutableArray<T> CreateRange<T>(IEnumerable<T> items)
		{
			Requires.NotNull(items, "items");
			if (items is IImmutableArray immutableArray)
			{
				Array array = immutableArray.Array;
				if (array == null)
				{
					throw new InvalidOperationException(System.SR.InvalidOperationOnDefaultArray);
				}
				return new ImmutableArray<T>((T[])array);
			}
			if (items.TryGetCount(out var count))
			{
				return new ImmutableArray<T>(items.ToArray(count));
			}
			return new ImmutableArray<T>(items.ToArray());
		}

		public static ImmutableArray<T> Create<T>(params T[] items)
		{
			if (items == null)
			{
				return Create<T>();
			}
			return CreateDefensiveCopy(items);
		}

		public static ImmutableArray<T> Create<T>(T[] items, int start, int length)
		{
			Requires.NotNull(items, "items");
			Requires.Range(start >= 0 && start <= items.Length, "start");
			Requires.Range(length >= 0 && start + length <= items.Length, "length");
			if (length == 0)
			{
				return Create<T>();
			}
			T[] array = new T[length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = items[start + i];
			}
			return new ImmutableArray<T>(array);
		}

		public static ImmutableArray<T> Create<T>(ImmutableArray<T> items, int start, int length)
		{
			Requires.Range(start >= 0 && start <= items.Length, "start");
			Requires.Range(length >= 0 && start + length <= items.Length, "length");
			if (length == 0)
			{
				return Create<T>();
			}
			if (start == 0 && length == items.Length)
			{
				return items;
			}
			T[] array = new T[length];
			Array.Copy(items.array, start, array, 0, length);
			return new ImmutableArray<T>(array);
		}

		public static ImmutableArray<TResult> CreateRange<TSource, TResult>(ImmutableArray<TSource> items, Func<TSource, TResult> selector)
		{
			Requires.NotNull(selector, "selector");
			int length = items.Length;
			if (length == 0)
			{
				return Create<TResult>();
			}
			TResult[] array = new TResult[length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = selector(items[i]);
			}
			return new ImmutableArray<TResult>(array);
		}

		public static ImmutableArray<TResult> CreateRange<TSource, TResult>(ImmutableArray<TSource> items, int start, int length, Func<TSource, TResult> selector)
		{
			int length2 = items.Length;
			Requires.Range(start >= 0 && start <= length2, "start");
			Requires.Range(length >= 0 && start + length <= length2, "length");
			Requires.NotNull(selector, "selector");
			if (length == 0)
			{
				return Create<TResult>();
			}
			TResult[] array = new TResult[length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = selector(items[i + start]);
			}
			return new ImmutableArray<TResult>(array);
		}

		public static ImmutableArray<TResult> CreateRange<TSource, TArg, TResult>(ImmutableArray<TSource> items, Func<TSource, TArg, TResult> selector, TArg arg)
		{
			Requires.NotNull(selector, "selector");
			int length = items.Length;
			if (length == 0)
			{
				return Create<TResult>();
			}
			TResult[] array = new TResult[length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = selector(items[i], arg);
			}
			return new ImmutableArray<TResult>(array);
		}

		public static ImmutableArray<TResult> CreateRange<TSource, TArg, TResult>(ImmutableArray<TSource> items, int start, int length, Func<TSource, TArg, TResult> selector, TArg arg)
		{
			int length2 = items.Length;
			Requires.Range(start >= 0 && start <= length2, "start");
			Requires.Range(length >= 0 && start + length <= length2, "length");
			Requires.NotNull(selector, "selector");
			if (length == 0)
			{
				return Create<TResult>();
			}
			TResult[] array = new TResult[length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = selector(items[i + start], arg);
			}
			return new ImmutableArray<TResult>(array);
		}

		public static ImmutableArray<T>.Builder CreateBuilder<T>()
		{
			return Create<T>().ToBuilder();
		}

		public static ImmutableArray<T>.Builder CreateBuilder<T>(int initialCapacity)
		{
			return new ImmutableArray<T>.Builder(initialCapacity);
		}

		public static ImmutableArray<TSource> ToImmutableArray<TSource>(this IEnumerable<TSource> items)
		{
			if (items is ImmutableArray<TSource>)
			{
				return (ImmutableArray<TSource>)(object)items;
			}
			return CreateRange(items);
		}

		public static ImmutableArray<TSource> ToImmutableArray<TSource>(this ImmutableArray<TSource>.Builder builder)
		{
			Requires.NotNull(builder, "builder");
			return builder.ToImmutable();
		}

		public static int BinarySearch<T>(this ImmutableArray<T> array, T value)
		{
			return Array.BinarySearch(array.array, value);
		}

		public static int BinarySearch<T>(this ImmutableArray<T> array, T value, IComparer<T> comparer)
		{
			return Array.BinarySearch(array.array, value, comparer);
		}

		public static int BinarySearch<T>(this ImmutableArray<T> array, int index, int length, T value)
		{
			return Array.BinarySearch(array.array, index, length, value);
		}

		public static int BinarySearch<T>(this ImmutableArray<T> array, int index, int length, T value, IComparer<T> comparer)
		{
			return Array.BinarySearch(array.array, index, length, value, comparer);
		}

		internal static ImmutableArray<T> CreateDefensiveCopy<T>(T[] items)
		{
			if (items.Length == 0)
			{
				return ImmutableArray<T>.Empty;
			}
			T[] array = new T[items.Length];
			Array.Copy(items, 0, array, 0, items.Length);
			return new ImmutableArray<T>(array);
		}
	}
	[DebuggerDisplay("{DebuggerDisplay,nq}")]
	[System.Runtime.Versioning.NonVersionable]
	public struct ImmutableArray<T> : IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable, IList<T>, ICollection<T>, IEquatable<ImmutableArray<T>>, IList, ICollection, IImmutableArray, IStructuralComparable, IStructuralEquatable, IImmutableList<T>
	{
		[DebuggerDisplay("Count = {Count}")]
		[DebuggerTypeProxy(typeof(ImmutableArrayBuilderDebuggerProxy<>))]
		public sealed class Builder : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyList<T>, IReadOnlyCollection<T>
		{
			private T[] _elements;

			private int _count;

			public int Capacity
			{
				get
				{
					return _elements.Length;
				}
				set
				{
					if (value < _count)
					{
						throw new ArgumentException(System.SR.CapacityMustBeGreaterThanOrEqualToCount, "value");
					}
					if (value == _elements.Length)
					{
						return;
					}
					if (value > 0)
					{
						T[] array = new T[value];
						if (_count > 0)
						{
							Array.Copy(_elements, 0, array, 0, _count);
						}
						_elements = array;
					}
					else
					{
						_elements = ImmutableArray<T>.Empty.array;
					}
				}
			}

			public int Count
			{
				get
				{
					return _count;
				}
				set
				{
					Requires.Range(value >= 0, "value");
					if (value < _count)
					{
						if (_count - value > 64)
						{
							Array.Clear(_elements, value, _count - value);
						}
						else
						{
							for (int i = value; i < Count; i++)
							{
								_elements[i] = default(T);
							}
						}
					}
					else if (value > _count)
					{
						EnsureCapacity(value);
					}
					_count = value;
				}
			}

			public T this[int index]
			{
				get
				{
					if (index >= Count)
					{
						ThrowIndexOutOfRangeException();
					}
					return _elements[index];
				}
				set
				{
					if (index >= Count)
					{
						ThrowIndexOutOfRangeException();
					}
					_elements[index] = value;
				}
			}

			bool ICollection<T>.IsReadOnly => false;

			internal Builder(int capacity)
			{
				Requires.Range(capacity >= 0, "capacity");
				_elements = new T[capacity];
				_count = 0;
			}

			internal Builder()
				: this(8)
			{
			}

			private static void ThrowIndexOutOfRangeException()
			{
				throw new IndexOutOfRangeException();
			}

			public ref readonly T ItemRef(int index)
			{
				if (index >= Count)
				{
					ThrowIndexOutOfRangeException();
				}
				return ref _elements[index];
			}

			public ImmutableArray<T> ToImmutable()
			{
				return new ImmutableArray<T>(ToArray());
			}

			public ImmutableArray<T> MoveToImmutable()
			{
				if (Capacity != Count)
				{
					throw new InvalidOperationException(System.SR.CapacityMustEqualCountOnMove);
				}
				T[] elements = _elements;
				_elements = ImmutableArray<T>.Empty.array;
				_count = 0;
				return new ImmutableArray<T>(elements);
			}

			public void Clear()
			{
				Count = 0;
			}

			public void Insert(int index, T item)
			{
				Requires.Range(index >= 0 && index <= Count, "index");
				EnsureCapacity(Count + 1);
				if (index < Count)
				{
					Array.Copy(_elements, index, _elements, index + 1, Count - index);
				}
				_count++;
				_elements[index] = item;
			}

			public void Add(T item)
			{
				int num = _count + 1;
				EnsureCapacity(num);
				_elements[_count] = item;
				_count = num;
			}

			public void AddRange(IEnumerable<T> items)
			{
				Requires.NotNull(items, "items");
				if (items.TryGetCount(out var count))
				{
					EnsureCapacity(Count + count);
					if (items.TryCopyTo(_elements, _count))
					{
						_count += count;
						return;
					}
				}
				foreach (T item in items)
				{
					Add(item);
				}
			}

			public void AddRange(params T[] items)
			{
				Requires.NotNull(items, "items");
				int count = Count;
				Count += items.Length;
				Array.Copy(items, 0, _elements, count, items.Length);
			}

			public void AddRange<TDerived>(TDerived[] items) where TDerived : T
			{
				Requires.NotNull(items, "items");
				int count = Count;
				Count += items.Length;
				Array.Copy(items, 0, _elements, count, items.Length);
			}

			public void AddRange(T[] items, int length)
			{
				Requires.NotNull(items, "items");
				Requires.Range(length >= 0 && length <= items.Length, "length");
				int count = Count;
				Count += length;
				Array.Copy(items, 0, _elements, count, length);
			}

			public void AddRange(ImmutableArray<T> items)
			{
				AddRange(items, items.Length);
			}

			public void AddRange(ImmutableArray<T> items, int length)
			{
				Requires.Range(length >= 0, "length");
				if (items.array != null)
				{
					AddRange(items.array, length);
				}
			}

			public void AddRange<TDerived>(ImmutableArray<TDerived> items) where TDerived : T
			{
				if (items.array != null)
				{
					AddRange(items.array);
				}
			}

			public void AddRange(Builder items)
			{
				Requires.NotNull(items, "items");
				AddRange(items._elements, items.Count);
			}

			public void AddRange<TDerived>(ImmutableArray<TDerived>.Builder items) where TDerived : T
			{
				Requires.NotNull(items, "items");
				AddRange(items._elements, items.Count);
			}

			public bool Remove(T element)
			{
				int num = IndexOf(element);
				if (num >= 0)
				{
					RemoveAt(num);
					return true;
				}
				return false;
			}

			public void RemoveAt(int index)
			{
				Requires.Range(index >= 0 && index < Count, "index");
				if (index < Count - 1)
				{
					Array.Copy(_elements, index + 1, _elements, index, Count - index - 1);
				}
				Count--;
			}

			public bool Contains(T item)
			{
				return IndexOf(item) >= 0;
			}

			public T[] ToArray()
			{
				if (Count == 0)
				{
					return ImmutableArray<T>.Empty.array;
				}
				T[] array = new T[Count];
				Array.Copy(_elements, 0, array, 0, Count);
				return array;
			}

			public void CopyTo(T[] array, int index)
			{
				Requires.NotNull(array, "array");
				Requires.Range(index >= 0 && index + Count <= array.Length, "index");
				Array.Copy(_elements, 0, array, index, Count);
			}

			private void EnsureCapacity(int capacity)
			{
				if (_elements.Length < capacity)
				{
					int newSize = Math.Max(_elements.Length * 2, capacity);
					Array.Resize(ref _elements, newSize);
				}
			}

			public int IndexOf(T item)
			{
				return IndexOf(item, 0, _count, EqualityComparer<T>.Default);
			}

			public int IndexOf(T item, int startIndex)
			{
				return IndexOf(item, startIndex, Count - startIndex, EqualityComparer<T>.Default);
			}

			public int IndexOf(T item, int startIndex, int count)
			{
				return IndexOf(item, startIndex, count, EqualityComparer<T>.Default);
			}

			public int IndexOf(T item, int startIndex, int count, IEqualityComparer<T> equalityComparer)
			{
				if (count == 0 && startIndex == 0)
				{
					return -1;
				}
				Requires.Range(startIndex >= 0 && startIndex < Count, "startIndex");
				Requires.Range(count >= 0 && startIndex + count <= Count, "count");
				equalityComparer = equalityComparer ?? EqualityComparer<T>.Default;
				if (equalityComparer == EqualityComparer<T>.Default)
				{
					return Array.IndexOf(_elements, item, startIndex, count);
				}
				for (int i = startIndex; i < startIndex + count; i++)
				{
					if (equalityComparer.Equals(_elements[i], item))
					{
						return i;
					}
				}
				return -1;
			}

			public int LastIndexOf(T item)
			{
				if (Count == 0)
				{
					return -1;
				}
				return LastIndexOf(item, Count - 1, Count, EqualityComparer<T>.Default);
			}

			public int LastIndexOf(T item, int startIndex)
			{
				if (Count == 0 && startIndex == 0)
				{
					return -1;
				}
				Requires.Range(startIndex >= 0 && startIndex < Count, "startIndex");
				return LastIndexOf(item, startIndex, startIndex + 1, EqualityComparer<T>.Default);
			}

			public int LastIndexOf(T item, int startIndex, int count)
			{
				return LastIndexOf(item, startIndex, count, EqualityComparer<T>.Default);
			}

			public int LastIndexOf(T item, int startIndex, int count, IEqualityComparer<T> equalityComparer)
			{
				if (count == 0 && startIndex == 0)
				{
					return -1;
				}
				Requires.Range(startIndex >= 0 && startIndex < Count, "startIndex");
				Requires.Range(count >= 0 && startIndex - count + 1 >= 0, "count");
				equalityComparer = equalityComparer ?? EqualityComparer<T>.Default;
				if (equalityComparer == EqualityComparer<T>.Default)
				{
					return Array.LastIndexOf(_elements, item, startIndex, count);
				}
				for (int num = startIndex; num >= startIndex - count + 1; num--)
				{
					if (equalityComparer.Equals(item, _elements[num]))
					{
						return num;
					}
				}
				return -1;
			}

			public void Reverse()
			{
				int num = 0;
				int num2 = _count - 1;
				T[] elements = _elements;
				while (num < num2)
				{
					T val = elements[num];
					elements[num] = elements[num2];
					elements[num2] = val;
					num++;
					num2--;
				}
			}

			public void Sort()
			{
				if (Count > 1)
				{
					Array.Sort(_elements, 0, Count, Comparer<T>.Default);
				}
			}

			public void Sort(Comparison<T> comparison)
			{
				Requires.NotNull(comparison, "comparison");
				if (Count > 1)
				{
					Array.Sort(_elements, 0, _count, Comparer<T>.Create(comparison));
				}
			}

			public void Sort(IComparer<T> comparer)
			{
				if (Count > 1)
				{
					Array.Sort(_elements, 0, _count, comparer);
				}
			}

			public void Sort(int index, int count, IComparer<T> comparer)
			{
				Requires.Range(index >= 0, "index");
				Requires.Range(count >= 0 && index + count <= Count, "count");
				if (count > 1)
				{
					Array.Sort(_elements, index, count, comparer);
				}
			}

			public IEnumerator<T> GetEnumerator()
			{
				for (int i = 0; i < Count; i++)
				{
					yield return this[i];
				}
			}

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

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

			private void AddRange<TDerived>(TDerived[] items, int length) where TDerived : T
			{
				EnsureCapacity(Count + length);
				int count = Count;
				Count += length;
				T[] elements = _elements;
				for (int i = 0; i < length; i++)
				{
					elements[count + i] = (T)(object)items[i];
				}
			}
		}

		public struct Enumerator
		{
			private readonly T[] _array;

			private int _index;

			public T Current => _array[_index];

			internal Enumerator(T[] array)
			{
				_array = array;
				_index = -1;
			}

			public bool MoveNext()
			{
				return ++_index < _array.Length;
			}
		}

		private class EnumeratorObject : IEnumerator<T>, IDisposable, IEnumerator
		{
			private static readonly IEnumerator<T> s_EmptyEnumerator = new EnumeratorObject(ImmutableArray<T>.Empty.array);

			private readonly T[] _array;

			private int _index;

			public T Current
			{
				get
				{
					if ((uint)_index < (uint)_array.Length)
					{
						return _array[_index];
					}
					throw new InvalidOperationException();
				}
			}

			object IEnumerator.Current => Current;

			private EnumeratorObject(T[] array)
			{
				_index = -1;
				_array = array;
			}

			public bool MoveNext()
			{
				int num = _index + 1;
				int num2 = _array.Length;
				if ((uint)num <= (uint)num2)
				{
					_index = num;
					return (uint)num < (uint)num2;
				}
				return false;
			}

			void IEnumerator.Reset()
			{
				_index = -1;
			}

			public void Dispose()
			{
			}

			internal static IEnumerator<T> Create(T[] array)
			{
				if (array.Length != 0)
				{
					return new EnumeratorObject(array);
				}
				return s_EmptyEnumerator;
			}
		}

		public static readonly ImmutableArray<T> Empty = new ImmutableArray<T>(new T[0]);

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		internal T[] array;

		T IList<T>.this[int index]
		{
			get
			{
				ImmutableArray<T> immutableArray = this;
				immutableArray.ThrowInvalidOperationIfNotInitialized();
				return immutableArray[index];
			}
			set
			{
				throw new NotSupportedException();
			}
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		bool ICollection<T>.IsReadOnly => true;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		int ICollection<T>.Count
		{
			get
			{
				ImmutableArray<T> immutableArray = this;
				immutableArray.ThrowInvalidOperationIfNotInitialized();
				return immutableArray.Length;
			}
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		int IReadOnlyCollection<T>.Count
		{
			get
			{
				ImmutableArray<T> immutableArray = this;
				immutableArray.ThrowInvalidOperationIfNotInitialized();
				return immutableArray.Length;
			}
		}

		T IReadOnlyList<T>.this[int index]
		{
			get
			{
				ImmutableArray<T> immutableArray = this;
				immutableArray.ThrowInvalidOperationIfNotInitialized();
				return immutableArray[index];
			}
		}

		[ExcludeFromCodeCoverage]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		bool IList.IsFixedSize => true;

		[ExcludeFromCodeCoverage]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		bool IList.IsReadOnly => true;

		[ExcludeFromCodeCoverage]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		int ICollection.Count
		{
			get
			{
				ImmutableArray<T> immutableArray = this;
				immutableArray.ThrowInvalidOperationIfNotInitialized();
				return immutableArray.Length;
			}
		}

		[ExcludeFromCodeCoverage]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		bool ICollection.IsSynchronized => true;

		[ExcludeFromCodeCoverage]
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		object ICollection.SyncRoot
		{
			get
			{
				throw new NotSupportedException();
			}
		}

		[ExcludeFromCodeCoverage]
		object IList.this[int index]
		{
			get
			{
				ImmutableArray<T> immutableArray = this;
				immutableArray.ThrowInvalidOperationIfNotInitialized();
				return immutableArray[index];
			}
			set
			{
				throw new NotSupportedException();
			}
		}

		public T this[int index]
		{
			[System.Runtime.Versioning.NonVersionable]
			get
			{
				return array[index];
			}
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public bool IsEmpty
		{
			[System.Runtime.Versioning.NonVersionable]
			get
			{
				return Length == 0;
			}
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public int Length
		{
			[System.Runtime.Versioning.NonVersionable]
			get
			{
				return array.Length;
			}
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public bool IsDefault => array == null;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public bool IsDefaultOrEmpty
		{
			get
			{
				ImmutableArray<T> immutableArray = this;
				if (immutableArray.array != null)
				{
					return immutableArray.array.Length == 0;
				}
				return true;
			}
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		Array IImmutableArray.Array => array;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		private string DebuggerDisplay
		{
			get
			{
				ImmutableArray<T> immutableArray = this;
				if (!immutableArray.IsDefault)
				{
					return string.Format(CultureInfo.CurrentCulture, "Length = {0}", immutableArray.Length);
				}
				return "Uninitialized";
			}
		}

		public ReadOnlySpan<T> AsSpan()
		{
			return new ReadOnlySpan<T>(array);
		}

		public ReadOnlyMemory<T> AsMemory()
		{
			return new ReadOnlyMemory<T>(array);
		}

		public int IndexOf(T item)
		{
			ImmutableArray<T> immutableArray = this;
			return immutableArray.IndexOf(item, 0, immutableArray.Length, EqualityComparer<T>.Default);
		}

		public int IndexOf(T item, int startIndex, IEqualityComparer<T> equalityComparer)
		{
			ImmutableArray<T> immutableArray = this;
			return immutableArray.IndexOf(item, startIndex, immutableArray.Length - startIndex, equalityComparer);
		}

		public int IndexOf(T item, int startIndex)
		{
			ImmutableArray<T> immutableArray = this;
			return immutableArray.IndexOf(item, startIndex, immutableArray.Length - startIndex, EqualityComparer<T>.Default);
		}

		public int IndexOf(T item, int startIndex, int count)
		{
			return IndexOf(item, startIndex, count, EqualityComparer<T>.Default);
		}

		public int IndexOf(T item, int startIndex, int count, IEqualityComparer<T> equalityComparer)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowNullRefIfNotInitialized();
			if (count == 0 && startIndex == 0)
			{
				return -1;
			}
			Requires.Range(startIndex >= 0 && startIndex < immutableArray.Length, "startIndex");
			Requires.Range(count >= 0 && startIndex + count <= immutableArray.Length, "count");
			equalityComparer = equalityComparer ?? EqualityComparer<T>.Default;
			if (equalityComparer == EqualityComparer<T>.Default)
			{
				return Array.IndexOf(immutableArray.array, item, startIndex, count);
			}
			for (int i = startIndex; i < startIndex + count; i++)
			{
				if (equalityComparer.Equals(immutableArray.array[i], item))
				{
					return i;
				}
			}
			return -1;
		}

		public int LastIndexOf(T item)
		{
			ImmutableArray<T> immutableArray = this;
			if (immutableArray.Length == 0)
			{
				return -1;
			}
			return immutableArray.LastIndexOf(item, immutableArray.Length - 1, immutableArray.Length, EqualityComparer<T>.Default);
		}

		public int LastIndexOf(T item, int startIndex)
		{
			ImmutableArray<T> immutableArray = this;
			if (immutableArray.Length == 0 && startIndex == 0)
			{
				return -1;
			}
			return immutableArray.LastIndexOf(item, startIndex, startIndex + 1, EqualityComparer<T>.Default);
		}

		public int LastIndexOf(T item, int startIndex, int count)
		{
			return LastIndexOf(item, startIndex, count, EqualityComparer<T>.Default);
		}

		public int LastIndexOf(T item, int startIndex, int count, IEqualityComparer<T> equalityComparer)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowNullRefIfNotInitialized();
			if (startIndex == 0 && count == 0)
			{
				return -1;
			}
			Requires.Range(startIndex >= 0 && startIndex < immutableArray.Length, "startIndex");
			Requires.Range(count >= 0 && startIndex - count + 1 >= 0, "count");
			equalityComparer = equalityComparer ?? EqualityComparer<T>.Default;
			if (equalityComparer == EqualityComparer<T>.Default)
			{
				return Array.LastIndexOf(immutableArray.array, item, startIndex, count);
			}
			for (int num = startIndex; num >= startIndex - count + 1; num--)
			{
				if (equalityComparer.Equals(item, immutableArray.array[num]))
				{
					return num;
				}
			}
			return -1;
		}

		public bool Contains(T item)
		{
			return IndexOf(item) >= 0;
		}

		public ImmutableArray<T> Insert(int index, T item)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowNullRefIfNotInitialized();
			Requires.Range(index >= 0 && index <= immutableArray.Length, "index");
			if (immutableArray.Length == 0)
			{
				return ImmutableArray.Create(item);
			}
			T[] array = new T[immutableArray.Length + 1];
			array[index] = item;
			if (index != 0)
			{
				Array.Copy(immutableArray.array, 0, array, 0, index);
			}
			if (index != immutableArray.Length)
			{
				Array.Copy(immutableArray.array, index, array, index + 1, immutableArray.Length - index);
			}
			return new ImmutableArray<T>(array);
		}

		public ImmutableArray<T> InsertRange(int index, IEnumerable<T> items)
		{
			ImmutableArray<T> result = this;
			result.ThrowNullRefIfNotInitialized();
			Requires.Range(index >= 0 && index <= result.Length, "index");
			Requires.NotNull(items, "items");
			if (result.Length == 0)
			{
				return ImmutableArray.CreateRange(items);
			}
			int count = ImmutableExtensions.GetCount(ref items);
			if (count == 0)
			{
				return result;
			}
			T[] array = new T[result.Length + count];
			if (index != 0)
			{
				Array.Copy(result.array, 0, array, 0, index);
			}
			if (index != result.Length)
			{
				Array.Copy(result.array, index, array, index + count, result.Length - index);
			}
			if (!items.TryCopyTo(array, index))
			{
				int num = index;
				foreach (T item in items)
				{
					array[num++] = item;
				}
			}
			return new ImmutableArray<T>(array);
		}

		public ImmutableArray<T> InsertRange(int index, ImmutableArray<T> items)
		{
			ImmutableArray<T> result = this;
			result.ThrowNullRefIfNotInitialized();
			items.ThrowNullRefIfNotInitialized();
			Requires.Range(index >= 0 && index <= result.Length, "index");
			if (result.IsEmpty)
			{
				return items;
			}
			if (items.IsEmpty)
			{
				return result;
			}
			T[] array = new T[result.Length + items.Length];
			if (index != 0)
			{
				Array.Copy(result.array, 0, array, 0, index);
			}
			if (index != result.Length)
			{
				Array.Copy(result.array, index, array, index + items.Length, result.Length - index);
			}
			Array.Copy(items.array, 0, array, index, items.Length);
			return new ImmutableArray<T>(array);
		}

		public ImmutableArray<T> Add(T item)
		{
			ImmutableArray<T> immutableArray = this;
			if (immutableArray.Length == 0)
			{
				return ImmutableArray.Create(item);
			}
			return immutableArray.Insert(immutableArray.Length, item);
		}

		public ImmutableArray<T> AddRange(IEnumerable<T> items)
		{
			ImmutableArray<T> immutableArray = this;
			return immutableArray.InsertRange(immutableArray.Length, items);
		}

		public ImmutableArray<T> AddRange(ImmutableArray<T> items)
		{
			ImmutableArray<T> immutableArray = this;
			return immutableArray.InsertRange(immutableArray.Length, items);
		}

		public ImmutableArray<T> SetItem(int index, T item)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowNullRefIfNotInitialized();
			Requires.Range(index >= 0 && index < immutableArray.Length, "index");
			T[] array = new T[immutableArray.Length];
			Array.Copy(immutableArray.array, 0, array, 0, immutableArray.Length);
			array[index] = item;
			return new ImmutableArray<T>(array);
		}

		public ImmutableArray<T> Replace(T oldValue, T newValue)
		{
			return Replace(oldValue, newValue, EqualityComparer<T>.Default);
		}

		public ImmutableArray<T> Replace(T oldValue, T newValue, IEqualityComparer<T> equalityComparer)
		{
			ImmutableArray<T> immutableArray = this;
			int num = immutableArray.IndexOf(oldValue, 0, immutableArray.Length, equalityComparer);
			if (num < 0)
			{
				throw new ArgumentException(System.SR.CannotFindOldValue, "oldValue");
			}
			return immutableArray.SetItem(num, newValue);
		}

		public ImmutableArray<T> Remove(T item)
		{
			return Remove(item, EqualityComparer<T>.Default);
		}

		public ImmutableArray<T> Remove(T item, IEqualityComparer<T> equalityComparer)
		{
			ImmutableArray<T> result = this;
			result.ThrowNullRefIfNotInitialized();
			int num = result.IndexOf(item, 0, result.Length, equalityComparer);
			if (num >= 0)
			{
				return result.RemoveAt(num);
			}
			return result;
		}

		public ImmutableArray<T> RemoveAt(int index)
		{
			return RemoveRange(index, 1);
		}

		public ImmutableArray<T> RemoveRange(int index, int length)
		{
			ImmutableArray<T> result = this;
			result.ThrowNullRefIfNotInitialized();
			Requires.Range(index >= 0 && index <= result.Length, "index");
			Requires.Range(length >= 0 && index + length <= result.Length, "length");
			if (length == 0)
			{
				return result;
			}
			T[] array = new T[result.Length - length];
			Array.Copy(result.array, 0, array, 0, index);
			Array.Copy(result.array, index + length, array, index, result.Length - index - length);
			return new ImmutableArray<T>(array);
		}

		public ImmutableArray<T> RemoveRange(IEnumerable<T> items)
		{
			return RemoveRange(items, EqualityComparer<T>.Default);
		}

		public ImmutableArray<T> RemoveRange(IEnumerable<T> items, IEqualityComparer<T> equalityComparer)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowNullRefIfNotInitialized();
			Requires.NotNull(items, "items");
			SortedSet<int> sortedSet = new SortedSet<int>();
			foreach (T item in items)
			{
				int num = immutableArray.IndexOf(item, 0, immutableArray.Length, equalityComparer);
				while (num >= 0 && !sortedSet.Add(num) && num + 1 < immutableArray.Length)
				{
					num = immutableArray.IndexOf(item, num + 1, equalityComparer);
				}
			}
			return immutableArray.RemoveAtRange(sortedSet);
		}

		public ImmutableArray<T> RemoveRange(ImmutableArray<T> items)
		{
			return RemoveRange(items, EqualityComparer<T>.Default);
		}

		public ImmutableArray<T> RemoveRange(ImmutableArray<T> items, IEqualityComparer<T> equalityComparer)
		{
			ImmutableArray<T> result = this;
			Requires.NotNull(items.array, "items");
			if (items.IsEmpty)
			{
				result.ThrowNullRefIfNotInitialized();
				return result;
			}
			if (items.Length == 1)
			{
				return result.Remove(items[0], equalityComparer);
			}
			return result.RemoveRange(items.array, equalityComparer);
		}

		public ImmutableArray<T> RemoveAll(Predicate<T> match)
		{
			ImmutableArray<T> result = this;
			result.ThrowNullRefIfNotInitialized();
			Requires.NotNull(match, "match");
			if (result.IsEmpty)
			{
				return result;
			}
			List<int> list = null;
			for (int i = 0; i < result.array.Length; i++)
			{
				if (match(result.array[i]))
				{
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(i);
				}
			}
			if (list == null)
			{
				return result;
			}
			return result.RemoveAtRange(list);
		}

		public ImmutableArray<T> Clear()
		{
			return Empty;
		}

		public ImmutableArray<T> Sort()
		{
			ImmutableArray<T> immutableArray = this;
			return immutableArray.Sort(0, immutableArray.Length, Comparer<T>.Default);
		}

		public ImmutableArray<T> Sort(Comparison<T> comparison)
		{
			Requires.NotNull(comparison, "comparison");
			ImmutableArray<T> immutableArray = this;
			return immutableArray.Sort(Comparer<T>.Create(comparison));
		}

		public ImmutableArray<T> Sort(IComparer<T> comparer)
		{
			ImmutableArray<T> immutableArray = this;
			return immutableArray.Sort(0, immutableArray.Length, comparer);
		}

		public ImmutableArray<T> Sort(int index, int count, IComparer<T> comparer)
		{
			ImmutableArray<T> result = this;
			result.ThrowNullRefIfNotInitialized();
			Requires.Range(index >= 0, "index");
			Requires.Range(count >= 0 && index + count <= result.Length, "count");
			if (count > 1)
			{
				if (comparer == null)
				{
					comparer = Comparer<T>.Default;
				}
				bool flag = false;
				for (int i = index + 1; i < index + count; i++)
				{
					if (comparer.Compare(result.array[i - 1], result.array[i]) > 0)
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					T[] array = new T[result.Length];
					Array.Copy(result.array, 0, array, 0, result.Length);
					Array.Sort(array, index, count, comparer);
					return new ImmutableArray<T>(array);
				}
			}
			return result;
		}

		public IEnumerable<TResult> OfType<TResult>()
		{
			ImmutableArray<T> immutableArray = this;
			if (immutableArray.array == null || immutableArray.array.Length == 0)
			{
				return Enumerable.Empty<TResult>();
			}
			return immutableArray.array.OfType<TResult>();
		}

		void IList<T>.Insert(int index, T item)
		{
			throw new NotSupportedException();
		}

		void IList<T>.RemoveAt(int index)
		{
			throw new NotSupportedException();
		}

		void ICollection<T>.Add(T item)
		{
			throw new NotSupportedException();
		}

		void ICollection<T>.Clear()
		{
			throw new NotSupportedException();
		}

		bool ICollection<T>.Remove(T item)
		{
			throw new NotSupportedException();
		}

		[ExcludeFromCodeCoverage]
		IImmutableList<T> IImmutableList<T>.Clear()
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.Clear();
		}

		[ExcludeFromCodeCoverage]
		IImmutableList<T> IImmutableList<T>.Add(T value)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.Add(value);
		}

		[ExcludeFromCodeCoverage]
		IImmutableList<T> IImmutableList<T>.AddRange(IEnumerable<T> items)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.AddRange(items);
		}

		[ExcludeFromCodeCoverage]
		IImmutableList<T> IImmutableList<T>.Insert(int index, T element)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.Insert(index, element);
		}

		[ExcludeFromCodeCoverage]
		IImmutableList<T> IImmutableList<T>.InsertRange(int index, IEnumerable<T> items)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.InsertRange(index, items);
		}

		[ExcludeFromCodeCoverage]
		IImmutableList<T> IImmutableList<T>.Remove(T value, IEqualityComparer<T> equalityComparer)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.Remove(value, equalityComparer);
		}

		[ExcludeFromCodeCoverage]
		IImmutableList<T> IImmutableList<T>.RemoveAll(Predicate<T> match)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.RemoveAll(match);
		}

		[ExcludeFromCodeCoverage]
		IImmutableList<T> IImmutableList<T>.RemoveRange(IEnumerable<T> items, IEqualityComparer<T> equalityComparer)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.RemoveRange(items, equalityComparer);
		}

		[ExcludeFromCodeCoverage]
		IImmutableList<T> IImmutableList<T>.RemoveRange(int index, int count)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.RemoveRange(index, count);
		}

		[ExcludeFromCodeCoverage]
		IImmutableList<T> IImmutableList<T>.RemoveAt(int index)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.RemoveAt(index);
		}

		[ExcludeFromCodeCoverage]
		IImmutableList<T> IImmutableList<T>.SetItem(int index, T value)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.SetItem(index, value);
		}

		IImmutableList<T> IImmutableList<T>.Replace(T oldValue, T newValue, IEqualityComparer<T> equalityComparer)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.Replace(oldValue, newValue, equalityComparer);
		}

		[ExcludeFromCodeCoverage]
		int IList.Add(object value)
		{
			throw new NotSupportedException();
		}

		[ExcludeFromCodeCoverage]
		void IList.Clear()
		{
			throw new NotSupportedException();
		}

		[ExcludeFromCodeCoverage]
		bool IList.Contains(object value)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.Contains((T)value);
		}

		[ExcludeFromCodeCoverage]
		int IList.IndexOf(object value)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			return immutableArray.IndexOf((T)value);
		}

		[ExcludeFromCodeCoverage]
		void IList.Insert(int index, object value)
		{
			throw new NotSupportedException();
		}

		[ExcludeFromCodeCoverage]
		void IList.Remove(object value)
		{
			throw new NotSupportedException();
		}

		[ExcludeFromCodeCoverage]
		void IList.RemoveAt(int index)
		{
			throw new NotSupportedException();
		}

		[ExcludeFromCodeCoverage]
		void ICollection.CopyTo(Array array, int index)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowInvalidOperationIfNotInitialized();
			Array.Copy(immutableArray.array, 0, array, index, immutableArray.Length);
		}

		bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
		{
			ImmutableArray<T> immutableArray = this;
			Array array = other as Array;
			if (array == null && other is IImmutableArray immutableArray2)
			{
				array = immutableArray2.Array;
				if (immutableArray.array == null && array == null)
				{
					return true;
				}
				if (immutableArray.array == null)
				{
					return false;
				}
			}
			IStructuralEquatable structuralEquatable = immutableArray.array;
			return structuralEquatable.Equals(array, comparer);
		}

		int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
		{
			ImmutableArray<T> immutableArray = this;
			return ((IStructuralEquatable)immutableArray.array)?.GetHashCode(comparer) ?? immutableArray.GetHashCode();
		}

		int IStructuralComparable.CompareTo(object other, IComparer comparer)
		{
			ImmutableArray<T> immutableArray = this;
			Array array = other as Array;
			if (array == null && other is IImmutableArray immutableArray2)
			{
				array = immutableArray2.Array;
				if (immutableArray.array == null && array == null)
				{
					return 0;
				}
				if ((immutableArray.array == null) ^ (array == null))
				{
					throw new ArgumentException(System.SR.ArrayInitializedStateNotEqual, "other");
				}
			}
			if (array != null)
			{
				IStructuralComparable structuralComparable = immutableArray.array;
				return structuralComparable.CompareTo(array, comparer);
			}
			throw new ArgumentException(System.SR.ArrayLengthsNotEqual, "other");
		}

		private ImmutableArray<T> RemoveAtRange(ICollection<int> indicesToRemove)
		{
			ImmutableArray<T> result = this;
			result.ThrowNullRefIfNotInitialized();
			Requires.NotNull(indicesToRemove, "indicesToRemove");
			if (indicesToRemove.Count == 0)
			{
				return result;
			}
			T[] array = new T[result.Length - indicesToRemove.Count];
			int num = 0;
			int num2 = 0;
			int num3 = -1;
			foreach (int item in indicesToRemove)
			{
				int num4 = ((num3 == -1) ? item : (item - num3 - 1));
				Array.Copy(result.array, num + num2, array, num, num4);
				num2++;
				num += num4;
				num3 = item;
			}
			Array.Copy(result.array, num + num2, array, num, result.Length - (num + num2));
			return new ImmutableArray<T>(array);
		}

		internal ImmutableArray(T[] items)
		{
			array = items;
		}

		[System.Runtime.Versioning.NonVersionable]
		public static bool operator ==(ImmutableArray<T> left, ImmutableArray<T> right)
		{
			return left.Equals(right);
		}

		[System.Runtime.Versioning.NonVersionable]
		public static bool operator !=(ImmutableArray<T> left, ImmutableArray<T> right)
		{
			return !left.Equals(right);
		}

		public static bool operator ==(ImmutableArray<T>? left, ImmutableArray<T>? right)
		{
			return left.GetValueOrDefault().Equals(right.GetValueOrDefault());
		}

		public static bool operator !=(ImmutableArray<T>? left, ImmutableArray<T>? right)
		{
			return !left.GetValueOrDefault().Equals(right.GetValueOrDefault());
		}

		public ref readonly T ItemRef(int index)
		{
			return ref array[index];
		}

		public void CopyTo(T[] destination)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowNullRefIfNotInitialized();
			Array.Copy(immutableArray.array, 0, destination, 0, immutableArray.Length);
		}

		public void CopyTo(T[] destination, int destinationIndex)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowNullRefIfNotInitialized();
			Array.Copy(immutableArray.array, 0, destination, destinationIndex, immutableArray.Length);
		}

		public void CopyTo(int sourceIndex, T[] destination, int destinationIndex, int length)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowNullRefIfNotInitialized();
			Array.Copy(immutableArray.array, sourceIndex, destination, destinationIndex, length);
		}

		public Builder ToBuilder()
		{
			ImmutableArray<T> items = this;
			if (items.Length == 0)
			{
				return new Builder();
			}
			Builder builder = new Builder(items.Length);
			builder.AddRange(items);
			return builder;
		}

		p

config/ServerCharacters-master/ServerCharacters/Libs/System.IO.Compression.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO.Compression;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;

[assembly: CompilationRelaxations(8)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ComVisible(false)]
[assembly: CLSCompliant(true)]
[assembly: SecurityTransparent]
[assembly: SecurityRules(SecurityRuleSet.Level2, SkipVerificationInFullTrust = true)]
[assembly: AssemblyTitle("System.IO.Compression.dll")]
[assembly: AssemblyDescription("System.IO.Compression.dll")]
[assembly: AssemblyDefaultAlias("System.IO.Compression.dll")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoftยฎ .NET Framework")]
[assembly: AssemblyCopyright("ยฉ Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyFileVersion("4.8.9032.0")]
[assembly: AssemblyInformationalVersion("4.8.9032.0")]
[assembly: SatelliteContractVersion("4.0.0.0")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyDelaySign(true)]
[assembly: AssemblyKeyFile("f:\\dd\\tools\\devdiv\\EcmaPublicKey.snk")]
[assembly: AssemblySignatureKey("002400000c800000140100000602000000240000525341310008000001000100613399aff18ef1a2c2514a273a42d9042b72321f1757102df9ebada69923e2738406c21e5b801552ab8d200a65a235e001ac9adc25f2d811eb09496a4c6a59d4619589c69f5baf0c4179a47311d92555cd006acc8b5959f2bd6e10e360c34537a1d266da8085856583c85d81da7f3ec01ed9564c58d93d713cd0172c8e23a10f0239b80c96b07736f5d8b022542a4e74251a5f432824318b3539a5a087f8e53d2f135f9ca47f3bb2e10aff0af0849504fb7cea3ff192dc8de0edad64c68efde34c56d302ad55fd6e80f302d5efcdeae953658d3452561b5f36c542efdbdd9f888538d374cef106acf7d93a4445c3c73cd911f0571aaf3d54da12b11ddec375b3", "a5a866e1ee186f807668209f3b11236ace5e21f117803a3143abb126dd035d7d2f876b6938aaf2ee3414d5420d753621400db44a49c486ce134300a2106adb6bdb433590fef8ad5c43cba82290dc49530effd86523d9483c00f458af46890036b0e2c61d077d7fbac467a506eba29e467a87198b053c749aa2a4d2840c784e6d")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyVersion("4.0.0.0")]
[assembly: TypeForwardedTo(typeof(CompressionLevel))]
[assembly: TypeForwardedTo(typeof(CompressionMode))]
[assembly: TypeForwardedTo(typeof(DeflateStream))]
[assembly: TypeForwardedTo(typeof(GZipStream))]
namespace System.IO.Compression;

internal static class Crc32Helper
{
	private static readonly uint[] crcTable = new uint[256]
	{
		0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, 249268274u, 2044508324u,
		3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, 498536548u, 1789927666u, 4089016648u, 2227061214u,
		450548861u, 1843258603u, 4107580753u, 2211677639u, 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u,
		4195302755u, 2366115317u, 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u,
		901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, 651767980u, 1373503546u,
		3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, 671266974u, 1594198024u, 3322730930u, 2970347812u,
		795835527u, 1483230225u, 3244367275u, 3060149565u, 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u,
		2680153253u, 3904427059u, 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u,
		1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, 1706088902u, 314042704u,
		2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, 1303535960u, 984961486u, 2747007092u, 3569037538u,
		1256170817u, 1037604311u, 2765210733u, 3554079995u, 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u,
		2852801631u, 3708648649u, 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u,
		1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, 3988292384u, 2596254646u,
		62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, 3814918930u, 2489596804u, 225274430u, 2053790376u,
		3826175755u, 2466906013u, 167816743u, 2097651377u, 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u,
		426522225u, 1852507879u, 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u,
		3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, 3624741850u, 2936675148u,
		906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, 3412177804u, 3160834842u, 628085408u, 1382605366u,
		3423369109u, 3138078467u, 570562233u, 1426400815u, 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u,
		752459403u, 1541320221u, 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u,
		2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, 2262029012u, 4057260610u,
		1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, 2282248934u, 4279200368u, 1711684554u, 285281116u,
		2405801727u, 4167216745u, 1634467795u, 376229701u, 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u,
		1231636301u, 1047427035u, 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u,
		3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, 3009837614u, 3294710456u,
		1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u
	};

	public static uint UpdateCrc32(uint crc32, byte[] buffer, int offset, int length)
	{
		crc32 ^= 0xFFFFFFFFu;
		while (--length >= 0)
		{
			crc32 = crcTable[(crc32 ^ buffer[offset++]) & 0xFF] ^ (crc32 >> 8);
		}
		crc32 ^= 0xFFFFFFFFu;
		return crc32;
	}
}
internal class WrappedStream : Stream
{
	private readonly Stream _baseStream;

	private readonly EventHandler _onClosed;

	private bool _canRead;

	private bool _canWrite;

	private bool _canSeek;

	private bool _isDisposed;

	private readonly bool _closeBaseStream;

	public override long Length
	{
		get
		{
			ThrowIfDisposed();
			return _baseStream.Length;
		}
	}

	public override long Position
	{
		get
		{
			ThrowIfDisposed();
			return _baseStream.Position;
		}
		set
		{
			ThrowIfDisposed();
			ThrowIfCantSeek();
			_baseStream.Position = value;
		}
	}

	public override bool CanRead
	{
		get
		{
			if (_canRead)
			{
				return _baseStream.CanRead;
			}
			return false;
		}
	}

	public override bool CanSeek
	{
		get
		{
			if (_canSeek)
			{
				return _baseStream.CanSeek;
			}
			return false;
		}
	}

	public override bool CanWrite
	{
		get
		{
			if (_canWrite)
			{
				return _baseStream.CanWrite;
			}
			return false;
		}
	}

	internal WrappedStream(Stream baseStream, bool canRead, bool canWrite, bool canSeek, EventHandler onClosed)
		: this(baseStream, canRead, canWrite, canSeek, closeBaseStream: false, onClosed)
	{
	}

	internal WrappedStream(Stream baseStream, bool canRead, bool canWrite, bool canSeek, bool closeBaseStream, EventHandler onClosed)
	{
		_baseStream = baseStream;
		_onClosed = onClosed;
		_canRead = canRead;
		_canSeek = canSeek;
		_canWrite = canWrite;
		_isDisposed = false;
		_closeBaseStream = closeBaseStream;
	}

	internal WrappedStream(Stream baseStream, EventHandler onClosed)
		: this(baseStream, canRead: true, canWrite: true, canSeek: true, onClosed)
	{
	}

	private void ThrowIfDisposed()
	{
		if (_isDisposed)
		{
			throw new ObjectDisposedException(GetType().Name, Messages.HiddenStreamName);
		}
	}

	private void ThrowIfCantRead()
	{
		if (!CanWrite)
		{
			throw new NotSupportedException(Messages.WritingNotSupported);
		}
	}

	private void ThrowIfCantWrite()
	{
		if (!CanWrite)
		{
			throw new NotSupportedException(Messages.WritingNotSupported);
		}
	}

	private void ThrowIfCantSeek()
	{
		if (!CanSeek)
		{
			throw new NotSupportedException(Messages.SeekingNotSupported);
		}
	}

	public override int Read(byte[] buffer, int offset, int count)
	{
		ThrowIfDisposed();
		ThrowIfCantRead();
		return _baseStream.Read(buffer, offset, count);
	}

	public override long Seek(long offset, SeekOrigin origin)
	{
		ThrowIfDisposed();
		ThrowIfCantSeek();
		return _baseStream.Seek(offset, origin);
	}

	public override void SetLength(long value)
	{
		ThrowIfDisposed();
		ThrowIfCantSeek();
		ThrowIfCantWrite();
		_baseStream.SetLength(value);
	}

	public override void Write(byte[] buffer, int offset, int count)
	{
		ThrowIfDisposed();
		ThrowIfCantWrite();
		_baseStream.Write(buffer, offset, count);
	}

	public override void Flush()
	{
		ThrowIfDisposed();
		ThrowIfCantWrite();
		_baseStream.Flush();
	}

	protected override void Dispose(bool disposing)
	{
		if (disposing && !_isDisposed)
		{
			if (_onClosed != null)
			{
				_onClosed(this, null);
			}
			if (_closeBaseStream)
			{
				_baseStream.Dispose();
			}
			_canRead = false;
			_canWrite = false;
			_canSeek = false;
			_isDisposed = true;
		}
		base.Dispose(disposing);
	}
}
internal class SubReadStream : Stream
{
	private readonly long _startInSuperStream;

	private long _positionInSuperStream;

	private readonly long _endInSuperStream;

	private readonly Stream _superStream;

	private bool _canRead;

	private bool _isDisposed;

	public override long Length
	{
		get
		{
			ThrowIfDisposed();
			return _endInSuperStream - _startInSuperStream;
		}
	}

	public override long Position
	{
		get
		{
			ThrowIfDisposed();
			return _positionInSuperStream - _startInSuperStream;
		}
		set
		{
			ThrowIfDisposed();
			throw new NotSupportedException(Messages.SeekingNotSupported);
		}
	}

	public override bool CanRead
	{
		get
		{
			if (_superStream.CanRead)
			{
				return _canRead;
			}
			return false;
		}
	}

	public override bool CanSeek => false;

	public override bool CanWrite => false;

	public SubReadStream(Stream superStream, long startPosition, long maxLength)
	{
		_startInSuperStream = startPosition;
		_positionInSuperStream = startPosition;
		_endInSuperStream = startPosition + maxLength;
		_superStream = superStream;
		_canRead = true;
		_isDisposed = false;
	}

	private void ThrowIfDisposed()
	{
		if (_isDisposed)
		{
			throw new ObjectDisposedException(GetType().Name, Messages.HiddenStreamName);
		}
	}

	private void ThrowIfCantRead()
	{
		if (!CanRead)
		{
			throw new NotSupportedException(Messages.ReadingNotSupported);
		}
	}

	public override int Read(byte[] buffer, int offset, int count)
	{
		int num = count;
		ThrowIfDisposed();
		ThrowIfCantRead();
		if (_superStream.Position != _positionInSuperStream)
		{
			_superStream.Seek(_positionInSuperStream, SeekOrigin.Begin);
		}
		if (_positionInSuperStream + count > _endInSuperStream)
		{
			count = (int)(_endInSuperStream - _positionInSuperStream);
		}
		int num2 = _superStream.Read(buffer, offset, count);
		_positionInSuperStream += num2;
		return num2;
	}

	public override long Seek(long offset, SeekOrigin origin)
	{
		ThrowIfDisposed();
		throw new NotSupportedException(Messages.SeekingNotSupported);
	}

	public override void SetLength(long value)
	{
		ThrowIfDisposed();
		throw new NotSupportedException(Messages.SetLengthRequiresSeekingAndWriting);
	}

	public override void Write(byte[] buffer, int offset, int count)
	{
		ThrowIfDisposed();
		throw new NotSupportedException(Messages.WritingNotSupported);
	}

	public override void Flush()
	{
		ThrowIfDisposed();
		throw new NotSupportedException(Messages.WritingNotSupported);
	}

	protected override void Dispose(bool disposing)
	{
		if (disposing && !_isDisposed)
		{
			_canRead = false;
			_isDisposed = true;
		}
		base.Dispose(disposing);
	}
}
internal class CheckSumAndSizeWriteStream : Stream
{
	private readonly Stream _baseStream;

	private readonly Stream _baseBaseStream;

	private long _position;

	private uint _checksum;

	private readonly bool _leaveOpenOnClose;

	private bool _canWrite;

	private bool _isDisposed;

	private bool _everWritten;

	private long _initialPosition;

	private readonly Action<long, long, uint> _saveCrcAndSizes;

	public override long Length
	{
		get
		{
			ThrowIfDisposed();
			throw new NotSupportedException(Messages.SeekingNotSupported);
		}
	}

	public override long Position
	{
		get
		{
			ThrowIfDisposed();
			return _position;
		}
		set
		{
			ThrowIfDisposed();
			throw new NotSupportedException(Messages.SeekingNotSupported);
		}
	}

	public override bool CanRead => false;

	public override bool CanSeek => false;

	public override bool CanWrite => _canWrite;

	public CheckSumAndSizeWriteStream(Stream baseStream, Stream baseBaseStream, bool leaveOpenOnClose, Action<long, long, uint> saveCrcAndSizes)
	{
		_baseStream = baseStream;
		_baseBaseStream = baseBaseStream;
		_position = 0L;
		_checksum = 0u;
		_leaveOpenOnClose = leaveOpenOnClose;
		_canWrite = true;
		_isDisposed = false;
		_initialPosition = 0L;
		_saveCrcAndSizes = saveCrcAndSizes;
	}

	private void ThrowIfDisposed()
	{
		if (_isDisposed)
		{
			throw new ObjectDisposedException(GetType().Name, Messages.HiddenStreamName);
		}
	}

	public override int Read(byte[] buffer, int offset, int count)
	{
		ThrowIfDisposed();
		throw new NotSupportedException(Messages.ReadingNotSupported);
	}

	public override long Seek(long offset, SeekOrigin origin)
	{
		ThrowIfDisposed();
		throw new NotSupportedException(Messages.SeekingNotSupported);
	}

	public override void SetLength(long value)
	{
		ThrowIfDisposed();
		throw new NotSupportedException(Messages.SetLengthRequiresSeekingAndWriting);
	}

	public override void Write(byte[] buffer, int offset, int count)
	{
		if (buffer == null)
		{
			throw new ArgumentNullException("buffer");
		}
		if (offset < 0)
		{
			throw new ArgumentOutOfRangeException("offset", Messages.ArgumentNeedNonNegative);
		}
		if (count < 0)
		{
			throw new ArgumentOutOfRangeException("count", Messages.ArgumentNeedNonNegative);
		}
		if (buffer.Length - offset < count)
		{
			throw new ArgumentException(Messages.OffsetLengthInvalid);
		}
		ThrowIfDisposed();
		if (count != 0)
		{
			if (!_everWritten)
			{
				_initialPosition = _baseBaseStream.Position;
				_everWritten = true;
			}
			_checksum = System.IO.Compression.Crc32Helper.UpdateCrc32(_checksum, buffer, offset, count);
			_baseStream.Write(buffer, offset, count);
			_position += count;
		}
	}

	public override void Flush()
	{
		ThrowIfDisposed();
		_baseStream.Flush();
	}

	protected override void Dispose(bool disposing)
	{
		if (disposing && !_isDisposed)
		{
			if (!_everWritten)
			{
				_initialPosition = _baseBaseStream.Position;
			}
			if (!_leaveOpenOnClose)
			{
				_baseStream.Close();
			}
			if (_saveCrcAndSizes != null)
			{
				_saveCrcAndSizes(_initialPosition, Position, _checksum);
			}
			_isDisposed = true;
		}
		base.Dispose(disposing);
	}
}
[__DynamicallyInvokable]
public class ZipArchive : IDisposable
{
	private Stream _archiveStream;

	private ZipArchiveEntry _archiveStreamOwner;

	private BinaryReader _archiveReader;

	private ZipArchiveMode _mode;

	private List<ZipArchiveEntry> _entries;

	private ReadOnlyCollection<ZipArchiveEntry> _entriesCollection;

	private Dictionary<string, ZipArchiveEntry> _entriesDictionary;

	private bool _readEntries;

	private bool _leaveOpen;

	private long _centralDirectoryStart;

	private bool _isDisposed;

	private uint _numberOfThisDisk;

	private long _expectedNumberOfEntries;

	private Stream _backingStream;

	private byte[] _archiveComment;

	private Encoding _entryNameEncoding;

	[__DynamicallyInvokable]
	public ReadOnlyCollection<ZipArchiveEntry> Entries
	{
		[__DynamicallyInvokable]
		get
		{
			if (_mode == ZipArchiveMode.Create)
			{
				throw new NotSupportedException(Messages.EntriesInCreateMode);
			}
			ThrowIfDisposed();
			EnsureCentralDirectoryRead();
			return _entriesCollection;
		}
	}

	[__DynamicallyInvokable]
	public ZipArchiveMode Mode
	{
		[__DynamicallyInvokable]
		get
		{
			return _mode;
		}
	}

	internal BinaryReader ArchiveReader => _archiveReader;

	internal Stream ArchiveStream => _archiveStream;

	internal uint NumberOfThisDisk => _numberOfThisDisk;

	internal Encoding EntryNameEncoding
	{
		get
		{
			return _entryNameEncoding;
		}
		private set
		{
			if (value != null && (value.Equals(Encoding.BigEndianUnicode) || value.Equals(Encoding.Unicode) || value.Equals(Encoding.UTF32) || value.Equals(Encoding.UTF7)))
			{
				throw new ArgumentException(Messages.EntryNameEncodingNotSupported, "entryNameEncoding");
			}
			_entryNameEncoding = value;
		}
	}

	[__DynamicallyInvokable]
	public ZipArchive(Stream stream)
		: this(stream, ZipArchiveMode.Read, leaveOpen: false, null)
	{
	}

	[__DynamicallyInvokable]
	public ZipArchive(Stream stream, ZipArchiveMode mode)
		: this(stream, mode, leaveOpen: false, null)
	{
	}

	[__DynamicallyInvokable]
	public ZipArchive(Stream stream, ZipArchiveMode mode, bool leaveOpen)
		: this(stream, mode, leaveOpen, null)
	{
	}

	[__DynamicallyInvokable]
	public ZipArchive(Stream stream, ZipArchiveMode mode, bool leaveOpen, Encoding entryNameEncoding)
	{
		if (stream == null)
		{
			throw new ArgumentNullException("stream");
		}
		EntryNameEncoding = entryNameEncoding;
		Init(stream, mode, leaveOpen);
	}

	[__DynamicallyInvokable]
	public ZipArchiveEntry CreateEntry(string entryName)
	{
		return DoCreateEntry(entryName, null);
	}

	[__DynamicallyInvokable]
	public ZipArchiveEntry CreateEntry(string entryName, CompressionLevel compressionLevel)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		return DoCreateEntry(entryName, compressionLevel);
	}

	[__DynamicallyInvokable]
	protected virtual void Dispose(bool disposing)
	{
		if (!disposing || _isDisposed)
		{
			return;
		}
		ZipArchiveMode mode = _mode;
		if (mode != 0)
		{
			_ = mode - 1;
			_ = 1;
			try
			{
				WriteFile();
			}
			catch (InvalidDataException)
			{
				CloseStreams();
				_isDisposed = true;
				throw;
			}
		}
		CloseStreams();
		_isDisposed = true;
	}

	[__DynamicallyInvokable]
	public void Dispose()
	{
		Dispose(disposing: true);
		GC.SuppressFinalize(this);
	}

	[__DynamicallyInvokable]
	public ZipArchiveEntry GetEntry(string entryName)
	{
		if (entryName == null)
		{
			throw new ArgumentNullException("entryName");
		}
		if (_mode == ZipArchiveMode.Create)
		{
			throw new NotSupportedException(Messages.EntriesInCreateMode);
		}
		EnsureCentralDirectoryRead();
		_entriesDictionary.TryGetValue(entryName, out var value);
		return value;
	}

	private ZipArchiveEntry DoCreateEntry(string entryName, CompressionLevel? compressionLevel)
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		if (entryName == null)
		{
			throw new ArgumentNullException("entryName");
		}
		if (string.IsNullOrEmpty(entryName))
		{
			throw new ArgumentException(Messages.CannotBeEmpty, "entryName");
		}
		if (_mode == ZipArchiveMode.Read)
		{
			throw new NotSupportedException(Messages.CreateInReadMode);
		}
		ThrowIfDisposed();
		ZipArchiveEntry zipArchiveEntry = (compressionLevel.HasValue ? new ZipArchiveEntry(this, entryName, compressionLevel.Value) : new ZipArchiveEntry(this, entryName));
		AddEntry(zipArchiveEntry);
		return zipArchiveEntry;
	}

	internal void AcquireArchiveStream(ZipArchiveEntry entry)
	{
		if (_archiveStreamOwner != null)
		{
			if (_archiveStreamOwner.EverOpenedForWrite)
			{
				throw new IOException(Messages.CreateModeCreateEntryWhileOpen);
			}
			_archiveStreamOwner.WriteAndFinishLocalEntry();
		}
		_archiveStreamOwner = entry;
	}

	private void AddEntry(ZipArchiveEntry entry)
	{
		_entries.Add(entry);
		string fullName = entry.FullName;
		if (!_entriesDictionary.ContainsKey(fullName))
		{
			_entriesDictionary.Add(fullName, entry);
		}
	}

	internal bool IsStillArchiveStreamOwner(ZipArchiveEntry entry)
	{
		return _archiveStreamOwner == entry;
	}

	internal void ReleaseArchiveStream(ZipArchiveEntry entry)
	{
		_archiveStreamOwner = null;
	}

	internal void RemoveEntry(ZipArchiveEntry entry)
	{
		_entries.Remove(entry);
		_entriesDictionary.Remove(entry.FullName);
	}

	internal void ThrowIfDisposed()
	{
		if (_isDisposed)
		{
			throw new ObjectDisposedException(GetType().Name);
		}
	}

	private void CloseStreams()
	{
		if (!_leaveOpen)
		{
			_archiveStream.Close();
			if (_backingStream != null)
			{
				_backingStream.Close();
			}
			if (_archiveReader != null)
			{
				_archiveReader.Close();
			}
		}
		else if (_backingStream != null)
		{
			_archiveStream.Close();
		}
	}

	private void EnsureCentralDirectoryRead()
	{
		if (!_readEntries)
		{
			ReadCentralDirectory();
			_readEntries = true;
		}
	}

	private void Init(Stream stream, ZipArchiveMode mode, bool leaveOpen)
	{
		Stream stream2 = null;
		try
		{
			_backingStream = null;
			switch (mode)
			{
			case ZipArchiveMode.Create:
				if (!stream.CanWrite)
				{
					throw new ArgumentException(Messages.CreateModeCapabilities);
				}
				break;
			case ZipArchiveMode.Read:
				if (!stream.CanRead)
				{
					throw new ArgumentException(Messages.ReadModeCapabilities);
				}
				if (!stream.CanSeek)
				{
					_backingStream = stream;
					stream2 = (stream = new MemoryStream());
					_backingStream.CopyTo(stream);
					stream.Seek(0L, SeekOrigin.Begin);
				}
				break;
			case ZipArchiveMode.Update:
				if (!stream.CanRead || !stream.CanWrite || !stream.CanSeek)
				{
					throw new ArgumentException(Messages.UpdateModeCapabilities);
				}
				break;
			default:
				throw new ArgumentOutOfRangeException("mode");
			}
			_mode = mode;
			_archiveStream = stream;
			_archiveStreamOwner = null;
			if (mode == ZipArchiveMode.Create)
			{
				_archiveReader = null;
			}
			else
			{
				_archiveReader = new BinaryReader(stream);
			}
			_entries = new List<ZipArchiveEntry>();
			_entriesCollection = new ReadOnlyCollection<ZipArchiveEntry>(_entries);
			_entriesDictionary = new Dictionary<string, ZipArchiveEntry>();
			_readEntries = false;
			_leaveOpen = leaveOpen;
			_centralDirectoryStart = 0L;
			_isDisposed = false;
			_numberOfThisDisk = 0u;
			_archiveComment = null;
			switch (mode)
			{
			case ZipArchiveMode.Create:
				_readEntries = true;
				return;
			case ZipArchiveMode.Read:
				ReadEndOfCentralDirectory();
				return;
			}
			if (_archiveStream.Length == 0L)
			{
				_readEntries = true;
				return;
			}
			ReadEndOfCentralDirectory();
			EnsureCentralDirectoryRead();
			foreach (ZipArchiveEntry entry in _entries)
			{
				entry.ThrowIfNotOpenable(needToUncompress: false, needToLoadIntoMemory: true);
			}
		}
		catch
		{
			stream2?.Close();
			throw;
		}
	}

	private void ReadCentralDirectory()
	{
		try
		{
			_archiveStream.Seek(_centralDirectoryStart, SeekOrigin.Begin);
			long num = 0L;
			bool saveExtraFieldsAndComments = Mode == ZipArchiveMode.Update;
			System.IO.Compression.ZipCentralDirectoryFileHeader header;
			while (System.IO.Compression.ZipCentralDirectoryFileHeader.TryReadBlock(_archiveReader, saveExtraFieldsAndComments, out header))
			{
				AddEntry(new ZipArchiveEntry(this, header));
				num++;
			}
			if (num != _expectedNumberOfEntries)
			{
				throw new InvalidDataException(Messages.NumEntriesWrong);
			}
		}
		catch (EndOfStreamException innerException)
		{
			throw new InvalidDataException(Messages.CentralDirectoryInvalid, innerException);
		}
	}

	private void ReadEndOfCentralDirectory()
	{
		try
		{
			_archiveStream.Seek(-18L, SeekOrigin.End);
			if (!System.IO.Compression.ZipHelper.SeekBackwardsToSignature(_archiveStream, 101010256u))
			{
				throw new InvalidDataException(Messages.EOCDNotFound);
			}
			long position = _archiveStream.Position;
			System.IO.Compression.ZipEndOfCentralDirectoryBlock eocdBlock;
			bool flag = System.IO.Compression.ZipEndOfCentralDirectoryBlock.TryReadBlock(_archiveReader, out eocdBlock);
			if (eocdBlock.NumberOfThisDisk != eocdBlock.NumberOfTheDiskWithTheStartOfTheCentralDirectory)
			{
				throw new InvalidDataException(Messages.SplitSpanned);
			}
			_numberOfThisDisk = eocdBlock.NumberOfThisDisk;
			_centralDirectoryStart = eocdBlock.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber;
			if (eocdBlock.NumberOfEntriesInTheCentralDirectory != eocdBlock.NumberOfEntriesInTheCentralDirectoryOnThisDisk)
			{
				throw new InvalidDataException(Messages.SplitSpanned);
			}
			_expectedNumberOfEntries = eocdBlock.NumberOfEntriesInTheCentralDirectory;
			if (_mode == ZipArchiveMode.Update)
			{
				_archiveComment = eocdBlock.ArchiveComment;
			}
			if (eocdBlock.NumberOfThisDisk == ushort.MaxValue || eocdBlock.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber == uint.MaxValue || eocdBlock.NumberOfEntriesInTheCentralDirectory == ushort.MaxValue)
			{
				_archiveStream.Seek(position - 16, SeekOrigin.Begin);
				if (System.IO.Compression.ZipHelper.SeekBackwardsToSignature(_archiveStream, 117853008u))
				{
					System.IO.Compression.Zip64EndOfCentralDirectoryLocator zip64EOCDLocator;
					bool flag2 = System.IO.Compression.Zip64EndOfCentralDirectoryLocator.TryReadBlock(_archiveReader, out zip64EOCDLocator);
					if (zip64EOCDLocator.OffsetOfZip64EOCD > long.MaxValue)
					{
						throw new InvalidDataException(Messages.FieldTooBigOffsetToZip64EOCD);
					}
					long offsetOfZip64EOCD = (long)zip64EOCDLocator.OffsetOfZip64EOCD;
					_archiveStream.Seek(offsetOfZip64EOCD, SeekOrigin.Begin);
					if (!System.IO.Compression.Zip64EndOfCentralDirectoryRecord.TryReadBlock(_archiveReader, out var zip64EOCDRecord))
					{
						throw new InvalidDataException(Messages.Zip64EOCDNotWhereExpected);
					}
					_numberOfThisDisk = zip64EOCDRecord.NumberOfThisDisk;
					if (zip64EOCDRecord.NumberOfEntriesTotal > long.MaxValue)
					{
						throw new InvalidDataException(Messages.FieldTooBigNumEntries);
					}
					if (zip64EOCDRecord.OffsetOfCentralDirectory > long.MaxValue)
					{
						throw new InvalidDataException(Messages.FieldTooBigOffsetToCD);
					}
					if (zip64EOCDRecord.NumberOfEntriesTotal != zip64EOCDRecord.NumberOfEntriesOnThisDisk)
					{
						throw new InvalidDataException(Messages.SplitSpanned);
					}
					_expectedNumberOfEntries = (long)zip64EOCDRecord.NumberOfEntriesTotal;
					_centralDirectoryStart = (long)zip64EOCDRecord.OffsetOfCentralDirectory;
				}
			}
			if (_centralDirectoryStart > _archiveStream.Length)
			{
				throw new InvalidDataException(Messages.FieldTooBigOffsetToCD);
			}
		}
		catch (EndOfStreamException innerException)
		{
			throw new InvalidDataException(Messages.CDCorrupt, innerException);
		}
		catch (IOException innerException2)
		{
			throw new InvalidDataException(Messages.CDCorrupt, innerException2);
		}
	}

	private void WriteFile()
	{
		if (_mode == ZipArchiveMode.Update)
		{
			List<ZipArchiveEntry> list = new List<ZipArchiveEntry>();
			foreach (ZipArchiveEntry entry in _entries)
			{
				if (!entry.LoadLocalHeaderExtraFieldAndCompressedBytesIfNeeded())
				{
					list.Add(entry);
				}
			}
			foreach (ZipArchiveEntry item in list)
			{
				item.Delete();
			}
			_archiveStream.Seek(0L, SeekOrigin.Begin);
			_archiveStream.SetLength(0L);
		}
		foreach (ZipArchiveEntry entry2 in _entries)
		{
			entry2.WriteAndFinishLocalEntry();
		}
		long position = _archiveStream.Position;
		foreach (ZipArchiveEntry entry3 in _entries)
		{
			entry3.WriteCentralDirectoryFileHeader();
		}
		long sizeOfCentralDirectory = _archiveStream.Position - position;
		WriteArchiveEpilogue(position, sizeOfCentralDirectory);
	}

	private void WriteArchiveEpilogue(long startOfCentralDirectory, long sizeOfCentralDirectory)
	{
		bool flag = false;
		if (startOfCentralDirectory >= uint.MaxValue || sizeOfCentralDirectory >= uint.MaxValue || _entries.Count >= 65535)
		{
			flag = true;
		}
		if (flag)
		{
			long position = _archiveStream.Position;
			System.IO.Compression.Zip64EndOfCentralDirectoryRecord.WriteBlock(_archiveStream, _entries.Count, startOfCentralDirectory, sizeOfCentralDirectory);
			System.IO.Compression.Zip64EndOfCentralDirectoryLocator.WriteBlock(_archiveStream, position);
		}
		System.IO.Compression.ZipEndOfCentralDirectoryBlock.WriteBlock(_archiveStream, _entries.Count, startOfCentralDirectory, sizeOfCentralDirectory, _archiveComment);
	}
}
[__DynamicallyInvokable]
public class ZipArchiveEntry
{
	private class DirectToArchiveWriterStream : Stream
	{
		private long _position;

		private System.IO.Compression.CheckSumAndSizeWriteStream _crcSizeStream;

		private bool _everWritten;

		private bool _isDisposed;

		private ZipArchiveEntry _entry;

		private bool _usedZip64inLH;

		private bool _canWrite;

		public override long Length
		{
			get
			{
				ThrowIfDisposed();
				throw new NotSupportedException(Messages.SeekingNotSupported);
			}
		}

		public override long Position
		{
			get
			{
				ThrowIfDisposed();
				return _position;
			}
			set
			{
				ThrowIfDisposed();
				throw new NotSupportedException(Messages.SeekingNotSupported);
			}
		}

		public override bool CanRead => false;

		public override bool CanSeek => false;

		public override bool CanWrite => _canWrite;

		public DirectToArchiveWriterStream(System.IO.Compression.CheckSumAndSizeWriteStream crcSizeStream, ZipArchiveEntry entry)
		{
			_position = 0L;
			_crcSizeStream = crcSizeStream;
			_everWritten = false;
			_isDisposed = false;
			_entry = entry;
			_usedZip64inLH = false;
			_canWrite = true;
		}

		private void ThrowIfDisposed()
		{
			if (_isDisposed)
			{
				throw new ObjectDisposedException(GetType().Name, Messages.HiddenStreamName);
			}
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			ThrowIfDisposed();
			throw new NotSupportedException(Messages.ReadingNotSupported);
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			ThrowIfDisposed();
			throw new NotSupportedException(Messages.SeekingNotSupported);
		}

		public override void SetLength(long value)
		{
			ThrowIfDisposed();
			throw new NotSupportedException(Messages.SetLengthRequiresSeekingAndWriting);
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			if (offset < 0)
			{
				throw new ArgumentOutOfRangeException("offset", Messages.ArgumentNeedNonNegative);
			}
			if (count < 0)
			{
				throw new ArgumentOutOfRangeException("count", Messages.ArgumentNeedNonNegative);
			}
			if (buffer.Length - offset < count)
			{
				throw new ArgumentException(Messages.OffsetLengthInvalid);
			}
			ThrowIfDisposed();
			if (count != 0)
			{
				if (!_everWritten)
				{
					_everWritten = true;
					_usedZip64inLH = _entry.WriteLocalFileHeader(isEmptyFile: false);
				}
				_crcSizeStream.Write(buffer, offset, count);
				_position += count;
			}
		}

		public override void Flush()
		{
			ThrowIfDisposed();
			_crcSizeStream.Flush();
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && !_isDisposed)
			{
				_crcSizeStream.Close();
				if (!_everWritten)
				{
					_entry.WriteLocalFileHeader(isEmptyFile: true);
				}
				else if (_entry._archive.ArchiveStream.CanSeek)
				{
					_entry.WriteCrcAndSizesInLocalHeader(_usedZip64inLH);
				}
				else
				{
					_entry.WriteDataDescriptor();
				}
				_canWrite = false;
				_isDisposed = true;
			}
			base.Dispose(disposing);
		}
	}

	[Flags]
	private enum BitFlagValues : ushort
	{
		DataDescriptor = 8,
		UnicodeFileName = 0x800
	}

	private enum CompressionMethodValues : ushort
	{
		Stored = 0,
		Deflate = 8
	}

	private enum OpenableValues
	{
		Openable,
		FileNonExistent,
		FileTooLarge
	}

	private const ushort DefaultVersionToExtract = 10;

	private ZipArchive _archive;

	private readonly bool _originallyInArchive;

	private readonly int _diskNumberStart;

	private System.IO.Compression.ZipVersionNeededValues _versionToExtract;

	private BitFlagValues _generalPurposeBitFlag;

	private CompressionMethodValues _storedCompressionMethod;

	private DateTimeOffset _lastModified;

	private long _compressedSize;

	private long _uncompressedSize;

	private long _offsetOfLocalHeader;

	private long? _storedOffsetOfCompressedData;

	private uint _crc32;

	private byte[] _compressedBytes;

	private MemoryStream _storedUncompressedData;

	private bool _currentlyOpenForWrite;

	private bool _everOpenedForWrite;

	private Stream _outstandingWriteStream;

	private uint _externalFileAttr;

	private string _storedEntryName;

	private byte[] _storedEntryNameBytes;

	private List<System.IO.Compression.ZipGenericExtraField> _cdUnknownExtraFields;

	private List<System.IO.Compression.ZipGenericExtraField> _lhUnknownExtraFields;

	private byte[] _fileComment;

	private CompressionLevel? _compressionLevel;

	[__DynamicallyInvokable]
	public ZipArchive Archive
	{
		[__DynamicallyInvokable]
		get
		{
			return _archive;
		}
	}

	[__DynamicallyInvokable]
	public long CompressedLength
	{
		[__DynamicallyInvokable]
		get
		{
			if (_everOpenedForWrite)
			{
				throw new InvalidOperationException(Messages.LengthAfterWrite);
			}
			return _compressedSize;
		}
	}

	public int ExternalAttributes
	{
		get
		{
			return (int)_externalFileAttr;
		}
		set
		{
			ThrowIfInvalidArchive();
			_externalFileAttr = (uint)value;
		}
	}

	[__DynamicallyInvokable]
	public string FullName
	{
		[__DynamicallyInvokable]
		get
		{
			return _storedEntryName;
		}
		private set
		{
			if (value == null)
			{
				throw new ArgumentNullException("FullName");
			}
			_storedEntryNameBytes = EncodeEntryName(value, out var isUTF);
			_storedEntryName = value;
			if (isUTF)
			{
				_generalPurposeBitFlag |= BitFlagValues.UnicodeFileName;
			}
			else
			{
				_generalPurposeBitFlag &= ~BitFlagValues.UnicodeFileName;
			}
			if (System.IO.Compression.ZipHelper.EndsWithDirChar(value))
			{
				VersionToExtractAtLeast(System.IO.Compression.ZipVersionNeededValues.ExplicitDirectory);
			}
		}
	}

	[__DynamicallyInvokable]
	public DateTimeOffset LastWriteTime
	{
		[__DynamicallyInvokable]
		get
		{
			return _lastModified;
		}
		[__DynamicallyInvokable]
		set
		{
			ThrowIfInvalidArchive();
			if (_archive.Mode == ZipArchiveMode.Read)
			{
				throw new NotSupportedException(Messages.ReadOnlyArchive);
			}
			if (_archive.Mode == ZipArchiveMode.Create && _everOpenedForWrite)
			{
				throw new IOException(Messages.FrozenAfterWrite);
			}
			if (value.DateTime.Year < 1980 || value.DateTime.Year > 2107)
			{
				throw new ArgumentOutOfRangeException("value", Messages.DateTimeOutOfRange);
			}
			_lastModified = value;
		}
	}

	[__DynamicallyInvokable]
	public long Length
	{
		[__DynamicallyInvokable]
		get
		{
			if (_everOpenedForWrite)
			{
				throw new InvalidOperationException(Messages.LengthAfterWrite);
			}
			return _uncompressedSize;
		}
	}

	[__DynamicallyInvokable]
	public string Name
	{
		[__DynamicallyInvokable]
		get
		{
			return Path.GetFileName(FullName);
		}
	}

	internal bool EverOpenedForWrite => _everOpenedForWrite;

	private long OffsetOfCompressedData
	{
		get
		{
			if (!_storedOffsetOfCompressedData.HasValue)
			{
				_archive.ArchiveStream.Seek(_offsetOfLocalHeader, SeekOrigin.Begin);
				if (!System.IO.Compression.ZipLocalFileHeader.TrySkipBlock(_archive.ArchiveReader))
				{
					throw new InvalidDataException(Messages.LocalFileHeaderCorrupt);
				}
				_storedOffsetOfCompressedData = _archive.ArchiveStream.Position;
			}
			return _storedOffsetOfCompressedData.Value;
		}
	}

	private MemoryStream UncompressedData
	{
		get
		{
			if (_storedUncompressedData == null)
			{
				_storedUncompressedData = new MemoryStream((int)_uncompressedSize);
				if (_originallyInArchive)
				{
					using Stream stream = OpenInReadMode(checkOpenable: false);
					try
					{
						stream.CopyTo(_storedUncompressedData);
					}
					catch (InvalidDataException)
					{
						_storedUncompressedData.Dispose();
						_storedUncompressedData = null;
						_currentlyOpenForWrite = false;
						_everOpenedForWrite = false;
						throw;
					}
				}
				CompressionMethod = CompressionMethodValues.Deflate;
			}
			return _storedUncompressedData;
		}
	}

	private CompressionMethodValues CompressionMethod
	{
		get
		{
			return _storedCompressionMethod;
		}
		set
		{
			if (value == CompressionMethodValues.Deflate)
			{
				VersionToExtractAtLeast(System.IO.Compression.ZipVersionNeededValues.ExplicitDirectory);
			}
			_storedCompressionMethod = value;
		}
	}

	internal ZipArchiveEntry(ZipArchive archive, System.IO.Compression.ZipCentralDirectoryFileHeader cd, CompressionLevel compressionLevel)
		: this(archive, cd)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		_compressionLevel = compressionLevel;
	}

	internal ZipArchiveEntry(ZipArchive archive, System.IO.Compression.ZipCentralDirectoryFileHeader cd)
	{
		_archive = archive;
		_originallyInArchive = true;
		_diskNumberStart = cd.DiskNumberStart;
		_versionToExtract = (System.IO.Compression.ZipVersionNeededValues)cd.VersionNeededToExtract;
		_generalPurposeBitFlag = (BitFlagValues)cd.GeneralPurposeBitFlag;
		CompressionMethod = (CompressionMethodValues)cd.CompressionMethod;
		_lastModified = new DateTimeOffset(System.IO.Compression.ZipHelper.DosTimeToDateTime(cd.LastModified));
		_compressedSize = cd.CompressedSize;
		_uncompressedSize = cd.UncompressedSize;
		_externalFileAttr = cd.ExternalFileAttributes;
		_offsetOfLocalHeader = cd.RelativeOffsetOfLocalHeader;
		_storedOffsetOfCompressedData = null;
		_crc32 = cd.Crc32;
		_compressedBytes = null;
		_storedUncompressedData = null;
		_currentlyOpenForWrite = false;
		_everOpenedForWrite = false;
		_outstandingWriteStream = null;
		FullName = DecodeEntryName(cd.Filename);
		_lhUnknownExtraFields = null;
		_cdUnknownExtraFields = cd.ExtraFields;
		_fileComment = cd.FileComment;
		_compressionLevel = null;
	}

	internal ZipArchiveEntry(ZipArchive archive, string entryName, CompressionLevel compressionLevel)
		: this(archive, entryName)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		_compressionLevel = compressionLevel;
	}

	internal ZipArchiveEntry(ZipArchive archive, string entryName)
	{
		_archive = archive;
		_originallyInArchive = false;
		_diskNumberStart = 0;
		_versionToExtract = System.IO.Compression.ZipVersionNeededValues.Default;
		_generalPurposeBitFlag = (BitFlagValues)0;
		CompressionMethod = CompressionMethodValues.Deflate;
		_lastModified = DateTimeOffset.Now;
		_compressedSize = 0L;
		_uncompressedSize = 0L;
		_externalFileAttr = 0u;
		_offsetOfLocalHeader = 0L;
		_storedOffsetOfCompressedData = null;
		_crc32 = 0u;
		_compressedBytes = null;
		_storedUncompressedData = null;
		_currentlyOpenForWrite = false;
		_everOpenedForWrite = false;
		_outstandingWriteStream = null;
		FullName = entryName;
		_cdUnknownExtraFields = null;
		_lhUnknownExtraFields = null;
		_fileComment = null;
		_compressionLevel = null;
		if (_storedEntryNameBytes.Length > 65535)
		{
			throw new ArgumentException(Messages.EntryNamesTooLong);
		}
		if (_archive.Mode == ZipArchiveMode.Create)
		{
			_archive.AcquireArchiveStream(this);
		}
	}

	[__DynamicallyInvokable]
	public void Delete()
	{
		if (_archive != null)
		{
			if (_currentlyOpenForWrite)
			{
				throw new IOException(Messages.DeleteOpenEntry);
			}
			if (_archive.Mode != ZipArchiveMode.Update)
			{
				throw new NotSupportedException(Messages.DeleteOnlyInUpdate);
			}
			_archive.ThrowIfDisposed();
			_archive.RemoveEntry(this);
			_archive = null;
			UnloadStreams();
		}
	}

	[__DynamicallyInvokable]
	public Stream Open()
	{
		ThrowIfInvalidArchive();
		return _archive.Mode switch
		{
			ZipArchiveMode.Read => OpenInReadMode(checkOpenable: true), 
			ZipArchiveMode.Create => OpenInWriteMode(), 
			_ => OpenInUpdateMode(), 
		};
	}

	[__DynamicallyInvokable]
	public override string ToString()
	{
		return FullName;
	}

	private string DecodeEntryName(byte[] entryNameBytes)
	{
		Encoding encoding = (((_generalPurposeBitFlag & BitFlagValues.UnicodeFileName) != 0) ? Encoding.UTF8 : ((_archive == null) ? Encoding.GetEncoding(0) : (_archive.EntryNameEncoding ?? Encoding.GetEncoding(0))));
		return new string(encoding.GetChars(entryNameBytes));
	}

	private byte[] EncodeEntryName(string entryName, out bool isUTF8)
	{
		Encoding encoding = ((_archive == null || _archive.EntryNameEncoding == null) ? (System.IO.Compression.ZipHelper.RequiresUnicode(entryName) ? Encoding.UTF8 : Encoding.GetEncoding(0)) : _archive.EntryNameEncoding);
		isUTF8 = encoding is UTF8Encoding && encoding.Equals(Encoding.UTF8);
		return encoding.GetBytes(entryName);
	}

	internal void WriteAndFinishLocalEntry()
	{
		CloseStreams();
		WriteLocalFileHeaderAndDataIfNeeded();
		UnloadStreams();
	}

	internal void WriteCentralDirectoryFileHeader()
	{
		BinaryWriter binaryWriter = new BinaryWriter(_archive.ArchiveStream);
		System.IO.Compression.Zip64ExtraField zip64ExtraField = default(System.IO.Compression.Zip64ExtraField);
		bool flag = false;
		uint value;
		uint value2;
		if (SizesTooLarge())
		{
			flag = true;
			value = uint.MaxValue;
			value2 = uint.MaxValue;
			zip64ExtraField.CompressedSize = _compressedSize;
			zip64ExtraField.UncompressedSize = _uncompressedSize;
		}
		else
		{
			value = (uint)_compressedSize;
			value2 = (uint)_uncompressedSize;
		}
		uint value3;
		if (_offsetOfLocalHeader > uint.MaxValue)
		{
			flag = true;
			value3 = uint.MaxValue;
			zip64ExtraField.LocalHeaderOffset = _offsetOfLocalHeader;
		}
		else
		{
			value3 = (uint)_offsetOfLocalHeader;
		}
		if (flag)
		{
			VersionToExtractAtLeast(System.IO.Compression.ZipVersionNeededValues.Zip64);
		}
		int num = (flag ? zip64ExtraField.TotalSize : 0) + ((_cdUnknownExtraFields != null) ? System.IO.Compression.ZipGenericExtraField.TotalSize(_cdUnknownExtraFields) : 0);
		ushort value4;
		if (num > 65535)
		{
			value4 = (ushort)(flag ? zip64ExtraField.TotalSize : 0);
			_cdUnknownExtraFields = null;
		}
		else
		{
			value4 = (ushort)num;
		}
		binaryWriter.Write(33639248u);
		binaryWriter.Write((ushort)_versionToExtract);
		binaryWriter.Write((ushort)_versionToExtract);
		binaryWriter.Write((ushort)_generalPurposeBitFlag);
		binaryWriter.Write((ushort)CompressionMethod);
		binaryWriter.Write(System.IO.Compression.ZipHelper.DateTimeToDosTime(_lastModified.DateTime));
		binaryWriter.Write(_crc32);
		binaryWriter.Write(value);
		binaryWriter.Write(value2);
		binaryWriter.Write((ushort)_storedEntryNameBytes.Length);
		binaryWriter.Write(value4);
		binaryWriter.Write((ushort)((_fileComment != null) ? ((ushort)_fileComment.Length) : 0));
		binaryWriter.Write((ushort)0);
		binaryWriter.Write((ushort)0);
		binaryWriter.Write(_externalFileAttr);
		binaryWriter.Write(value3);
		binaryWriter.Write(_storedEntryNameBytes);
		if (flag)
		{
			zip64ExtraField.WriteBlock(_archive.ArchiveStream);
		}
		if (_cdUnknownExtraFields != null)
		{
			System.IO.Compression.ZipGenericExtraField.WriteAllBlocks(_cdUnknownExtraFields, _archive.ArchiveStream);
		}
		if (_fileComment != null)
		{
			binaryWriter.Write(_fileComment);
		}
	}

	internal bool LoadLocalHeaderExtraFieldAndCompressedBytesIfNeeded()
	{
		if (_originallyInArchive)
		{
			_archive.ArchiveStream.Seek(_offsetOfLocalHeader, SeekOrigin.Begin);
			_lhUnknownExtraFields = System.IO.Compression.ZipLocalFileHeader.GetExtraFields(_archive.ArchiveReader);
		}
		if (!_everOpenedForWrite && _originallyInArchive)
		{
			_compressedBytes = new byte[_compressedSize];
			_archive.ArchiveStream.Seek(OffsetOfCompressedData, SeekOrigin.Begin);
			System.IO.Compression.ZipHelper.ReadBytes(_archive.ArchiveStream, _compressedBytes, (int)_compressedSize);
		}
		return true;
	}

	internal void ThrowIfNotOpenable(bool needToUncompress, bool needToLoadIntoMemory)
	{
		if (!IsOpenable(needToUncompress, needToLoadIntoMemory, out var message))
		{
			throw new InvalidDataException(message);
		}
	}

	private System.IO.Compression.CheckSumAndSizeWriteStream GetDataCompressor(Stream backingStream, bool leaveBackingStreamOpen, EventHandler onClose)
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected O, but got Unknown
		Stream baseStream = (Stream)(_compressionLevel.HasValue ? new DeflateStream(backingStream, _compressionLevel.Value, leaveBackingStreamOpen) : new DeflateStream(backingStream, (CompressionMode)1, leaveBackingStreamOpen));
		bool flag = true;
		bool leaveOpenOnClose = leaveBackingStreamOpen && !flag;
		return new System.IO.Compression.CheckSumAndSizeWriteStream(baseStream, backingStream, leaveOpenOnClose, delegate(long initialPosition, long currentPosition, uint checkSum)
		{
			_crc32 = checkSum;
			_uncompressedSize = currentPosition;
			_compressedSize = backingStream.Position - initialPosition;
			if (onClose != null)
			{
				onClose(this, EventArgs.Empty);
			}
		});
	}

	private Stream GetDataDecompressor(Stream compressedStreamToRead)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown
		Stream stream = null;
		CompressionMethodValues compressionMethod = CompressionMethod;
		if (compressionMethod != 0 && compressionMethod == CompressionMethodValues.Deflate)
		{
			return (Stream)new DeflateStream(compressedStreamToRead, (CompressionMode)0);
		}
		return compressedStreamToRead;
	}

	private Stream OpenInReadMode(bool checkOpenable)
	{
		if (checkOpenable)
		{
			ThrowIfNotOpenable(needToUncompress: true, needToLoadIntoMemory: false);
		}
		Stream compressedStreamToRead = new System.IO.Compression.SubReadStream(_archive.ArchiveStream, OffsetOfCompressedData, _compressedSize);
		return GetDataDecompressor(compressedStreamToRead);
	}

	private Stream OpenInWriteMode()
	{
		if (_everOpenedForWrite)
		{
			throw new IOException(Messages.CreateModeWriteOnceAndOneEntryAtATime);
		}
		_everOpenedForWrite = true;
		System.IO.Compression.CheckSumAndSizeWriteStream dataCompressor = GetDataCompressor(_archive.ArchiveStream, leaveBackingStreamOpen: true, delegate
		{
			_archive.ReleaseArchiveStream(this);
			_outstandingWriteStream = null;
		});
		_outstandingWriteStream = new DirectToArchiveWriterStream(dataCompressor, this);
		return new System.IO.Compression.WrappedStream(_outstandingWriteStream, delegate
		{
			_outstandingWriteStream.Close();
		});
	}

	private Stream OpenInUpdateMode()
	{
		if (_currentlyOpenForWrite)
		{
			throw new IOException(Messages.UpdateModeOneStream);
		}
		ThrowIfNotOpenable(needToUncompress: true, needToLoadIntoMemory: true);
		_everOpenedForWrite = true;
		_currentlyOpenForWrite = true;
		UncompressedData.Seek(0L, SeekOrigin.Begin);
		return new System.IO.Compression.WrappedStream(UncompressedData, delegate
		{
			_currentlyOpenForWrite = false;
		});
	}

	private bool IsOpenable(bool needToUncompress, bool needToLoadIntoMemory, out string message)
	{
		message = null;
		if (_originallyInArchive)
		{
			if (needToUncompress && CompressionMethod != 0 && CompressionMethod != CompressionMethodValues.Deflate)
			{
				message = Messages.UnsupportedCompression;
				return false;
			}
			if (_diskNumberStart != _archive.NumberOfThisDisk)
			{
				message = Messages.SplitSpanned;
				return false;
			}
			if (_offsetOfLocalHeader > _archive.ArchiveStream.Length)
			{
				message = Messages.LocalFileHeaderCorrupt;
				return false;
			}
			_archive.ArchiveStream.Seek(_offsetOfLocalHeader, SeekOrigin.Begin);
			if (!System.IO.Compression.ZipLocalFileHeader.TrySkipBlock(_archive.ArchiveReader))
			{
				message = Messages.LocalFileHeaderCorrupt;
				return false;
			}
			if (OffsetOfCompressedData + _compressedSize > _archive.ArchiveStream.Length)
			{
				message = Messages.LocalFileHeaderCorrupt;
				return false;
			}
			if (needToLoadIntoMemory && _compressedSize > int.MaxValue)
			{
				message = Messages.EntryTooLarge;
				return false;
			}
		}
		return true;
	}

	private bool SizesTooLarge()
	{
		if (_compressedSize <= uint.MaxValue)
		{
			return _uncompressedSize > uint.MaxValue;
		}
		return true;
	}

	private bool WriteLocalFileHeader(bool isEmptyFile)
	{
		BinaryWriter binaryWriter = new BinaryWriter(_archive.ArchiveStream);
		System.IO.Compression.Zip64ExtraField zip64ExtraField = default(System.IO.Compression.Zip64ExtraField);
		bool flag = false;
		uint value;
		uint value2;
		if (isEmptyFile)
		{
			CompressionMethod = CompressionMethodValues.Stored;
			value = 0u;
			value2 = 0u;
		}
		else if (_archive.Mode == ZipArchiveMode.Create && !_archive.ArchiveStream.CanSeek && !isEmptyFile)
		{
			_generalPurposeBitFlag |= BitFlagValues.DataDescriptor;
			flag = false;
			value = 0u;
			value2 = 0u;
		}
		else if (SizesTooLarge())
		{
			flag = true;
			value = uint.MaxValue;
			value2 = uint.MaxValue;
			zip64ExtraField.CompressedSize = _compressedSize;
			zip64ExtraField.UncompressedSize = _uncompressedSize;
			VersionToExtractAtLeast(System.IO.Compression.ZipVersionNeededValues.Zip64);
		}
		else
		{
			flag = false;
			value = (uint)_compressedSize;
			value2 = (uint)_uncompressedSize;
		}
		_offsetOfLocalHeader = binaryWriter.BaseStream.Position;
		int num = (flag ? zip64ExtraField.TotalSize : 0) + ((_lhUnknownExtraFields != null) ? System.IO.Compression.ZipGenericExtraField.TotalSize(_lhUnknownExtraFields) : 0);
		ushort value3;
		if (num > 65535)
		{
			value3 = (ushort)(flag ? zip64ExtraField.TotalSize : 0);
			_lhUnknownExtraFields = null;
		}
		else
		{
			value3 = (ushort)num;
		}
		binaryWriter.Write(67324752u);
		binaryWriter.Write((ushort)_versionToExtract);
		binaryWriter.Write((ushort)_generalPurposeBitFlag);
		binaryWriter.Write((ushort)CompressionMethod);
		binaryWriter.Write(System.IO.Compression.ZipHelper.DateTimeToDosTime(_lastModified.DateTime));
		binaryWriter.Write(_crc32);
		binaryWriter.Write(value);
		binaryWriter.Write(value2);
		binaryWriter.Write((ushort)_storedEntryNameBytes.Length);
		binaryWriter.Write(value3);
		binaryWriter.Write(_storedEntryNameBytes);
		if (flag)
		{
			zip64ExtraField.WriteBlock(_archive.ArchiveStream);
		}
		if (_lhUnknownExtraFields != null)
		{
			System.IO.Compression.ZipGenericExtraField.WriteAllBlocks(_lhUnknownExtraFields, _archive.ArchiveStream);
		}
		return flag;
	}

	private void WriteLocalFileHeaderAndDataIfNeeded()
	{
		if (_storedUncompressedData != null || _compressedBytes != null)
		{
			if (_storedUncompressedData != null)
			{
				_uncompressedSize = _storedUncompressedData.Length;
				using Stream destination = new DirectToArchiveWriterStream(GetDataCompressor(_archive.ArchiveStream, leaveBackingStreamOpen: true, null), this);
				_storedUncompressedData.Seek(0L, SeekOrigin.Begin);
				_storedUncompressedData.CopyTo(destination);
				_storedUncompressedData.Close();
				_storedUncompressedData = null;
				return;
			}
			if (_uncompressedSize == 0L)
			{
				CompressionMethod = CompressionMethodValues.Stored;
			}
			WriteLocalFileHeader(isEmptyFile: false);
			using MemoryStream memoryStream = new MemoryStream(_compressedBytes);
			memoryStream.CopyTo(_archive.ArchiveStream);
			return;
		}
		if (_archive.Mode == ZipArchiveMode.Update || !_everOpenedForWrite)
		{
			_everOpenedForWrite = true;
			WriteLocalFileHeader(isEmptyFile: true);
		}
	}

	private void WriteCrcAndSizesInLocalHeader(bool zip64HeaderUsed)
	{
		long position = _archive.ArchiveStream.Position;
		BinaryWriter binaryWriter = new BinaryWriter(_archive.ArchiveStream);
		bool flag = SizesTooLarge();
		bool flag2 = flag && !zip64HeaderUsed;
		uint value = (uint)(flag ? uint.MaxValue : _compressedSize);
		uint value2 = (uint)(flag ? uint.MaxValue : _uncompressedSize);
		if (flag2)
		{
			_generalPurposeBitFlag |= BitFlagValues.DataDescriptor;
			_archive.ArchiveStream.Seek(_offsetOfLocalHeader + 6, SeekOrigin.Begin);
			binaryWriter.Write((ushort)_generalPurposeBitFlag);
		}
		_archive.ArchiveStream.Seek(_offsetOfLocalHeader + 14, SeekOrigin.Begin);
		if (!flag2)
		{
			binaryWriter.Write(_crc32);
			binaryWriter.Write(value);
			binaryWriter.Write(value2);
		}
		else
		{
			binaryWriter.Write(0u);
			binaryWriter.Write(0u);
			binaryWriter.Write(0u);
		}
		if (zip64HeaderUsed)
		{
			_archive.ArchiveStream.Seek(_offsetOfLocalHeader + 30 + _storedEntryNameBytes.Length + 4, SeekOrigin.Begin);
			binaryWriter.Write(_uncompressedSize);
			binaryWriter.Write(_compressedSize);
			_archive.ArchiveStream.Seek(position, SeekOrigin.Begin);
		}
		_archive.ArchiveStream.Seek(position, SeekOrigin.Begin);
		if (flag2)
		{
			binaryWriter.Write(_crc32);
			binaryWriter.Write(_compressedSize);
			binaryWriter.Write(_uncompressedSize);
		}
	}

	private void WriteDataDescriptor()
	{
		BinaryWriter binaryWriter = new BinaryWriter(_archive.ArchiveStream);
		binaryWriter.Write(134695760u);
		binaryWriter.Write(_crc32);
		if (SizesTooLarge())
		{
			binaryWriter.Write(_compressedSize);
			binaryWriter.Write(_uncompressedSize);
		}
		else
		{
			binaryWriter.Write((uint)_compressedSize);
			binaryWriter.Write((uint)_uncompressedSize);
		}
	}

	private void UnloadStreams()
	{
		if (_storedUncompressedData != null)
		{
			_storedUncompressedData.Close();
		}
		_compressedBytes = null;
		_outstandingWriteStream = null;
	}

	private void CloseStreams()
	{
		if (_outstandingWriteStream != null)
		{
			_outstandingWriteStream.Close();
		}
	}

	private void VersionToExtractAtLeast(System.IO.Compression.ZipVersionNeededValues value)
	{
		if ((int)_versionToExtract < (int)value)
		{
			_versionToExtract = value;
		}
	}

	private void ThrowIfInvalidArchive()
	{
		if (_archive == null)
		{
			throw new InvalidOperationException(Messages.DeletedEntry);
		}
		_archive.ThrowIfDisposed();
	}
}
[__DynamicallyInvokable]
public enum ZipArchiveMode
{
	[__DynamicallyInvokable]
	Read,
	[__DynamicallyInvokable]
	Create,
	[__DynamicallyInvokable]
	Update
}
internal struct ZipGenericExtraField
{
	private const int SizeOfHeader = 4;

	private ushort _tag;

	private ushort _size;

	private byte[] _data;

	public ushort Tag => _tag;

	public ushort Size => _size;

	public byte[] Data => _data;

	public void WriteBlock(Stream stream)
	{
		BinaryWriter binaryWriter = new BinaryWriter(stream);
		binaryWriter.Write(Tag);
		binaryWriter.Write(Size);
		binaryWriter.Write(Data);
	}

	public static bool TryReadBlock(BinaryReader reader, long endExtraField, out System.IO.Compression.ZipGenericExtraField field)
	{
		field = default(System.IO.Compression.ZipGenericExtraField);
		if (endExtraField - reader.BaseStream.Position < 4)
		{
			return false;
		}
		field._tag = reader.ReadUInt16();
		field._size = reader.ReadUInt16();
		if (endExtraField - reader.BaseStream.Position < field._size)
		{
			return false;
		}
		field._data = reader.ReadBytes(field._size);
		return true;
	}

	public static List<System.IO.Compression.ZipGenericExtraField> ParseExtraField(Stream extraFieldData)
	{
		List<System.IO.Compression.ZipGenericExtraField> list = new List<System.IO.Compression.ZipGenericExtraField>();
		using BinaryReader reader = new BinaryReader(extraFieldData);
		System.IO.Compression.ZipGenericExtraField field;
		while (TryReadBlock(reader, extraFieldData.Length, out field))
		{
			list.Add(field);
		}
		return list;
	}

	public static int TotalSize(List<System.IO.Compression.ZipGenericExtraField> fields)
	{
		int num = 0;
		foreach (System.IO.Compression.ZipGenericExtraField field in fields)
		{
			num += field.Size + 4;
		}
		return num;
	}

	public static void WriteAllBlocks(List<System.IO.Compression.ZipGenericExtraField> fields, Stream stream)
	{
		foreach (System.IO.Compression.ZipGenericExtraField field in fields)
		{
			field.WriteBlock(stream);
		}
	}
}
internal struct Zip64ExtraField
{
	public const int OffsetToFirstField = 4;

	private const ushort TagConstant = 1;

	private ushort _size;

	private long? _uncompressedSize;

	private long? _compressedSize;

	private long? _localHeaderOffset;

	private int? _startDiskNumber;

	public ushort TotalSize => (ushort)(_size + 4);

	public long? UncompressedSize
	{
		get
		{
			return _uncompressedSize;
		}
		set
		{
			_uncompressedSize = value;
			UpdateSize();
		}
	}

	public long? CompressedSize
	{
		get
		{
			return _compressedSize;
		}
		set
		{
			_compressedSize = value;
			UpdateSize();
		}
	}

	public long? LocalHeaderOffset
	{
		get
		{
			return _localHeaderOffset;
		}
		set
		{
			_localHeaderOffset = value;
			UpdateSize();
		}
	}

	public int? StartDiskNumber => _startDiskNumber;

	private void UpdateSize()
	{
		_size = 0;
		if (_uncompressedSize.HasValue)
		{
			_size += 8;
		}
		if (_compressedSize.HasValue)
		{
			_size += 8;
		}
		if (_localHeaderOffset.HasValue)
		{
			_size += 8;
		}
		if (_startDiskNumber.HasValue)
		{
			_size += 4;
		}
	}

	public static System.IO.Compression.Zip64ExtraField GetJustZip64Block(Stream extraFieldStream, bool readUncompressedSize, bool readCompressedSize, bool readLocalHeaderOffset, bool readStartDiskNumber)
	{
		System.IO.Compression.Zip64ExtraField zip64Block;
		using (BinaryReader reader = new BinaryReader(extraFieldStream))
		{
			System.IO.Compression.ZipGenericExtraField field;
			while (System.IO.Compression.ZipGenericExtraField.TryReadBlock(reader, extraFieldStream.Length, out field))
			{
				if (TryGetZip64BlockFromGenericExtraField(field, readUncompressedSize, readCompressedSize, readLocalHeaderOffset, readStartDiskNumber, out zip64Block))
				{
					return zip64Block;
				}
			}
		}
		zip64Block = default(System.IO.Compression.Zip64ExtraField);
		zip64Block._compressedSize = null;
		zip64Block._uncompressedSize = null;
		zip64Block._localHeaderOffset = null;
		zip64Block._startDiskNumber = null;
		return zip64Block;
	}

	private static bool TryGetZip64BlockFromGenericExtraField(System.IO.Compression.ZipGenericExtraField extraField, bool readUncompressedSize, bool readCompressedSize, bool readLocalHeaderOffset, bool readStartDiskNumber, out System.IO.Compression.Zip64ExtraField zip64Block)
	{
		zip64Block = default(System.IO.Compression.Zip64ExtraField);
		zip64Block._compressedSize = null;
		zip64Block._uncompressedSize = null;
		zip64Block._localHeaderOffset = null;
		zip64Block._startDiskNumber = null;
		if (extraField.Tag != 1)
		{
			return false;
		}
		MemoryStream memoryStream = null;
		try
		{
			memoryStream = new MemoryStream(extraField.Data);
			using BinaryReader binaryReader = new BinaryReader(memoryStream);
			memoryStream = null;
			zip64Block._size = extraField.Size;
			ushort num = 0;
			if (readUncompressedSize)
			{
				num += 8;
			}
			if (readCompressedSize)
			{
				num += 8;
			}
			if (readLocalHeaderOffset)
			{
				num += 8;
			}
			if (readStartDiskNumber)
			{
				num += 4;
			}
			if (num != zip64Block._size)
			{
				return false;
			}
			if (readUncompressedSize)
			{
				zip64Block._uncompressedSize = binaryReader.ReadInt64();
			}
			if (readCompressedSize)
			{
				zip64Block._compressedSize = binaryReader.ReadInt64();
			}
			if (readLocalHeaderOffset)
			{
				zip64Block._localHeaderOffset = binaryReader.ReadInt64();
			}
			if (readStartDiskNumber)
			{
				zip64Block._startDiskNumber = binaryReader.ReadInt32();
			}
			if (zip64Block._uncompressedSize < 0)
			{
				throw new InvalidDataException(Messages.FieldTooBigUncompressedSize);
			}
			if (zip64Block._compressedSize < 0)
			{
				throw new InvalidDataException(Messages.FieldTooBigCompressedSize);
			}
			if (zip64Block._localHeaderOffset < 0)
			{
				throw new InvalidDataException(Messages.FieldTooBigLocalHeaderOffset);
			}
			if (zip64Block._startDiskNumber < 0)
			{
				throw new InvalidDataException(Messages.FieldTooBigStartDiskNumber);
			}
			return true;
		}
		finally
		{
			memoryStream?.Close();
		}
	}

	public static System.IO.Compression.Zip64ExtraField GetAndRemoveZip64Block(List<System.IO.Compression.ZipGenericExtraField> extraFields, bool readUncompressedSize, bool readCompressedSize, bool readLocalHeaderOffset, bool readStartDiskNumber)
	{
		System.IO.Compression.Zip64ExtraField zip64Block = default(System.IO.Compression.Zip64ExtraField);
		zip64Block._compressedSize = null;
		zip64Block._uncompressedSize = null;
		zip64Block._localHeaderOffset = null;
		zip64Block._startDiskNumber = null;
		List<System.IO.Compression.ZipGenericExtraField> list = new List<System.IO.Compression.ZipGenericExtraField>();
		bool flag = false;
		foreach (System.IO.Compression.ZipGenericExtraField extraField in extraFields)
		{
			if (extraField.Tag == 1)
			{
				list.Add(extraField);
				if (!flag && TryGetZip64BlockFromGenericExtraField(extraField, readUncompressedSize, readCompressedSize, readLocalHeaderOffset, readStartDiskNumber, out zip64Block))
				{
					flag = true;
				}
			}
		}
		foreach (System.IO.Compression.ZipGenericExtraField item in list)
		{
			extraFields.Remove(item);
		}
		return zip64Block;
	}

	public static void RemoveZip64Blocks(List<System.IO.Compression.ZipGenericExtraField> extraFields)
	{
		List<System.IO.Compression.ZipGenericExtraField> list = new List<System.IO.Compression.ZipGenericExtraField>();
		foreach (System.IO.Compression.ZipGenericExtraField extraField in extraFields)
		{
			if (extraField.Tag == 1)
			{
				list.Add(extraField);
			}
		}
		foreach (System.IO.Compression.ZipGenericExtraField item in list)
		{
			extraFields.Remove(item);
		}
	}

	public void WriteBlock(Stream stream)
	{
		BinaryWriter binaryWriter = new BinaryWriter(stream);
		binaryWriter.Write((ushort)1);
		binaryWriter.Write(_size);
		if (_uncompressedSize.HasValue)
		{
			binaryWriter.Write(_uncompressedSize.Value);
		}
		if (_compressedSize.HasValue)
		{
			binaryWriter.Write(_compressedSize.Value);
		}
		if (_localHeaderOffset.HasValue)
		{
			binaryWriter.Write(_localHeaderOffset.Value);
		}
		if (_startDiskNumber.HasValue)
		{
			binaryWriter.Write(_startDiskNumber.Value);
		}
	}
}
internal struct Zip64EndOfCentralDirectoryLocator
{
	public const uint SignatureConstant = 117853008u;

	public const int SizeOfBlockWithoutSignature = 16;

	public uint NumberOfDiskWithZip64EOCD;

	public ulong OffsetOfZip64EOCD;

	public uint TotalNumberOfDisks;

	public static bool TryReadBlock(BinaryReader reader, out System.IO.Compression.Zip64EndOfCentralDirectoryLocator zip64EOCDLocator)
	{
		zip64EOCDLocator = default(System.IO.Compression.Zip64EndOfCentralDirectoryLocator);
		if (reader.ReadUInt32() != 117853008)
		{
			return false;
		}
		zip64EOCDLocator.NumberOfDiskWithZip64EOCD = reader.ReadUInt32();
		zip64EOCDLocator.OffsetOfZip64EOCD = reader.ReadUInt64();
		zip64EOCDLocator.TotalNumberOfDisks = reader.ReadUInt32();
		return true;
	}

	public static void WriteBlock(Stream stream, long zip64EOCDRecordStart)
	{
		BinaryWriter binaryWriter = new BinaryWriter(stream);
		binaryWriter.Write(117853008u);
		binaryWriter.Write(0u);
		binaryWriter.Write(zip64EOCDRecordStart);
		binaryWriter.Write(1u);
	}
}
internal struct Zip64EndOfCentralDirectoryRecord
{
	private const uint SignatureConstant = 101075792u;

	private const ulong NormalSize = 44uL;

	public ulong SizeOfThisRecord;

	public ushort VersionMadeBy;

	public ushort VersionNeededToExtract;

	public uint NumberOfThisDisk;

	public uint NumberOfDiskWithStartOfCD;

	public ulong NumberOfEntriesOnThisDisk;

	public ulong NumberOfEntriesTotal;

	public ulong SizeOfCentralDirectory;

	public ulong OffsetOfCentralDirectory;

	public static bool TryReadBlock(BinaryReader reader, out System.IO.Compression.Zip64EndOfCentralDirectoryRecord zip64EOCDRecord)
	{
		zip64EOCDRecord = default(System.IO.Compression.Zip64EndOfCentralDirectoryRecord);
		if (reader.ReadUInt32() != 101075792)
		{
			return false;
		}
		zip64EOCDRecord.SizeOfThisRecord = reader.ReadUInt64();
		zip64EOCDRecord.VersionMadeBy = reader.ReadUInt16();
		zip64EOCDRecord.VersionNeededToExtract = reader.ReadUInt16();
		zip64EOCDRecord.NumberOfThisDisk = reader.ReadUInt32();
		zip64EOCDRecord.NumberOfDiskWithStartOfCD = reader.ReadUInt32();
		zip64EOCDRecord.NumberOfEntriesOnThisDisk = reader.ReadUInt64();
		zip64EOCDRecord.NumberOfEntriesTotal = reader.ReadUInt64();
		zip64EOCDRecord.SizeOfCentralDirectory = reader.ReadUInt64();
		zip64EOCDRecord.OffsetOfCentralDirectory = reader.ReadUInt64();
		return true;
	}

	public static void WriteBlock(Stream stream, long numberOfEntries, long startOfCentralDirectory, long sizeOfCentralDirectory)
	{
		BinaryWriter binaryWriter = new BinaryWriter(stream);
		binaryWriter.Write(101075792u);
		binaryWriter.Write(44uL);
		binaryWriter.Write((ushort)45);
		binaryWriter.Write((ushort)45);
		binaryWriter.Write(0u);
		binaryWriter.Write(0u);
		binaryWriter.Write(numberOfEntries);
		binaryWriter.Write(numberOfEntries);
		binaryWriter.Write(sizeOfCentralDirectory);
		binaryWriter.Write(startOfCentralDirectory);
	}
}
[StructLayout(LayoutKind.Sequential, Size = 1)]
internal struct ZipLocalFileHeader
{
	public const uint DataDescriptorSignature = 134695760u;

	public const uint SignatureConstant = 67324752u;

	public const int OffsetToCrcFromHeaderStart = 14;

	public const int OffsetToBitFlagFromHeaderStart = 6;

	public const int SizeOfLocalHeader = 30;

	public static List<System.IO.Compression.ZipGenericExtraField> GetExtraFields(BinaryReader reader)
	{
		reader.BaseStream.Seek(26L, SeekOrigin.Current);
		ushort num = reader.ReadUInt16();
		ushort num2 = reader.ReadUInt16();
		reader.BaseStream.Seek(num, SeekOrigin.Current);
		List<System.IO.Compression.ZipGenericExtraField> list;
		using (Stream extraFieldData = new System.IO.Compression.SubReadStream(reader.BaseStream, reader.BaseStream.Position, num2))
		{
			list = System.IO.Compression.ZipGenericExtraField.ParseExtraField(extraFieldData);
		}
		System.IO.Compression.Zip64ExtraField.RemoveZip64Blocks(list);
		return list;
	}

	public static bool TrySkipBlock(BinaryReader reader)
	{
		if (reader.ReadUInt32() != 67324752)
		{
			return false;
		}
		if (reader.BaseStream.Length < reader.BaseStream.Position + 22)
		{
			return false;
		}
		reader.BaseStream.Seek(22L, SeekOrigin.Current);
		ushort num = reader.ReadUInt16();
		ushort num2 = reader.ReadUInt16();
		if (reader.BaseStream.Length < reader.BaseStream.Position + num + num2)
		{
			return false;
		}
		reader.BaseStream.Seek(num + num2, SeekOrigin.Current);
		return true;
	}
}
internal struct ZipCentralDirectoryFileHeader
{
	public const uint SignatureConstant = 33639248u;

	public ushort VersionMadeBy;

	public ushort VersionNeededToExtract;

	public ushort GeneralPurposeBitFlag;

	public ushort CompressionMethod;

	public uint LastModified;

	public uint Crc32;

	public long CompressedSize;

	public long UncompressedSize;

	public ushort FilenameLength;

	public ushort ExtraFieldLength;

	public ushort FileCommentLength;

	public int DiskNumberStart;

	public ushort InternalFileAttributes;

	public uint ExternalFileAttributes;

	public long RelativeOffsetOfLocalHeader;

	public byte[] Filename;

	public byte[] FileComment;

	public List<System.IO.Compression.ZipGenericExtraField> ExtraFields;

	public static bool TryReadBlock(BinaryReader reader, bool saveExtraFieldsAndComments, out System.IO.Compression.ZipCentralDirectoryFileHeader header)
	{
		header = default(System.IO.Compression.ZipCentralDirectoryFileHeader);
		if (reader.ReadUInt32() != 33639248)
		{
			return false;
		}
		header.VersionMadeBy = reader.ReadUInt16();
		header.VersionNeededToExtract = reader.ReadUInt16();
		header.GeneralPurposeBitFlag = reader.ReadUInt16();
		header.CompressionMethod = reader.ReadUInt16();
		header.LastModified = reader.ReadUInt32();
		header.Crc32 = reader.ReadUInt32();
		uint num = reader.ReadUInt32();
		uint num2 = reader.ReadUInt32();
		header.FilenameLength = reader.ReadUInt16();
		header.ExtraFieldLength = reader.ReadUInt16();
		header.FileCommentLength = reader.ReadUInt16();
		ushort num3 = reader.ReadUInt16();
		header.InternalFileAttributes = reader.ReadUInt16();
		header.ExternalFileAttributes = reader.ReadUInt32();
		uint num4 = reader.ReadUInt32();
		header.Filename = reader.ReadBytes(header.FilenameLength);
		bool readUncompressedSize = num2 == uint.MaxValue;
		bool readCompressedSize = num == uint.MaxValue;
		bool readLocalHeaderOffset = num4 == uint.MaxValue;
		bool readStartDiskNumber = num3 == ushort.MaxValue;
		long position = reader.BaseStream.Position + header.ExtraFieldLength;
		System.IO.Compression.Zip64ExtraField zip64ExtraField;
		using (Stream stream = new System.IO.Compression.SubReadStream(reader.BaseStream, reader.BaseStream.Position, header.ExtraFieldLength))
		{
			if (saveExtraFieldsAndComments)
			{
				header.ExtraFields = System.IO.Compression.ZipGenericExtraField.ParseExtraField(stream);
				zip64ExtraField = System.IO.Compression.Zip64ExtraField.GetAndRemoveZip64Block(header.ExtraFields, readUncompressedSize, readCompressedSize, readLocalHeaderOffset, readStartDiskNumber);
			}
			else
			{
				header.ExtraFields = null;
				zip64ExtraField = System.IO.Compression.Zip64ExtraField.GetJustZip64Block(stream, readUncompressedSize, readCompressedSize, readLocalHeaderOffset, readStartDiskNumber);
			}
		}
		reader.BaseStream.AdvanceToPosition(position);
		if (saveExtraFieldsAndComments)
		{
			header.FileComment = reader.ReadBytes(header.FileCommentLength);
		}
		else
		{
			reader.BaseStream.Position += header.FileCommentLength;
			header.FileComment = null;
		}
		header.UncompressedSize = ((!zip64ExtraField.UncompressedSize.HasValue) ? num2 : zip64ExtraField.UncompressedSize.Value);
		header.CompressedSize = ((!zip64ExtraField.CompressedSize.HasValue) ? num : zip64ExtraField.CompressedSize.Value);
		header.RelativeOffsetOfLocalHeader = ((!zip64ExtraField.LocalHeaderOffset.HasValue) ? num4 : zip64ExtraField.LocalHeaderOffset.Value);
		header.DiskNumberStart = ((!zip64ExtraField.StartDiskNumber.HasValue) ? num3 : zip64ExtraField.StartDiskNumber.Value);
		return true;
	}
}
internal struct ZipEndOfCentralDirectoryBlock
{
	public const uint SignatureConstant = 101010256u;

	public const int SizeOfBlockWithoutSignature = 18;

	public uint Signature;

	public ushort NumberOfThisDisk;

	public ushort NumberOfTheDiskWithTheStartOfTheCentralDirectory;

	public ushort NumberOfEntriesInTheCentralDirectoryOnThisDisk;

	public ushort NumberOfEntriesInTheCentralDirectory;

	public uint SizeOfCentralDirectory;

	public uint OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber;

	public byte[] ArchiveComment;

	public static void WriteBlock(Stream stream, long numberOfEntries, long startOfCentralDirectory, long sizeOfCentralDirectory, byte[] archiveComment)
	{
		BinaryWriter binaryWriter = new BinaryWriter(stream);
		ushort value = ((numberOfEntries > 65535) ? ushort.MaxValue : ((ushort)numberOfEntries));
		uint value2 = (uint)((startOfCentralDirectory > uint.MaxValue) ? uint.MaxValue : startOfCentralDirectory);
		uint value3 = (uint)((sizeOfCentralDirectory > uint.MaxValue) ? uint.MaxValue : sizeOfCentralDirectory);
		binaryWriter.Write(101010256u);
		binaryWriter.Write((ushort)0);
		binaryWriter.Write((ushort)0);
		binaryWriter.Write(value);
		binaryWriter.Write(value);
		binaryWriter.Write(value3);
		binaryWriter.Write(value2);
		binaryWriter.Write((ushort)((archiveComment != null) ? ((ushort)archiveComment.Length) : 0));
		if (archiveComment != null)
		{
			binaryWriter.Write(archiveComment);
		}
	}

	public static bool TryReadBlock(BinaryReader reader, out System.IO.Compression.ZipEndOfCentralDirectoryBlock eocdBlock)
	{
		eocdBlock = default(System.IO.Compression.ZipEndOfCentralDirectoryBlock);
		if (reader.ReadUInt32() != 101010256)
		{
			return false;
		}
		eocdBlock.Signature = 101010256u;
		eocdBlock.NumberOfThisDisk = reader.ReadUInt16();
		eocdBlock.NumberOfTheDiskWithTheStartOfTheCentralDirectory = reader.ReadUInt16();
		eocdBlock.NumberOfEntriesInTheCentralDirectoryOnThisDisk = reader.ReadUInt16();
		eocdBlock.NumberOfEntriesInTheCentralDirectory = reader.ReadUInt16();
		eocdBlock.SizeOfCentralDirectory = reader.ReadUInt32();
		eocdBlock.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber = reader.ReadUInt32();
		ushort count = reader.ReadUInt16();
		eocdBlock.ArchiveComment = reader.ReadBytes(count);
		return true;
	}
}
internal static class ZipHelper
{
	internal const uint Mask32Bit = uint.MaxValue;

	internal const ushort Mask16Bit = ushort.MaxValue;

	private const int BackwardsSeekingBufferSize = 32;

	internal const int ValidZipDate_YearMin = 1980;

	internal const int ValidZipDate_YearMax = 2107;

	private static readonly DateTime InvalidDateIndicator = new DateTime(1980, 1, 1, 0, 0, 0);

	internal static bool EndsWithDirChar(string test)
	{
		return Path.GetFileName(test) == "";
	}

	internal static bool RequiresUnicode(string test)
	{
		foreach (char c in test)
		{
			if (c > '\u007f')
			{
				return true;
			}
		}
		return false;
	}

	internal static void ReadBytes(Stream stream, byte[] buffer, int bytesToRead)
	{
		int num = bytesToRead;
		int num2 = 0;
		while (num > 0)
		{
			int num3 = stream.Read(buffer, num2, num);
			if (num3 == 0)
			{
				throw new IOException(Messages.UnexpectedEndOfStream);
			}
			num2 += num3;
			num -= num3;
		}
	}

	internal static DateTime DosTimeToDateTime(uint dateTime)
	{
		int year = (int)(1980 + (dateTime >> 25));
		int month = (int)((dateTime >> 21) & 0xF);
		int day = (int)((dateTime >> 16) & 0x1F);
		int hour = (int)((dateTime >> 11) & 0x1F);
		int minute = (int)((dateTime >> 5) & 0x3F);
		int second = (int)((dateTime & 0x1F) * 2);
		try
		{
			return new DateTime(year, month, day, hour, minute, second, 0);
		}
		catch (ArgumentOutOfRangeException)
		{
			return InvalidDateIndicator;
		}
		catch (ArgumentException)
		{
			return InvalidDateIndicator;
		}
	}

	internal static uint DateTimeToDosTime(DateTime dateTime)
	{
		int num = (dateTime.Year - 1980) & 0x7F;
		num = (num << 4) + dateTime.Month;
		num = (num << 5) + dateTime.Day;
		num = (num << 5) + dateTime.Hour;
		num = (num << 6) + dateTime.Minute;
		return (uint)((num << 5) + dateTime.Second / 2);
	}

	internal static bool SeekBackwardsToSignature(Stream stream, uint signatureToFind)
	{
		int bufferPointer = 0;
		uint num = 0u;
		byte[] array = new byte[32];
		bool flag = false;
		bool flag2 = false;
		while (!flag2 && !flag)
		{
			flag = SeekBackwardsAndRead(stream, array, out bufferPointer);
			while (bufferPointer >= 0 && !flag2)
			{
				num = (num << 8) | array[bufferPointer];
				if (num == signatureToFind)
				{
					flag2 = true;
				}
				else
				{
					bufferPointer--;
				}
			}
		}
		if (!flag2)
		{
			return false;
		}
		stream.Seek(bufferPointer, SeekOrigin.Current);
		return true;
	}

	internal static void AdvanceToPosition(this Stream stream, long position)
	{
		long num = position - stream.Position;
		while (num != 0L)
		{
			int count = (int)((num > 64) ? 64 : num);
			int num2 = stream.Read(new byte[64], 0, count);
			if (num2 == 0)
			{
				throw new IOException(Messages.UnexpectedEndOfStream);
			}
			num -= num2;
		}
	}

	private static bool SeekBackwardsAndRead(Stream stream, byte[] buffer, out int bufferPointer)
	{
		if (stream.Position >= buffer.Length)
		{
			stream.Seek(-buffer.Length, SeekOrigin.Current);
			ReadBytes(stream, buffer, buffer.Length);
			stream.Seek(-buffer.Length, SeekOrigin.Current);
			bufferPointer = buffer.Length - 1;
			return false;
		}
		int num = (int)stream.Position;
		stream.Seek(0L, SeekOrigin.Begin);
		ReadBytes(stream, buffer, num);
		stream.Seek(0L, SeekOrigin.Begin);
		bufferPointer = num - 1;
		return true;
	}
}
internal enum ZipVersionNeededValues : ushort
{
	Default = 10,
	ExplicitDirectory = 20,
	Deflate = 20,
	Zip64 = 45
}
[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[DebuggerNonUserCode]
[CompilerGenerated]
internal class Messages
{
	private static ResourceManager resourceMan;

	private static CultureInfo resourceCulture;

	[EditorBrowsable(EditorBrowsableState.Advanced)]
	internal static ResourceManager ResourceManager
	{
		get
		{
			if (resourceMan == null)
			{
				ResourceManager resourceManager = new ResourceManager("System.IO.Compression.Messages", typeof(Messages).Assembly);
				resourceMan = resourceManager;
			}
			return resourceMan;
		}
	}

	[EditorBrowsable(EditorBrowsableState.Advanced)]
	internal static CultureInfo Culture
	{
		get
		{
			return resourceCulture;
		}
		set
		{
			resourceCulture = value;
		}
	}

	internal static string ArgumentNeedNonNegative => ResourceManager.GetString("ArgumentNeedNonNegative", resourceCulture);

	internal static string CannotBeEmpty => ResourceManager.GetString("CannotBeEmpty", resourceCulture);

	internal static string CDCorrupt => ResourceManager.GetString("CDCorrupt", resourceCulture);

	internal static string CentralDirectoryInvalid => ResourceManager.GetString("CentralDirectoryInvalid", resourceCulture);

	internal static string CreateInReadMode => ResourceManager.GetString("CreateInReadMode", resourceCulture);

	internal static string CreateModeCapabilities => ResourceManager.GetString("CreateModeCapabilities", resourceCulture);

	internal static string CreateModeCreateEntryWhileOpen => ResourceManager.GetString("CreateModeCreateEntryWhileOpen", resourceCulture);

	internal static string CreateModeWriteOnceAndOneEntryAtATime => ResourceManager.GetString("CreateModeWriteOnceAndOneEntryAtATime", resourceCulture);

	internal static string DateTimeInvalid => ResourceManager.GetString("DateTimeInvalid", resourceCulture);

	internal static string DateTimeOutOfRange => ResourceManager.GetString("DateTimeOutOfRange", resourceCulture);

	internal static string DeletedEntry => ResourceManager.GetString("DeletedEntry", resourceCulture);

	internal static string DeleteOnlyInUpdate => ResourceManager.GetString("DeleteOnlyInUpdate", resourceCulture);

	internal static string DeleteOpenEntry => ResourceManager.GetString("DeleteOpenEntry", resourceCulture);

	internal static string EntriesInCreateMode => ResourceManager.GetString("EntriesInCreateMode", resourceCulture);

	internal static string EntryNameEncodingNotSupported => ResourceManager.GetString("EntryNameEncodingNotSupported", resourceCulture);

	internal static string EntryNamesTooLong => ResourceManager.GetString("EntryNamesTooLong", resourceCulture);

	internal static string EntryTooLarge => ResourceManager.GetString("EntryTooLarge", resourceCulture);

	internal static string EOCDNotFound => ResourceManager.GetString("EOCDNotFound", resourceCulture);

	internal static string FieldTooBigCompressedSize => ResourceManager.GetString("FieldTooBigCompressedSize", resourceCulture);

	internal static string FieldTooBigLocalHeaderOffset => ResourceManager.GetString("FieldTooBigLocalHeaderOffset", resourceCulture);

	internal static string FieldTooBigNumEntries => ResourceManager.GetString("FieldTooBigNumEntries", resourceCulture);

	internal static string FieldTooBigOffsetToCD => ResourceManager.GetString("FieldTooBigOffsetToCD", resourceCulture);

	internal static string FieldTooBigOffsetToZip64EOCD => ResourceManager.GetString("FieldTooBigOffsetToZip64EOCD", resourceCulture);

	internal static string FieldTooBigStartDiskNumber => ResourceManager.GetString("FieldTooBigStartDiskNumber", resourceCulture);

	internal static string FieldTooBigUncompressedSize => ResourceManager.GetString("FieldTooBigUncompressedSize", resourceCulture);

	internal static string FrozenAfterWrite => ResourceManager.GetString("FrozenAfterWrite", resourceCulture);

	internal static string HiddenStreamName => ResourceManager.GetString("HiddenStreamName", resourceCulture);

	internal static string LengthAfterWrite => ResourceManager.GetString("LengthAfterWrite", resourceCulture);

	internal static string LocalFileHeaderCorrupt => ResourceManager.GetString("LocalFileHeaderCorrupt", resourceCulture);

	internal static string NumEntriesWrong => ResourceManager.GetString("NumEntriesWrong", resourceCulture);

	internal static string OffsetLengthInvalid => ResourceManager.GetString("OffsetLengthInvalid", resourceCulture);

	internal static string ReadingNotSupported => ResourceManager.GetString("ReadingNotSupported", resourceCulture);

	internal static string ReadModeCapabilities => ResourceManager.GetString("ReadModeCapabilities", resourceCulture);

	internal static string ReadOnlyArchive => ResourceManager.GetString("ReadOnlyArchive", resourceCulture);

	internal static string SeekingNotSupported => ResourceManager.GetString("SeekingNotSupported", resourceCulture);

	internal static string SetLengthRequiresSeekingAndWriting => ResourceManager.GetString("SetLengthRequiresSeekingAndWriting", resourceCulture);

	internal static string SplitSpanned => ResourceManager.GetString("SplitSpanned", resourceCulture);

	internal static string UnexpectedEndOfStream => ResourceManager.GetString("UnexpectedEndOfStream", resourceCulture);

	internal static string UnsupportedCompression => ResourceManager.GetString("UnsupportedCompression", resourceCulture);

	internal static string UpdateModeCapabilities => ResourceManager.GetString("UpdateModeCapabilities", resourceCulture);

	internal static string UpdateModeOneStream => ResourceManager.GetString("UpdateModeOneStream", resourceCulture);

	internal static string WritingNotSupported => ResourceManager.GetString("WritingNotSupported", resourceCulture);

	internal static string Zip64EOCDNotWhereExpected => ResourceManager.GetString("Zip64EOCDNotWhereExpected", resourceCulture);

	internal Messages()
	{
	}
}
[AttributeUsage(AttributeTargets.All, Inherited = false)]
internal sealed class __DynamicallyInvokableAttribute : Attribute
{
}

config/ServerCharacters-master/ServerCharacters/Libs/System.IO.Compression.FileSystem.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading;

[assembly: CompilationRelaxations(8)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ComVisible(false)]
[assembly: CLSCompliant(true)]
[assembly: SecurityTransparent]
[assembly: SecurityRules(SecurityRuleSet.Level2, SkipVerificationInFullTrust = true)]
[assembly: AssemblyTitle("System.IO.Compression.FileSystem.dll")]
[assembly: AssemblyDescription("System.IO.Compression.FileSystem.dll")]
[assembly: AssemblyDefaultAlias("System.IO.Compression.FileSystem.dll")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoftยฎ .NET Framework")]
[assembly: AssemblyCopyright("ยฉ Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyFileVersion("4.8.9032.0")]
[assembly: AssemblyInformationalVersion("4.8.9032.0")]
[assembly: SatelliteContractVersion("4.0.0.0")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyDelaySign(true)]
[assembly: AssemblyKeyFile("f:\\dd\\tools\\devdiv\\EcmaPublicKey.snk")]
[assembly: AssemblySignatureKey("002400000c800000140100000602000000240000525341310008000001000100613399aff18ef1a2c2514a273a42d9042b72321f1757102df9ebada69923e2738406c21e5b801552ab8d200a65a235e001ac9adc25f2d811eb09496a4c6a59d4619589c69f5baf0c4179a47311d92555cd006acc8b5959f2bd6e10e360c34537a1d266da8085856583c85d81da7f3ec01ed9564c58d93d713cd0172c8e23a10f0239b80c96b07736f5d8b022542a4e74251a5f432824318b3539a5a087f8e53d2f135f9ca47f3bb2e10aff0af0849504fb7cea3ff192dc8de0edad64c68efde34c56d302ad55fd6e80f302d5efcdeae953658d3452561b5f36c542efdbdd9f888538d374cef106acf7d93a4445c3c73cd911f0571aaf3d54da12b11ddec375b3", "a5a866e1ee186f807668209f3b11236ace5e21f117803a3143abb126dd035d7d2f876b6938aaf2ee3414d5420d753621400db44a49c486ce134300a2106adb6bdb433590fef8ad5c43cba82290dc49530effd86523d9483c00f458af46890036b0e2c61d077d7fbac467a506eba29e467a87198b053c749aa2a4d2840c784e6d")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyVersion("4.0.0.0")]
namespace System
{
	internal static class AppContextDefaultValues
	{
		public static void PopulateDefaultValues()
		{
			ParseTargetFrameworkName(out var identifier, out var profile, out var version);
			PopulateDefaultValuesPartial(identifier, profile, version);
		}

		private static void ParseTargetFrameworkName(out string identifier, out string profile, out int version)
		{
			string targetFrameworkName = AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName;
			if (!TryParseFrameworkName(targetFrameworkName, out identifier, out version, out profile))
			{
				identifier = ".NETFramework";
				version = 40000;
				profile = string.Empty;
			}
		}

		private static bool TryParseFrameworkName(string frameworkName, out string identifier, out int version, out string profile)
		{
			identifier = (profile = string.Empty);
			version = 0;
			if (frameworkName == null || frameworkName.Length == 0)
			{
				return false;
			}
			string[] array = frameworkName.Split(new char[1] { ',' });
			version = 0;
			if (array.Length < 2 || array.Length > 3)
			{
				return false;
			}
			identifier = array[0].Trim();
			if (identifier.Length == 0)
			{
				return false;
			}
			bool flag = false;
			profile = null;
			for (int i = 1; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { '=' });
				if (array2.Length != 2)
				{
					return false;
				}
				string text = array2[0].Trim();
				string text2 = array2[1].Trim();
				if (text.Equals("Version", StringComparison.OrdinalIgnoreCase))
				{
					flag = true;
					if (text2.Length > 0 && (text2[0] == 'v' || text2[0] == 'V'))
					{
						text2 = text2.Substring(1);
					}
					Version version2 = new Version(text2);
					version = version2.Major * 10000;
					if (version2.Minor > 0)
					{
						version += version2.Minor * 100;
					}
					if (version2.Build > 0)
					{
						version += version2.Build;
					}
				}
				else
				{
					if (!text.Equals("Profile", StringComparison.OrdinalIgnoreCase))
					{
						return false;
					}
					if (!string.IsNullOrEmpty(text2))
					{
						profile = text2;
					}
				}
			}
			if (!flag)
			{
				return false;
			}
			return true;
		}

		private static void PopulateDefaultValuesPartial(string platformIdentifier, string profile, int version)
		{
			switch (platformIdentifier)
			{
			case ".NETCore":
			case ".NETFramework":
				if (version <= 40600)
				{
					LocalAppContext.DefineSwitchDefault("Switch.System.IO.Compression.ZipFile.UseBackslash", initialValue: true);
				}
				break;
			case "WindowsPhone":
			case "WindowsPhoneApp":
				if (version <= 80100)
				{
					LocalAppContext.DefineSwitchDefault("Switch.System.IO.Compression.ZipFile.UseBackslash", initialValue: true);
				}
				break;
			}
		}
	}
	internal static class LocalAppContextSwitches
	{
		private static int _zipFileUseBackslash;

		private static int _doNotAddTrailingSeparator;

		internal const string ZipFileUseBackslashName = "Switch.System.IO.Compression.ZipFile.UseBackslash";

		internal const string DoNotAddTrailingSeparatorString = "Switch.System.IO.Compression.DoNotAddTrailingSeparator";

		public static bool ZipFileUseBackslash
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return LocalAppContext.GetCachedSwitchValue("Switch.System.IO.Compression.ZipFile.UseBackslash", ref _zipFileUseBackslash);
			}
		}

		public static bool DoNotAddTrailingSeparator
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return LocalAppContext.GetCachedSwitchValue("Switch.System.IO.Compression.DoNotAddTrailingSeparator", ref _doNotAddTrailingSeparator);
			}
		}
	}
	internal static class LocalAppContext
	{
		private delegate bool TryGetSwitchDelegate(string switchName, out bool value);

		private static TryGetSwitchDelegate TryGetSwitchFromCentralAppContext;

		private static bool s_canForwardCalls;

		private static Dictionary<string, bool> s_switchMap;

		private static readonly object s_syncLock;

		private static bool DisableCaching { get; set; }

		static LocalAppContext()
		{
			s_switchMap = new Dictionary<string, bool>();
			s_syncLock = new object();
			s_canForwardCalls = SetupDelegate();
			AppContextDefaultValues.PopulateDefaultValues();
			DisableCaching = IsSwitchEnabled("TestSwitch.LocalAppContext.DisableCaching");
		}

		public static bool IsSwitchEnabled(string switchName)
		{
			if (s_canForwardCalls && TryGetSwitchFromCentralAppContext(switchName, out var value))
			{
				return value;
			}
			return IsSwitchEnabledLocal(switchName);
		}

		private static bool IsSwitchEnabledLocal(string switchName)
		{
			bool flag;
			bool value;
			lock (s_switchMap)
			{
				flag = s_switchMap.TryGetValue(switchName, out value);
			}
			if (flag)
			{
				return value;
			}
			return false;
		}

		private static bool SetupDelegate()
		{
			Type type = typeof(object).Assembly.GetType("System.AppContext");
			if (type == null)
			{
				return false;
			}
			MethodInfo method = type.GetMethod("TryGetSwitch", BindingFlags.Static | BindingFlags.Public, null, new Type[2]
			{
				typeof(string),
				typeof(bool).MakeByRefType()
			}, null);
			if (method == null)
			{
				return false;
			}
			TryGetSwitchFromCentralAppContext = (TryGetSwitchDelegate)Delegate.CreateDelegate(typeof(TryGetSwitchDelegate), method);
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static bool GetCachedSwitchValue(string switchName, ref int switchValue)
		{
			if (switchValue < 0)
			{
				return false;
			}
			if (switchValue > 0)
			{
				return true;
			}
			return GetCachedSwitchValueInternal(switchName, ref switchValue);
		}

		private static bool GetCachedSwitchValueInternal(string switchName, ref int switchValue)
		{
			if (DisableCaching)
			{
				return IsSwitchEnabled(switchName);
			}
			bool flag = IsSwitchEnabled(switchName);
			switchValue = (flag ? 1 : (-1));
			return flag;
		}

		internal static void DefineSwitchDefault(string switchName, bool initialValue)
		{
			s_switchMap[switchName] = initialValue;
		}
	}
}
namespace System.IO.Compression
{
	public static class ZipFile
	{
		private static readonly char s_pathSeperator = (System.LocalAppContextSwitches.ZipFileUseBackslash ? '\\' : '/');

		public static ZipArchive OpenRead(string archiveFileName)
		{
			return Open(archiveFileName, ZipArchiveMode.Read);
		}

		public static ZipArchive Open(string archiveFileName, ZipArchiveMode mode)
		{
			return Open(archiveFileName, mode, null);
		}

		public static ZipArchive Open(string archiveFileName, ZipArchiveMode mode, Encoding entryNameEncoding)
		{
			FileMode mode2;
			FileAccess access;
			FileShare share;
			switch (mode)
			{
			case ZipArchiveMode.Read:
				mode2 = FileMode.Open;
				access = FileAccess.Read;
				share = FileShare.Read;
				break;
			case ZipArchiveMode.Create:
				mode2 = FileMode.CreateNew;
				access = FileAccess.Write;
				share = FileShare.None;
				break;
			case ZipArchiveMode.Update:
				mode2 = FileMode.OpenOrCreate;
				access = FileAccess.ReadWrite;
				share = FileShare.None;
				break;
			default:
				throw new ArgumentOutOfRangeException("mode");
			}
			FileStream fileStream = null;
			try
			{
				fileStream = File.Open(archiveFileName, mode2, access, share);
				return new ZipArchive(fileStream, mode, leaveOpen: false, entryNameEncoding);
			}
			catch
			{
				fileStream?.Dispose();
				throw;
			}
		}

		public static void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName)
		{
			DoCreateFromDirectory(sourceDirectoryName, destinationArchiveFileName, null, includeBaseDirectory: false, null);
		}

		public static void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName, CompressionLevel compressionLevel, bool includeBaseDirectory)
		{
			DoCreateFromDirectory(sourceDirectoryName, destinationArchiveFileName, compressionLevel, includeBaseDirectory, null);
		}

		public static void CreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName, CompressionLevel compressionLevel, bool includeBaseDirectory, Encoding entryNameEncoding)
		{
			DoCreateFromDirectory(sourceDirectoryName, destinationArchiveFileName, compressionLevel, includeBaseDirectory, entryNameEncoding);
		}

		public static void ExtractToDirectory(string sourceArchiveFileName, string destinationDirectoryName)
		{
			ExtractToDirectory(sourceArchiveFileName, destinationDirectoryName, null);
		}

		public static void ExtractToDirectory(string sourceArchiveFileName, string destinationDirectoryName, Encoding entryNameEncoding)
		{
			if (sourceArchiveFileName == null)
			{
				throw new ArgumentNullException("sourceArchiveFileName");
			}
			using ZipArchive source = Open(sourceArchiveFileName, ZipArchiveMode.Read, entryNameEncoding);
			source.ExtractToDirectory(destinationDirectoryName);
		}

		private static void DoCreateFromDirectory(string sourceDirectoryName, string destinationArchiveFileName, CompressionLevel? compressionLevel, bool includeBaseDirectory, Encoding entryNameEncoding)
		{
			sourceDirectoryName = Path.GetFullPath(sourceDirectoryName);
			destinationArchiveFileName = Path.GetFullPath(destinationArchiveFileName);
			using ZipArchive zipArchive = Open(destinationArchiveFileName, ZipArchiveMode.Create, entryNameEncoding);
			bool flag = true;
			DirectoryInfo directoryInfo = new DirectoryInfo(sourceDirectoryName);
			string fullName = directoryInfo.FullName;
			if (includeBaseDirectory && directoryInfo.Parent != null)
			{
				fullName = directoryInfo.Parent.FullName;
			}
			foreach (FileSystemInfo item in directoryInfo.EnumerateFileSystemInfos("*", SearchOption.AllDirectories))
			{
				flag = false;
				int length = item.FullName.Length - fullName.Length;
				string text;
				if (System.LocalAppContextSwitches.ZipFileUseBackslash)
				{
					text = item.FullName.Substring(fullName.Length, length);
					text = text.TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
				}
				else
				{
					text = EntryFromPath(item.FullName, fullName.Length, length);
				}
				if (item is FileInfo)
				{
					ZipFileExtensions.DoCreateEntryFromFile(zipArchive, item.FullName, text, compressionLevel);
				}
				else if (item is DirectoryInfo possiblyEmptyDir && IsDirEmpty(possiblyEmptyDir))
				{
					string text2 = text;
					char c = s_pathSeperator;
					zipArchive.CreateEntry(text2 + c);
				}
			}
			if (includeBaseDirectory && flag)
			{
				string text = (System.LocalAppContextSwitches.ZipFileUseBackslash ? directoryInfo.Name : EntryFromPath(directoryInfo.Name, 0, directoryInfo.Name.Length));
				string text3 = text;
				char c = s_pathSeperator;
				zipArchive.CreateEntry(text3 + c);
			}
		}

		private static string EntryFromPath(string entry, int offset, int length)
		{
			while (length > 0 && (entry[offset] == Path.DirectorySeparatorChar || entry[offset] == Path.AltDirectorySeparatorChar))
			{
				offset++;
				length--;
			}
			if (length == 0)
			{
				return string.Empty;
			}
			char[] array = entry.ToCharArray(offset, length);
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i] == Path.DirectorySeparatorChar || array[i] == Path.AltDirectorySeparatorChar)
				{
					array[i] = s_pathSeperator;
				}
			}
			return new string(array);
		}

		private static bool IsDirEmpty(DirectoryInfo possiblyEmptyDir)
		{
			using (IEnumerator<FileSystemInfo> enumerator = possiblyEmptyDir.EnumerateFileSystemInfos("*", SearchOption.AllDirectories).GetEnumerator())
			{
				if (enumerator.MoveNext())
				{
					FileSystemInfo current = enumerator.Current;
					return false;
				}
			}
			return true;
		}
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	public static class ZipFileExtensions
	{
		public static ZipArchiveEntry CreateEntryFromFile(this ZipArchive destination, string sourceFileName, string entryName)
		{
			return DoCreateEntryFromFile(destination, sourceFileName, entryName, null);
		}

		public static ZipArchiveEntry CreateEntryFromFile(this ZipArchive destination, string sourceFileName, string entryName, CompressionLevel compressionLevel)
		{
			return DoCreateEntryFromFile(destination, sourceFileName, entryName, compressionLevel);
		}

		public static void ExtractToDirectory(this ZipArchive source, string destinationDirectoryName)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (destinationDirectoryName == null)
			{
				throw new ArgumentNullException("destinationDirectoryName");
			}
			DirectoryInfo directoryInfo = Directory.CreateDirectory(destinationDirectoryName);
			string text = directoryInfo.FullName;
			if (!System.LocalAppContextSwitches.DoNotAddTrailingSeparator)
			{
				int length = text.Length;
				if (length != 0 && text[length - 1] != Path.DirectorySeparatorChar)
				{
					string text2 = text;
					char directorySeparatorChar = Path.DirectorySeparatorChar;
					text = text2 + directorySeparatorChar;
				}
			}
			foreach (ZipArchiveEntry entry in source.Entries)
			{
				string fullPath = Path.GetFullPath(Path.Combine(text, entry.FullName));
				if (!fullPath.StartsWith(text, StringComparison.OrdinalIgnoreCase))
				{
					throw new IOException(SR.GetString("IO_ExtractingResultsInOutside"));
				}
				if (Path.GetFileName(fullPath).Length == 0)
				{
					if (entry.Length != 0L)
					{
						throw new IOException(SR.GetString("IO_DirectoryNameWithData"));
					}
					Directory.CreateDirectory(fullPath);
				}
				else
				{
					Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
					entry.ExtractToFile(fullPath, overwrite: false);
				}
			}
		}

		internal static ZipArchiveEntry DoCreateEntryFromFile(ZipArchive destination, string sourceFileName, string entryName, CompressionLevel? compressionLevel)
		{
			if (destination == null)
			{
				throw new ArgumentNullException("destination");
			}
			if (sourceFileName == null)
			{
				throw new ArgumentNullException("sourceFileName");
			}
			if (entryName == null)
			{
				throw new ArgumentNullException("entryName");
			}
			using Stream stream = File.Open(sourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
			ZipArchiveEntry zipArchiveEntry = (compressionLevel.HasValue ? destination.CreateEntry(entryName, compressionLevel.Value) : destination.CreateEntry(entryName));
			DateTime dateTime = File.GetLastWriteTime(sourceFileName);
			if (dateTime.Year < 1980 || dateTime.Year > 2107)
			{
				dateTime = new DateTime(1980, 1, 1, 0, 0, 0);
			}
			zipArchiveEntry.LastWriteTime = dateTime;
			using (Stream destination2 = zipArchiveEntry.Open())
			{
				stream.CopyTo(destination2);
			}
			return zipArchiveEntry;
		}

		public static void ExtractToFile(this ZipArchiveEntry source, string destinationFileName)
		{
			source.ExtractToFile(destinationFileName, overwrite: false);
		}

		public static void ExtractToFile(this ZipArchiveEntry source, string destinationFileName, bool overwrite)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (destinationFileName == null)
			{
				throw new ArgumentNullException("destinationFileName");
			}
			FileMode mode = ((!overwrite) ? FileMode.CreateNew : FileMode.Create);
			using (Stream destination = File.Open(destinationFileName, mode, FileAccess.Write, FileShare.None))
			{
				using Stream stream = source.Open();
				stream.CopyTo(destination);
			}
			File.SetLastWriteTime(destinationFileName, source.LastWriteTime.DateTime);
		}
	}
	internal sealed class SR
	{
		internal const string IO_DirectoryNameWithData = "IO_DirectoryNameWithData";

		internal const string IO_ExtractingResultsInOutside = "IO_ExtractingResultsInOutside";

		private static SR loader;

		private ResourceManager resources;

		private static CultureInfo Culture => null;

		public static ResourceManager Resources => GetLoader().resources;

		internal SR()
		{
			resources = new ResourceManager("System.IO.Compression.FileSystem", GetType().Assembly);
		}

		private static SR GetLoader()
		{
			if (loader == null)
			{
				SR value = new SR();
				Interlocked.CompareExchange(ref loader, value, null);
			}
			return loader;
		}

		public static string GetString(string name, params object[] args)
		{
			SR sR = GetLoader();
			if (sR == null)
			{
				return null;
			}
			string @string = sR.resources.GetString(name, Culture);
			if (args != null && args.Length != 0)
			{
				for (int i = 0; i < args.Length; i++)
				{
					if (args[i] is string text && text.Length > 1024)
					{
						args[i] = text.Substring(0, 1021) + "...";
					}
				}
				return string.Format(CultureInfo.CurrentCulture, @string, args);
			}
			return @string;
		}

		public static string GetString(string name)
		{
			return GetLoader()?.resources.GetString(name, Culture);
		}

		public static string GetString(string name, out bool usedFallback)
		{
			usedFallback = false;
			return GetString(name);
		}

		public static object GetObject(string name)
		{
			return GetLoader()?.resources.GetObject(name, Culture);
		}
	}
}

config/ServerCharacters-master/ServerCharacters/Libs/System.IO.Compression.ZipFile.dll

Decompiled 2 weeks ago
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;

[assembly: AssemblyTitle("System.IO.Compression.ZipFile")]
[assembly: AssemblyDescription("System.IO.Compression.ZipFile")]
[assembly: AssemblyDefaultAlias("System.IO.Compression.ZipFile")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoftยฎ .NET Framework")]
[assembly: AssemblyCopyright("ยฉ Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyMetadata("", "")]
[assembly: AssemblyFileVersion("4.8.9032.0")]
[assembly: AssemblyInformationalVersion("4.8.9032.0")]
[assembly: AssemblyVersion("4.0.0.0")]
[assembly: TypeForwardedTo(typeof(ZipFile))]
[assembly: TypeForwardedTo(typeof(ZipFileExtensions))]

config/ServerCharacters-master/ServerCharacters/Libs/System.Memory.dll

Decompiled 2 weeks ago
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Buffers.Text;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using FxResources.System.Memory;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Memory")]
[assembly: AssemblyDescription("System.Memory")]
[assembly: AssemblyDefaultAlias("System.Memory")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoftยฎ .NET Framework")]
[assembly: AssemblyCopyright("ยฉ Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.28619.01")]
[assembly: AssemblyInformationalVersion("4.6.28619.01 @BuiltBy: dlab14-DDVSOWINAGE069 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/corefx/tree/7601f4f6225089ffb291dc7d58293c7bbf5c5d4f")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.1.1")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsByRefLikeAttribute : Attribute
	{
	}
}
namespace FxResources.System.Memory
{
	internal static class SR
	{
	}
}
namespace System
{
	public readonly struct SequencePosition : IEquatable<SequencePosition>
	{
		private readonly object _object;

		private readonly int _integer;

		public SequencePosition(object @object, int integer)
		{
			_object = @object;
			_integer = integer;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public object GetObject()
		{
			return _object;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public int GetInteger()
		{
			return _integer;
		}

		public bool Equals(SequencePosition other)
		{
			if (_integer == other._integer)
			{
				return object.Equals(_object, other._object);
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is SequencePosition other)
			{
				return Equals(other);
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			return HashHelpers.Combine(_object?.GetHashCode() ?? 0, _integer);
		}
	}
	internal static class ThrowHelper
	{
		internal static void ThrowArgumentNullException(System.ExceptionArgument argument)
		{
			throw CreateArgumentNullException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentNullException(System.ExceptionArgument argument)
		{
			return new ArgumentNullException(argument.ToString());
		}

		internal static void ThrowArrayTypeMismatchException()
		{
			throw CreateArrayTypeMismatchException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArrayTypeMismatchException()
		{
			return new ArrayTypeMismatchException();
		}

		internal static void ThrowArgumentException_InvalidTypeWithPointersNotSupported(Type type)
		{
			throw CreateArgumentException_InvalidTypeWithPointersNotSupported(type);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_InvalidTypeWithPointersNotSupported(Type type)
		{
			return new ArgumentException(System.SR.Format(System.SR.Argument_InvalidTypeWithPointersNotSupported, type));
		}

		internal static void ThrowArgumentException_DestinationTooShort()
		{
			throw CreateArgumentException_DestinationTooShort();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_DestinationTooShort()
		{
			return new ArgumentException(System.SR.Argument_DestinationTooShort);
		}

		internal static void ThrowIndexOutOfRangeException()
		{
			throw CreateIndexOutOfRangeException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateIndexOutOfRangeException()
		{
			return new IndexOutOfRangeException();
		}

		internal static void ThrowArgumentOutOfRangeException()
		{
			throw CreateArgumentOutOfRangeException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException()
		{
			return new ArgumentOutOfRangeException();
		}

		internal static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument)
		{
			throw CreateArgumentOutOfRangeException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException(System.ExceptionArgument argument)
		{
			return new ArgumentOutOfRangeException(argument.ToString());
		}

		internal static void ThrowArgumentOutOfRangeException_PrecisionTooLarge()
		{
			throw CreateArgumentOutOfRangeException_PrecisionTooLarge();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_PrecisionTooLarge()
		{
			return new ArgumentOutOfRangeException("precision", System.SR.Format(System.SR.Argument_PrecisionTooLarge, (byte)99));
		}

		internal static void ThrowArgumentOutOfRangeException_SymbolDoesNotFit()
		{
			throw CreateArgumentOutOfRangeException_SymbolDoesNotFit();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_SymbolDoesNotFit()
		{
			return new ArgumentOutOfRangeException("symbol", System.SR.Argument_BadFormatSpecifier);
		}

		internal static void ThrowInvalidOperationException()
		{
			throw CreateInvalidOperationException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException()
		{
			return new InvalidOperationException();
		}

		internal static void ThrowInvalidOperationException_OutstandingReferences()
		{
			throw CreateInvalidOperationException_OutstandingReferences();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_OutstandingReferences()
		{
			return new InvalidOperationException(System.SR.OutstandingReferences);
		}

		internal static void ThrowInvalidOperationException_UnexpectedSegmentType()
		{
			throw CreateInvalidOperationException_UnexpectedSegmentType();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_UnexpectedSegmentType()
		{
			return new InvalidOperationException(System.SR.UnexpectedSegmentType);
		}

		internal static void ThrowInvalidOperationException_EndPositionNotReached()
		{
			throw CreateInvalidOperationException_EndPositionNotReached();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_EndPositionNotReached()
		{
			return new InvalidOperationException(System.SR.EndPositionNotReached);
		}

		internal static void ThrowArgumentOutOfRangeException_PositionOutOfRange()
		{
			throw CreateArgumentOutOfRangeException_PositionOutOfRange();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_PositionOutOfRange()
		{
			return new ArgumentOutOfRangeException("position");
		}

		internal static void ThrowArgumentOutOfRangeException_OffsetOutOfRange()
		{
			throw CreateArgumentOutOfRangeException_OffsetOutOfRange();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_OffsetOutOfRange()
		{
			return new ArgumentOutOfRangeException("offset");
		}

		internal static void ThrowObjectDisposedException_ArrayMemoryPoolBuffer()
		{
			throw CreateObjectDisposedException_ArrayMemoryPoolBuffer();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateObjectDisposedException_ArrayMemoryPoolBuffer()
		{
			return new ObjectDisposedException("ArrayMemoryPoolBuffer");
		}

		internal static void ThrowFormatException_BadFormatSpecifier()
		{
			throw CreateFormatException_BadFormatSpecifier();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateFormatException_BadFormatSpecifier()
		{
			return new FormatException(System.SR.Argument_BadFormatSpecifier);
		}

		internal static void ThrowArgumentException_OverlapAlignmentMismatch()
		{
			throw CreateArgumentException_OverlapAlignmentMismatch();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_OverlapAlignmentMismatch()
		{
			return new ArgumentException(System.SR.Argument_OverlapAlignmentMismatch);
		}

		internal static void ThrowNotSupportedException()
		{
			throw CreateThrowNotSupportedException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateThrowNotSupportedException()
		{
			return new NotSupportedException();
		}

		public static bool TryFormatThrowFormatException(out int bytesWritten)
		{
			bytesWritten = 0;
			ThrowFormatException_BadFormatSpecifier();
			return false;
		}

		public static bool TryParseThrowFormatException<T>(out T value, out int bytesConsumed)
		{
			value = default(T);
			bytesConsumed = 0;
			ThrowFormatException_BadFormatSpecifier();
			return false;
		}

		public static void ThrowArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment)
		{
			throw CreateArgumentValidationException(startSegment, startIndex, endSegment);
		}

		private static Exception CreateArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment)
		{
			if (startSegment == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.startSegment);
			}
			if (endSegment == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.endSegment);
			}
			if (startSegment != endSegment && startSegment.RunningIndex > endSegment.RunningIndex)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.endSegment);
			}
			if ((uint)startSegment.Memory.Length < (uint)startIndex)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.startIndex);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.endIndex);
		}

		public static void ThrowArgumentValidationException(Array array, int start)
		{
			throw CreateArgumentValidationException(array, start);
		}

		private static Exception CreateArgumentValidationException(Array array, int start)
		{
			if (array == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.array);
			}
			if ((uint)start > (uint)array.Length)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.length);
		}

		public static void ThrowStartOrEndArgumentValidationException(long start)
		{
			throw CreateStartOrEndArgumentValidationException(start);
		}

		private static Exception CreateStartOrEndArgumentValidationException(long start)
		{
			if (start < 0)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.length);
		}
	}
	internal enum ExceptionArgument
	{
		length,
		start,
		minimumBufferSize,
		elementIndex,
		comparable,
		comparer,
		destination,
		offset,
		startSegment,
		endSegment,
		startIndex,
		endIndex,
		array,
		culture,
		manager
	}
	internal static class DecimalDecCalc
	{
		private static uint D32DivMod1E9(uint hi32, ref uint lo32)
		{
			ulong num = ((ulong)hi32 << 32) | lo32;
			lo32 = (uint)(num / 1000000000);
			return (uint)(num % 1000000000);
		}

		internal static uint DecDivMod1E9(ref MutableDecimal value)
		{
			return D32DivMod1E9(D32DivMod1E9(D32DivMod1E9(0u, ref value.High), ref value.Mid), ref value.Low);
		}

		internal static void DecAddInt32(ref MutableDecimal value, uint i)
		{
			if (D32AddCarry(ref value.Low, i) && D32AddCarry(ref value.Mid, 1u))
			{
				D32AddCarry(ref value.High, 1u);
			}
		}

		private static bool D32AddCarry(ref uint value, uint i)
		{
			uint num = value;
			uint num2 = (value = num + i);
			if (num2 >= num)
			{
				return num2 < i;
			}
			return true;
		}

		internal static void DecMul10(ref MutableDecimal value)
		{
			MutableDecimal d = value;
			DecShiftLeft(ref value);
			DecShiftLeft(ref value);
			DecAdd(ref value, d);
			DecShiftLeft(ref value);
		}

		private static void DecShiftLeft(ref MutableDecimal value)
		{
			uint num = (((value.Low & 0x80000000u) != 0) ? 1u : 0u);
			uint num2 = (((value.Mid & 0x80000000u) != 0) ? 1u : 0u);
			value.Low <<= 1;
			value.Mid = (value.Mid << 1) | num;
			value.High = (value.High << 1) | num2;
		}

		private static void DecAdd(ref MutableDecimal value, MutableDecimal d)
		{
			if (D32AddCarry(ref value.Low, d.Low) && D32AddCarry(ref value.Mid, 1u))
			{
				D32AddCarry(ref value.High, 1u);
			}
			if (D32AddCarry(ref value.Mid, d.Mid))
			{
				D32AddCarry(ref value.High, 1u);
			}
			D32AddCarry(ref value.High, d.High);
		}
	}
	internal static class Number
	{
		private static class DoubleHelper
		{
			public unsafe static uint Exponent(double d)
			{
				return (*(uint*)((byte*)(&d) + 4) >> 20) & 0x7FFu;
			}

			public unsafe static ulong Mantissa(double d)
			{
				return *(uint*)(&d) | ((ulong)(uint)(*(int*)((byte*)(&d) + 4) & 0xFFFFF) << 32);
			}

			public unsafe static bool Sign(double d)
			{
				return *(uint*)((byte*)(&d) + 4) >> 31 != 0;
			}
		}

		internal const int DECIMAL_PRECISION = 29;

		private static readonly ulong[] s_rgval64Power10 = new ulong[30]
		{
			11529215046068469760uL, 14411518807585587200uL, 18014398509481984000uL, 11258999068426240000uL, 14073748835532800000uL, 17592186044416000000uL, 10995116277760000000uL, 13743895347200000000uL, 17179869184000000000uL, 10737418240000000000uL,
			13421772800000000000uL, 16777216000000000000uL, 10485760000000000000uL, 13107200000000000000uL, 16384000000000000000uL, 14757395258967641293uL, 11805916207174113035uL, 9444732965739290428uL, 15111572745182864686uL, 12089258196146291749uL,
			9671406556917033399uL, 15474250491067253438uL, 12379400392853802751uL, 9903520314283042201uL, 15845632502852867522uL, 12676506002282294018uL, 10141204801825835215uL, 16225927682921336344uL, 12980742146337069075uL, 10384593717069655260uL
		};

		private static readonly sbyte[] s_rgexp64Power10 = new sbyte[15]
		{
			4, 7, 10, 14, 17, 20, 24, 27, 30, 34,
			37, 40, 44, 47, 50
		};

		private static readonly ulong[] s_rgval64Power10By16 = new ulong[42]
		{
			10240000000000000000uL, 11368683772161602974uL, 12621774483536188886uL, 14012984643248170708uL, 15557538194652854266uL, 17272337110188889248uL, 9588073174409622172uL, 10644899600020376798uL, 11818212630765741798uL, 13120851772591970216uL,
			14567071740625403792uL, 16172698447808779622uL, 17955302187076837696uL, 9967194951097567532uL, 11065809325636130658uL, 12285516299433008778uL, 13639663065038175358uL, 15143067982934716296uL, 16812182738118149112uL, 9332636185032188787uL,
			10361307573072618722uL, 16615349947311448416uL, 14965776766268445891uL, 13479973333575319909uL, 12141680576410806707uL, 10936253623915059637uL, 9850501549098619819uL, 17745086042373215136uL, 15983352577617880260uL, 14396524142538228461uL,
			12967236152753103031uL, 11679847981112819795uL, 10520271803096747049uL, 9475818434452569218uL, 17070116948172427008uL, 15375394465392026135uL, 13848924157002783096uL, 12474001934591998882uL, 11235582092889474480uL, 10120112665365530972uL,
			18230774251475056952uL, 16420821625123739930uL
		};

		private static readonly short[] s_rgexp64Power10By16 = new short[21]
		{
			54, 107, 160, 213, 266, 319, 373, 426, 479, 532,
			585, 638, 691, 745, 798, 851, 904, 957, 1010, 1064,
			1117
		};

		public static void RoundNumber(ref NumberBuffer number, int pos)
		{
			Span<byte> digits = number.Digits;
			int i;
			for (i = 0; i < pos && digits[i] != 0; i++)
			{
			}
			if (i == pos && digits[i] >= 53)
			{
				while (i > 0 && digits[i - 1] == 57)
				{
					i--;
				}
				if (i > 0)
				{
					digits[i - 1]++;
				}
				else
				{
					number.Scale++;
					digits[0] = 49;
					i = 1;
				}
			}
			else
			{
				while (i > 0 && digits[i - 1] == 48)
				{
					i--;
				}
			}
			if (i == 0)
			{
				number.Scale = 0;
				number.IsNegative = false;
			}
			digits[i] = 0;
		}

		internal static bool NumberBufferToDouble(ref NumberBuffer number, out double value)
		{
			double num = NumberToDouble(ref number);
			uint num2 = DoubleHelper.Exponent(num);
			ulong num3 = DoubleHelper.Mantissa(num);
			switch (num2)
			{
			case 2047u:
				value = 0.0;
				return false;
			case 0u:
				if (num3 == 0L)
				{
					num = 0.0;
				}
				break;
			}
			value = num;
			return true;
		}

		public unsafe static bool NumberBufferToDecimal(ref NumberBuffer number, ref decimal value)
		{
			MutableDecimal value2 = default(MutableDecimal);
			byte* ptr = number.UnsafeDigits;
			int num = number.Scale;
			if (*ptr == 0)
			{
				if (num > 0)
				{
					num = 0;
				}
			}
			else
			{
				if (num > 29)
				{
					return false;
				}
				while ((num > 0 || (*ptr != 0 && num > -28)) && (value2.High < 429496729 || (value2.High == 429496729 && (value2.Mid < 2576980377u || (value2.Mid == 2576980377u && (value2.Low < 2576980377u || (value2.Low == 2576980377u && *ptr <= 53)))))))
				{
					DecimalDecCalc.DecMul10(ref value2);
					if (*ptr != 0)
					{
						DecimalDecCalc.DecAddInt32(ref value2, (uint)(*(ptr++) - 48));
					}
					num--;
				}
				if (*(ptr++) >= 53)
				{
					bool flag = true;
					if (*(ptr - 1) == 53 && *(ptr - 2) % 2 == 0)
					{
						int num2 = 20;
						while (*ptr == 48 && num2 != 0)
						{
							ptr++;
							num2--;
						}
						if (*ptr == 0 || num2 == 0)
						{
							flag = false;
						}
					}
					if (flag)
					{
						DecimalDecCalc.DecAddInt32(ref value2, 1u);
						if ((value2.High | value2.Mid | value2.Low) == 0)
						{
							value2.High = 429496729u;
							value2.Mid = 2576980377u;
							value2.Low = 2576980378u;
							num++;
						}
					}
				}
			}
			if (num > 0)
			{
				return false;
			}
			if (num <= -29)
			{
				value2.High = 0u;
				value2.Low = 0u;
				value2.Mid = 0u;
				value2.Scale = 28;
			}
			else
			{
				value2.Scale = -num;
			}
			value2.IsNegative = number.IsNegative;
			value = System.Runtime.CompilerServices.Unsafe.As<MutableDecimal, decimal>(ref value2);
			return true;
		}

		public static void DecimalToNumber(decimal value, ref NumberBuffer number)
		{
			ref MutableDecimal reference = ref System.Runtime.CompilerServices.Unsafe.As<decimal, MutableDecimal>(ref value);
			Span<byte> digits = number.Digits;
			number.IsNegative = reference.IsNegative;
			int num = 29;
			while ((reference.Mid != 0) | (reference.High != 0))
			{
				uint num2 = DecimalDecCalc.DecDivMod1E9(ref reference);
				for (int i = 0; i < 9; i++)
				{
					digits[--num] = (byte)(num2 % 10 + 48);
					num2 /= 10;
				}
			}
			for (uint num3 = reference.Low; num3 != 0; num3 /= 10)
			{
				digits[--num] = (byte)(num3 % 10 + 48);
			}
			int num4 = 29 - num;
			number.Scale = num4 - reference.Scale;
			Span<byte> digits2 = number.Digits;
			int index = 0;
			while (--num4 >= 0)
			{
				digits2[index++] = digits[num++];
			}
			digits2[index] = 0;
		}

		private static uint DigitsToInt(ReadOnlySpan<byte> digits, int count)
		{
			uint value;
			int bytesConsumed;
			bool flag = Utf8Parser.TryParse(digits.Slice(0, count), out value, out bytesConsumed, 'D');
			return value;
		}

		private static ulong Mul32x32To64(uint a, uint b)
		{
			return (ulong)a * (ulong)b;
		}

		private static ulong Mul64Lossy(ulong a, ulong b, ref int pexp)
		{
			ulong num = Mul32x32To64((uint)(a >> 32), (uint)(b >> 32)) + (Mul32x32To64((uint)(a >> 32), (uint)b) >> 32) + (Mul32x32To64((uint)a, (uint)(b >> 32)) >> 32);
			if ((num & 0x8000000000000000uL) == 0L)
			{
				num <<= 1;
				pexp--;
			}
			return num;
		}

		private static int abs(int value)
		{
			if (value < 0)
			{
				return -value;
			}
			return value;
		}

		private unsafe static double NumberToDouble(ref NumberBuffer number)
		{
			ReadOnlySpan<byte> digits = number.Digits;
			int i = 0;
			int numDigits = number.NumDigits;
			int num = numDigits;
			for (; digits[i] == 48; i++)
			{
				num--;
			}
			if (num == 0)
			{
				return 0.0;
			}
			int num2 = Math.Min(num, 9);
			num -= num2;
			ulong num3 = DigitsToInt(digits, num2);
			if (num > 0)
			{
				num2 = Math.Min(num, 9);
				num -= num2;
				uint b = (uint)(s_rgval64Power10[num2 - 1] >> 64 - s_rgexp64Power10[num2 - 1]);
				num3 = Mul32x32To64((uint)num3, b) + DigitsToInt(digits.Slice(9), num2);
			}
			int num4 = number.Scale - (numDigits - num);
			int num5 = abs(num4);
			if (num5 >= 352)
			{
				ulong num6 = ((num4 > 0) ? 9218868437227405312uL : 0);
				if (number.IsNegative)
				{
					num6 |= 0x8000000000000000uL;
				}
				return *(double*)(&num6);
			}
			int pexp = 64;
			if ((num3 & 0xFFFFFFFF00000000uL) == 0L)
			{
				num3 <<= 32;
				pexp -= 32;
			}
			if ((num3 & 0xFFFF000000000000uL) == 0L)
			{
				num3 <<= 16;
				pexp -= 16;
			}
			if ((num3 & 0xFF00000000000000uL) == 0L)
			{
				num3 <<= 8;
				pexp -= 8;
			}
			if ((num3 & 0xF000000000000000uL) == 0L)
			{
				num3 <<= 4;
				pexp -= 4;
			}
			if ((num3 & 0xC000000000000000uL) == 0L)
			{
				num3 <<= 2;
				pexp -= 2;
			}
			if ((num3 & 0x8000000000000000uL) == 0L)
			{
				num3 <<= 1;
				pexp--;
			}
			int num7 = num5 & 0xF;
			if (num7 != 0)
			{
				int num8 = s_rgexp64Power10[num7 - 1];
				pexp += ((num4 < 0) ? (-num8 + 1) : num8);
				ulong b2 = s_rgval64Power10[num7 + ((num4 < 0) ? 15 : 0) - 1];
				num3 = Mul64Lossy(num3, b2, ref pexp);
			}
			num7 = num5 >> 4;
			if (num7 != 0)
			{
				int num9 = s_rgexp64Power10By16[num7 - 1];
				pexp += ((num4 < 0) ? (-num9 + 1) : num9);
				ulong b3 = s_rgval64Power10By16[num7 + ((num4 < 0) ? 21 : 0) - 1];
				num3 = Mul64Lossy(num3, b3, ref pexp);
			}
			if (((uint)(int)num3 & 0x400u) != 0)
			{
				ulong num10 = num3 + 1023 + (ulong)(((int)num3 >> 11) & 1);
				if (num10 < num3)
				{
					num10 = (num10 >> 1) | 0x8000000000000000uL;
					pexp++;
				}
				num3 = num10;
			}
			pexp += 1022;
			num3 = ((pexp <= 0) ? ((pexp == -52 && num3 >= 9223372036854775896uL) ? 1 : ((pexp > -52) ? (num3 >> -pexp + 11 + 1) : 0)) : ((pexp < 2047) ? ((ulong)((long)pexp << 52) + ((num3 >> 11) & 0xFFFFFFFFFFFFFL)) : 9218868437227405312uL));
			if (number.IsNegative)
			{
				num3 |= 0x8000000000000000uL;
			}
			return *(double*)(&num3);
		}
	}
	internal ref struct NumberBuffer
	{
		public int Scale;

		public bool IsNegative;

		public const int BufferSize = 51;

		private byte _b0;

		private byte _b1;

		private byte _b2;

		private byte _b3;

		private byte _b4;

		private byte _b5;

		private byte _b6;

		private byte _b7;

		private byte _b8;

		private byte _b9;

		private byte _b10;

		private byte _b11;

		private byte _b12;

		private byte _b13;

		private byte _b14;

		private byte _b15;

		private byte _b16;

		private byte _b17;

		private byte _b18;

		private byte _b19;

		private byte _b20;

		private byte _b21;

		private byte _b22;

		private byte _b23;

		private byte _b24;

		private byte _b25;

		private byte _b26;

		private byte _b27;

		private byte _b28;

		private byte _b29;

		private byte _b30;

		private byte _b31;

		private byte _b32;

		private byte _b33;

		private byte _b34;

		private byte _b35;

		private byte _b36;

		private byte _b37;

		private byte _b38;

		private byte _b39;

		private byte _b40;

		private byte _b41;

		private byte _b42;

		private byte _b43;

		private byte _b44;

		private byte _b45;

		private byte _b46;

		private byte _b47;

		private byte _b48;

		private byte _b49;

		private byte _b50;

		public unsafe Span<byte> Digits => new Span<byte>(System.Runtime.CompilerServices.Unsafe.AsPointer<byte>(ref _b0), 51);

		public unsafe byte* UnsafeDigits => (byte*)System.Runtime.CompilerServices.Unsafe.AsPointer<byte>(ref _b0);

		public int NumDigits => Digits.IndexOf<byte>(0);

		[Conditional("DEBUG")]
		public void CheckConsistency()
		{
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append('[');
			stringBuilder.Append('"');
			Span<byte> digits = Digits;
			for (int i = 0; i < 51; i++)
			{
				byte b = digits[i];
				if (b == 0)
				{
					break;
				}
				stringBuilder.Append((char)b);
			}
			stringBuilder.Append('"');
			stringBuilder.Append(", Scale = " + Scale);
			stringBuilder.Append(", IsNegative   = " + IsNegative);
			stringBuilder.Append(']');
			return stringBuilder.ToString();
		}
	}
	[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly struct Memory<T>
	{
		private readonly object _object;

		private readonly int _index;

		private readonly int _length;

		private const int RemoveFlagsBitMask = int.MaxValue;

		public static Memory<T> Empty => default(Memory<T>);

		public int Length => _length & 0x7FFFFFFF;

		public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;

		public Span<T> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				Span<T> result;
				if (_index < 0)
				{
					result = ((MemoryManager<T>)_object).GetSpan();
					return result.Slice(_index & 0x7FFFFFFF, _length);
				}
				if (typeof(T) == typeof(char) && _object is string text)
				{
					result = new Span<T>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)text), MemoryExtensions.StringAdjustment, text.Length);
					return result.Slice(_index, _length);
				}
				if (_object != null)
				{
					return new Span<T>((T[])_object, _index, _length & 0x7FFFFFFF);
				}
				result = default(Span<T>);
				return result;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory(T[] array)
		{
			if (array == null)
			{
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			_object = array;
			_index = 0;
			_length = array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(T[] array, int start)
		{
			if (array == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = array.Length - start;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(MemoryManager<T> manager, int length)
		{
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = manager;
			_index = int.MinValue;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(MemoryManager<T> manager, int start, int length)
		{
			if (length < 0 || start < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = manager;
			_index = start | int.MinValue;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(object obj, int start, int length)
		{
			_object = obj;
			_index = start;
			_length = length;
		}

		public static implicit operator Memory<T>(T[] array)
		{
			return new Memory<T>(array);
		}

		public static implicit operator Memory<T>(ArraySegment<T> segment)
		{
			return new Memory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public static implicit operator ReadOnlyMemory<T>(Memory<T> memory)
		{
			return System.Runtime.CompilerServices.Unsafe.As<Memory<T>, ReadOnlyMemory<T>>(ref memory);
		}

		public override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (!(_object is string text))
				{
					return Span.ToString();
				}
				return text.Substring(_index, _length & 0x7FFFFFFF);
			}
			return $"System.Memory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<T> Slice(int start)
		{
			int length = _length;
			int num = length & 0x7FFFFFFF;
			if ((uint)start > (uint)num)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Memory<T>(_object, _index + start, length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<T> Slice(int start, int length)
		{
			int length2 = _length;
			int num = length2 & 0x7FFFFFFF;
			if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			return new Memory<T>(_object, _index + start, length | (length2 & int.MinValue));
		}

		public void CopyTo(Memory<T> destination)
		{
			Span.CopyTo(destination.Span);
		}

		public bool TryCopyTo(Memory<T> destination)
		{
			return Span.TryCopyTo(destination.Span);
		}

		public unsafe MemoryHandle Pin()
		{
			if (_index < 0)
			{
				return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
			}
			if (typeof(T) == typeof(char) && _object is string value)
			{
				GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
				void* pointer = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = System.Runtime.CompilerServices.Unsafe.Add<T>(System.Runtime.CompilerServices.Unsafe.AsPointer<T>(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer3, handle2);
			}
			return default(MemoryHandle);
		}

		public T[] ToArray()
		{
			return Span.ToArray();
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is ReadOnlyMemory<T> readOnlyMemory)
			{
				return readOnlyMemory.Equals(this);
			}
			if (obj is Memory<T> other)
			{
				return Equals(other);
			}
			return false;
		}

		public bool Equals(Memory<T> other)
		{
			if (_object == other._object && _index == other._index)
			{
				return _length == other._length;
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			if (_object == null)
			{
				return 0;
			}
			int hashCode = _object.GetHashCode();
			int index = _index;
			int hashCode2 = index.GetHashCode();
			index = _length;
			return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
		}

		private static int CombineHashCodes(int left, int right)
		{
			return ((left << 5) + left) ^ right;
		}

		private static int CombineHashCodes(int h1, int h2, int h3)
		{
			return CombineHashCodes(CombineHashCodes(h1, h2), h3);
		}
	}
	internal sealed class MemoryDebugView<T>
	{
		private readonly ReadOnlyMemory<T> _memory;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items => _memory.ToArray();

		public MemoryDebugView(Memory<T> memory)
		{
			_memory = memory;
		}

		public MemoryDebugView(ReadOnlyMemory<T> memory)
		{
			_memory = memory;
		}
	}
	public static class MemoryExtensions
	{
		internal static readonly IntPtr StringAdjustment = MeasureStringAdjustment();

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span)
		{
			return span.TrimStart().TrimEnd();
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span)
		{
			int i;
			for (i = 0; i < span.Length && char.IsWhiteSpace(span[i]); i++)
			{
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span)
		{
			int num = span.Length - 1;
			while (num >= 0 && char.IsWhiteSpace(span[num]))
			{
				num--;
			}
			return span.Slice(0, num + 1);
		}

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, char trimChar)
		{
			return span.TrimStart(trimChar).TrimEnd(trimChar);
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, char trimChar)
		{
			int i;
			for (i = 0; i < span.Length && span[i] == trimChar; i++)
			{
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, char trimChar)
		{
			int num = span.Length - 1;
			while (num >= 0 && span[num] == trimChar)
			{
				num--;
			}
			return span.Slice(0, num + 1);
		}

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			return span.TrimStart(trimChars).TrimEnd(trimChars);
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			if (trimChars.IsEmpty)
			{
				return span.TrimStart();
			}
			int i;
			for (i = 0; i < span.Length; i++)
			{
				int num = 0;
				while (num < trimChars.Length)
				{
					if (span[i] != trimChars[num])
					{
						num++;
						continue;
					}
					goto IL_003c;
				}
				break;
				IL_003c:;
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			if (trimChars.IsEmpty)
			{
				return span.TrimEnd();
			}
			int num;
			for (num = span.Length - 1; num >= 0; num--)
			{
				int num2 = 0;
				while (num2 < trimChars.Length)
				{
					if (span[num] != trimChars[num2])
					{
						num2++;
						continue;
					}
					goto IL_0044;
				}
				break;
				IL_0044:;
			}
			return span.Slice(0, num + 1);
		}

		public static bool IsWhiteSpace(this ReadOnlySpan<char> span)
		{
			for (int i = 0; i < span.Length; i++)
			{
				if (!char.IsWhiteSpace(span[i]))
				{
					return false;
				}
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this Span<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this Span<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool SequenceEqual<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
		{
			int length = span.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length == other.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size);
				}
				return false;
			}
			if (length == other.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
			}
			return false;
		}

		public static int SequenceCompareTo<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IComparable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool SequenceEqual<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
		{
			int length = span.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length == other.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size);
				}
				return false;
			}
			if (length == other.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int SequenceCompareTo<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IComparable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool StartsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length <= span.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size);
				}
				return false;
			}
			if (length <= span.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool StartsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length <= span.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size);
				}
				return false;
			}
			if (length <= span.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool EndsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = span.Length;
			int length2 = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length2 <= length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool EndsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = span.Length;
			int length2 = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length2 <= length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2);
			}
			return false;
		}

		public static void Reverse<T>(this Span<T> span)
		{
			ref T reference = ref MemoryMarshal.GetReference(span);
			int num = 0;
			int num2 = span.Length - 1;
			while (num < num2)
			{
				T val = System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num);
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num) = System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num2);
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num2) = val;
				num++;
				num2--;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this T[] array)
		{
			return new Span<T>(array);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this T[] array, int start, int length)
		{
			return new Span<T>(array, start, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment)
		{
			return new Span<T>(segment.Array, segment.Offset, segment.Count);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Span<T>(segment.Array, segment.Offset + start, segment.Count - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start, int length)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			if ((uint)length > segment.Count - start)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
			}
			return new Span<T>(segment.Array, segment.Offset + start, length);
		}

		public static Memory<T> AsMemory<T>(this T[] array)
		{
			return new Memory<T>(array);
		}

		public static Memory<T> AsMemory<T>(this T[] array, int start)
		{
			return new Memory<T>(array, start);
		}

		public static Memory<T> AsMemory<T>(this T[] array, int start, int length)
		{
			return new Memory<T>(array, start, length);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment)
		{
			return new Memory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Memory<T>(segment.Array, segment.Offset + start, segment.Count - start);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start, int length)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			if ((uint)length > segment.Count - start)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
			}
			return new Memory<T>(segment.Array, segment.Offset + start, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void CopyTo<T>(this T[] source, Span<T> destination)
		{
			new ReadOnlySpan<T>(source).CopyTo(destination);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void CopyTo<T>(this T[] source, Memory<T> destination)
		{
			source.CopyTo(destination.Span);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other)
		{
			return ((ReadOnlySpan<T>)span).Overlaps(other);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other, out int elementOffset)
		{
			return ((ReadOnlySpan<T>)span).Overlaps(other, out elementOffset);
		}

		public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other)
		{
			if (span.IsEmpty || other.IsEmpty)
			{
				return false;
			}
			IntPtr intPtr = System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (System.Runtime.CompilerServices.Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr >= (uint)(span.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>()))
				{
					return (uint)(int)intPtr > (uint)(-(other.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>()));
				}
				return true;
			}
			if ((ulong)(long)intPtr >= (ulong)((long)span.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>()))
			{
				return (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>()));
			}
			return true;
		}

		public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other, out int elementOffset)
		{
			if (span.IsEmpty || other.IsEmpty)
			{
				elementOffset = 0;
				return false;
			}
			IntPtr intPtr = System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (System.Runtime.CompilerServices.Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr < (uint)(span.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>()) || (uint)(int)intPtr > (uint)(-(other.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>())))
				{
					if ((int)intPtr % System.Runtime.CompilerServices.Unsafe.SizeOf<T>() != 0)
					{
						System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
					}
					elementOffset = (int)intPtr / System.Runtime.CompilerServices.Unsafe.SizeOf<T>();
					return true;
				}
				elementOffset = 0;
				return false;
			}
			if ((ulong)(long)intPtr < (ulong)((long)span.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>()) || (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>())))
			{
				if ((long)intPtr % System.Runtime.CompilerServices.Unsafe.SizeOf<T>() != 0L)
				{
					System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
				}
				elementOffset = (int)((long)intPtr / System.Runtime.CompilerServices.Unsafe.SizeOf<T>());
				return true;
			}
			elementOffset = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T>(this Span<T> span, IComparable<T> comparable)
		{
			return span.BinarySearch<T, IComparable<T>>(comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this Span<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			return BinarySearch((ReadOnlySpan<T>)span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparer>(this Span<T> span, T value, TComparer comparer) where TComparer : IComparer<T>
		{
			return ((ReadOnlySpan<T>)span).BinarySearch(value, comparer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T>(this ReadOnlySpan<T> span, IComparable<T> comparable)
		{
			return MemoryExtensions.BinarySearch<T, IComparable<T>>(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			return System.SpanHelpers.BinarySearch(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparer>(this ReadOnlySpan<T> span, T value, TComparer comparer) where TComparer : IComparer<T>
		{
			if (comparer == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparer);
			}
			System.SpanHelpers.ComparerComparable<T, TComparer> comparable = new System.SpanHelpers.ComparerComparable<T, TComparer>(value, comparer);
			return BinarySearch(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool IsTypeComparableAsBytes<T>(out NUInt size)
		{
			if (typeof(T) == typeof(byte) || typeof(T) == typeof(sbyte))
			{
				size = (NUInt)1;
				return true;
			}
			if (typeof(T) == typeof(char) || typeof(T) == typeof(short) || typeof(T) == typeof(ushort))
			{
				size = (NUInt)2;
				return true;
			}
			if (typeof(T) == typeof(int) || typeof(T) == typeof(uint))
			{
				size = (NUInt)4;
				return true;
			}
			if (typeof(T) == typeof(long) || typeof(T) == typeof(ulong))
			{
				size = (NUInt)8;
				return true;
			}
			size = default(NUInt);
			return false;
		}

		public static Span<T> AsSpan<T>(this T[] array, int start)
		{
			return Span<T>.Create(array, start);
		}

		public static bool Contains(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			return span.IndexOf(value, comparisonType) >= 0;
		}

		public static bool Equals(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.SequenceEqual(other);
			case StringComparison.OrdinalIgnoreCase:
				if (span.Length != other.Length)
				{
					return false;
				}
				return EqualsOrdinalIgnoreCase(span, other);
			default:
				return span.ToString().Equals(other.ToString(), comparisonType);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool EqualsOrdinalIgnoreCase(ReadOnlySpan<char> span, ReadOnlySpan<char> other)
		{
			if (other.Length == 0)
			{
				return true;
			}
			return CompareToOrdinalIgnoreCase(span, other) == 0;
		}

		public static int CompareTo(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType)
		{
			return comparisonType switch
			{
				StringComparison.Ordinal => span.SequenceCompareTo(other), 
				StringComparison.OrdinalIgnoreCase => CompareToOrdinalIgnoreCase(span, other), 
				_ => string.Compare(span.ToString(), other.ToString(), comparisonType), 
			};
		}

		private unsafe static int CompareToOrdinalIgnoreCase(ReadOnlySpan<char> strA, ReadOnlySpan<char> strB)
		{
			int num = Math.Min(strA.Length, strB.Length);
			int num2 = num;
			fixed (char* ptr = &MemoryMarshal.GetReference(strA))
			{
				fixed (char* ptr3 = &MemoryMarshal.GetReference(strB))
				{
					char* ptr2 = ptr;
					char* ptr4 = ptr3;
					while (num != 0 && *ptr2 <= '\u007f' && *ptr4 <= '\u007f')
					{
						int num3 = *ptr2;
						int num4 = *ptr4;
						if (num3 == num4)
						{
							ptr2++;
							ptr4++;
							num--;
							continue;
						}
						if ((uint)(num3 - 97) <= 25u)
						{
							num3 -= 32;
						}
						if ((uint)(num4 - 97) <= 25u)
						{
							num4 -= 32;
						}
						if (num3 != num4)
						{
							return num3 - num4;
						}
						ptr2++;
						ptr4++;
						num--;
					}
					if (num == 0)
					{
						return strA.Length - strB.Length;
					}
					num2 -= num;
					return string.Compare(strA.Slice(num2).ToString(), strB.Slice(num2).ToString(), StringComparison.OrdinalIgnoreCase);
				}
			}
		}

		public static int IndexOf(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			if (comparisonType == StringComparison.Ordinal)
			{
				return span.IndexOf(value);
			}
			return span.ToString().IndexOf(value.ToString(), comparisonType);
		}

		public static int ToLower(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture)
		{
			if (culture == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture);
			}
			if (destination.Length < source.Length)
			{
				return -1;
			}
			string text = source.ToString();
			string text2 = text.ToLower(culture);
			AsSpan(text2).CopyTo(destination);
			return source.Length;
		}

		public static int ToLowerInvariant(this ReadOnlySpan<char> source, Span<char> destination)
		{
			return source.ToLower(destination, CultureInfo.InvariantCulture);
		}

		public static int ToUpper(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture)
		{
			if (culture == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture);
			}
			if (destination.Length < source.Length)
			{
				return -1;
			}
			string text = source.ToString();
			string text2 = text.ToUpper(culture);
			AsSpan(text2).CopyTo(destination);
			return source.Length;
		}

		public static int ToUpperInvariant(this ReadOnlySpan<char> source, Span<char> destination)
		{
			return source.ToUpper(destination, CultureInfo.InvariantCulture);
		}

		public static bool EndsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.EndsWith(value);
			case StringComparison.OrdinalIgnoreCase:
				if (value.Length <= span.Length)
				{
					return EqualsOrdinalIgnoreCase(span.Slice(span.Length - value.Length), value);
				}
				return false;
			default:
			{
				string text = span.ToString();
				string value2 = value.ToString();
				return text.EndsWith(value2, comparisonType);
			}
			}
		}

		public static bool StartsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.StartsWith(value);
			case StringComparison.OrdinalIgnoreCase:
				if (value.Length <= span.Length)
				{
					return EqualsOrdinalIgnoreCase(span.Slice(0, value.Length), value);
				}
				return false;
			default:
			{
				string text = span.ToString();
				string value2 = value.ToString();
				return text.StartsWith(value2, comparisonType);
			}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text)
		{
			if (text == null)
			{
				return default(ReadOnlySpan<char>);
			}
			return new ReadOnlySpan<char>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text), StringAdjustment, text.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text, int start)
		{
			if (text == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlySpan<char>);
			}
			if ((uint)start > (uint)text.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlySpan<char>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text), StringAdjustment + start * 2, text.Length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text, int start, int length)
		{
			if (text == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlySpan<char>);
			}
			if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlySpan<char>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text), StringAdjustment + start * 2, length);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text)
		{
			if (text == null)
			{
				return default(ReadOnlyMemory<char>);
			}
			return new ReadOnlyMemory<char>(text, 0, text.Length);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text, int start)
		{
			if (text == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlyMemory<char>);
			}
			if ((uint)start > (uint)text.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<char>(text, start, text.Length - start);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text, int start, int length)
		{
			if (text == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlyMemory<char>);
			}
			if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<char>(text, start, length);
		}

		private unsafe static IntPtr MeasureStringAdjustment()
		{
			string text = "a";
			fixed (char* ptr = text)
			{
				return System.Runtime.CompilerServices.Unsafe.ByteOffset<char>(ref System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text).Data, ref System.Runtime.CompilerServices.Unsafe.AsRef<char>((void*)ptr));
			}
		}
	}
	[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly struct ReadOnlyMemory<T>
	{
		private readonly object _object;

		private readonly int _index;

		private readonly int _length;

		internal const int RemoveFlagsBitMask = int.MaxValue;

		public static ReadOnlyMemory<T> Empty => default(ReadOnlyMemory<T>);

		public int Length => _length & 0x7FFFFFFF;

		public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;

		public ReadOnlySpan<T> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if (_index < 0)
				{
					return ((MemoryManager<T>)_object).GetSpan().Slice(_index & 0x7FFFFFFF, _length);
				}
				ReadOnlySpan<T> result;
				if (typeof(T) == typeof(char) && _object is string text)
				{
					result = new ReadOnlySpan<T>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)text), MemoryExtensions.StringAdjustment, text.Length);
					return result.Slice(_index, _length);
				}
				if (_object != null)
				{
					return new ReadOnlySpan<T>((T[])_object, _index, _length & 0x7FFFFFFF);
				}
				result = default(ReadOnlySpan<T>);
				return result;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory(T[] array)
		{
			if (array == null)
			{
				this = default(ReadOnlyMemory<T>);
				return;
			}
			_object = array;
			_index = 0;
			_length = array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(ReadOnlyMemory<T>);
				return;
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ReadOnlyMemory(object obj, int start, int length)
		{
			_object = obj;
			_index = start;
			_length = length;
		}

		public static implicit operator ReadOnlyMemory<T>(T[] array)
		{
			return new ReadOnlyMemory<T>(array);
		}

		public static implicit operator ReadOnlyMemory<T>(ArraySegment<T> segment)
		{
			return new ReadOnlyMemory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (!(_object is string text))
				{
					return Span.ToString();
				}
				return text.Substring(_index, _length & 0x7FFFFFFF);
			}
			return $"System.ReadOnlyMemory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory<T> Slice(int start)
		{
			int length = _length;
			int num = length & 0x7FFFFFFF;
			if ((uint)start > (uint)num)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<T>(_object, _index + start, length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory<T> Slice(int start, int length)
		{
			int length2 = _length;
			int num = _length & 0x7FFFFFFF;
			if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<T>(_object, _index + start, length | (length2 & int.MinValue));
		}

		public void CopyTo(Memory<T> destination)
		{
			Span.CopyTo(destination.Span);
		}

		public bool TryCopyTo(Memory<T> destination)
		{
			return Span.TryCopyTo(destination.Span);
		}

		public unsafe MemoryHandle Pin()
		{
			if (_index < 0)
			{
				return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
			}
			if (typeof(T) == typeof(char) && _object is string value)
			{
				GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
				void* pointer = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = System.Runtime.CompilerServices.Unsafe.Add<T>(System.Runtime.CompilerServices.Unsafe.AsPointer<T>(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer3, handle2);
			}
			return default(MemoryHandle);
		}

		public T[] ToArray()
		{
			return Span.ToArray();
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is ReadOnlyMemory<T> other)
			{
				return Equals(other);
			}
			if (obj is Memory<T> memory)
			{
				return Equals(memory);
			}
			return false;
		}

		public bool Equals(ReadOnlyMemory<T> other)
		{
			if (_object == other._object && _index == other._index)
			{
				return _length == other._length;
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			if (_object == null)
			{
				return 0;
			}
			int hashCode = _object.GetHashCode();
			int index = _index;
			int hashCode2 = index.GetHashCode();
			index = _length;
			return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
		}

		private static int CombineHashCodes(int left, int right)
		{
			return ((left << 5) + left) ^ right;
		}

		private static int CombineHashCodes(int h1, int h2, int h3)
		{
			return CombineHashCodes(CombineHashCodes(h1, h2), h3);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal object GetObjectStartLength(out int start, out int length)
		{
			start = _index;
			length = _length;
			return _object;
		}
	}
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly ref struct ReadOnlySpan<T>
	{
		public ref struct Enumerator
		{
			private readonly ReadOnlySpan<T> _span;

			private int _index;

			public ref readonly T Current
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return ref _span[_index];
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal Enumerator(ReadOnlySpan<T> span)
			{
				_span = span;
				_index = -1;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public bool MoveNext()
			{
				int num = _index + 1;
				if (num < _span.Length)
				{
					_index = num;
					return true;
				}
				return false;
			}
		}

		private readonly Pinnable<T> _pinnable;

		private readonly IntPtr _byteOffset;

		private readonly int _length;

		public int Length => _length;

		public bool IsEmpty => _length == 0;

		public static ReadOnlySpan<T> Empty => default(ReadOnlySpan<T>);

		public unsafe ref readonly T this[int index]
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if ((uint)index >= (uint)_length)
				{
					System.ThrowHelper.ThrowIndexOutOfRangeException();
				}
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset), index);
			}
		}

		internal Pinnable<T> Pinnable => _pinnable;

		internal IntPtr ByteOffset => _byteOffset;

		public static bool operator !=(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
		{
			return !(left == right);
		}

		[Obsolete("Equals() on ReadOnlySpan will always throw an exception. Use == instead.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
		}

		[Obsolete("GetHashCode() on ReadOnlySpan will always throw an exception.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
		}

		public static implicit operator ReadOnlySpan<T>(T[] array)
		{
			return new ReadOnlySpan<T>(array);
		}

		public static implicit operator ReadOnlySpan<T>(ArraySegment<T> segment)
		{
			return new ReadOnlySpan<T>(segment.Array, segment.Offset, segment.Count);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan(T[] array)
		{
			if (array == null)
			{
				this = default(ReadOnlySpan<T>);
				return;
			}
			_length = array.Length;
			_pinnable = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				this = default(ReadOnlySpan<T>);
				return;
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[CLSCompliant(false)]
		public unsafe ReadOnlySpan(void* pointer, int length)
		{
			if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
			}
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = null;
			_byteOffset = new IntPtr(pointer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ReadOnlySpan(Pinnable<T> pinnable, IntPtr byteOffset, int length)
		{
			_length = length;
			_pinnable = pinnable;
			_byteOffset = byteOffset;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public unsafe ref readonly T GetPinnableReference()
		{
			if (_length != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
			}
			return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>((void*)null);
		}

		public void CopyTo(Span<T> destination)
		{
			if (!TryCopyTo(destination))
			{
				System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
			}
		}

		public bool TryCopyTo(Span<T> destination)
		{
			int length = _length;
			int length2 = destination.Length;
			if (length == 0)
			{
				return true;
			}
			if ((uint)length > (uint)length2)
			{
				return false;
			}
			ref T src = ref DangerousGetPinnableReference();
			System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
			return true;
		}

		public static bool operator ==(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
		{
			if (left._length == right._length)
			{
				return System.Runtime.CompilerServices.Unsafe.AreSame<T>(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (_byteOffset == MemoryExtensions.StringAdjustment)
				{
					object obj = System.Runtime.CompilerServices.Unsafe.As<object>((object)_pinnable);
					if (obj is string text && _length == text.Length)
					{
						return text;
					}
				}
				fixed (char* value = &System.Runtime.CompilerServices.Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
				{
					return new string(value, 0, _length);
				}
			}
			return $"System.ReadOnlySpan<{typeof(T).Name}>[{_length}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan<T> Slice(int start)
		{
			if ((uint)start > (uint)_length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			int length = _length - start;
			return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan<T> Slice(int start, int length)
		{
			if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
		}

		public T[] ToArray()
		{
			if (_length == 0)
			{
				return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
			}
			T[] array = new T[_length];
			CopyTo(array);
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		internal unsafe ref T DangerousGetPinnableReference()
		{
			if (_pinnable == null)
			{
				IntPtr byteOffset = _byteOffset;
				return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
		}
	}
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly ref struct Span<T>
	{
		public ref struct Enumerator
		{
			private readonly Span<T> _span;

			private int _index;

			public ref T Current
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return ref _span[_index];
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal Enumerator(Span<T> span)
			{
				_span = span;
				_index = -1;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public bool MoveNext()
			{
				int num = _index + 1;
				if (num < _span.Length)
				{
					_index = num;
					return true;
				}
				return false;
			}
		}

		private readonly Pinnable<T> _pinnable;

		private readonly IntPtr _byteOffset;

		private readonly int _length;

		public int Length => _length;

		public bool IsEmpty => _length == 0;

		public static Span<T> Empty => default(Span<T>);

		public unsafe ref T this[int index]
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if ((uint)index >= (uint)_length)
				{
					System.ThrowHelper.ThrowIndexOutOfRangeException();
				}
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset), index);
			}
		}

		internal Pinnable<T> Pinnable => _pinnable;

		internal IntPtr ByteOffset => _byteOffset;

		public static bool operator !=(Span<T> left, Span<T> right)
		{
			return !(left == right);
		}

		[Obsolete("Equals() on Span will always throw an exception. Use == instead.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
		}

		[Obsolete("GetHashCode() on Span will always throw an exception.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
		}

		public static implicit operator Span<T>(T[] array)
		{
			return new Span<T>(array);
		}

		public static implicit operator Span<T>(ArraySegment<T> segment)
		{
			return new Span<T>(segment.Array, segment.Offset, segment.Count);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span(T[] array)
		{
			if (array == null)
			{
				this = default(Span<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			_length = array.Length;
			_pinnable = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static Span<T> Create(T[] array, int start)
		{
			if (array == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(Span<T>);
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
			int length = array.Length - start;
			return new Span<T>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array), byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				this = default(Span<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[CLSCompliant(false)]
		public unsafe Span(void* pointer, int length)
		{
			if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
			}
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = null;
			_byteOffset = new IntPtr(pointer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Span(Pinnable<T> pinnable, IntPtr byteOffset, int length)
		{
			_length = length;
			_pinnable = pinnable;
			_byteOffset = byteOffset;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public unsafe ref T GetPinnableReference()
		{
			if (_length != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
			}
			return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>((void*)null);
		}

		public unsafe void Clear()
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			UIntPtr byteLength = (UIntPtr)(ulong)((uint)length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>());
			if ((System.Runtime.CompilerServices.Unsafe.SizeOf<T>() & (sizeof(IntPtr) - 1)) != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					byte* ptr = (byte*)byteOffset.ToPointer();
					System.SpanHelpers.ClearLessThanPointerSized(ptr, byteLength);
				}
				else
				{
					System.SpanHelpers.ClearLessThanPointerSized(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset)), byteLength);
				}
			}
			else if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				UIntPtr pointerSizeLength = (UIntPtr)(ulong)(length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>() / sizeof(IntPtr));
				System.SpanHelpers.ClearPointerSizedWithReferences(ref System.Runtime.CompilerServices.Unsafe.As<T, IntPtr>(ref DangerousGetPinnableReference()), pointerSizeLength);
			}
			else
			{
				System.SpanHelpers.ClearPointerSizedWithoutReferences(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref DangerousGetPinnableReference()), byteLength);
			}
		}

		public unsafe void Fill(T value)
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			if (System.Runtime.CompilerServices.Unsafe.SizeOf<T>() == 1)
			{
				byte b = System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value);
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(byteOffset.ToPointer(), b, (uint)length);
				}
				else
				{
					System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset)), b, (uint)length);
				}
				return;
			}
			ref T reference = ref DangerousGetPinnableReference();
			int i;
			for (i = 0; i < (length & -8); i += 8)
			{
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 1) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 2) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 3) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 4) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 5) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 6) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 7) = value;
			}
			if (i < (length & -4))
			{
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 1) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 2) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 3) = value;
				i += 4;
			}
			for (; i < length; i++)
			{
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i) = value;
			}
		}

		public void CopyTo(Span<T> destination)
		{
			if (!TryCopyTo(destination))
			{
				System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
			}
		}

		public bool TryCopyTo(Span<T> destination)
		{
			int length = _length;
			int length2 = destination._length;
			if (length == 0)
			{
				return true;
			}
			if ((uint)length > (uint)length2)
			{
				return false;
			}
			ref T src = ref DangerousGetPinnableReference();
			System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
			return true;
		}

		public static bool operator ==(Span<T> left, Span<T> right)
		{
			if (left._length == right._length)
			{
				return System.Runtime.CompilerServices.Unsafe.AreSame<T>(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public static implicit operator ReadOnlySpan<T>(Span<T> span)
		{
			return new ReadOnlySpan<T>(span._pinnable, span._byteOffset, span._length);
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				fixed (char* value = &System.Runtime.CompilerServices.Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
				{
					return new string(value, 0, _length);
				}
			}
			return $"System.Span<{typeof(T).Name}>[{_length}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<T> Slice(int start)
		{
			if ((uint)start > (uint)_length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			int length = _length - start;
			return new Span<T>(_pinnable, byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<T> Slice(int start, int length)
		{
			if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			return new Span<T>(_pinnable, byteOffset, length);
		}

		public T[] ToArray()
		{
			if (_length == 0)
			{
				return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
			}
			T[] array = new T[_length];
			CopyTo(array);
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		internal unsafe ref T DangerousGetPinnableReference()
		{
			if (_pinnable == null)
			{
				IntPtr byteOffset = _byteOffset;
				return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
		}
	}
	internal sealed class SpanDebugView<T>
	{
		private readonly T[] _array;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items => _array;

		public SpanDebugView(Span<T> span)
		{
			_array = span.ToArray();
		}

		public SpanDebugView(ReadOnlySpan<T> span)
		{
			_array = span.ToArray();
		}
	}
	internal static class SpanHelpers
	{
		internal struct ComparerComparable<T, TComparer> : IComparable<T> where TComparer : IComparer<T>
		{
			private readonly T _value;

			private readonly TComparer _comparer;

			public ComparerComparable(T value, TComparer comparer)
			{
				_value = value;
				_comparer = comparer;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public int CompareTo(T other)
			{
				return _comparer.Compare(_value, other);
			}
		}

		[StructLayout(LayoutKind.Sequential, Size = 64)]
		private struct Reg64
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 32)]
		private struct Reg32
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 16)]
		private struct Reg16
		{
		}

		public static class PerTypeValues<T>
		{
			public static readonly bool IsReferenceOrContainsReferences = IsReferenceOrContainsReferencesCore(typeof(T));

			public static readonly T[] EmptyArray = new T[0];

			public static readonly IntPtr ArrayAdjustment = MeasureArrayAdjustment();

			private static IntPtr MeasureArrayAdjustment()
			{
				T[] array = new T[1];
				return System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array).Data, ref array[0]);
			}
		}

		private const ulong XorPowerOfTwoToHighByte = 283686952306184uL;

		private const ulong XorPowerOfTwoToHighChar = 4295098372uL;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			if (comparable == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparable);
			}
			return BinarySearch(ref MemoryMarshal.GetReference(span), span.Length, comparable);
		}

		public static int BinarySearch<T, TComparable>(ref T spanStart, int length, TComparable comparable) where TComparable : IComparable<T>
		{
			int num = 0;
			int num2 = length - 1;
			while (num <= num2)
			{
				int num3 = num2 + num >>> 1;
				int num4 = comparable.CompareTo(System.Runtime.CompilerServices.Unsafe.Add<T>(ref spanStart, num3));
				if (num4 == 0)
				{
					return num3;
				}
				if (num4 > 0)
				{
					num = num3 + 1;
				}
				else
				{
					num2 = num3 - 1;
				}
			}
			return ~num;
		}

		public static int IndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			byte value2 = value;
			ref byte second = ref System.Runtime.CompilerServices.Unsafe.Add<byte>(ref value, 1);
			int num = valueLength - 1;
			int num2 = 0;
			while (true)
			{
				int num3 = searchSpaceLength - num2 - num;
				if (num3 <= 0)
				{
					break;
				}
				int num4 = IndexOf(ref System.Runtime.CompilerServices.Unsafe.Add<byte>(ref searchSpace, num2), value2, num3);
				if (num4 == -1)
				{
					break;
				}
				num2 += num4;
				if (SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.Add<byte>(ref searchSpace, num2 + 1), ref second, num))
				{
					return num2;
				}
				num2++;
			}
			return -1;
		}

		public static int IndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			int num = -1;
			for (int i = 0; i < valueLength; i++)
			{
				int num2 = IndexOf(ref searchSpace, System.Runtime.CompilerServices.Unsafe.Add<byte>(ref value, i), searchSpaceLength);
				if ((uint)num2 < (uint)num)
				{
					num = num2;
					searchSpaceLength = num2;
					if (num == 0)
					{
						break;
					}
				}

config/ServerCharacters-master/ServerCharacters/Libs/System.Runtime.CompilerServices.Unsafe.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;

[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyFileVersion("4.0.0.0")]
[assembly: AssemblyInformationalVersion("4.0.0.0")]
[assembly: AssemblyTitle("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyDescription("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyCopyright("ยฉ Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyProduct("Microsoftยฎ .NET Framework")]
[assembly: CLSCompliant(false)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("4.0.4.1")]
namespace System.Runtime.CompilerServices
{
	public static class Unsafe
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static T Read<T>(void* source)
		{
			return Unsafe.Read<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static T ReadUnaligned<T>(void* source)
		{
			return Unsafe.ReadUnaligned<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static T ReadUnaligned<T>(ref byte source)
		{
			return Unsafe.ReadUnaligned<T>(ref source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Write<T>(void* destination, T value)
		{
			Unsafe.Write(destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void WriteUnaligned<T>(void* destination, T value)
		{
			Unsafe.WriteUnaligned(destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void WriteUnaligned<T>(ref byte destination, T value)
		{
			Unsafe.WriteUnaligned(ref destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Copy<T>(void* destination, ref T source)
		{
			Unsafe.Write(destination, source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Copy<T>(ref T destination, void* source)
		{
			destination = Unsafe.Read<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* AsPointer<T>(ref T value)
		{
			return Unsafe.AsPointer(ref value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static int SizeOf<T>()
		{
			return Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void CopyBlock(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(destination, source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void CopyBlock(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(ref destination, ref source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(destination, source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(ref destination, ref source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void InitBlock(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(ref startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(ref startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static T As<T>(object o) where T : class
		{
			return (T)o;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static ref T AsRef<T>(void* source)
		{
			return ref *(T*)source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T AsRef<T>(in T source)
		{
			return ref source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref TTo As<TFrom, TTo>(ref TFrom source)
		{
			return ref Unsafe.As<TFrom, TTo>(ref source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Add<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* Add<T>(void* source, int elementOffset)
		{
			return (byte*)source + (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Add<T>(ref T source, IntPtr elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T AddByteOffset<T>(ref T source, IntPtr byteOffset)
		{
			return ref Unsafe.AddByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Subtract<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* Subtract<T>(void* source, int elementOffset)
		{
			return (byte*)source - (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Subtract<T>(ref T source, IntPtr elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T SubtractByteOffset<T>(ref T source, IntPtr byteOffset)
		{
			return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static IntPtr ByteOffset<T>(ref T origin, ref T target)
		{
			return Unsafe.ByteOffset(target: ref target, origin: ref origin);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool AreSame<T>(ref T left, ref T right)
		{
			return Unsafe.AreSame(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool IsAddressGreaterThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressGreaterThan(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool IsAddressLessThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressLessThan(ref left, ref right);
		}
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class NonVersionableAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}