Decompiled source of GarfieldKartArchipelago v0.4.3

Archipelago.MultiClient.Net.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.WebSockets;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Archipelago.MultiClient.Net.Colors;
using Archipelago.MultiClient.Net.ConcurrentCollection;
using Archipelago.MultiClient.Net.Converters;
using Archipelago.MultiClient.Net.DataPackage;
using Archipelago.MultiClient.Net.Enums;
using Archipelago.MultiClient.Net.Exceptions;
using Archipelago.MultiClient.Net.Extensions;
using Archipelago.MultiClient.Net.Helpers;
using Archipelago.MultiClient.Net.MessageLog.Messages;
using Archipelago.MultiClient.Net.MessageLog.Parts;
using Archipelago.MultiClient.Net.Models;
using Archipelago.MultiClient.Net.Packets;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ComVisible(false)]
[assembly: Guid("35a803ad-85ed-42e9-b1e3-c6b72096f0c1")]
[assembly: InternalsVisibleTo("Archipelago.MultiClient.Net.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyCompany("Jarno Westhof, Hussein Farran, Zach Parks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyDescription("A client library for use with .NET based prog-langs for interfacing with Archipelago hosts.")]
[assembly: AssemblyFileVersion("6.7.0.0")]
[assembly: AssemblyInformationalVersion("6.7.0+c807746b6f1774cf1afe12af819acb078b55a333")]
[assembly: AssemblyProduct("Archipelago.MultiClient.Net")]
[assembly: AssemblyTitle("Archipelago.MultiClient.Net")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ArchipelagoMW/Archipelago.MultiClient.Net")]
[assembly: AssemblyVersion("6.7.0.0")]
internal interface IConcurrentHashSet<T>
{
	bool TryAdd(T item);

	bool Contains(T item);

	void UnionWith(T[] otherSet);

	T[] ToArray();

	ReadOnlyCollection<T> AsToReadOnlyCollection();

	ReadOnlyCollection<T> AsToReadOnlyCollectionExcept(IConcurrentHashSet<T> otherSet);
}
public class AttemptingStringEnumConverter : StringEnumConverter
{
	public AttemptingStringEnumConverter()
	{
	}

	public AttemptingStringEnumConverter(Type namingStrategyType)
		: base(namingStrategyType)
	{
	}

	public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
	{
		try
		{
			return ((StringEnumConverter)this).ReadJson(reader, objectType, existingValue, serializer);
		}
		catch (JsonSerializationException)
		{
			return objectType.IsValueType ? Activator.CreateInstance(objectType) : null;
		}
	}
}
namespace Archipelago.MultiClient.Net
{
	[Serializable]
	public abstract class ArchipelagoPacketBase
	{
		[JsonIgnore]
		internal JObject jobject;

		[JsonProperty("cmd")]
		[JsonConverter(typeof(StringEnumConverter))]
		public abstract ArchipelagoPacketType PacketType { get; }

		public JObject ToJObject()
		{
			return jobject;
		}
	}
	public interface IArchipelagoSession : IArchipelagoSessionActions
	{
		IArchipelagoSocketHelper Socket { get; }

		IReceivedItemsHelper Items { get; }

		ILocationCheckHelper Locations { get; }

		IPlayerHelper Players { get; }

		IDataStorageHelper DataStorage { get; }

		IConnectionInfoProvider ConnectionInfo { get; }

		IRoomStateHelper RoomState { get; }

		IMessageLogHelper MessageLog { get; }

		IHintsHelper Hints { get; }

		Task<RoomInfoPacket> ConnectAsync();

		Task<LoginResult> LoginAsync(string game, string name, ItemsHandlingFlags itemsHandlingFlags, Version version = null, string[] tags = null, string uuid = null, string password = null, bool requestSlotData = true);

		LoginResult TryConnectAndLogin(string game, string name, ItemsHandlingFlags itemsHandlingFlags, Version version = null, string[] tags = null, string uuid = null, string password = null, bool requestSlotData = true);
	}
	public class ArchipelagoSession : IArchipelagoSession, IArchipelagoSessionActions
	{
		private const int ArchipelagoConnectionTimeoutInSeconds = 4;

		private ConnectionInfoHelper connectionInfo;

		private TaskCompletionSource<LoginResult> loginResultTask = new TaskCompletionSource<LoginResult>();

		private TaskCompletionSource<RoomInfoPacket> roomInfoPacketTask = new TaskCompletionSource<RoomInfoPacket>();

		public IArchipelagoSocketHelper Socket { get; }

		public IReceivedItemsHelper Items { get; }

		public ILocationCheckHelper Locations { get; }

		public IPlayerHelper Players { get; }

		public IDataStorageHelper DataStorage { get; }

		public IConnectionInfoProvider ConnectionInfo => connectionInfo;

		public IRoomStateHelper RoomState { get; }

		public IMessageLogHelper MessageLog { get; }

		public IHintsHelper Hints { get; }

		internal ArchipelagoSession(IArchipelagoSocketHelper socket, IReceivedItemsHelper items, ILocationCheckHelper locations, IPlayerHelper players, IRoomStateHelper roomState, ConnectionInfoHelper connectionInfoHelper, IDataStorageHelper dataStorage, IMessageLogHelper messageLog, IHintsHelper createHints)
		{
			Socket = socket;
			Items = items;
			Locations = locations;
			Players = players;
			RoomState = roomState;
			connectionInfo = connectionInfoHelper;
			DataStorage = dataStorage;
			MessageLog = messageLog;
			Hints = createHints;
			socket.PacketReceived += Socket_PacketReceived;
		}

		private void Socket_PacketReceived(ArchipelagoPacketBase packet)
		{
			if (!(packet is ConnectedPacket) && !(packet is ConnectionRefusedPacket))
			{
				if (packet is RoomInfoPacket result)
				{
					roomInfoPacketTask.TrySetResult(result);
				}
			}
			else
			{
				loginResultTask.TrySetResult(LoginResult.FromPacket(packet));
			}
		}

		public Task<RoomInfoPacket> ConnectAsync()
		{
			roomInfoPacketTask = new TaskCompletionSource<RoomInfoPacket>();
			Task.Factory.StartNew(delegate
			{
				try
				{
					Task task = Socket.ConnectAsync();
					task.Wait(TimeSpan.FromSeconds(4.0));
					if (!task.IsCompleted)
					{
						roomInfoPacketTask.TrySetCanceled();
					}
				}
				catch (AggregateException)
				{
					roomInfoPacketTask.TrySetCanceled();
				}
			});
			return roomInfoPacketTask.Task;
		}

		public Task<LoginResult> LoginAsync(string game, string name, ItemsHandlingFlags itemsHandlingFlags, Version version = null, string[] tags = null, string uuid = null, string password = null, bool requestSlotData = true)
		{
			loginResultTask = new TaskCompletionSource<LoginResult>();
			if (!roomInfoPacketTask.Task.IsCompleted)
			{
				loginResultTask.TrySetResult(new LoginFailure("You are not connected, run ConnectAsync() first"));
				return loginResultTask.Task;
			}
			connectionInfo.SetConnectionParameters(game, tags, itemsHandlingFlags, uuid);
			try
			{
				Socket.SendPacket(BuildConnectPacket(name, password, version, requestSlotData));
			}
			catch (ArchipelagoSocketClosedException)
			{
				loginResultTask.TrySetResult(new LoginFailure("You are not connected, run ConnectAsync() first"));
				return loginResultTask.Task;
			}
			SetResultAfterTimeout(loginResultTask, 4, new LoginFailure("Connection timed out."));
			return loginResultTask.Task;
		}

		private static void SetResultAfterTimeout<T>(TaskCompletionSource<T> task, int timeoutInSeconds, T result)
		{
			new CancellationTokenSource(TimeSpan.FromSeconds(timeoutInSeconds)).Token.Register(delegate
			{
				task.TrySetResult(result);
			});
		}

		public LoginResult TryConnectAndLogin(string game, string name, ItemsHandlingFlags itemsHandlingFlags, Version version = null, string[] tags = null, string uuid = null, string password = null, bool requestSlotData = true)
		{
			Task<RoomInfoPacket> task = ConnectAsync();
			try
			{
				task.Wait(TimeSpan.FromSeconds(4.0));
			}
			catch (AggregateException ex)
			{
				if (ex.GetBaseException() is OperationCanceledException)
				{
					return new LoginFailure("Connection timed out.");
				}
				return new LoginFailure(ex.GetBaseException().Message);
			}
			if (!task.IsCompleted)
			{
				return new LoginFailure("Connection timed out.");
			}
			return LoginAsync(game, name, itemsHandlingFlags, version, tags, uuid, password, requestSlotData).Result;
		}

		private ConnectPacket BuildConnectPacket(string name, string password, Version version, bool requestSlotData)
		{
			return new ConnectPacket
			{
				Game = ConnectionInfo.Game,
				Name = name,
				Password = password,
				Tags = ConnectionInfo.Tags,
				Uuid = ConnectionInfo.Uuid,
				Version = ((version != null) ? new NetworkVersion(version) : new NetworkVersion(0, 6, 0)),
				ItemsHandling = ConnectionInfo.ItemsHandlingFlags,
				RequestSlotData = requestSlotData
			};
		}

		public void Say(string message)
		{
			Socket.SendPacket(new SayPacket
			{
				Text = message
			});
		}

		public void SetClientState(ArchipelagoClientState state)
		{
			Socket.SendPacket(new StatusUpdatePacket
			{
				Status = state
			});
		}

		public void SetGoalAchieved()
		{
			SetClientState(ArchipelagoClientState.ClientGoal);
		}
	}
	public interface IArchipelagoSessionActions
	{
		void Say(string message);

		void SetClientState(ArchipelagoClientState state);

		void SetGoalAchieved();
	}
	public static class ArchipelagoSessionFactory
	{
		public static ArchipelagoSession CreateSession(Uri uri)
		{
			ArchipelagoSocketHelper socket = new ArchipelagoSocketHelper(uri);
			DataPackageCache cache = new DataPackageCache(socket);
			ConnectionInfoHelper connectionInfoHelper = new ConnectionInfoHelper(socket);
			PlayerHelper playerHelper = new PlayerHelper(socket, connectionInfoHelper);
			ItemInfoResolver itemInfoResolver = new ItemInfoResolver(cache, connectionInfoHelper);
			LocationCheckHelper locationCheckHelper = new LocationCheckHelper(socket, itemInfoResolver, connectionInfoHelper, playerHelper);
			ReceivedItemsHelper items = new ReceivedItemsHelper(socket, locationCheckHelper, itemInfoResolver, connectionInfoHelper, playerHelper);
			RoomStateHelper roomStateHelper = new RoomStateHelper(socket, locationCheckHelper);
			DataStorageHelper dataStorageHelper = new DataStorageHelper(socket, connectionInfoHelper);
			MessageLogHelper messageLog = new MessageLogHelper(socket, itemInfoResolver, playerHelper, connectionInfoHelper);
			HintsHelper createHints = new HintsHelper(socket, playerHelper, locationCheckHelper, roomStateHelper, dataStorageHelper);
			return new ArchipelagoSession(socket, items, locationCheckHelper, playerHelper, roomStateHelper, connectionInfoHelper, dataStorageHelper, messageLog, createHints);
		}

		public static ArchipelagoSession CreateSession(string hostname, int port = 38281)
		{
			return CreateSession(ParseUri(hostname, port));
		}

		internal static Uri ParseUri(string hostname, int port)
		{
			string text = hostname;
			if (!text.StartsWith("ws://") && !text.StartsWith("wss://"))
			{
				text = "unspecified://" + text;
			}
			if (!text.Substring(text.IndexOf("://", StringComparison.Ordinal) + 3).Contains(":"))
			{
				text += $":{port}";
			}
			if (text.EndsWith(":"))
			{
				text += port;
			}
			return new Uri(text);
		}
	}
	public abstract class LoginResult
	{
		public abstract bool Successful { get; }

		public static LoginResult FromPacket(ArchipelagoPacketBase packet)
		{
			if (!(packet is ConnectedPacket connectedPacket))
			{
				if (packet is ConnectionRefusedPacket connectionRefusedPacket)
				{
					return new LoginFailure(connectionRefusedPacket);
				}
				throw new ArgumentOutOfRangeException("packet", "packet is not a connection result packet");
			}
			return new LoginSuccessful(connectedPacket);
		}
	}
	public class LoginSuccessful : LoginResult
	{
		public override bool Successful => true;

		public int Team { get; }

		public int Slot { get; }

		public Dictionary<string, object> SlotData { get; }

		public LoginSuccessful(ConnectedPacket connectedPacket)
		{
			Team = connectedPacket.Team;
			Slot = connectedPacket.Slot;
			SlotData = connectedPacket.SlotData;
		}
	}
	public class LoginFailure : LoginResult
	{
		public override bool Successful => false;

		public ConnectionRefusedError[] ErrorCodes { get; }

		public string[] Errors { get; }

		public LoginFailure(ConnectionRefusedPacket connectionRefusedPacket)
		{
			if (connectionRefusedPacket.Errors != null)
			{
				ErrorCodes = connectionRefusedPacket.Errors.ToArray();
				Errors = ErrorCodes.Select(GetErrorMessage).ToArray();
			}
			else
			{
				ErrorCodes = new ConnectionRefusedError[0];
				Errors = new string[0];
			}
		}

		public LoginFailure(string message)
		{
			ErrorCodes = new ConnectionRefusedError[0];
			Errors = new string[1] { message };
		}

		private static string GetErrorMessage(ConnectionRefusedError errorCode)
		{
			return errorCode switch
			{
				ConnectionRefusedError.InvalidSlot => "The slot name did not match any slot on the server.", 
				ConnectionRefusedError.InvalidGame => "The slot is set to a different game on the server.", 
				ConnectionRefusedError.SlotAlreadyTaken => "The slot already has a connection with a different uuid established.", 
				ConnectionRefusedError.IncompatibleVersion => "The client and server version mismatch.", 
				ConnectionRefusedError.InvalidPassword => "The password is invalid.", 
				ConnectionRefusedError.InvalidItemsHandling => "The item handling flags provided are invalid.", 
				_ => $"Unknown error: {errorCode}.", 
			};
		}
	}
	internal class TwoWayLookup<TA, TB> : IEnumerable<KeyValuePair<TB, TA>>, IEnumerable
	{
		private readonly Dictionary<TA, TB> aToB = new Dictionary<TA, TB>();

		private readonly Dictionary<TB, TA> bToA = new Dictionary<TB, TA>();

		public TA this[TB b] => bToA[b];

		public TB this[TA a] => aToB[a];

		public void Add(TA a, TB b)
		{
			aToB[a] = b;
			bToA[b] = a;
		}

		public void Add(TB b, TA a)
		{
			Add(a, b);
		}

		public bool TryGetValue(TA a, out TB b)
		{
			return aToB.TryGetValue(a, out b);
		}

		public bool TryGetValue(TB b, out TA a)
		{
			return bToA.TryGetValue(b, out a);
		}

		public IEnumerator<KeyValuePair<TB, TA>> GetEnumerator()
		{
			return bToA.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
}
namespace Archipelago.MultiClient.Net.Packets
{
	public class BouncedPacket : BouncePacket
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Bounced;
	}
	public class BouncePacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Bounce;

		[JsonProperty("games")]
		public List<string> Games { get; set; } = new List<string>();


		[JsonProperty("slots")]
		public List<int> Slots { get; set; } = new List<int>();


		[JsonProperty("tags")]
		public List<string> Tags { get; set; } = new List<string>();


		[JsonProperty("data")]
		public Dictionary<string, JToken> Data { get; set; }
	}
	public class ConnectedPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Connected;

		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }

		[JsonProperty("players")]
		public NetworkPlayer[] Players { get; set; }

		[JsonProperty("missing_locations")]
		public long[] MissingChecks { get; set; }

		[JsonProperty("checked_locations")]
		public long[] LocationsChecked { get; set; }

		[JsonProperty("slot_data")]
		public Dictionary<string, object> SlotData { get; set; }

		[JsonProperty("slot_info")]
		public Dictionary<int, NetworkSlot> SlotInfo { get; set; }

		[JsonProperty("hint_points")]
		public int? HintPoints { get; set; }
	}
	public class ConnectionRefusedPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.ConnectionRefused;

		[JsonProperty("errors", ItemConverterType = typeof(AttemptingStringEnumConverter))]
		public ConnectionRefusedError[] Errors { get; set; }
	}
	public class ConnectPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Connect;

		[JsonProperty("password")]
		public string Password { get; set; }

		[JsonProperty("game")]
		public string Game { get; set; }

		[JsonProperty("name")]
		public string Name { get; set; }

		[JsonProperty("uuid")]
		public string Uuid { get; set; }

		[JsonProperty("version")]
		public NetworkVersion Version { get; set; }

		[JsonProperty("tags")]
		public string[] Tags { get; set; }

		[JsonProperty("items_handling")]
		public ItemsHandlingFlags ItemsHandling { get; set; }

		[JsonProperty("slot_data")]
		public bool RequestSlotData { get; set; }
	}
	public class ConnectUpdatePacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.ConnectUpdate;

		[JsonProperty("tags")]
		public string[] Tags { get; set; }

		[JsonProperty("items_handling")]
		public ItemsHandlingFlags? ItemsHandling { get; set; }
	}
	public class CreateHintsPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.CreateHints;

		[JsonProperty("locations")]
		public long[] Locations { get; set; }

		[JsonProperty("player")]
		public int Player { get; set; }

		[JsonProperty("status")]
		public HintStatus Status { get; set; }
	}
	public class DataPackagePacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.DataPackage;

		[JsonProperty("data")]
		public Archipelago.MultiClient.Net.Models.DataPackage DataPackage { get; set; }
	}
	public class GetDataPackagePacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.GetDataPackage;

		[JsonProperty("games")]
		public string[] Games { get; set; }
	}
	public class GetPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Get;

		[JsonProperty("keys")]
		public string[] Keys { get; set; }
	}
	public class InvalidPacketPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.InvalidPacket;

		[JsonProperty("type")]
		public InvalidPacketErrorType ErrorType { get; set; }

		[JsonProperty("text")]
		public string ErrorText { get; set; }

		[JsonProperty("original_cmd")]
		public ArchipelagoPacketType OriginalCmd { get; set; }
	}
	public class LocationChecksPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.LocationChecks;

		[JsonProperty("locations")]
		public long[] Locations { get; set; }
	}
	public class LocationInfoPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.LocationInfo;

		[JsonProperty("locations")]
		public NetworkItem[] Locations { get; set; }
	}
	public class LocationScoutsPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.LocationScouts;

		[JsonProperty("locations")]
		public long[] Locations { get; set; }

		[JsonProperty("create_as_hint")]
		public int CreateAsHint { get; set; }
	}
	public class PrintJsonPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.PrintJSON;

		[JsonProperty("data")]
		public JsonMessagePart[] Data { get; set; }

		[JsonProperty("type")]
		[JsonConverter(typeof(AttemptingStringEnumConverter))]
		public JsonMessageType? MessageType { get; set; }
	}
	public class ItemPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("receiving")]
		public int ReceivingPlayer { get; set; }

		[JsonProperty("item")]
		public NetworkItem Item { get; set; }
	}
	public class ItemCheatPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("receiving")]
		public int ReceivingPlayer { get; set; }

		[JsonProperty("item")]
		public NetworkItem Item { get; set; }

		[JsonProperty("team")]
		public int Team { get; set; }
	}
	public class HintPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("receiving")]
		public int ReceivingPlayer { get; set; }

		[JsonProperty("item")]
		public NetworkItem Item { get; set; }

		[JsonProperty("found")]
		public bool? Found { get; set; }
	}
	public class JoinPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }

		[JsonProperty("tags")]
		public string[] Tags { get; set; }
	}
	public class LeavePrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }
	}
	public class ChatPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }

		[JsonProperty("message")]
		public string Message { get; set; }
	}
	public class ServerChatPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("message")]
		public string Message { get; set; }
	}
	public class TutorialPrintJsonPacket : PrintJsonPacket
	{
	}
	public class TagsChangedPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }

		[JsonProperty("tags")]
		public string[] Tags { get; set; }
	}
	public class CommandResultPrintJsonPacket : PrintJsonPacket
	{
	}
	public class AdminCommandResultPrintJsonPacket : PrintJsonPacket
	{
	}
	public class GoalPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }
	}
	public class ReleasePrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }
	}
	public class CollectPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }
	}
	public class CountdownPrintJsonPacket : PrintJsonPacket
	{
		[JsonProperty("countdown")]
		public int RemainingSeconds { get; set; }
	}
	public class ReceivedItemsPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.ReceivedItems;

		[JsonProperty("index")]
		public int Index { get; set; }

		[JsonProperty("items")]
		public NetworkItem[] Items { get; set; }
	}
	public class RetrievedPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Retrieved;

		[JsonProperty("keys")]
		public Dictionary<string, JToken> Data { get; set; }
	}
	public class RoomInfoPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.RoomInfo;

		[JsonProperty("version")]
		public NetworkVersion Version { get; set; }

		[JsonProperty("generator_version")]
		public NetworkVersion GeneratorVersion { get; set; }

		[JsonProperty("tags")]
		public string[] Tags { get; set; }

		[JsonProperty("password")]
		public bool Password { get; set; }

		[JsonProperty("permissions")]
		public Dictionary<string, Permissions> Permissions { get; set; }

		[JsonProperty("hint_cost")]
		public int HintCostPercentage { get; set; }

		[JsonProperty("location_check_points")]
		public int LocationCheckPoints { get; set; }

		[JsonProperty("players")]
		public NetworkPlayer[] Players { get; set; }

		[JsonProperty("games")]
		public string[] Games { get; set; }

		[JsonProperty("datapackage_checksums")]
		public Dictionary<string, string> DataPackageChecksums { get; set; }

		[JsonProperty("seed_name")]
		public string SeedName { get; set; }

		[JsonProperty("time")]
		public double Timestamp { get; set; }
	}
	public class RoomUpdatePacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.RoomUpdate;

		[JsonProperty("tags")]
		public string[] Tags { get; set; }

		[JsonProperty("password")]
		public bool? Password { get; set; }

		[JsonProperty("permissions")]
		public Dictionary<string, Permissions> Permissions { get; set; } = new Dictionary<string, Permissions>();


		[JsonProperty("hint_cost")]
		public int? HintCostPercentage { get; set; }

		[JsonProperty("location_check_points")]
		public int? LocationCheckPoints { get; set; }

		[JsonProperty("players")]
		public NetworkPlayer[] Players { get; set; }

		[JsonProperty("hint_points")]
		public int? HintPoints { get; set; }

		[JsonProperty("checked_locations")]
		public long[] CheckedLocations { get; set; }
	}
	public class SayPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Say;

		[JsonProperty("text")]
		public string Text { get; set; }
	}
	public class SetNotifyPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.SetNotify;

		[JsonProperty("keys")]
		public string[] Keys { get; set; }
	}
	public class SetPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Set;

		[JsonProperty("key")]
		public string Key { get; set; }

		[JsonProperty("default")]
		public JToken DefaultValue { get; set; }

		[JsonProperty("operations")]
		public OperationSpecification[] Operations { get; set; }

		[JsonProperty("want_reply")]
		public bool WantReply { get; set; }

		[JsonExtensionData]
		public Dictionary<string, JToken> AdditionalArguments { get; set; }

		[OnDeserialized]
		internal void OnDeserializedMethod(StreamingContext context)
		{
			AdditionalArguments?.Remove("cmd");
		}
	}
	public class SetReplyPacket : SetPacket
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.SetReply;

		[JsonProperty("value")]
		public JToken Value { get; set; }

		[JsonProperty("original_value")]
		public JToken OriginalValue { get; set; }
	}
	public class StatusUpdatePacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.StatusUpdate;

		[JsonProperty("status")]
		public ArchipelagoClientState Status { get; set; }
	}
	public class SyncPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Sync;
	}
	internal class UnknownPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.Unknown;
	}
	public class UpdateHintPacket : ArchipelagoPacketBase
	{
		public override ArchipelagoPacketType PacketType => ArchipelagoPacketType.UpdateHint;

		[JsonProperty("player")]
		public int Player { get; set; }

		[JsonProperty("location")]
		public long Location { get; set; }

		[JsonProperty("status")]
		public HintStatus Status { get; set; }
	}
}
namespace Archipelago.MultiClient.Net.Models
{
	public struct Color : IEquatable<Color>
	{
		public static Color Red = new Color(byte.MaxValue, 0, 0);

		public static Color Green = new Color(0, 128, 0);

		public static Color Yellow = new Color(byte.MaxValue, byte.MaxValue, 0);

		public static Color Blue = new Color(0, 0, byte.MaxValue);

		public static Color Magenta = new Color(byte.MaxValue, 0, byte.MaxValue);

		public static Color Cyan = new Color(0, byte.MaxValue, byte.MaxValue);

		public static Color Black = new Color(0, 0, 0);

		public static Color White = new Color(byte.MaxValue, byte.MaxValue, byte.MaxValue);

		public static Color SlateBlue = new Color(106, 90, 205);

		public static Color Salmon = new Color(250, 128, 114);

		public static Color Plum = new Color(221, 160, 221);

		public byte R { get; set; }

		public byte G { get; set; }

		public byte B { get; set; }

		public Color(byte r, byte g, byte b)
		{
			R = r;
			G = g;
			B = b;
		}

		public override bool Equals(object obj)
		{
			if (obj is Color color && R == color.R && G == color.G)
			{
				return B == color.B;
			}
			return false;
		}

		public bool Equals(Color other)
		{
			if (R == other.R && G == other.G)
			{
				return B == other.B;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return ((-1520100960 * -1521134295 + R.GetHashCode()) * -1521134295 + G.GetHashCode()) * -1521134295 + B.GetHashCode();
		}

		public static bool operator ==(Color left, Color right)
		{
			return left.Equals(right);
		}

		public static bool operator !=(Color left, Color right)
		{
			return !(left == right);
		}
	}
	public class DataPackage
	{
		[JsonProperty("games")]
		public Dictionary<string, GameData> Games { get; set; } = new Dictionary<string, GameData>();

	}
	public class DataStorageElement
	{
		internal DataStorageElementContext Context;

		internal List<OperationSpecification> Operations = new List<OperationSpecification>(0);

		internal DataStorageHelper.DataStorageUpdatedHandler Callbacks;

		internal Dictionary<string, JToken> AdditionalArguments = new Dictionary<string, JToken>(0);

		private JToken cachedValue;

		public event DataStorageHelper.DataStorageUpdatedHandler OnValueChanged
		{
			add
			{
				Context.AddHandler(Context.Key, value);
			}
			remove
			{
				Context.RemoveHandler(Context.Key, value);
			}
		}

		internal DataStorageElement(DataStorageElementContext context)
		{
			Context = context;
		}

		internal DataStorageElement(OperationType operationType, JToken value)
		{
			Operations = new List<OperationSpecification>(1)
			{
				new OperationSpecification
				{
					OperationType = operationType,
					Value = value
				}
			};
		}

		internal DataStorageElement(DataStorageElement source, OperationType operationType, JToken value)
			: this(source.Context)
		{
			Operations = source.Operations.ToList();
			Callbacks = source.Callbacks;
			AdditionalArguments = source.AdditionalArguments;
			Operations.Add(new OperationSpecification
			{
				OperationType = operationType,
				Value = value
			});
		}

		internal DataStorageElement(DataStorageElement source, Callback callback)
			: this(source.Context)
		{
			Operations = source.Operations.ToList();
			Callbacks = source.Callbacks;
			AdditionalArguments = source.AdditionalArguments;
			Callbacks = (DataStorageHelper.DataStorageUpdatedHandler)Delegate.Combine(Callbacks, callback.Method);
		}

		internal DataStorageElement(DataStorageElement source, AdditionalArgument additionalArgument)
			: this(source.Context)
		{
			Operations = source.Operations.ToList();
			Callbacks = source.Callbacks;
			AdditionalArguments = source.AdditionalArguments;
			AdditionalArguments[additionalArgument.Key] = additionalArgument.Value;
		}

		public static DataStorageElement operator ++(DataStorageElement a)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(1));
		}

		public static DataStorageElement operator --(DataStorageElement a)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(-1));
		}

		public static DataStorageElement operator +(DataStorageElement a, int b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator +(DataStorageElement a, long b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator +(DataStorageElement a, float b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator +(DataStorageElement a, double b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator +(DataStorageElement a, decimal b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator +(DataStorageElement a, string b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator +(DataStorageElement a, JToken b)
		{
			return new DataStorageElement(a, OperationType.Add, b);
		}

		public static DataStorageElement operator +(DataStorageElement a, IEnumerable b)
		{
			return new DataStorageElement(a, OperationType.Add, (JToken)(object)JArray.FromObject((object)b));
		}

		public static DataStorageElement operator +(DataStorageElement a, OperationSpecification s)
		{
			return new DataStorageElement(a, s.OperationType, s.Value);
		}

		public static DataStorageElement operator +(DataStorageElement a, Callback c)
		{
			return new DataStorageElement(a, c);
		}

		public static DataStorageElement operator +(DataStorageElement a, AdditionalArgument arg)
		{
			return new DataStorageElement(a, arg);
		}

		public static DataStorageElement operator *(DataStorageElement a, int b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator *(DataStorageElement a, long b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator *(DataStorageElement a, float b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator *(DataStorageElement a, double b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator *(DataStorageElement a, decimal b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator %(DataStorageElement a, int b)
		{
			return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator %(DataStorageElement a, long b)
		{
			return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator %(DataStorageElement a, float b)
		{
			return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator %(DataStorageElement a, double b)
		{
			return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator %(DataStorageElement a, decimal b)
		{
			return new DataStorageElement(a, OperationType.Mod, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator ^(DataStorageElement a, int b)
		{
			return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator ^(DataStorageElement a, long b)
		{
			return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator ^(DataStorageElement a, float b)
		{
			return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator ^(DataStorageElement a, double b)
		{
			return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator ^(DataStorageElement a, decimal b)
		{
			return new DataStorageElement(a, OperationType.Pow, JToken.op_Implicit(b));
		}

		public static DataStorageElement operator -(DataStorageElement a, int b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(-b)));
		}

		public static DataStorageElement operator -(DataStorageElement a, long b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(-b)));
		}

		public static DataStorageElement operator -(DataStorageElement a, float b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(0f - b)));
		}

		public static DataStorageElement operator -(DataStorageElement a, double b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(0.0 - b)));
		}

		public static DataStorageElement operator -(DataStorageElement a, decimal b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.FromObject((object)(-b)));
		}

		public static DataStorageElement operator /(DataStorageElement a, int b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1m / (decimal)b)));
		}

		public static DataStorageElement operator /(DataStorageElement a, long b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1m / (decimal)b)));
		}

		public static DataStorageElement operator /(DataStorageElement a, float b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1.0 / (double)b)));
		}

		public static DataStorageElement operator /(DataStorageElement a, double b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1.0 / b)));
		}

		public static DataStorageElement operator /(DataStorageElement a, decimal b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.FromObject((object)(1m / b)));
		}

		public static implicit operator DataStorageElement(bool b)
		{
			return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(b));
		}

		public static implicit operator DataStorageElement(int i)
		{
			return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(i));
		}

		public static implicit operator DataStorageElement(long l)
		{
			return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(l));
		}

		public static implicit operator DataStorageElement(decimal m)
		{
			return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(m));
		}

		public static implicit operator DataStorageElement(double d)
		{
			return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(d));
		}

		public static implicit operator DataStorageElement(float f)
		{
			return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(f));
		}

		public static implicit operator DataStorageElement(string s)
		{
			if (s != null)
			{
				return new DataStorageElement(OperationType.Replace, JToken.op_Implicit(s));
			}
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JValue.CreateNull());
		}

		public static implicit operator DataStorageElement(JToken o)
		{
			return new DataStorageElement(OperationType.Replace, o);
		}

		public static implicit operator DataStorageElement(Array a)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)a));
		}

		public static implicit operator DataStorageElement(List<bool> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<int> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<long> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<decimal> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<double> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<float> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<string> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator DataStorageElement(List<object> l)
		{
			return new DataStorageElement(OperationType.Replace, (JToken)(object)JArray.FromObject((object)l));
		}

		public static implicit operator bool(DataStorageElement e)
		{
			return RetrieveAndReturnBoolValue<bool>(e);
		}

		public static implicit operator bool?(DataStorageElement e)
		{
			return RetrieveAndReturnBoolValue<bool?>(e);
		}

		public static implicit operator int(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<int>(e);
		}

		public static implicit operator int?(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<int?>(e);
		}

		public static implicit operator long(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<long>(e);
		}

		public static implicit operator long?(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<long?>(e);
		}

		public static implicit operator float(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<float>(e);
		}

		public static implicit operator float?(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<float?>(e);
		}

		public static implicit operator double(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<double>(e);
		}

		public static implicit operator double?(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<double?>(e);
		}

		public static implicit operator decimal(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<decimal>(e);
		}

		public static implicit operator decimal?(DataStorageElement e)
		{
			return RetrieveAndReturnDecimalValue<decimal?>(e);
		}

		public static implicit operator string(DataStorageElement e)
		{
			return RetrieveAndReturnStringValue(e);
		}

		public static implicit operator bool[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<bool[]>(e);
		}

		public static implicit operator int[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<int[]>(e);
		}

		public static implicit operator long[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<long[]>(e);
		}

		public static implicit operator decimal[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<decimal[]>(e);
		}

		public static implicit operator double[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<double[]>(e);
		}

		public static implicit operator float[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<float[]>(e);
		}

		public static implicit operator string[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<string[]>(e);
		}

		public static implicit operator object[](DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<object[]>(e);
		}

		public static implicit operator List<bool>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<bool>>(e);
		}

		public static implicit operator List<int>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<int>>(e);
		}

		public static implicit operator List<long>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<long>>(e);
		}

		public static implicit operator List<decimal>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<decimal>>(e);
		}

		public static implicit operator List<double>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<double>>(e);
		}

		public static implicit operator List<float>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<float>>(e);
		}

		public static implicit operator List<string>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<string>>(e);
		}

		public static implicit operator List<object>(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<List<object>>(e);
		}

		public static implicit operator Array(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<Array>(e);
		}

		public static implicit operator JArray(DataStorageElement e)
		{
			return RetrieveAndReturnArrayValue<JArray>(e);
		}

		public static implicit operator JToken(DataStorageElement e)
		{
			return e.Context.GetData(e.Context.Key);
		}

		public static DataStorageElement operator +(DataStorageElement a, BigInteger b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.Parse(b.ToString()));
		}

		public static DataStorageElement operator *(DataStorageElement a, BigInteger b)
		{
			return new DataStorageElement(a, OperationType.Mul, JToken.Parse(b.ToString()));
		}

		public static DataStorageElement operator %(DataStorageElement a, BigInteger b)
		{
			return new DataStorageElement(a, OperationType.Mod, JToken.Parse(b.ToString()));
		}

		public static DataStorageElement operator ^(DataStorageElement a, BigInteger b)
		{
			return new DataStorageElement(a, OperationType.Pow, JToken.Parse(b.ToString()));
		}

		public static DataStorageElement operator -(DataStorageElement a, BigInteger b)
		{
			return new DataStorageElement(a, OperationType.Add, JToken.Parse((-b).ToString()));
		}

		public static DataStorageElement operator /(DataStorageElement a, BigInteger b)
		{
			throw new InvalidOperationException("DataStorage[Key] / BigInterger is not supported, due to loss of precision when using integer division");
		}

		public static implicit operator DataStorageElement(BigInteger bi)
		{
			return new DataStorageElement(OperationType.Replace, JToken.Parse(bi.ToString()));
		}

		public static implicit operator BigInteger(DataStorageElement e)
		{
			return RetrieveAndReturnBigIntegerValue<BigInteger>(e);
		}

		public static implicit operator BigInteger?(DataStorageElement e)
		{
			return RetrieveAndReturnBigIntegerValue<BigInteger?>(e);
		}

		private static T RetrieveAndReturnBigIntegerValue<T>(DataStorageElement e)
		{
			if (e.cachedValue != null)
			{
				if (!BigInteger.TryParse(((object)e.cachedValue).ToString(), out var result))
				{
					return default(T);
				}
				return (T)Convert.ChangeType(result, IsNullable<T>() ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T));
			}
			BigInteger result2;
			BigInteger? bigInteger = (BigInteger.TryParse(((object)e.Context.GetData(e.Context.Key)).ToString(), out result2) ? new BigInteger?(result2) : null);
			if (!bigInteger.HasValue && !IsNullable<T>())
			{
				bigInteger = Activator.CreateInstance<BigInteger>();
			}
			foreach (OperationSpecification operation in e.Operations)
			{
				if (operation.OperationType == OperationType.Floor || operation.OperationType == OperationType.Ceil)
				{
					continue;
				}
				if (!BigInteger.TryParse(((object)operation.Value).ToString(), NumberStyles.AllowLeadingSign, null, out var result3))
				{
					throw new InvalidOperationException($"DataStorage[Key] cannot be converted to BigInterger as its value its not an integer number, value: {operation.Value}");
				}
				switch (operation.OperationType)
				{
				case OperationType.Replace:
					bigInteger = result3;
					break;
				case OperationType.Add:
					bigInteger += result3;
					break;
				case OperationType.Mul:
					bigInteger *= result3;
					break;
				case OperationType.Mod:
					bigInteger %= result3;
					break;
				case OperationType.Pow:
					bigInteger = BigInteger.Pow(bigInteger.Value, (int)operation.Value);
					break;
				case OperationType.Max:
				{
					BigInteger value = result3;
					BigInteger? bigInteger2 = bigInteger;
					if (value > bigInteger2)
					{
						bigInteger = result3;
					}
					break;
				}
				case OperationType.Min:
				{
					BigInteger value = result3;
					BigInteger? bigInteger2 = bigInteger;
					if (value < bigInteger2)
					{
						bigInteger = result3;
					}
					break;
				}
				case OperationType.Xor:
					bigInteger ^= result3;
					break;
				case OperationType.Or:
					bigInteger |= result3;
					break;
				case OperationType.And:
					bigInteger &= result3;
					break;
				case OperationType.LeftShift:
					bigInteger <<= (int)operation.Value;
					break;
				case OperationType.RightShift:
					bigInteger >>= (int)operation.Value;
					break;
				}
			}
			e.cachedValue = JToken.Parse(bigInteger.ToString());
			if (!bigInteger.HasValue)
			{
				return default(T);
			}
			return (T)Convert.ChangeType(bigInteger.Value, IsNullable<T>() ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T));
		}

		public void Initialize(JToken value)
		{
			Context.Initialize(Context.Key, value);
		}

		public void Initialize(IEnumerable value)
		{
			Context.Initialize(Context.Key, (JToken)(object)JArray.FromObject((object)value));
		}

		public Task<T> GetAsync<T>()
		{
			return GetAsync().ContinueWith((Task<JToken> r) => r.Result.ToObject<T>());
		}

		public Task<JToken> GetAsync()
		{
			return Context.GetAsync(Context.Key);
		}

		private static T RetrieveAndReturnArrayValue<T>(DataStorageElement e)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Invalid comparison between Unknown and I4
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			if (e.cachedValue != null)
			{
				return ((JToken)(JArray)e.cachedValue).ToObject<T>();
			}
			JArray val = (JArray)(((object)e.Context.GetData(e.Context.Key).ToObject<JArray>()) ?? ((object)new JArray()));
			foreach (OperationSpecification operation in e.Operations)
			{
				switch (operation.OperationType)
				{
				case OperationType.Add:
					if ((int)operation.Value.Type != 2)
					{
						throw new InvalidOperationException($"Cannot perform operation {OperationType.Add} on Array value, with a non Array value: {operation.Value}");
					}
					((JContainer)val).Merge((object)operation.Value);
					break;
				case OperationType.Replace:
					if ((int)operation.Value.Type != 2)
					{
						throw new InvalidOperationException($"Cannot replace Array value, with a non Array value: {operation.Value}");
					}
					val = (JArray)(((object)operation.Value.ToObject<JArray>()) ?? ((object)new JArray()));
					break;
				default:
					throw new InvalidOperationException($"Cannot perform operation {operation.OperationType} on Array value");
				}
			}
			e.cachedValue = (JToken)(object)val;
			return ((JToken)val).ToObject<T>();
		}

		private static string RetrieveAndReturnStringValue(DataStorageElement e)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Invalid comparison between Unknown and I4
			if (e.cachedValue != null)
			{
				return (string)e.cachedValue;
			}
			JToken val = e.Context.GetData(e.Context.Key);
			string text = (((int)val.Type == 10) ? null : ((object)val).ToString());
			foreach (OperationSpecification operation in e.Operations)
			{
				switch (operation.OperationType)
				{
				case OperationType.Add:
					text += (string)operation.Value;
					break;
				case OperationType.Mul:
					if ((int)operation.Value.Type != 6)
					{
						throw new InvalidOperationException($"Cannot perform operation {OperationType.Mul} on string value, with a non interger value: {operation.Value}");
					}
					text = string.Concat(Enumerable.Repeat(text, (int)operation.Value));
					break;
				case OperationType.Replace:
					text = (string)operation.Value;
					break;
				default:
					throw new InvalidOperationException($"Cannot perform operation {operation.OperationType} on string value");
				}
			}
			if (text == null)
			{
				e.cachedValue = (JToken)(object)JValue.CreateNull();
			}
			else
			{
				e.cachedValue = JToken.op_Implicit(text);
			}
			return (string)e.cachedValue;
		}

		private static T RetrieveAndReturnBoolValue<T>(DataStorageElement e)
		{
			if (e.cachedValue != null)
			{
				return e.cachedValue.ToObject<T>();
			}
			bool? flag = e.Context.GetData(e.Context.Key).ToObject<bool?>() ?? ((bool?)Activator.CreateInstance(typeof(T)));
			foreach (OperationSpecification operation in e.Operations)
			{
				if (operation.OperationType == OperationType.Replace)
				{
					flag = (bool?)operation.Value;
					continue;
				}
				throw new InvalidOperationException($"Cannot perform operation {operation.OperationType} on boolean value");
			}
			e.cachedValue = JToken.op_Implicit(flag);
			if (!flag.HasValue)
			{
				return default(T);
			}
			return (T)Convert.ChangeType(flag.Value, IsNullable<T>() ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T));
		}

		private static T RetrieveAndReturnDecimalValue<T>(DataStorageElement e)
		{
			if (e.cachedValue != null)
			{
				return e.cachedValue.ToObject<T>();
			}
			decimal? num = e.Context.GetData(e.Context.Key).ToObject<decimal?>();
			if (!num.HasValue && !IsNullable<T>())
			{
				num = Activator.CreateInstance<decimal>();
			}
			foreach (OperationSpecification operation in e.Operations)
			{
				switch (operation.OperationType)
				{
				case OperationType.Replace:
					num = (decimal)operation.Value;
					break;
				case OperationType.Add:
					num += (decimal?)(decimal)operation.Value;
					break;
				case OperationType.Mul:
					num *= (decimal?)(decimal)operation.Value;
					break;
				case OperationType.Mod:
					num %= (decimal?)(decimal)operation.Value;
					break;
				case OperationType.Pow:
					num = (decimal)Math.Pow((double)num.Value, (double)operation.Value);
					break;
				case OperationType.Max:
					num = Math.Max(num.Value, (decimal)operation.Value);
					break;
				case OperationType.Min:
					num = Math.Min(num.Value, (decimal)operation.Value);
					break;
				case OperationType.Xor:
					num = (long)num.Value ^ (long)operation.Value;
					break;
				case OperationType.Or:
					num = (long)num.Value | (long)operation.Value;
					break;
				case OperationType.And:
					num = (long)num.Value & (long)operation.Value;
					break;
				case OperationType.LeftShift:
					num = (long)num.Value << (int)operation.Value;
					break;
				case OperationType.RightShift:
					num = (long)num.Value >> (int)operation.Value;
					break;
				case OperationType.Floor:
					num = Math.Floor(num.Value);
					break;
				case OperationType.Ceil:
					num = Math.Ceiling(num.Value);
					break;
				}
			}
			e.cachedValue = JToken.op_Implicit(num);
			if (!num.HasValue)
			{
				return default(T);
			}
			return (T)Convert.ChangeType(num.Value, IsNullable<T>() ? Nullable.GetUnderlyingType(typeof(T)) : typeof(T));
		}

		private static bool IsNullable<T>()
		{
			if (typeof(T).IsGenericType)
			{
				return typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>).GetGenericTypeDefinition();
			}
			return false;
		}

		public T To<T>()
		{
			if (Operations.Count != 0)
			{
				throw new InvalidOperationException("DataStorageElement.To<T>() cannot be used together with other operations on the DataStorageElement");
			}
			return Context.GetData(Context.Key).ToObject<T>();
		}

		public override string ToString()
		{
			return (Context?.ToString() ?? "(null)") + ", (" + ListOperations() + ")";
		}

		private string ListOperations()
		{
			if (Operations != null)
			{
				return string.Join(", ", Operations.Select((OperationSpecification o) => o.ToString()).ToArray());
			}
			return "none";
		}
	}
	internal class DataStorageElementContext
	{
		internal string Key { get; set; }

		internal Action<string, DataStorageHelper.DataStorageUpdatedHandler> AddHandler { get; set; }

		internal Action<string, DataStorageHelper.DataStorageUpdatedHandler> RemoveHandler { get; set; }

		internal Func<string, JToken> GetData { get; set; }

		internal Action<string, JToken> Initialize { get; set; }

		internal Func<string, Task<JToken>> GetAsync { get; set; }

		public override string ToString()
		{
			return "Key: " + Key;
		}
	}
	public class GameData
	{
		[JsonProperty("location_name_to_id")]
		public Dictionary<string, long> LocationLookup { get; set; } = new Dictionary<string, long>();


		[JsonProperty("item_name_to_id")]
		public Dictionary<string, long> ItemLookup { get; set; } = new Dictionary<string, long>();


		[Obsolete("use Checksum instead")]
		[JsonProperty("version")]
		public int Version { get; set; }

		[JsonProperty("checksum")]
		public string Checksum { get; set; }
	}
	public class Hint
	{
		[JsonProperty("receiving_player")]
		public int ReceivingPlayer { get; set; }

		[JsonProperty("finding_player")]
		public int FindingPlayer { get; set; }

		[JsonProperty("item")]
		public long ItemId { get; set; }

		[JsonProperty("location")]
		public long LocationId { get; set; }

		[JsonProperty("item_flags")]
		public ItemFlags ItemFlags { get; set; }

		[JsonProperty("found")]
		public bool Found { get; set; }

		[JsonProperty("entrance")]
		public string Entrance { get; set; }

		[JsonProperty("status")]
		public HintStatus Status { get; set; }
	}
	public class ItemInfo
	{
		private readonly IItemInfoResolver itemInfoResolver;

		public long ItemId { get; }

		public long LocationId { get; }

		public PlayerInfo Player { get; }

		public ItemFlags Flags { get; }

		public string ItemName => itemInfoResolver.GetItemName(ItemId, ItemGame);

		public string ItemDisplayName => ItemName ?? $"Item: {ItemId}";

		public string LocationName => itemInfoResolver.GetLocationName(LocationId, LocationGame);

		public string LocationDisplayName => LocationName ?? $"Location: {LocationId}";

		public string ItemGame { get; }

		public string LocationGame { get; }

		public ItemInfo(NetworkItem item, string receiverGame, string senderGame, IItemInfoResolver itemInfoResolver, PlayerInfo player)
		{
			this.itemInfoResolver = itemInfoResolver;
			ItemGame = receiverGame;
			LocationGame = senderGame;
			ItemId = item.Item;
			LocationId = item.Location;
			Flags = item.Flags;
			Player = player;
		}

		public SerializableItemInfo ToSerializable()
		{
			return new SerializableItemInfo
			{
				IsScout = (GetType() == typeof(ScoutedItemInfo)),
				ItemId = ItemId,
				LocationId = LocationId,
				PlayerSlot = Player,
				Player = Player,
				Flags = Flags,
				ItemGame = ItemGame,
				ItemName = ItemName,
				LocationGame = LocationGame,
				LocationName = LocationName
			};
		}
	}
	public class ScoutedItemInfo : ItemInfo
	{
		public new PlayerInfo Player => base.Player;

		public bool IsReceiverRelatedToActivePlayer { get; }

		public ScoutedItemInfo(NetworkItem item, string receiverGame, string senderGame, IItemInfoResolver itemInfoResolver, IPlayerHelper players, PlayerInfo player)
			: base(item, receiverGame, senderGame, itemInfoResolver, player)
		{
			IsReceiverRelatedToActivePlayer = (players.ActivePlayer ?? new PlayerInfo()).IsRelatedTo(player);
		}
	}
	public class JsonMessagePart
	{
		[JsonProperty("type")]
		[JsonConverter(typeof(AttemptingStringEnumConverter), new object[] { typeof(SnakeCaseNamingStrategy) })]
		public JsonMessagePartType? Type { get; set; }

		[JsonProperty("color")]
		[JsonConverter(typeof(AttemptingStringEnumConverter), new object[] { typeof(SnakeCaseNamingStrategy) })]
		public JsonMessagePartColor? Color { get; set; }

		[JsonProperty("text")]
		public string Text { get; set; }

		[JsonProperty("player")]
		public int? Player { get; set; }

		[JsonProperty("flags")]
		public ItemFlags? Flags { get; set; }

		[JsonProperty("hint_status")]
		public HintStatus? HintStatus { get; set; }
	}
	public struct NetworkItem
	{
		[JsonProperty("item")]
		public long Item { get; set; }

		[JsonProperty("location")]
		public long Location { get; set; }

		[JsonProperty("player")]
		public int Player { get; set; }

		[JsonProperty("flags")]
		public ItemFlags Flags { get; set; }
	}
	public struct NetworkPlayer
	{
		[JsonProperty("team")]
		public int Team { get; set; }

		[JsonProperty("slot")]
		public int Slot { get; set; }

		[JsonProperty("alias")]
		public string Alias { get; set; }

		[JsonProperty("name")]
		public string Name { get; set; }
	}
	public struct NetworkSlot
	{
		[JsonProperty("name")]
		public string Name { get; set; }

		[JsonProperty("game")]
		public string Game { get; set; }

		[JsonProperty("type")]
		public SlotType Type { get; set; }

		[JsonProperty("group_members")]
		public int[] GroupMembers { get; set; }
	}
	public class NetworkVersion
	{
		[JsonProperty("major")]
		public int Major { get; set; }

		[JsonProperty("minor")]
		public int Minor { get; set; }

		[JsonProperty("build")]
		public int Build { get; set; }

		[JsonProperty("class")]
		public string Class => "Version";

		public NetworkVersion()
		{
		}

		public NetworkVersion(int major, int minor, int build)
		{
			Major = major;
			Minor = minor;
			Build = build;
		}

		public NetworkVersion(Version version)
		{
			Major = version.Major;
			Minor = version.Minor;
			Build = version.Build;
		}

		public Version ToVersion()
		{
			return new Version(Major, Minor, Build);
		}
	}
	public class OperationSpecification
	{
		[JsonProperty("operation")]
		[JsonConverter(typeof(AttemptingStringEnumConverter), new object[] { typeof(SnakeCaseNamingStrategy) })]
		public OperationType OperationType;

		[JsonProperty("value")]
		public JToken Value { get; set; }

		public override string ToString()
		{
			return $"{OperationType}: {Value}";
		}
	}
	public static class Operation
	{
		public static OperationSpecification Min(int i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Min(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Min(float i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Min(double i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Min(decimal i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Min(JToken i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = i
			};
		}

		public static OperationSpecification Min(BigInteger i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Min,
				Value = JToken.Parse(i.ToString())
			};
		}

		public static OperationSpecification Max(int i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Max(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Max(float i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Max(double i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Max(decimal i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Max(JToken i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = i
			};
		}

		public static OperationSpecification Max(BigInteger i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Max,
				Value = JToken.Parse(i.ToString())
			};
		}

		public static OperationSpecification Remove(JToken value)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Remove,
				Value = value
			};
		}

		public static OperationSpecification Pop(int value)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Pop,
				Value = JToken.op_Implicit(value)
			};
		}

		public static OperationSpecification Pop(JToken value)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Pop,
				Value = value
			};
		}

		public static OperationSpecification Update(IDictionary dictionary)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Update,
				Value = (JToken)(object)JObject.FromObject((object)dictionary)
			};
		}

		public static OperationSpecification Floor()
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Floor,
				Value = null
			};
		}

		public static OperationSpecification Ceiling()
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Ceil,
				Value = null
			};
		}
	}
	public static class Bitwise
	{
		public static OperationSpecification Xor(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Xor,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Xor(BigInteger i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Xor,
				Value = JToken.Parse(i.ToString())
			};
		}

		public static OperationSpecification Or(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Or,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification Or(BigInteger i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.Or,
				Value = JToken.Parse(i.ToString())
			};
		}

		public static OperationSpecification And(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.And,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification And(BigInteger i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.And,
				Value = JToken.Parse(i.ToString())
			};
		}

		public static OperationSpecification LeftShift(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.LeftShift,
				Value = JToken.op_Implicit(i)
			};
		}

		public static OperationSpecification RightShift(long i)
		{
			return new OperationSpecification
			{
				OperationType = OperationType.RightShift,
				Value = JToken.op_Implicit(i)
			};
		}
	}
	public class Callback
	{
		internal DataStorageHelper.DataStorageUpdatedHandler Method { get; set; }

		private Callback()
		{
		}

		public static Callback Add(DataStorageHelper.DataStorageUpdatedHandler callback)
		{
			return new Callback
			{
				Method = callback
			};
		}
	}
	public class AdditionalArgument
	{
		internal string Key { get; set; }

		internal JToken Value { get; set; }

		private AdditionalArgument()
		{
		}

		public static AdditionalArgument Add(string name, JToken value)
		{
			return new AdditionalArgument
			{
				Key = name,
				Value = value
			};
		}
	}
	public class MinimalSerializableItemInfo
	{
		public long ItemId { get; set; }

		public long LocationId { get; set; }

		public int PlayerSlot { get; set; }

		public ItemFlags Flags { get; set; }

		public string ItemGame { get; set; }

		public string LocationGame { get; set; }
	}
	public class SerializableItemInfo : MinimalSerializableItemInfo
	{
		public bool IsScout { get; set; }

		public PlayerInfo Player { get; set; }

		public string ItemName { get; set; }

		public string LocationName { get; set; }

		[JsonIgnore]
		public string ItemDisplayName => ItemName ?? $"Item: {base.ItemId}";

		[JsonIgnore]
		public string LocationDisplayName => LocationName ?? $"Location: {base.LocationId}";

		public string ToJson(bool full = false)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			MinimalSerializableItemInfo minimalSerializableItemInfo = this;
			if (!full)
			{
				minimalSerializableItemInfo = new MinimalSerializableItemInfo
				{
					ItemId = base.ItemId,
					LocationId = base.LocationId,
					PlayerSlot = base.PlayerSlot,
					Flags = base.Flags
				};
				if (IsScout)
				{
					minimalSerializableItemInfo.ItemGame = base.ItemGame;
				}
				else
				{
					minimalSerializableItemInfo.LocationGame = base.LocationGame;
				}
			}
			JsonSerializerSettings val = new JsonSerializerSettings
			{
				NullValueHandling = (NullValueHandling)1,
				Formatting = (Formatting)0
			};
			return JsonConvert.SerializeObject((object)minimalSerializableItemInfo, val);
		}

		public static SerializableItemInfo FromJson(string json, IArchipelagoSession session = null)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			ItemInfoStreamingContext additional = ((session != null) ? new ItemInfoStreamingContext
			{
				Items = session.Items,
				Locations = session.Locations,
				PlayerHelper = session.Players,
				ConnectionInfo = session.ConnectionInfo
			} : null);
			JsonSerializerSettings val = new JsonSerializerSettings
			{
				Context = new StreamingContext(StreamingContextStates.Other, additional)
			};
			return JsonConvert.DeserializeObject<SerializableItemInfo>(json, val);
		}

		[OnDeserialized]
		internal void OnDeserializedMethod(StreamingContext streamingContext)
		{
			if (base.ItemGame == null && base.LocationGame != null)
			{
				IsScout = false;
			}
			else if (base.ItemGame != null && base.LocationGame == null)
			{
				IsScout = true;
			}
			if (streamingContext.Context is ItemInfoStreamingContext itemInfoStreamingContext)
			{
				if (IsScout && base.LocationGame == null)
				{
					base.LocationGame = itemInfoStreamingContext.ConnectionInfo.Game;
				}
				else if (!IsScout && base.ItemGame == null)
				{
					base.ItemGame = itemInfoStreamingContext.ConnectionInfo.Game;
				}
				if (ItemName == null)
				{
					ItemName = itemInfoStreamingContext.Items.GetItemName(base.ItemId, base.ItemGame);
				}
				if (LocationName == null)
				{
					LocationName = itemInfoStreamingContext.Locations.GetLocationNameFromId(base.LocationId, base.LocationGame);
				}
				if (Player == null)
				{
					Player = itemInfoStreamingContext.PlayerHelper.GetPlayerInfo(base.PlayerSlot);
				}
			}
		}
	}
	internal class ItemInfoStreamingContext
	{
		public IReceivedItemsHelper Items { get; set; }

		public ILocationCheckHelper Locations { get; set; }

		public IPlayerHelper PlayerHelper { get; set; }

		public IConnectionInfoProvider ConnectionInfo { get; set; }
	}
}
namespace Archipelago.MultiClient.Net.MessageLog.Parts
{
	public class EntranceMessagePart : MessagePart
	{
		internal EntranceMessagePart(JsonMessagePart messagePart)
			: base(MessagePartType.Entrance, messagePart, Archipelago.MultiClient.Net.Colors.PaletteColor.Blue)
		{
			base.Text = messagePart.Text;
		}
	}
	public class HintStatusMessagePart : MessagePart
	{
		internal HintStatusMessagePart(JsonMessagePart messagePart)
			: base(MessagePartType.HintStatus, messagePart)
		{
			base.Text = messagePart.Text;
			if (messagePart.HintStatus.HasValue)
			{
				base.PaletteColor = ColorUtils.GetColor(messagePart.HintStatus.Value);
			}
		}
	}
	public class ItemMessagePart : MessagePart
	{
		public ItemFlags Flags { get; }

		public long ItemId { get; }

		public int Player { get; }

		internal ItemMessagePart(IPlayerHelper players, IItemInfoResolver items, JsonMessagePart part)
			: base(MessagePartType.Item, part)
		{
			Flags = part.Flags.GetValueOrDefault();
			base.PaletteColor = ColorUtils.GetColor(Flags);
			Player = part.Player.GetValueOrDefault();
			string game = (players.GetPlayerInfo(Player) ?? new PlayerInfo()).Game;
			JsonMessagePartType? type = part.Type;
			if (type.HasValue)
			{
				switch (type.GetValueOrDefault())
				{
				case JsonMessagePartType.ItemId:
					ItemId = long.Parse(part.Text);
					base.Text = items.GetItemName(ItemId, game) ?? $"Item: {ItemId}";
					break;
				case JsonMessagePartType.ItemName:
					ItemId = 0L;
					base.Text = part.Text;
					break;
				}
			}
		}
	}
	public class LocationMessagePart : MessagePart
	{
		public long LocationId { get; }

		public int Player { get; }

		internal LocationMessagePart(IPlayerHelper players, IItemInfoResolver itemInfoResolver, JsonMessagePart part)
			: base(MessagePartType.Location, part, Archipelago.MultiClient.Net.Colors.PaletteColor.Green)
		{
			Player = part.Player.GetValueOrDefault();
			string game = (players.GetPlayerInfo(Player) ?? new PlayerInfo()).Game;
			JsonMessagePartType? type = part.Type;
			if (type.HasValue)
			{
				switch (type.GetValueOrDefault())
				{
				case JsonMessagePartType.LocationId:
					LocationId = long.Parse(part.Text);
					base.Text = itemInfoResolver.GetLocationName(LocationId, game) ?? $"Location: {LocationId}";
					break;
				case JsonMessagePartType.LocationName:
					LocationId = itemInfoResolver.GetLocationId(part.Text, game);
					base.Text = part.Text;
					break;
				}
			}
		}
	}
	public class MessagePart
	{
		public string Text { get; internal set; }

		public MessagePartType Type { get; internal set; }

		public Color Color => GetColor(BuiltInPalettes.Dark);

		public PaletteColor? PaletteColor { get; protected set; }

		public bool IsBackgroundColor { get; internal set; }

		internal MessagePart(MessagePartType type, JsonMessagePart messagePart, PaletteColor? color = null)
		{
			Type = type;
			Text = messagePart.Text;
			if (color.HasValue)
			{
				PaletteColor = color.Value;
			}
			else if (messagePart.Color.HasValue)
			{
				PaletteColor = ColorUtils.GetColor(messagePart.Color.Value);
				IsBackgroundColor = messagePart.Color.Value >= JsonMessagePartColor.BlackBg;
			}
			else
			{
				PaletteColor = null;
			}
		}

		public T GetColor<T>(Palette<T> palette)
		{
			return palette[PaletteColor];
		}

		public override string ToString()
		{
			return Text;
		}
	}
	public enum MessagePartType
	{
		Text,
		Player,
		Item,
		Location,
		Entrance,
		HintStatus
	}
	public class PlayerMessagePart : MessagePart
	{
		public bool IsActivePlayer { get; }

		public int SlotId { get; }

		internal PlayerMessagePart(IPlayerHelper players, IConnectionInfoProvider connectionInfo, JsonMessagePart part)
			: base(MessagePartType.Player, part)
		{
			switch (part.Type)
			{
			case JsonMessagePartType.PlayerId:
				SlotId = int.Parse(part.Text);
				IsActivePlayer = SlotId == connectionInfo.Slot;
				base.Text = players.GetPlayerAlias(SlotId) ?? $"Player {SlotId}";
				break;
			case JsonMessagePartType.PlayerName:
				SlotId = 0;
				IsActivePlayer = false;
				base.Text = part.Text;
				break;
			}
			base.PaletteColor = (IsActivePlayer ? Archipelago.MultiClient.Net.Colors.PaletteColor.Magenta : Archipelago.MultiClient.Net.Colors.PaletteColor.Yellow);
		}
	}
}
namespace Archipelago.MultiClient.Net.MessageLog.Messages
{
	public class AdminCommandResultLogMessage : LogMessage
	{
		internal AdminCommandResultLogMessage(MessagePart[] parts)
			: base(parts)
		{
		}
	}
	public class ChatLogMessage : PlayerSpecificLogMessage
	{
		public string Message { get; }

		internal ChatLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot, string message)
			: base(parts, players, team, slot)
		{
			Message = message;
		}
	}
	public class CollectLogMessage : PlayerSpecificLogMessage
	{
		internal CollectLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot)
			: base(parts, players, team, slot)
		{
		}
	}
	public class CommandResultLogMessage : LogMessage
	{
		internal CommandResultLogMessage(MessagePart[] parts)
			: base(parts)
		{
		}
	}
	public class CountdownLogMessage : LogMessage
	{
		public int RemainingSeconds { get; }

		internal CountdownLogMessage(MessagePart[] parts, int remainingSeconds)
			: base(parts)
		{
			RemainingSeconds = remainingSeconds;
		}
	}
	public class GoalLogMessage : PlayerSpecificLogMessage
	{
		internal GoalLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot)
			: base(parts, players, team, slot)
		{
		}
	}
	public class HintItemSendLogMessage : ItemSendLogMessage
	{
		public bool IsFound { get; }

		internal HintItemSendLogMessage(MessagePart[] parts, IPlayerHelper players, int receiver, int sender, NetworkItem item, bool found, IItemInfoResolver itemInfoResolver)
			: base(parts, players, receiver, sender, item, itemInfoResolver)
		{
			IsFound = found;
		}
	}
	public class ItemCheatLogMessage : ItemSendLogMessage
	{
		internal ItemCheatLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot, NetworkItem item, IItemInfoResolver itemInfoResolver)
			: base(parts, players, slot, 0, item, team, itemInfoResolver)
		{
		}
	}
	public class ItemSendLogMessage : LogMessage
	{
		private PlayerInfo ActivePlayer { get; }

		public PlayerInfo Receiver { get; }

		public PlayerInfo Sender { get; }

		public bool IsReceiverTheActivePlayer => Receiver == ActivePlayer;

		public bool IsSenderTheActivePlayer => Sender == ActivePlayer;

		public bool IsRelatedToActivePlayer
		{
			get
			{
				if (!ActivePlayer.IsRelatedTo(Receiver))
				{
					return ActivePlayer.IsRelatedTo(Sender);
				}
				return true;
			}
		}

		public ItemInfo Item { get; }

		internal ItemSendLogMessage(MessagePart[] parts, IPlayerHelper players, int receiver, int sender, NetworkItem item, IItemInfoResolver itemInfoResolver)
			: this(parts, players, receiver, sender, item, players.ActivePlayer.Team, itemInfoResolver)
		{
		}

		internal ItemSendLogMessage(MessagePart[] parts, IPlayerHelper players, int receiver, int sender, NetworkItem item, int team, IItemInfoResolver itemInfoResolver)
			: base(parts)
		{
			ActivePlayer = players.ActivePlayer ?? new PlayerInfo();
			Receiver = players.GetPlayerInfo(team, receiver) ?? new PlayerInfo();
			Sender = players.GetPlayerInfo(team, sender) ?? new PlayerInfo();
			PlayerInfo player = players.GetPlayerInfo(team, item.Player) ?? new PlayerInfo();
			Item = new ItemInfo(item, Receiver.Game, Sender.Game, itemInfoResolver, player);
		}
	}
	public class JoinLogMessage : PlayerSpecificLogMessage
	{
		public string[] Tags { get; }

		internal JoinLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot, string[] tags)
			: base(parts, players, team, slot)
		{
			Tags = tags;
		}
	}
	public class LeaveLogMessage : PlayerSpecificLogMessage
	{
		internal LeaveLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot)
			: base(parts, players, team, slot)
		{
		}
	}
	public class LogMessage
	{
		public MessagePart[] Parts { get; }

		internal LogMessage(MessagePart[] parts)
		{
			Parts = parts;
		}

		public override string ToString()
		{
			if (Parts.Length == 1)
			{
				return Parts[0].Text;
			}
			StringBuilder stringBuilder = new StringBuilder();
			MessagePart[] parts = Parts;
			foreach (MessagePart messagePart in parts)
			{
				stringBuilder.Append(messagePart.Text);
			}
			return stringBuilder.ToString();
		}
	}
	public abstract class PlayerSpecificLogMessage : LogMessage
	{
		private PlayerInfo ActivePlayer { get; }

		public PlayerInfo Player { get; }

		public bool IsActivePlayer => Player == ActivePlayer;

		public bool IsRelatedToActivePlayer => ActivePlayer.IsRelatedTo(Player);

		internal PlayerSpecificLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot)
			: base(parts)
		{
			ActivePlayer = players.ActivePlayer ?? new PlayerInfo();
			Player = players.GetPlayerInfo(team, slot) ?? new PlayerInfo();
		}
	}
	public class ReleaseLogMessage : PlayerSpecificLogMessage
	{
		internal ReleaseLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot)
			: base(parts, players, team, slot)
		{
		}
	}
	public class ServerChatLogMessage : LogMessage
	{
		public string Message { get; }

		internal ServerChatLogMessage(MessagePart[] parts, string message)
			: base(parts)
		{
			Message = message;
		}
	}
	public class TagsChangedLogMessage : PlayerSpecificLogMessage
	{
		public string[] Tags { get; }

		internal TagsChangedLogMessage(MessagePart[] parts, IPlayerHelper players, int team, int slot, string[] tags)
			: base(parts, players, team, slot)
		{
			Tags = tags;
		}
	}
	public class TutorialLogMessage : LogMessage
	{
		internal TutorialLogMessage(MessagePart[] parts)
			: base(parts)
		{
		}
	}
}
namespace Archipelago.MultiClient.Net.Helpers
{
	public class ArchipelagoSocketHelper : BaseArchipelagoSocketHelper<ClientWebSocket>, IArchipelagoSocketHelper
	{
		public Uri Uri { get; }

		internal ArchipelagoSocketHelper(Uri hostUri)
			: base(CreateWebSocket(), 1024)
		{
			Uri = hostUri;
			SecurityProtocolType securityProtocolType = SecurityProtocolType.Tls13;
			ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | securityProtocolType;
		}

		private static ClientWebSocket CreateWebSocket()
		{
			return new ClientWebSocket();
		}

		public async Task ConnectAsync()
		{
			await ConnectToProvidedUri(Uri);
			StartPolling();
		}

		private async Task ConnectToProvidedUri(Uri uri)
		{
			if (uri.Scheme != "unspecified")
			{
				try
				{
					await Socket.ConnectAsync(uri, CancellationToken.None);
					return;
				}
				catch (Exception e)
				{
					OnError(e);
					throw;
				}
			}
			List<Exception> errors = new List<Exception>(0);
			try
			{
				await Socket.ConnectAsync(uri.AsWss(), CancellationToken.None);
				if (Socket.State == WebSocketState.Open)
				{
					return;
				}
			}
			catch (Exception item)
			{
				errors.Add(item);
				Socket = CreateWebSocket();
			}
			try
			{
				await Socket.ConnectAsync(uri.AsWs(), CancellationToken.None);
			}
			catch (Exception item2)
			{
				errors.Add(item2);
				OnError(new AggregateException(errors));
				throw;
			}
		}
	}
	public class BaseArchipelagoSocketHelper<T> where T : WebSocket
	{
		private static readonly ArchipelagoPacketConverter Converter = new ArchipelagoPacketConverter();

		private readonly BlockingCollection<Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>>> sendQueue = new BlockingCollection<Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>>>();

		internal T Socket;

		private readonly int bufferSize;

		public bool Connected
		{
			get
			{
				if (Socket.State != WebSocketState.Open)
				{
					return Socket.State == WebSocketState.CloseReceived;
				}
				return true;
			}
		}

		public event ArchipelagoSocketHelperDelagates.PacketReceivedHandler PacketReceived;

		public event ArchipelagoSocketHelperDelagates.PacketsSentHandler PacketsSent;

		public event ArchipelagoSocketHelperDelagates.ErrorReceivedHandler ErrorReceived;

		public event ArchipelagoSocketHelperDelagates.SocketClosedHandler SocketClosed;

		public event ArchipelagoSocketHelperDelagates.SocketOpenedHandler SocketOpened;

		internal BaseArchipelagoSocketHelper(T socket, int bufferSize = 1024)
		{
			Socket = socket;
			this.bufferSize = bufferSize;
		}

		internal void StartPolling()
		{
			if (this.SocketOpened != null)
			{
				this.SocketOpened();
			}
			Task.Run((Func<Task?>)PollingLoop);
			Task.Run((Func<Task?>)SendLoop);
		}

		private async Task PollingLoop()
		{
			byte[] buffer = new byte[bufferSize];
			while (Socket.State == WebSocketState.Open)
			{
				string message = null;
				try
				{
					message = await ReadMessageAsync(buffer);
				}
				catch (Exception e)
				{
					OnError(e);
				}
				OnMessageReceived(message);
			}
		}

		private async Task SendLoop()
		{
			while (Socket.State == WebSocketState.Open)
			{
				try
				{
					await HandleSendBuffer();
				}
				catch (Exception e)
				{
					OnError(e);
				}
				await Task.Delay(20);
			}
		}

		private async Task<string> ReadMessageAsync(byte[] buffer)
		{
			using MemoryStream readStream = new MemoryStream(buffer.Length);
			WebSocketReceiveResult result;
			do
			{
				result = await Socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
				if (result.MessageType == WebSocketMessageType.Close)
				{
					try
					{
						await Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
					}
					catch
					{
					}
					OnSocketClosed();
				}
				else
				{
					readStream.Write(buffer, 0, result.Count);
				}
			}
			while (!result.EndOfMessage);
			return Encoding.UTF8.GetString(readStream.ToArray());
		}

		public async Task DisconnectAsync()
		{
			await Socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closure requested by client", CancellationToken.None);
			OnSocketClosed();
		}

		public void SendPacket(ArchipelagoPacketBase packet)
		{
			SendMultiplePackets(new List<ArchipelagoPacketBase> { packet });
		}

		public void SendMultiplePackets(List<ArchipelagoPacketBase> packets)
		{
			SendMultiplePackets(packets.ToArray());
		}

		public void SendMultiplePackets(params ArchipelagoPacketBase[] packets)
		{
			SendMultiplePacketsAsync(packets).Wait();
		}

		public Task SendPacketAsync(ArchipelagoPacketBase packet)
		{
			return SendMultiplePacketsAsync(new List<ArchipelagoPacketBase> { packet });
		}

		public Task SendMultiplePacketsAsync(List<ArchipelagoPacketBase> packets)
		{
			return SendMultiplePacketsAsync(packets.ToArray());
		}

		public Task SendMultiplePacketsAsync(params ArchipelagoPacketBase[] packets)
		{
			TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>();
			foreach (ArchipelagoPacketBase item in packets)
			{
				sendQueue.Add(new Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>>(item, taskCompletionSource));
			}
			return taskCompletionSource.Task;
		}

		private async Task HandleSendBuffer()
		{
			List<ArchipelagoPacketBase> list = new List<ArchipelagoPacketBase>();
			List<TaskCompletionSource<bool>> tasks = new List<TaskCompletionSource<bool>>();
			Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>> tuple = sendQueue.Take();
			list.Add(tuple.Item1);
			tasks.Add(tuple.Item2);
			Tuple<ArchipelagoPacketBase, TaskCompletionSource<bool>> item;
			while (sendQueue.TryTake(out item))
			{
				list.Add(item.Item1);
				tasks.Add(item.Item2);
			}
			if (!list.Any())
			{
				return;
			}
			if (Socket.State != WebSocketState.Open)
			{
				throw new ArchipelagoSocketClosedException();
			}
			ArchipelagoPacketBase[] packets = list.ToArray();
			string s = JsonConvert.SerializeObject((object)packets);
			byte[] messageBuffer = Encoding.UTF8.GetBytes(s);
			int messagesCount = (int)Math.Ceiling((double)messageBuffer.Length / (double)bufferSize);
			for (int i = 0; i < messagesCount; i++)
			{
				int num = bufferSize * i;
				int num2 = bufferSize;
				bool endOfMessage = i + 1 == messagesCount;
				if (num2 * (i + 1) > messageBuffer.Length)
				{
					num2 = messageBuffer.Length - num;
				}
				await Socket.SendAsync(new ArraySegment<byte>(messageBuffer, num, num2), WebSocketMessageType.Text, endOfMessage, CancellationToken.None);
			}
			foreach (TaskCompletionSource<bool> item2 in tasks)
			{
				item2.TrySetResult(result: true);
			}
			OnPacketSend(packets);
		}

		private void OnPacketSend(ArchipelagoPacketBase[] packets)
		{
			try
			{
				if (this.PacketsSent != null)
				{
					this.PacketsSent(packets);
				}
			}
			catch (Exception e)
			{
				OnError(e);
			}
		}

		private void OnSocketClosed()
		{
			try
			{
				if (this.SocketClosed != null)
				{
					this.SocketClosed("");
				}
			}
			catch (Exception e)
			{
				OnError(e);
			}
		}

		private void OnMessageReceived(string message)
		{
			try
			{
				if (string.IsNullOrEmpty(message) || this.PacketReceived == null)
				{
					return;
				}
				List<ArchipelagoPacketBase> list = null;
				try
				{
					list = JsonConvert.DeserializeObject<List<ArchipelagoPacketBase>>(message, (JsonConverter[])(object)new JsonConverter[1] { Converter });
				}
				catch (Exception e)
				{
					OnError(e);
				}
				if (list == null)
				{
					return;
				}
				foreach (ArchipelagoPacketBase item in list)
				{
					this.PacketReceived(item);
				}
			}
			catch (Exception e2)
			{
				OnError(e2);
			}
		}

		protected void OnError(Exception e)
		{
			try
			{
				if (this.ErrorReceived != null)
				{
					this.ErrorReceived(e, e.Message);
				}
			}
			catch (Exception ex)
			{
				Console.Out.WriteLine("Error occured during reporting of errorOuter Errror: " + e.Message + " " + e.StackTrace + "Inner Errror: " + ex.Message + " " + ex.StackTrace);
			}
		}
	}
	public interface IConnectionInfoProvider
	{
		string Game { get; }

		int Team { get; }

		int Slot { get; }

		string[] Tags { get; }

		ItemsHandlingFlags ItemsHandlingFlags { get; }

		string Uuid { get; }

		void UpdateConnectionOptions(string[] tags);

		void UpdateConnectionOptions(ItemsHandlingFlags itemsHandlingFlags);

		void UpdateConnectionOptions(string[] tags, ItemsHandlingFlags itemsHandlingFlags);
	}
	public class ConnectionInfoHelper : IConnectionInfoProvider
	{
		private readonly IArchipelagoSocketHelper socket;

		public string Game { get; private set; }

		public int Team { get; private set; }

		public int Slot { get; private set; }

		public string[] Tags { get; internal set; }

		public ItemsHandlingFlags ItemsHandlingFlags { get; internal set; }

		public string Uuid { get; private set; }

		internal ConnectionInfoHelper(IArchipelagoSocketHelper socket)
		{
			this.socket = socket;
			Reset();
			socket.PacketReceived += PacketReceived;
		}

		private void PacketReceived(ArchipelagoPacketBase packet)
		{
			if (!(packet is ConnectedPacket connectedPacket))
			{
				if (packet is ConnectionRefusedPacket)
				{
					Reset();
				}
				return;
			}
			Team = connectedPacket.Team;
			Slot = connectedPacket.Slot;
			if (connectedPacket.SlotInfo != null && connectedPacket.SlotInfo.ContainsKey(Slot))
			{
				Game = connectedPacket.SlotInfo[Slot].Game;
			}
		}

		internal void SetConnectionParameters(string game, string[] tags, ItemsHandlingFlags itemsHandlingFlags, string uuid)
		{
			Game = game;
			Tags = tags ?? new string[0];
			ItemsHandlingFlags = itemsHandlingFlags;
			Uuid = uuid ?? Guid.NewGuid().ToString();
		}

		private void Reset()
		{
			Game = null;
			Team = -1;
			Slot = -1;
			Tags = new string[0];
			ItemsHandlingFlags = ItemsHandlingFlags.NoItems;
			Uuid = null;
		}

		public void UpdateConnectionOptions(string[] tags)
		{
			UpdateConnectionOptions(tags, ItemsHandlingFlags);
		}

		public void UpdateConnectionOptions(ItemsHandlingFlags itemsHandlingFlags)
		{
			UpdateConnectionOptions(Tags, ItemsHandlingFlags);
		}

		public void UpdateConnectionOptions(string[] tags, ItemsHandlingFlags itemsHandlingFlags)
		{
			SetConnectionParameters(Game, tags, itemsHandlingFlags, Uuid);
			socket.SendPacket(new ConnectUpdatePacket
			{
				Tags = Tags,
				ItemsHandling = ItemsHandlingFlags
			});
		}
	}
	public interface IDataStorageHelper : IDataStorageWrapper
	{
		DataStorageElement this[Scope scope, string key] { get; set; }

		DataStorageElement this[string key] { get; set; }
	}
	public class DataStorageHelper : IDataStorageHelper, IDataStorageWrapper
	{
		public delegate void DataStorageUpdatedHandler(JToken originalValue, JToken newValue, Dictionary<string, JToken> additionalArguments);

		private readonly Dictionary<string, DataStorageUpdatedHandler> onValueChangedEventHandlers = new Dictionary<string, DataStorageUpdatedHandler>();

		private readonly Dictionary<Guid, DataStorageUpdatedHandler> operationSpecificCallbacks = new Dictionary<Guid, DataStorageUpdatedHandler>();

		private readonly Dictionary<string, TaskCompletionSource<JToken>> asyncRetrievalTasks = new Dictionary<string, TaskCompletionSource<JToken>>();

		private readonly IArchipelagoSocketHelper socket;

		private readonly IConnectionInfoProvider connectionInfoProvider;

		public DataStorageElement this[Scope scope, string key]
		{
			get
			{
				return this[AddScope(scope, key)];
			}
			set
			{
				this[AddScope(scope, key)] = value;
			}
		}

		public DataStorageElement this[string key]
		{
			get
			{
				return new DataStorageElement(GetContextForKey(key));
			}
			set
			{
				SetValue(key, value);
			}
		}

		internal DataStorageHelper(IArchipelagoSocketHelper socket, IConnectionInfoProvider connectionInfoProvider)
		{
			this.socket = socket;
			this.connectionInfoProvider = connectionInfoProvider;
			socket.PacketReceived += OnPacketReceived;
		}

		private void OnPacketReceived(ArchipelagoPacketBase packet)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Invalid comparison between Unknown and I4
			if (!(packet is RetrievedPacket retrievedPacket))
			{
				if (packet is SetReplyPacket setReplyPacket)
				{
					if (setReplyPacket.AdditionalArguments != null && setReplyPacket.AdditionalArguments.ContainsKey("Reference") && (int)setReplyPacket.AdditionalArguments["Reference"].Type == 8 && ((string)setReplyPacket.AdditionalArguments["Reference"]).TryParseNGuid(out var g) && operationSpecificCallbacks.TryGetValue(g, out var value))
					{
						value(setReplyPacket.OriginalValue, setReplyPacket.Value, setReplyPacket.AdditionalArguments);
						operationSpecificCallbacks.Remove(g);
					}
					if (onValueChangedEventHandlers.TryGetValue(setReplyPacket.Key, out var value2))
					{
						value2(setReplyPacket.OriginalValue, setReplyPacket.Value, setReplyPacket.AdditionalArguments);
					}
				}
				return;
			}
			foreach (KeyValuePair<string, JToken> datum in retrievedPacket.Data)
			{
				if (asyncRetrievalTasks.TryGetValue(datum.Key, out var value3))
				{
					value3.TrySetResult(datum.Value);
					asyncRetrievalTasks.Remove(datum.Key);
				}
			}
		}

		private Task<JToken> GetAsync(string key)
		{
			if (asyncRetrievalTasks.TryGetValue(key, out var value))
			{
				return value.Task;
			}
			TaskCompletionSource<JToken> taskCompletionSource = new TaskCompletionSource<JToken>();
			asyncRetrievalTasks[key] = taskCompletionSource;
			socket.SendPacketAsync(new GetPacket
			{
				Keys = new string[1] { key }
			});
			return taskCompletionSource.Task;
		}

		private void Initialize(string key, JToken value)
		{
			socket.SendPacketAsync(new SetPacket
			{
				Key = key,
				DefaultValue = value,
				Operations = new OperationSpecification[1]
				{
					new OperationSpecification
					{
						OperationType = OperationType.Default
					}
				}
			});
		}

		private JToken GetValue(string key)
		{
			Task<JToken> async = GetAsync(key);
			if (!async.Wait(TimeSpan.FromSeconds(2.0)))
			{
				throw new TimeoutException("Timed out retrieving data for key `" + key + "`. This may be due to an attempt to retrieve a value from the DataStorageHelper in a synchronous fashion from within a PacketReceived handler. When using the DataStorageHelper from within code which runs on the websocket thread then use the asynchronous getters. Ex: `DataStorageHelper[\"" + key + "\"].GetAsync().ContinueWith(x => {});`Be aware that DataStorageHelper calls tend to cause packet responses, so making a call from within a PacketReceived handler may cause an infinite loop.");
			}
			return async.Result;
		}

		private void SetValue(string key, DataStorageElement e)
		{
			if (key.StartsWith("_read_"))
			{
				throw new InvalidOperationException("DataStorage write operation on readonly key '" + key + "' is not allowed");
			}
			if (e == null)
			{
				e = new DataStorageElement(OperationType.Replace, (JToken)(object)JValue.CreateNull());
			}
			if (e.Context == null)
			{
				e.Context = GetContextForKey(key);
			}
			else if (e.Context.Key != key)
			{
				e.Operations.Insert(0, new OperationSpecification
				{
					OperationType = OperationType.Replace,
					Value = GetValue(e.Context.Key)
				});
			}
			Dictionary<string, JToken> dictionary = e.AdditionalArguments ?? new Dictionary<string, JToken>(0);
			if (e.Callbacks != null)
			{
				Guid key2 = Guid.NewGuid();
				operationSpecificCallbacks[key2] = e.Callbacks;
				dictionary["Reference"] = JToken.op_Implicit(key2.ToString("N"));
				socket.SendPacketAsync(new SetPacket
				{
					Key = key,
					Operations = e.Operations.ToArray(),
					WantReply = true,
					AdditionalArguments = dictionary
				});
			}
			else
			{
				socket.SendPacketAsync(new SetPacket
				{
					Key = key,
					Operations = e.Operations.ToArray(),
					AdditionalArguments = dictionary
				});
			}
		}

		private DataStorageElementContext GetContextForKey(string key)
		{
			return new DataStorageElementContext
			{
				Key = key,
				GetData = GetValue,
				GetAsync = GetAsync,
				Initialize = Initialize,
				AddHandler = AddHandler,
				RemoveHandler = RemoveHandler
			};
		}

		private void AddHandler(string key, DataStorageUpdatedHandler handler)
		{
			if (onValueChangedEventHandlers.ContainsKey(key))
			{
				Dictionary<string, DataStorageUpdatedHandler> dictionary = onValueChangedEventHandlers;
				dictionary[key] = (DataStorageUpdatedHandler)Delegate.Combine(dictionary[key], handler);
			}
			else
			{
				onValueChangedEventHandlers[key] = handler;
			}
			socket.SendPacketAsync(new SetNotifyPacket
			{
				Keys = new string[1] { key }
			});
		}

		private void RemoveHandler(string key, DataStorageUpdatedHandler handler)
		{
			if (onValueChangedEventHandlers.ContainsKey(key))
			{
				Dictionary<string, DataStorageUpdatedHandler> dictionary = onValueChangedEventHandlers;
				dictionary[key] = (DataStorageUpdatedHandler)Delegate.Remove(dictionary[key], handler);
				if (onValueChangedEventHandlers[key] == null)
				{
					onValueChangedEventHandlers.Remove(key);
				}
			}
		}

		private string AddScope(Scope scope, string key)
		{
			return scope switch
			{
				Scope.Global => key, 
				Scope.Game => $"{scope}:{connectionInfoProvider.Game}:{key}", 
				Scope.Team => $"{scope}:{connectionInfoProvider.Team}:{key}", 
				Scope.Slot => $"{scope}:{connectionInfoProvider.Slot}:{key}", 
				Scope.ReadOnly => "_read_" + key, 
				_ => throw new ArgumentOutOfRangeException("scope", scope, "Invalid scope for key " + key), 
			};
		}

		private DataStorageElement GetHintsElement(int? slot = null, int? team = null)
		{
			return this[Scope.ReadOnly, $"hints_{team ?? connectionInfoProvider.Team}_{slot ?? connectionInfoProvider.Slot}"];
		}

		private DataStorageElement GetSlotDataElement(int? slot = null)
		{
			return this[Scope.ReadOnly, $"slot_data_{slot ?? connectionInfoProvider.Slot}"];
		}

		private DataStorageElement GetItemNameGroupsElement(string game = null)
		{
			return this[Scope.ReadOnly, "item_name_groups_" + (game ?? connectionInfoProvider.Game)];
		}

		private DataStorageElement GetLocationNameGroupsElement(string game = null)
		{
			return this[Scope.ReadOnly, "location_name_groups_" + (game ?? connectionInfoProvider.Game)];
		}

		private DataStorageElement GetClientStatusElement(int? slot = null, int? team = null)
		{
			return this[Scope.ReadOnly, $"client_status_{team ?? connectionInfoProvider.Team}_{slot ?? connectionInfoProvider.Slot}"];
		}

		private DataStorageElement GetRaceModeElement()
		{
			return this[Scope.ReadOnly, "race_mode"];
		}

		public Hint[] GetHints(int? slot = null, int? team = null)
		{
			return GetHintsElement(slot, team).To<Hint[]>();
		}

		public Task<Hint[]> GetHintsAsync(int? slot = null, int? team = null)
		{
			return GetHintsElement(slot, team).GetAsync<Hint[]>();
		}

		public void TrackHints(Action<Hint[]> onHintsUpdated, bool retrieveCurrentlyUnlockedHints = true, int? slot = null, int? team = null)
		{
			GetHintsElement(slot, team).OnValueChanged += delegate(JToken _, JToken newValue, Dictionary<string, JToken> x)
			{
				onHintsUpdated(newValue.ToObject<Hint[]>());
			};
			if (retrieveCurrentlyUnlockedHints)
			{
				GetHintsAsync(slot, team).ContinueWith(delegate(Task<Hint[]> t)
				{
					onHintsUpdated(t.Result);
				});
			}
		}

		public Dictionary<string, object> GetSlotData(int? slot = null)
		{
			return GetSlotData<Dictionary<string, object>>(slot);
		}

		public T GetSlotData<T>(int? slot = null) where T : class
		{
			return GetSlotDataElement(slot).To<T>();
		}

		public Task<Dictionary<string, object>> GetSlotDataAsync(int? slot = null)
		{
			return GetSlotDataAsync<Dictionary<string, object>>(slot);
		}

		public Task<T> GetSlotDataAsync<T>(int? slot = null) where T : class
		{
			return GetSlotDataElement(slot).GetAsync<T>();
		}

		public Dictionary<string, string[]> GetItemNameGroups(string game = null)
		{
			return GetItemNameGroupsElement(game).To<Dictionary<string, string[]>>();
		}

		public Task<Dictionary<string, string[]>> GetItemNameGroupsAsync(string game = null)
		{
			return GetItemNameGroupsElement(game).GetAsync<Dictionary<string, string[]>>();
		}

		public Dictionary<string, string[]> GetLocationNameGroups(string game = null)
		{
			return GetLocationNameGroupsElement(game).To<Dictionary<string, string[]>>();
		}

		public Task<Dictionary<string, string[]>> GetLocationNameGroupsAsync(string game = null)
		{
			return GetLocationNameGroupsElement(game).GetAsync<Dictionary<string, string[]>>();
		}

		public ArchipelagoClientState GetClientStatus(int? slot = null, int? team = null)
		{
			return GetClientStatusElement(slot, team).To<ArchipelagoClientState?>().GetValueOrDefault();
		}

		public Task<ArchipelagoClientState> GetClientStatusAsync(int? slot = null, int? team = null)
		{
			return GetClientStatusElement(slot, team).GetAsync<ArchipelagoClientState?>().ContinueWith((Task<ArchipelagoClientState?> r) => r.Result.GetValueOrDefault());
		}

		public void TrackClientStatus(Action<ArchipelagoClientState> onStatusUpdated, bool retrieveCurrentClientStatus = true, int? slot = null, int? team = null)
		{
			Get

GarfieldKartAPMod.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Archipelago.MultiClient.Net;
using Archipelago.MultiClient.Net.Enums;
using Archipelago.MultiClient.Net.Helpers;
using Archipelago.MultiClient.Net.MessageLog.Messages;
using Archipelago.MultiClient.Net.Models;
using Aube;
using Aube.Relays;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GarfieldKartAPMod.Helpers;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("GarfieldKartAPMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+cd827e2a5a49801c6b092e76691f3a2140ac3575")]
[assembly: AssemblyProduct("GarfieldKartAPMod")]
[assembly: AssemblyTitle("GarfieldKartAPMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace GarfieldKartAPMod
{
	public class ArchipelagoClient
	{
		private ArchipelagoSession session;

		private readonly Queue<string> pendingNotifications = new Queue<string>();

		public bool IsConnected
		{
			get
			{
				ArchipelagoSession obj = session;
				if (obj == null)
				{
					return false;
				}
				return obj.Socket.Connected;
			}
		}

		public event Action OnConnected;

		public event Action<string> OnConnectionFailed;

		public event Action OnDisconnected;

		public void Connect(string hostname, int port, string slotName, string password = "")
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			try
			{
				Log.Message($"Attempting to connect to {hostname}:{port} as {slotName}");
				session = ArchipelagoSessionFactory.CreateSession(hostname, port);
				session.Socket.ErrorReceived += new ErrorReceivedHandler(OnError);
				session.Socket.SocketClosed += new SocketClosedHandler(OnSocketClosed);
				LoginResult val = session.TryConnectAndLogin("Garfield Kart - Furious Racing", slotName, (ItemsHandlingFlags)7, new Version(0, 6, 5), (string[])null, (string)null, string.IsNullOrEmpty(password) ? null : password, true);
				if (val.Successful)
				{
					LoginSuccessful val2 = (LoginSuccessful)val;
					GarfieldKartAPMod.sessionSlotData = val2.SlotData;
					Log.Message($"Connected successfully! Slot: {val2.Slot}");
					session.MessageLog.OnMessageReceived += new MessageReceivedHandler(OnMessageReceived);
					ArchipelagoItemTracker.LoadFromServer();
					this.OnConnected?.Invoke();
					ArchipelagoItemTracker.LogAllReceivedItems();
					ArchipelagoItemTracker.LogAllCheckedLocations();
				}
				else
				{
					LoginFailure val3 = (LoginFailure)val;
					string text = string.Join(", ", val3.Errors);
					Log.Error("Connection failed: " + text);
					this.OnConnectionFailed?.Invoke(text);
					session = null;
				}
			}
			catch (Exception ex)
			{
				Log.Error($"Connection exception: {ex}");
				this.OnConnectionFailed?.Invoke(ex.Message);
				session = null;
			}
		}

		public ArchipelagoSession GetSession()
		{
			return session;
		}

		public void Disconnect()
		{
			if (session != null)
			{
				session.Socket.DisconnectAsync();
				session = null;
				Log.Message("Disconnected from Archipelago");
			}
		}

		private void OnMessageReceived(LogMessage message)
		{
			pendingNotifications.Enqueue(((object)message).ToString());
		}

		private void OnError(Exception ex, string message)
		{
			Log.Error("Socket error: " + message + " - " + ex.Message);
		}

		private void OnSocketClosed(string reason)
		{
			Log.Warning("Socket closed: " + reason);
			this.OnDisconnected?.Invoke();
		}

		public void SendLocation(long locationId)
		{
			if (IsConnected)
			{
				ArchipelagoItemTracker.AddCheckedLocation(locationId);
				session.Locations.CompleteLocationChecks(new long[1] { locationId });
				Log.Message($"Sent location check: {locationId}");
			}
		}

		public string GetSlotDataValue(string key)
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>
			{
				["lap_count"] = 3,
				["disable_cpu_items"] = 0,
				["springs_only"] = 0
			};
			if (session == null || GarfieldKartAPMod.sessionSlotData == null)
			{
				return null;
			}
			if (GarfieldKartAPMod.sessionSlotData.TryGetValue(key, out var value))
			{
				return value.ToString();
			}
			if (!dictionary.TryGetValue(key, out var value2))
			{
				throw new SlotDataException("Invalid option requested from apworld: " + key + ". Did you generate on the wrong version?");
			}
			return value2.ToString();
		}

		public bool HasPendingNotifications()
		{
			return pendingNotifications.Count > 0;
		}

		public string DequeuePendingNotification()
		{
			return pendingNotifications.Dequeue();
		}
	}
	public static class ArchipelagoConstants
	{
		public const long LOC_CATZ_IN_THE_HOOD_VICTORY = 1L;

		public const long LOC_CRAZY_DUNES_VICTORY = 2L;

		public const long LOC_PALEROCK_LAKE_VICTORY = 3L;

		public const long LOC_CITY_SLICKER_VICTORY = 4L;

		public const long LOC_COUNTRY_BUMPKIN_VICTORY = 5L;

		public const long LOC_SPOOKY_MANOR_VICTORY = 6L;

		public const long LOC_MALLY_MARKET_VICTORY = 7L;

		public const long LOC_VALLEY_OF_THE_KINGS_VICTORY = 8L;

		public const long LOC_MISTY_FOR_ME_VICTORY = 9L;

		public const long LOC_SNEAK_A_PEAK_VICTORY = 10L;

		public const long LOC_BLAZING_OASIS_VICTORY = 11L;

		public const long LOC_PASTACOSI_FACTORY_VICTORY = 12L;

		public const long LOC_MYSTERIOUS_TEMPLE_VICTORY = 13L;

		public const long LOC_PROHIBITED_SITE_VICTORY = 14L;

		public const long LOC_CASKOU_PARK_VICTORY = 15L;

		public const long LOC_LOOPY_LAGOON_VICTORY = 16L;

		public const long LOC_CATZ_IN_THE_HOOD_TIME_TRIAL_BRONZE = 21L;

		public const long LOC_CRAZY_DUNES_TIME_TRIAL_BRONZE = 22L;

		public const long LOC_PALEROCK_LAKE_TIME_TRIAL_BRONZE = 23L;

		public const long LOC_CITY_SLICKER_TIME_TRIAL_BRONZE = 24L;

		public const long LOC_COUNTRY_BUMPKIN_TIME_TRIAL_BRONZE = 25L;

		public const long LOC_SPOOKY_MANOR_TIME_TRIAL_BRONZE = 26L;

		public const long LOC_MALLY_MARKET_TIME_TRIAL_BRONZE = 27L;

		public const long LOC_VALLEY_OF_THE_KINGS_TIME_TRIAL_BRONZE = 28L;

		public const long LOC_MISTY_FOR_ME_TIME_TRIAL_BRONZE = 29L;

		public const long LOC_SNEAK_A_PEAK_TIME_TRIAL_BRONZE = 30L;

		public const long LOC_BLAZING_OASIS_TIME_TRIAL_BRONZE = 31L;

		public const long LOC_PASTACOSI_FACTORY_TIME_TRIAL_BRONZE = 32L;

		public const long LOC_MYSTERIOUS_TEMPLE_TIME_TRIAL_BRONZE = 33L;

		public const long LOC_PROHIBITED_SITE_TIME_TRIAL_BRONZE = 34L;

		public const long LOC_CASKOU_PARK_TIME_TRIAL_BRONZE = 35L;

		public const long LOC_LOOPY_LAGOON_TIME_TRIAL_BRONZE = 36L;

		public const long LOC_CATZ_IN_THE_HOOD_TIME_TRIAL_SILVER = 41L;

		public const long LOC_CRAZY_DUNES_TIME_TRIAL_SILVER = 42L;

		public const long LOC_PALEROCK_LAKE_TIME_TRIAL_SILVER = 43L;

		public const long LOC_CITY_SLICKER_TIME_TRIAL_SILVER = 44L;

		public const long LOC_COUNTRY_BUMPKIN_TIME_TRIAL_SILVER = 45L;

		public const long LOC_SPOOKY_MANOR_TIME_TRIAL_SILVER = 46L;

		public const long LOC_MALLY_MARKET_TIME_TRIAL_SILVER = 47L;

		public const long LOC_VALLEY_OF_THE_KINGS_TIME_TRIAL_SILVER = 48L;

		public const long LOC_MISTY_FOR_ME_TIME_TRIAL_SILVER = 49L;

		public const long LOC_SNEAK_A_PEAK_TIME_TRIAL_SILVER = 50L;

		public const long LOC_BLAZING_OASIS_TIME_TRIAL_SILVER = 51L;

		public const long LOC_PASTACOSI_FACTORY_TIME_TRIAL_SILVER = 52L;

		public const long LOC_MYSTERIOUS_TEMPLE_TIME_TRIAL_SILVER = 53L;

		public const long LOC_PROHIBITED_SITE_TIME_TRIAL_SILVER = 54L;

		public const long LOC_CASKOU_PARK_TIME_TRIAL_SILVER = 55L;

		public const long LOC_LOOPY_LAGOON_TIME_TRIAL_SILVER = 56L;

		public const long LOC_CATZ_IN_THE_HOOD_TIME_TRIAL_GOLD = 61L;

		public const long LOC_CRAZY_DUNES_TIME_TRIAL_GOLD = 62L;

		public const long LOC_PALEROCK_LAKE_TIME_TRIAL_GOLD = 63L;

		public const long LOC_CITY_SLICKER_TIME_TRIAL_GOLD = 64L;

		public const long LOC_COUNTRY_BUMPKIN_TIME_TRIAL_GOLD = 65L;

		public const long LOC_SPOOKY_MANOR_TIME_TRIAL_GOLD = 66L;

		public const long LOC_MALLY_MARKET_TIME_TRIAL_GOLD = 67L;

		public const long LOC_VALLEY_OF_THE_KINGS_TIME_TRIAL_GOLD = 68L;

		public const long LOC_MISTY_FOR_ME_TIME_TRIAL_GOLD = 69L;

		public const long LOC_SNEAK_A_PEAK_TIME_TRIAL_GOLD = 70L;

		public const long LOC_BLAZING_OASIS_TIME_TRIAL_GOLD = 71L;

		public const long LOC_PASTACOSI_FACTORY_TIME_TRIAL_GOLD = 72L;

		public const long LOC_MYSTERIOUS_TEMPLE_TIME_TRIAL_GOLD = 73L;

		public const long LOC_PROHIBITED_SITE_TIME_TRIAL_GOLD = 74L;

		public const long LOC_CASKOU_PARK_TIME_TRIAL_GOLD = 75L;

		public const long LOC_LOOPY_LAGOON_TIME_TRIAL_GOLD = 76L;

		public const long LOC_CATZ_IN_THE_HOOD_TIME_TRIAL_PLATINUM = 81L;

		public const long LOC_CRAZY_DUNES_TIME_TRIAL_PLATINUM = 82L;

		public const long LOC_PALEROCK_LAKE_TIME_TRIAL_PLATINUM = 83L;

		public const long LOC_CITY_SLICKER_TIME_TRIAL_PLATINUM = 84L;

		public const long LOC_COUNTRY_BUMPKIN_TIME_TRIAL_PLATINUM = 85L;

		public const long LOC_SPOOKY_MANOR_TIME_TRIAL_PLATINUM = 86L;

		public const long LOC_MALLY_MARKET_TIME_TRIAL_PLATINUM = 87L;

		public const long LOC_VALLEY_OF_THE_KINGS_TIME_TRIAL_PLATINUM = 88L;

		public const long LOC_MISTY_FOR_ME_TIME_TRIAL_PLATINUM = 89L;

		public const long LOC_SNEAK_A_PEAK_TIME_TRIAL_PLATINUM = 90L;

		public const long LOC_BLAZING_OASIS_TIME_TRIAL_PLATINUM = 91L;

		public const long LOC_PASTACOSI_FACTORY_TIME_TRIAL_PLATINUM = 92L;

		public const long LOC_MYSTERIOUS_TEMPLE_TIME_TRIAL_PLATINUM = 93L;

		public const long LOC_PROHIBITED_SITE_TIME_TRIAL_PLATINUM = 94L;

		public const long LOC_CASKOU_PARK_TIME_TRIAL_PLATINUM = 95L;

		public const long LOC_LOOPY_LAGOON_TIME_TRIAL_PLATINUM = 96L;

		public const long LOC_LASAGNA_CUP_VICTORY = 101L;

		public const long LOC_PIZZA_CUP_VICTORY = 102L;

		public const long LOC_BURGER_CUP_VICTORY = 103L;

		public const long LOC_ICE_CREAM_CUP_VICTORY = 104L;

		public const long LOC_CATZ_IN_THE_HOOD_PUZZLE_PIECE_1 = 201L;

		public const long LOC_CATZ_IN_THE_HOOD_PUZZLE_PIECE_2 = 202L;

		public const long LOC_CATZ_IN_THE_HOOD_PUZZLE_PIECE_3 = 203L;

		public const long LOC_CRAZY_DUNES_PUZZLE_PIECE_1 = 204L;

		public const long LOC_CRAZY_DUNES_PUZZLE_PIECE_2 = 205L;

		public const long LOC_CRAZY_DUNES_PUZZLE_PIECE_3 = 206L;

		public const long LOC_PALEROCK_LAKE_PUZZLE_PIECE_1 = 207L;

		public const long LOC_PALEROCK_LAKE_PUZZLE_PIECE_2 = 208L;

		public const long LOC_PALEROCK_LAKE_PUZZLE_PIECE_3 = 209L;

		public const long LOC_CITY_SLICKER_PUZZLE_PIECE_1 = 210L;

		public const long LOC_CITY_SLICKER_PUZZLE_PIECE_2 = 211L;

		public const long LOC_CITY_SLICKER_PUZZLE_PIECE_3 = 212L;

		public const long LOC_COUNTRY_BUMPKIN_PUZZLE_PIECE_1 = 213L;

		public const long LOC_COUNTRY_BUMPKIN_PUZZLE_PIECE_2 = 214L;

		public const long LOC_COUNTRY_BUMPKIN_PUZZLE_PIECE_3 = 215L;

		public const long LOC_SPOOKY_MANOR_PUZZLE_PIECE_1 = 216L;

		public const long LOC_SPOOKY_MANOR_PUZZLE_PIECE_2 = 217L;

		public const long LOC_SPOOKY_MANOR_PUZZLE_PIECE_3 = 218L;

		public const long LOC_MALLY_MARKET_PUZZLE_PIECE_1 = 219L;

		public const long LOC_MALLY_MARKET_PUZZLE_PIECE_2 = 220L;

		public const long LOC_MALLY_MARKET_PUZZLE_PIECE_3 = 221L;

		public const long LOC_VALLEY_OF_THE_KINGS_PUZZLE_PIECE_1 = 222L;

		public const long LOC_VALLEY_OF_THE_KINGS_PUZZLE_PIECE_2 = 223L;

		public const long LOC_VALLEY_OF_THE_KINGS_PUZZLE_PIECE_3 = 224L;

		public const long LOC_MISTY_FOR_ME_PUZZLE_PIECE_1 = 225L;

		public const long LOC_MISTY_FOR_ME_PUZZLE_PIECE_2 = 226L;

		public const long LOC_MISTY_FOR_ME_PUZZLE_PIECE_3 = 227L;

		public const long LOC_SNEAK_A_PEAK_PUZZLE_PIECE_1 = 228L;

		public const long LOC_SNEAK_A_PEAK_PUZZLE_PIECE_2 = 229L;

		public const long LOC_SNEAK_A_PEAK_PUZZLE_PIECE_3 = 230L;

		public const long LOC_BLAZING_OASIS_PUZZLE_PIECE_1 = 231L;

		public const long LOC_BLAZING_OASIS_PUZZLE_PIECE_2 = 232L;

		public const long LOC_BLAZING_OASIS_PUZZLE_PIECE_3 = 233L;

		public const long LOC_PASTACOSI_FACTORY_PUZZLE_PIECE_1 = 234L;

		public const long LOC_PASTACOSI_FACTORY_PUZZLE_PIECE_2 = 235L;

		public const long LOC_PASTACOSI_FACTORY_PUZZLE_PIECE_3 = 236L;

		public const long LOC_MYSTERIOUS_TEMPLE_PUZZLE_PIECE_1 = 237L;

		public const long LOC_MYSTERIOUS_TEMPLE_PUZZLE_PIECE_2 = 238L;

		public const long LOC_MYSTERIOUS_TEMPLE_PUZZLE_PIECE_3 = 239L;

		public const long LOC_PROHIBITED_SITE_PUZZLE_PIECE_1 = 240L;

		public const long LOC_PROHIBITED_SITE_PUZZLE_PIECE_2 = 241L;

		public const long LOC_PROHIBITED_SITE_PUZZLE_PIECE_3 = 242L;

		public const long LOC_CASKOU_PARK_PUZZLE_PIECE_1 = 243L;

		public const long LOC_CASKOU_PARK_PUZZLE_PIECE_2 = 244L;

		public const long LOC_CASKOU_PARK_PUZZLE_PIECE_3 = 245L;

		public const long LOC_LOOPY_LAGOON_PUZZLE_PIECE_1 = 246L;

		public const long LOC_LOOPY_LAGOON_PUZZLE_PIECE_2 = 247L;

		public const long LOC_LOOPY_LAGOON_PUZZLE_PIECE_3 = 248L;

		public const long LOC_LASAGNA_CUP_UNLOCK_SPOILER_1 = 301L;

		public const long LOC_PIZZA_CUP_UNLOCK_SPOILER_1 = 302L;

		public const long LOC_BURGER_CUP_UNLOCK_SPOILER_1 = 303L;

		public const long LOC_ICE_CREAM_CUP_UNLOCK_SPOILER_1 = 304L;

		public const long LOC_LASAGNA_CUP_UNLOCK_SPOILER_2 = 311L;

		public const long LOC_PIZZA_CUP_UNLOCK_SPOILER_2 = 312L;

		public const long LOC_BURGER_CUP_UNLOCK_SPOILER_2 = 313L;

		public const long LOC_ICE_CREAM_CUP_UNLOCK_SPOILER_2 = 314L;

		public const long LOC_LASAGNA_CUP_UNLOCK_BRONZE_SPOILER_1 = 321L;

		public const long LOC_PIZZA_CUP_UNLOCK_BRONZE_SPOILER_1 = 322L;

		public const long LOC_BURGER_CUP_UNLOCK_BRONZE_SPOILER_1 = 323L;

		public const long LOC_ICE_CREAM_CUP_UNLOCK_BRONZE_SPOILER_1 = 324L;

		public const long LOC_LASAGNA_CUP_UNLOCK_BRONZE_SPOILER_2 = 331L;

		public const long LOC_PIZZA_CUP_UNLOCK_BRONZE_SPOILER_2 = 332L;

		public const long LOC_BURGER_CUP_UNLOCK_BRONZE_SPOILER_2 = 333L;

		public const long LOC_ICE_CREAM_CUP_UNLOCK_BRONZE_SPOILER_2 = 334L;

		public const long LOC_LASAGNA_CUP_UNLOCK_SILVER_SPOILER_1 = 341L;

		public const long LOC_PIZZA_CUP_UNLOCK_SILVER_SPOILER_1 = 342L;

		public const long LOC_BURGER_CUP_UNLOCK_SILVER_SPOILER_1 = 343L;

		public const long LOC_ICE_CREAM_CUP_UNLOCK_SILVER_SPOILER_1 = 344L;

		public const long LOC_LASAGNA_CUP_UNLOCK_SILVER_SPOILER_2 = 351L;

		public const long LOC_PIZZA_CUP_UNLOCK_SILVER_SPOILER_2 = 352L;

		public const long LOC_BURGER_CUP_UNLOCK_SILVER_SPOILER_2 = 353L;

		public const long LOC_ICE_CREAM_CUP_UNLOCK_SILVER_SPOILER_2 = 354L;

		public const long LOC_LASAGNA_CUP_UNLOCK_GOLD_SPOILER_1 = 361L;

		public const long LOC_PIZZA_CUP_UNLOCK_GOLD_SPOILER_1 = 362L;

		public const long LOC_BURGER_CUP_UNLOCK_GOLD_SPOILER_1 = 363L;

		public const long LOC_ICE_CREAM_CUP_UNLOCK_GOLD_SPOILER_1 = 364L;

		public const long LOC_LASAGNA_CUP_UNLOCK_GOLD_SPOILER_2 = 371L;

		public const long LOC_PIZZA_CUP_UNLOCK_GOLD_SPOILER_2 = 372L;

		public const long LOC_BURGER_CUP_UNLOCK_GOLD_SPOILER_2 = 373L;

		public const long LOC_ICE_CREAM_CUP_UNLOCK_GOLD_SPOILER_2 = 374L;

		public const long LOC_CATZ_IN_THE_HOOD_HAT_UNLOCK = 401L;

		public const long LOC_CRAZY_DUNES_HAT_UNLOCK = 402L;

		public const long LOC_PALEROCK_LAKE_HAT_UNLOCK = 403L;

		public const long LOC_CITY_SLICKER_HAT_UNLOCK = 404L;

		public const long LOC_COUNTRY_BUMPKIN_HAT_UNLOCK = 405L;

		public const long LOC_SPOOKY_MANOR_HAT_UNLOCK = 406L;

		public const long LOC_MALLY_MARKET_HAT_UNLOCK = 407L;

		public const long LOC_VALLEY_OF_THE_KINGS_HAT_UNLOCK = 408L;

		public const long LOC_MISTY_FOR_ME_HAT_UNLOCK = 409L;

		public const long LOC_SNEAK_A_PEAK_HAT_UNLOCK = 410L;

		public const long LOC_BLAZING_OASIS_HAT_UNLOCK = 411L;

		public const long LOC_PASTACOSI_FACTORY_HAT_UNLOCK = 412L;

		public const long LOC_MYSTERIOUS_TEMPLE_HAT_UNLOCK = 413L;

		public const long LOC_PROHIBITED_SITE_HAT_UNLOCK = 414L;

		public const long LOC_CASKOU_PARK_HAT_UNLOCK = 415L;

		public const long LOC_LOOPY_LAGOON_HAT_UNLOCK = 416L;

		public const long LOC_CATZ_IN_THE_HOOD_BRONZE_HAT_UNLOCK = 421L;

		public const long LOC_CRAZY_DUNES_BRONZE_HAT_UNLOCK = 422L;

		public const long LOC_PALEROCK_LAKE_BRONZE_HAT_UNLOCK = 423L;

		public const long LOC_CITY_SLICKER_BRONZE_HAT_UNLOCK = 424L;

		public const long LOC_COUNTRY_BUMPKIN_BRONZE_HAT_UNLOCK = 425L;

		public const long LOC_SPOOKY_MANOR_BRONZE_HAT_UNLOCK = 426L;

		public const long LOC_MALLY_MARKET_BRONZE_HAT_UNLOCK = 427L;

		public const long LOC_VALLEY_OF_THE_KINGS_BRONZE_HAT_UNLOCK = 428L;

		public const long LOC_MISTY_FOR_ME_BRONZE_HAT_UNLOCK = 429L;

		public const long LOC_SNEAK_A_PEAK_BRONZE_HAT_UNLOCK = 430L;

		public const long LOC_BLAZING_OASIS_BRONZE_HAT_UNLOCK = 431L;

		public const long LOC_PASTACOSI_FACTORY_BRONZE_HAT_UNLOCK = 432L;

		public const long LOC_MYSTERIOUS_TEMPLE_BRONZE_HAT_UNLOCK = 433L;

		public const long LOC_PROHIBITED_SITE_BRONZE_HAT_UNLOCK = 434L;

		public const long LOC_CASKOU_PARK_BRONZE_HAT_UNLOCK = 435L;

		public const long LOC_LOOPY_LAGOON_BRONZE_HAT_UNLOCK = 436L;

		public const long LOC_CATZ_IN_THE_HOOD_SILVER_HAT_UNLOCK = 441L;

		public const long LOC_CRAZY_DUNES_SILVER_HAT_UNLOCK = 442L;

		public const long LOC_PALEROCK_LAKE_SILVER_HAT_UNLOCK = 443L;

		public const long LOC_CITY_SLICKER_SILVER_HAT_UNLOCK = 444L;

		public const long LOC_COUNTRY_BUMPKIN_SILVER_HAT_UNLOCK = 445L;

		public const long LOC_SPOOKY_MANOR_SILVER_HAT_UNLOCK = 446L;

		public const long LOC_MALLY_MARKET_SILVER_HAT_UNLOCK = 447L;

		public const long LOC_VALLEY_OF_THE_KINGS_SILVER_HAT_UNLOCK = 448L;

		public const long LOC_MISTY_FOR_ME_SILVER_HAT_UNLOCK = 449L;

		public const long LOC_SNEAK_A_PEAK_SILVER_HAT_UNLOCK = 450L;

		public const long LOC_BLAZING_OASIS_SILVER_HAT_UNLOCK = 451L;

		public const long LOC_PASTACOSI_FACTORY_SILVER_HAT_UNLOCK = 452L;

		public const long LOC_MYSTERIOUS_TEMPLE_SILVER_HAT_UNLOCK = 453L;

		public const long LOC_PROHIBITED_SITE_SILVER_HAT_UNLOCK = 454L;

		public const long LOC_CASKOU_PARK_SILVER_HAT_UNLOCK = 455L;

		public const long LOC_LOOPY_LAGOON_SILVER_HAT_UNLOCK = 456L;

		public const long LOC_CATZ_IN_THE_HOOD_GOLD_HAT_UNLOCK = 461L;

		public const long LOC_CRAZY_DUNES_GOLD_HAT_UNLOCK = 462L;

		public const long LOC_PALEROCK_LAKE_GOLD_HAT_UNLOCK = 463L;

		public const long LOC_CITY_SLICKER_GOLD_HAT_UNLOCK = 464L;

		public const long LOC_COUNTRY_BUMPKIN_GOLD_HAT_UNLOCK = 465L;

		public const long LOC_SPOOKY_MANOR_GOLD_HAT_UNLOCK = 466L;

		public const long LOC_MALLY_MARKET_GOLD_HAT_UNLOCK = 467L;

		public const long LOC_VALLEY_OF_THE_KINGS_GOLD_HAT_UNLOCK = 468L;

		public const long LOC_MISTY_FOR_ME_GOLD_HAT_UNLOCK = 469L;

		public const long LOC_SNEAK_A_PEAK_GOLD_HAT_UNLOCK = 470L;

		public const long LOC_BLAZING_OASIS_GOLD_HAT_UNLOCK = 471L;

		public const long LOC_PASTACOSI_FACTORY_GOLD_HAT_UNLOCK = 472L;

		public const long LOC_MYSTERIOUS_TEMPLE_GOLD_HAT_UNLOCK = 473L;

		public const long LOC_PROHIBITED_SITE_GOLD_HAT_UNLOCK = 474L;

		public const long LOC_CASKOU_PARK_GOLD_HAT_UNLOCK = 475L;

		public const long LOC_LOOPY_LAGOON_GOLD_HAT_UNLOCK = 476L;

		public const long LOC_WIN_RACE_AS_GARFIELD = 1001L;

		public const long LOC_WIN_RACE_AS_JON = 1002L;

		public const long LOC_WIN_RACE_AS_LIZ = 1003L;

		public const long LOC_WIN_RACE_AS_ODIE = 1004L;

		public const long LOC_WIN_RACE_AS_ARLENE = 1005L;

		public const long LOC_WIN_RACE_AS_NERMAL = 1006L;

		public const long LOC_WIN_RACE_AS_SQUEAK = 1007L;

		public const long LOC_WIN_RACE_AS_HARRY = 1008L;

		public const long LOC_WIN_RACE_WITH_FORMULA_ZZZZ = 1051L;

		public const long LOC_WIN_RACE_WITH_ABSTRACT_KART = 1052L;

		public const long LOC_WIN_RACE_WITH_MEDI_KART = 1053L;

		public const long LOC_WIN_RACE_WITH_WOOF_MOBILE = 1054L;

		public const long LOC_WIN_RACE_WITH_KISSY_KART = 1055L;

		public const long LOC_WIN_RACE_WITH_CUTIE_PIE_CAT = 1056L;

		public const long LOC_WIN_RACE_WITH_RAT_RACER = 1057L;

		public const long LOC_WIN_RACE_WITH_MUCK_MADNESS = 1058L;

		public const long LOC_FIND_ITEM_PIE = 1101L;

		public const long LOC_FIND_ITEM_HOMING_PIE = 1102L;

		public const long LOC_FIND_ITEM_DIAMOND = 1103L;

		public const long LOC_FIND_ITEM_MAGIC_WAND = 1104L;

		public const long LOC_FIND_ITEM_PERFUME = 1105L;

		public const long LOC_FIND_ITEM_LASAGNA = 1106L;

		public const long LOC_FIND_ITEM_UFO = 1107L;

		public const long LOC_FIND_ITEM_PILLOW = 1108L;

		public const long LOC_FIND_ITEM_SPRING = 1109L;

		public const long ITEM_CATZ_IN_THE_HOOD_PUZZLE_PIECE_1 = 1L;

		public const long ITEM_CATZ_IN_THE_HOOD_PUZZLE_PIECE_2 = 2L;

		public const long ITEM_CATZ_IN_THE_HOOD_PUZZLE_PIECE_3 = 3L;

		public const long ITEM_CRAZY_DUNES_PUZZLE_PIECE_1 = 4L;

		public const long ITEM_CRAZY_DUNES_PUZZLE_PIECE_2 = 5L;

		public const long ITEM_CRAZY_DUNES_PUZZLE_PIECE_3 = 6L;

		public const long ITEM_PALEROCK_LAKE_PUZZLE_PIECE_1 = 7L;

		public const long ITEM_PALEROCK_LAKE_PUZZLE_PIECE_2 = 8L;

		public const long ITEM_PALEROCK_LAKE_PUZZLE_PIECE_3 = 9L;

		public const long ITEM_CITY_SLICKER_PUZZLE_PIECE_1 = 10L;

		public const long ITEM_CITY_SLICKER_PUZZLE_PIECE_2 = 11L;

		public const long ITEM_CITY_SLICKER_PUZZLE_PIECE_3 = 12L;

		public const long ITEM_COUNTRY_BUMPKIN_PUZZLE_PIECE_1 = 13L;

		public const long ITEM_COUNTRY_BUMPKIN_PUZZLE_PIECE_2 = 14L;

		public const long ITEM_COUNTRY_BUMPKIN_PUZZLE_PIECE_3 = 15L;

		public const long ITEM_SPOOKY_MANOR_PUZZLE_PIECE_1 = 16L;

		public const long ITEM_SPOOKY_MANOR_PUZZLE_PIECE_2 = 17L;

		public const long ITEM_SPOOKY_MANOR_PUZZLE_PIECE_3 = 18L;

		public const long ITEM_MALLY_MARKET_PUZZLE_PIECE_1 = 19L;

		public const long ITEM_MALLY_MARKET_PUZZLE_PIECE_2 = 20L;

		public const long ITEM_MALLY_MARKET_PUZZLE_PIECE_3 = 21L;

		public const long ITEM_VALLEY_OF_THE_KINGS_PUZZLE_PIECE_1 = 22L;

		public const long ITEM_VALLEY_OF_THE_KINGS_PUZZLE_PIECE_2 = 23L;

		public const long ITEM_VALLEY_OF_THE_KINGS_PUZZLE_PIECE_3 = 24L;

		public const long ITEM_MISTY_FOR_ME_PUZZLE_PIECE_1 = 25L;

		public const long ITEM_MISTY_FOR_ME_PUZZLE_PIECE_2 = 26L;

		public const long ITEM_MISTY_FOR_ME_PUZZLE_PIECE_3 = 27L;

		public const long ITEM_SNEAK_A_PEAK_PUZZLE_PIECE_1 = 28L;

		public const long ITEM_SNEAK_A_PEAK_PUZZLE_PIECE_2 = 29L;

		public const long ITEM_SNEAK_A_PEAK_PUZZLE_PIECE_3 = 30L;

		public const long ITEM_BLAZING_OASIS_PUZZLE_PIECE_1 = 31L;

		public const long ITEM_BLAZING_OASIS_PUZZLE_PIECE_2 = 32L;

		public const long ITEM_BLAZING_OASIS_PUZZLE_PIECE_3 = 33L;

		public const long ITEM_PASTACOSI_FACTORY_PUZZLE_PIECE_1 = 34L;

		public const long ITEM_PASTACOSI_FACTORY_PUZZLE_PIECE_2 = 35L;

		public const long ITEM_PASTACOSI_FACTORY_PUZZLE_PIECE_3 = 36L;

		public const long ITEM_MYSTERIOUS_TEMPLE_PUZZLE_PIECE_1 = 37L;

		public const long ITEM_MYSTERIOUS_TEMPLE_PUZZLE_PIECE_2 = 38L;

		public const long ITEM_MYSTERIOUS_TEMPLE_PUZZLE_PIECE_3 = 39L;

		public const long ITEM_PROHIBITED_SITE_PUZZLE_PIECE_1 = 40L;

		public const long ITEM_PROHIBITED_SITE_PUZZLE_PIECE_2 = 41L;

		public const long ITEM_PROHIBITED_SITE_PUZZLE_PIECE_3 = 42L;

		public const long ITEM_CASKOU_PARK_PUZZLE_PIECE_1 = 43L;

		public const long ITEM_CASKOU_PARK_PUZZLE_PIECE_2 = 44L;

		public const long ITEM_CASKOU_PARK_PUZZLE_PIECE_3 = 45L;

		public const long ITEM_LOOPY_LAGOON_PUZZLE_PIECE_1 = 46L;

		public const long ITEM_LOOPY_LAGOON_PUZZLE_PIECE_2 = 47L;

		public const long ITEM_LOOPY_LAGOON_PUZZLE_PIECE_3 = 48L;

		public const long ITEM_PROGRESSIVE_COURSE_UNLOCK = 100L;

		public const long ITEM_COURSE_UNLOCK_CATZ_IN_THE_HOOD = 101L;

		public const long ITEM_COURSE_UNLOCK_CRAZY_DUNES = 102L;

		public const long ITEM_COURSE_UNLOCK_PALEROCK_LAKE = 103L;

		public const long ITEM_COURSE_UNLOCK_CITY_SLICKER = 104L;

		public const long ITEM_COURSE_UNLOCK_COUNTRY_BUMPKIN = 105L;

		public const long ITEM_COURSE_UNLOCK_SPOOKY_MANOR = 106L;

		public const long ITEM_COURSE_UNLOCK_MALLY_MARKET = 107L;

		public const long ITEM_COURSE_UNLOCK_VALLEY_OF_THE_KINGS = 108L;

		public const long ITEM_COURSE_UNLOCK_MISTY_FOR_ME = 109L;

		public const long ITEM_COURSE_UNLOCK_SNEAK_A_PEAK = 110L;

		public const long ITEM_COURSE_UNLOCK_BLAZING_OASIS = 111L;

		public const long ITEM_COURSE_UNLOCK_PASTACOSI_FACTORY = 112L;

		public const long ITEM_COURSE_UNLOCK_MYSTERIOUS_TEMPLE = 113L;

		public const long ITEM_COURSE_UNLOCK_PROHIBITED_SITE = 114L;

		public const long ITEM_COURSE_UNLOCK_CASKOU_PARK = 115L;

		public const long ITEM_COURSE_UNLOCK_LOOPY_LAGOON = 116L;

		public const long ITEM_PROGRESSIVE_TIME_TRIAL_UNLOCK = 150L;

		public const long ITEM_TIME_TRIAL_UNLOCK_CATZ_IN_THE_HOOD = 151L;

		public const long ITEM_TIME_TRIAL_UNLOCK_CRAZY_DUNES = 152L;

		public const long ITEM_TIME_TRIAL_UNLOCK_PALEROCK_LAKE = 153L;

		public const long ITEM_TIME_TRIAL_UNLOCK_CITY_SLICKER = 154L;

		public const long ITEM_TIME_TRIAL_UNLOCK_COUNTRY_BUMPKIN = 155L;

		public const long ITEM_TIME_TRIAL_UNLOCK_SPOOKY_MANOR = 156L;

		public const long ITEM_TIME_TRIAL_UNLOCK_MALLY_MARKET = 157L;

		public const long ITEM_TIME_TRIAL_UNLOCK_VALLEY_OF_THE_KINGS = 158L;

		public const long ITEM_TIME_TRIAL_UNLOCK_MISTY_FOR_ME = 159L;

		public const long ITEM_TIME_TRIAL_UNLOCK_SNEAK_A_PEAK = 160L;

		public const long ITEM_TIME_TRIAL_UNLOCK_BLAZING_OASIS = 161L;

		public const long ITEM_TIME_TRIAL_UNLOCK_PASTACOSI_FACTORY = 162L;

		public const long ITEM_TIME_TRIAL_UNLOCK_MYSTERIOUS_TEMPLE = 163L;

		public const long ITEM_TIME_TRIAL_UNLOCK_PROHIBITED_SITE = 164L;

		public const long ITEM_TIME_TRIAL_UNLOCK_CASKOU_PARK = 165L;

		public const long ITEM_TIME_TRIAL_UNLOCK_LOOPY_LAGOON = 166L;

		public const long ITEM_PROGRESSIVE_CUP_UNLOCK = 200L;

		public const long ITEM_CUP_UNLOCK_LASAGNA = 201L;

		public const long ITEM_CUP_UNLOCK_PIZZA = 202L;

		public const long ITEM_CUP_UNLOCK_BURGER = 203L;

		public const long ITEM_CUP_UNLOCK_ICE_CREAM = 204L;

		public const long ITEM_CHARACTER_GARFIELD = 301L;

		public const long ITEM_CHARACTER_JON = 302L;

		public const long ITEM_CHARACTER_LIZ = 303L;

		public const long ITEM_CHARACTER_ODIE = 304L;

		public const long ITEM_CHARACTER_ARLENE = 305L;

		public const long ITEM_CHARACTER_NERMAL = 306L;

		public const long ITEM_CHARACTER_SQUEAK = 307L;

		public const long ITEM_CHARACTER_HARRY = 308L;

		public const long ITEM_KART_FORMULA_ZZZZ = 351L;

		public const long ITEM_KART_ABSTRACT_KART = 352L;

		public const long ITEM_KART_MEDI_KART = 353L;

		public const long ITEM_KART_WOOF_MOBILE = 354L;

		public const long ITEM_KART_KISSY_KART = 355L;

		public const long ITEM_KART_CUTIE_PIE_CAT = 356L;

		public const long ITEM_KART_RAT_RACER = 357L;

		public const long ITEM_KART_MUCK_MADNESS = 358L;

		public const long ITEM_PROGRESSIVE_BEDDY_BYE_CAP = 401L;

		public const long ITEM_PROGRESSIVE_WHIZZY_WIZARD = 402L;

		public const long ITEM_PROGRESSIVE_TIC_TOQUE = 403L;

		public const long ITEM_PROGRESSIVE_ELASTO_HAT = 404L;

		public const long ITEM_PROGRESSIVE_CHEFS_SPECIAL = 405L;

		public const long ITEM_PROGRESSIVE_CUTIE_PIE_CROWN = 406L;

		public const long ITEM_PROGRESSIVE_VIKING_HELMET = 407L;

		public const long ITEM_PROGRESSIVE_STINK_O_RAMA = 408L;

		public const long ITEM_PROGRESSIVE_SPACE_BUBBLE = 409L;

		public const long ITEM_PROGRESSIVE_PIZZAIOLO_HAT = 410L;

		public const long ITEM_PROGRESSIVE_BUNNY_BAND = 411L;

		public const long ITEM_PROGRESSIVE_JOE_MONTAGNA = 412L;

		public const long ITEM_PROGRESSIVE_ARISTO_CATIC_BICORN = 413L;

		public const long ITEM_PROGRESSIVE_TOUTANKHAMEOW = 414L;

		public const long ITEM_PROGRESSIVE_APPRENTICE_SORCERER = 415L;

		public const long ITEM_PROGRESSIVE_MULE_HEAD = 416L;

		public const long ITEM_UNLOCK_BEDDY_BYE_CAP = 421L;

		public const long ITEM_UNLOCK_WHIZZY_WIZARD = 422L;

		public const long ITEM_UNLOCK_TIC_TOQUE = 423L;

		public const long ITEM_UNLOCK_ELASTO_HAT = 424L;

		public const long ITEM_UNLOCK_CHEFS_SPECIAL = 425L;

		public const long ITEM_UNLOCK_CUTIE_PIE_CROWN = 426L;

		public const long ITEM_UNLOCK_VIKING_HELMET = 427L;

		public const long ITEM_UNLOCK_STINK_O_RAMA = 428L;

		public const long ITEM_UNLOCK_SPACE_BUBBLE = 429L;

		public const long ITEM_UNLOCK_PIZZAIOLO_HAT = 430L;

		public const long ITEM_UNLOCK_BUNNY_BAND = 431L;

		public const long ITEM_UNLOCK_JOE_MONTAGNA = 432L;

		public const long ITEM_UNLOCK_ARISTO_CATIC_BICORN = 433L;

		public const long ITEM_UNLOCK_TOUTANKHAMEOW = 434L;

		public const long ITEM_UNLOCK_APPRENTICE_SORCERER = 435L;

		public const long ITEM_UNLOCK_MULE_HEAD = 436L;

		public const long ITEM_PROGRESSIVE_BOMBASTIC_SPOILER = 501L;

		public const long ITEM_PROGRESSIVE_WHACKY_SPOILER = 502L;

		public const long ITEM_PROGRESSIVE_SUPERFIT_SPOILER = 503L;

		public const long ITEM_PROGRESSIVE_CYCLOBONE_SPOILER = 504L;

		public const long ITEM_PROGRESSIVE_FOXY_SPOILER = 505L;

		public const long ITEM_PROGRESSIVE_SHIMMERING_SPOILER = 506L;

		public const long ITEM_PROGRESSIVE_HOLEY_MOLEY_SPOILER = 507L;

		public const long ITEM_PROGRESSIVE_STAINED_SPOILER = 508L;

		public const long ITEM_UNLOCK_BOMBASTIC_SPOILER = 521L;

		public const long ITEM_UNLOCK_WHACKY_SPOILER = 522L;

		public const long ITEM_UNLOCK_SUPERFIT_SPOILER = 523L;

		public const long ITEM_UNLOCK_CYCLOBONE_SPOILER = 524L;

		public const long ITEM_UNLOCK_FOXY_SPOILER = 525L;

		public const long ITEM_UNLOCK_SHIMMERING_SPOILER = 526L;

		public const long ITEM_UNLOCK_HOLEY_MOLEY_SPOILER = 527L;

		public const long ITEM_UNLOCK_STAINED_SPOILER = 528L;

		public const long ITEM_PIE = 901L;

		public const long ITEM_HOMING_PIE = 902L;

		public const long ITEM_DIAMOND = 903L;

		public const long ITEM_MAGIC_WAND = 904L;

		public const long ITEM_PERFUME = 905L;

		public const long ITEM_LASAGNA = 906L;

		public const long ITEM_UFO = 907L;

		public const long ITEM_PILLOW = 908L;

		public const long ITEM_SPRING = 909L;

		public const long ITEM_FILLER = 1000L;

		public const long ITEM_GIVE_ITEM_FILLER = 1001L;

		public const long ITEM_TRAP = 1500L;

		public const long ITEM_HANDLING_TRAP = 1501L;

		public const long GOAL_GRAND_PRIX = 0L;

		public const long GOAL_RACES = 1L;

		public const long GOAL_TIME_TRIALS = 2L;

		public const long GOAL_PUZZLE_PIECE = 3L;

		public const long OPTION_RANDOMIZE_RACES_CUPS = 0L;

		public const long OPTION_RANDOMIZE_RACES_RACES = 1L;

		public const long OPTION_RANDOMIZE_RACES_BOTH = 2L;

		public const long OPTION_RANDOMIZE_HATS_SPOILERS_OFF = 0L;

		public const long OPTION_RANDOMIZE_HATS_SPOILERS_PROG = 1L;

		public const long OPTION_RANDOMIZE_HATS_SPOILERS_COMBINE = 2L;

		public static string GetSceneNameFromTrackId(TrackId trackId)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected I4, but got Unknown
			return (int)trackId switch
			{
				4 => "E2C1", 
				12 => "E4C1", 
				8 => "E3C1", 
				0 => "E1C1", 
				9 => "E3C2", 
				5 => "E2C2", 
				1 => "E1C2", 
				13 => "E4C2", 
				2 => "E1C3", 
				10 => "E3C3", 
				14 => "E4C3", 
				6 => "E2C3", 
				15 => "E4C4", 
				3 => "E1C4", 
				7 => "E2C4", 
				11 => "E3C4", 
				_ => null, 
			};
		}

		public static long GetRaceVictoryLoc(string startScene)
		{
			return startScene switch
			{
				"E2C1" => 1L, 
				"E4C1" => 2L, 
				"E3C1" => 3L, 
				"E1C1" => 4L, 
				"E3C2" => 5L, 
				"E2C2" => 6L, 
				"E1C2" => 7L, 
				"E4C2" => 8L, 
				"E1C3" => 9L, 
				"E3C3" => 10L, 
				"E4C3" => 11L, 
				"E2C3" => 12L, 
				"E4C4" => 13L, 
				"E1C4" => 14L, 
				"E2C4" => 15L, 
				"E3C4" => 16L, 
				_ => -1L, 
			};
		}

		public static long GetPuzzlePiece(string startScene, int puzzleIndex)
		{
			return startScene switch
			{
				"E2C1" => 1L + (long)puzzleIndex, 
				"E4C1" => 4L + (long)puzzleIndex, 
				"E3C1" => 7L + (long)puzzleIndex, 
				"E1C1" => 10L + (long)puzzleIndex, 
				"E3C2" => 13L + (long)puzzleIndex, 
				"E2C2" => 16L + (long)puzzleIndex, 
				"E1C2" => 19L + (long)puzzleIndex, 
				"E4C2" => 22L + (long)puzzleIndex, 
				"E1C3" => 25L + (long)puzzleIndex, 
				"E3C3" => 28L + (long)puzzleIndex, 
				"E4C3" => 31L + (long)puzzleIndex, 
				"E2C3" => 34L + (long)puzzleIndex, 
				"E4C4" => 37L + (long)puzzleIndex, 
				"E1C4" => 40L + (long)puzzleIndex, 
				"E2C4" => 43L + (long)puzzleIndex, 
				"E3C4" => 46L + (long)puzzleIndex, 
				_ => -1L, 
			};
		}

		public static long GetPuzzlePieceLoc(string startScene, int puzzleIndex)
		{
			return startScene switch
			{
				"E2C1" => 201L + (long)puzzleIndex, 
				"E4C1" => 204L + (long)puzzleIndex, 
				"E3C1" => 207L + (long)puzzleIndex, 
				"E1C1" => 210L + (long)puzzleIndex, 
				"E3C2" => 213L + (long)puzzleIndex, 
				"E2C2" => 216L + (long)puzzleIndex, 
				"E1C2" => 219L + (long)puzzleIndex, 
				"E4C2" => 222L + (long)puzzleIndex, 
				"E1C3" => 225L + (long)puzzleIndex, 
				"E3C3" => 228L + (long)puzzleIndex, 
				"E4C3" => 231L + (long)puzzleIndex, 
				"E2C3" => 234L + (long)puzzleIndex, 
				"E4C4" => 237L + (long)puzzleIndex, 
				"E1C4" => 240L + (long)puzzleIndex, 
				"E2C4" => 243L + (long)puzzleIndex, 
				"E3C4" => 246L + (long)puzzleIndex, 
				_ => -1L, 
			};
		}

		public static List<long> GetTimeTrialLocs(string startScene, E_TimeTrialMedal medal)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Expected I4, but got Unknown
			int num = (int)medal;
			List<long> list = new List<long>();
			if (num == 0)
			{
				return list;
			}
			switch (startScene)
			{
			case "E2C1":
				if (num >= 1)
				{
					list.Add(21L);
				}
				if (num >= 2)
				{
					list.Add(41L);
				}
				if (num >= 3)
				{
					list.Add(61L);
				}
				if (num >= 4)
				{
					list.Add(81L);
				}
				break;
			case "E4C1":
				if (num >= 1)
				{
					list.Add(22L);
				}
				if (num >= 2)
				{
					list.Add(42L);
				}
				if (num >= 3)
				{
					list.Add(62L);
				}
				if (num >= 4)
				{
					list.Add(82L);
				}
				break;
			case "E3C1":
				if (num >= 1)
				{
					list.Add(23L);
				}
				if (num >= 2)
				{
					list.Add(43L);
				}
				if (num >= 3)
				{
					list.Add(63L);
				}
				if (num >= 4)
				{
					list.Add(83L);
				}
				break;
			case "E1C1":
				if (num >= 1)
				{
					list.Add(24L);
				}
				if (num >= 2)
				{
					list.Add(44L);
				}
				if (num >= 3)
				{
					list.Add(64L);
				}
				if (num >= 4)
				{
					list.Add(84L);
				}
				break;
			case "E3C2":
				if (num >= 1)
				{
					list.Add(25L);
				}
				if (num >= 2)
				{
					list.Add(45L);
				}
				if (num >= 3)
				{
					list.Add(65L);
				}
				if (num >= 4)
				{
					list.Add(85L);
				}
				break;
			case "E2C2":
				if (num >= 1)
				{
					list.Add(26L);
				}
				if (num >= 2)
				{
					list.Add(46L);
				}
				if (num >= 3)
				{
					list.Add(66L);
				}
				if (num >= 4)
				{
					list.Add(86L);
				}
				break;
			case "E1C2":
				if (num >= 1)
				{
					list.Add(27L);
				}
				if (num >= 2)
				{
					list.Add(47L);
				}
				if (num >= 3)
				{
					list.Add(67L);
				}
				if (num >= 4)
				{
					list.Add(87L);
				}
				break;
			case "E4C2":
				if (num >= 1)
				{
					list.Add(28L);
				}
				if (num >= 2)
				{
					list.Add(48L);
				}
				if (num >= 3)
				{
					list.Add(68L);
				}
				if (num >= 4)
				{
					list.Add(88L);
				}
				break;
			case "E1C3":
				if (num >= 1)
				{
					list.Add(29L);
				}
				if (num >= 2)
				{
					list.Add(49L);
				}
				if (num >= 3)
				{
					list.Add(69L);
				}
				if (num >= 4)
				{
					list.Add(89L);
				}
				break;
			case "E3C3":
				if (num >= 1)
				{
					list.Add(30L);
				}
				if (num >= 2)
				{
					list.Add(50L);
				}
				if (num >= 3)
				{
					list.Add(70L);
				}
				if (num >= 4)
				{
					list.Add(90L);
				}
				break;
			case "E4C3":
				if (num >= 1)
				{
					list.Add(31L);
				}
				if (num >= 2)
				{
					list.Add(51L);
				}
				if (num >= 3)
				{
					list.Add(71L);
				}
				if (num >= 4)
				{
					list.Add(91L);
				}
				break;
			case "E2C3":
				if (num >= 1)
				{
					list.Add(32L);
				}
				if (num >= 2)
				{
					list.Add(52L);
				}
				if (num >= 3)
				{
					list.Add(72L);
				}
				if (num >= 4)
				{
					list.Add(92L);
				}
				break;
			case "E4C4":
				if (num >= 1)
				{
					list.Add(33L);
				}
				if (num >= 2)
				{
					list.Add(53L);
				}
				if (num >= 3)
				{
					list.Add(73L);
				}
				if (num >= 4)
				{
					list.Add(93L);
				}
				break;
			case "E1C4":
				if (num >= 1)
				{
					list.Add(34L);
				}
				if (num >= 2)
				{
					list.Add(54L);
				}
				if (num >= 3)
				{
					list.Add(74L);
				}
				if (num >= 4)
				{
					list.Add(94L);
				}
				break;
			case "E2C4":
				if (num >= 1)
				{
					list.Add(35L);
				}
				if (num >= 2)
				{
					list.Add(55L);
				}
				if (num >= 3)
				{
					list.Add(75L);
				}
				if (num >= 4)
				{
					list.Add(95L);
				}
				break;
			case "E3C4":
				if (num >= 1)
				{
					list.Add(36L);
				}
				if (num >= 2)
				{
					list.Add(56L);
				}
				if (num >= 3)
				{
					list.Add(76L);
				}
				if (num >= 4)
				{
					list.Add(96L);
				}
				break;
			}
			return list;
		}

		public static List<long> GetHatLocs(string startScene, Difficulty difficulty)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Expected I4, but got Unknown
			int num = (int)difficulty;
			List<long> list = new List<long>();
			switch (startScene)
			{
			case "E2C1":
				list.Add(401L);
				if (num >= 0)
				{
					list.Add(421L);
				}
				if (num >= 1)
				{
					list.Add(441L);
				}
				if (num >= 2)
				{
					list.Add(461L);
				}
				break;
			case "E4C1":
				list.Add(402L);
				if (num >= 0)
				{
					list.Add(422L);
				}
				if (num >= 1)
				{
					list.Add(442L);
				}
				if (num >= 2)
				{
					list.Add(462L);
				}
				break;
			case "E3C1":
				list.Add(403L);
				if (num >= 0)
				{
					list.Add(423L);
				}
				if (num >= 1)
				{
					list.Add(443L);
				}
				if (num >= 2)
				{
					list.Add(463L);
				}
				break;
			case "E1C1":
				list.Add(404L);
				if (num >= 0)
				{
					list.Add(424L);
				}
				if (num >= 1)
				{
					list.Add(444L);
				}
				if (num >= 2)
				{
					list.Add(464L);
				}
				break;
			case "E3C2":
				list.Add(405L);
				if (num >= 0)
				{
					list.Add(425L);
				}
				if (num >= 1)
				{
					list.Add(445L);
				}
				if (num >= 2)
				{
					list.Add(465L);
				}
				break;
			case "E2C2":
				list.Add(406L);
				if (num >= 0)
				{
					list.Add(426L);
				}
				if (num >= 1)
				{
					list.Add(446L);
				}
				if (num >= 2)
				{
					list.Add(466L);
				}
				break;
			case "E1C2":
				list.Add(407L);
				if (num >= 0)
				{
					list.Add(427L);
				}
				if (num >= 1)
				{
					list.Add(447L);
				}
				if (num >= 2)
				{
					list.Add(467L);
				}
				break;
			case "E4C2":
				list.Add(408L);
				if (num >= 0)
				{
					list.Add(428L);
				}
				if (num >= 1)
				{
					list.Add(448L);
				}
				if (num >= 2)
				{
					list.Add(468L);
				}
				break;
			case "E1C3":
				list.Add(409L);
				if (num >= 0)
				{
					list.Add(429L);
				}
				if (num >= 1)
				{
					list.Add(449L);
				}
				if (num >= 2)
				{
					list.Add(469L);
				}
				break;
			case "E3C3":
				list.Add(410L);
				if (num >= 0)
				{
					list.Add(430L);
				}
				if (num >= 1)
				{
					list.Add(450L);
				}
				if (num >= 2)
				{
					list.Add(470L);
				}
				break;
			case "E4C3":
				list.Add(411L);
				if (num >= 0)
				{
					list.Add(431L);
				}
				if (num >= 1)
				{
					list.Add(451L);
				}
				if (num >= 2)
				{
					list.Add(471L);
				}
				break;
			case "E2C3":
				list.Add(412L);
				if (num >= 0)
				{
					list.Add(432L);
				}
				if (num >= 1)
				{
					list.Add(452L);
				}
				if (num >= 2)
				{
					list.Add(472L);
				}
				break;
			case "E4C4":
				list.Add(413L);
				if (num >= 0)
				{
					list.Add(433L);
				}
				if (num >= 1)
				{
					list.Add(453L);
				}
				if (num >= 2)
				{
					list.Add(473L);
				}
				break;
			case "E1C4":
				list.Add(414L);
				if (num >= 0)
				{
					list.Add(434L);
				}
				if (num >= 1)
				{
					list.Add(454L);
				}
				if (num >= 2)
				{
					list.Add(474L);
				}
				break;
			case "E2C4":
				list.Add(415L);
				if (num >= 0)
				{
					list.Add(435L);
				}
				if (num >= 1)
				{
					list.Add(455L);
				}
				if (num >= 2)
				{
					list.Add(475L);
				}
				break;
			case "E3C4":
				list.Add(416L);
				if (num >= 0)
				{
					list.Add(436L);
				}
				if (num >= 1)
				{
					list.Add(456L);
				}
				if (num >= 2)
				{
					list.Add(476L);
				}
				break;
			}
			return list;
		}

		public static long GetHatItemId(string hat, bool progressive)
		{
			switch (hat)
			{
			case "EgyptPriestHatN":
			case "EgyptPriestHatR":
			case "EgyptPriestHatU":
				if (!progressive)
				{
					return 423L;
				}
				return 403L;
			case "SleepingHatN":
			case "SleepingHatR":
			case "SleepingHatU":
				if (!progressive)
				{
					return 421L;
				}
				return 401L;
			case "PharaonHatN":
			case "PharaonHatR":
			case "PharaonHatU":
				if (!progressive)
				{
					return 434L;
				}
				return 414L;
			case "BeautyHatN":
			case "BeautyHatR":
			case "BeautyHatU":
				if (!progressive)
				{
					return 433L;
				}
				return 413L;
			case "PiratHatN":
			case "PiratHatR":
			case "PiratHatU":
				if (!progressive)
				{
					return 428L;
				}
				return 408L;
			case "FootballHelmetN":
			case "FootballHelmetR":
			case "FootballHelmetU":
				if (!progressive)
				{
					return 432L;
				}
				return 412L;
			case "ChickenHatN":
			case "ChickenHatR":
			case "ChickenHatU":
				if (!progressive)
				{
					return 424L;
				}
				return 404L;
			case "SpaceHelmetN":
			case "SpaceHelmetR":
			case "SpaceHelmetU":
				if (!progressive)
				{
					return 429L;
				}
				return 409L;
			case "CrownHatN":
			case "CrownHatR":
			case "CrownHatU":
				if (!progressive)
				{
					return 426L;
				}
				return 406L;
			case "PizzaioloHatN":
			case "PizzaioloHatR":
			case "PizzaioloHatU":
				if (!progressive)
				{
					return 430L;
				}
				return 410L;
			case "VikingHelmetN":
			case "VikingHelmetR":
			case "VikingHelmetU":
				if (!progressive)
				{
					return 427L;
				}
				return 407L;
			case "MagicHatN":
			case "MagicHatR":
			case "MagicHatU":
				if (!progressive)
				{
					return 422L;
				}
				return 402L;
			case "WizardHatN":
			case "WizardHatR":
			case "WizardHatU":
				if (!progressive)
				{
					return 435L;
				}
				return 415L;
			case "DunkeyHatN":
			case "DunkeyHatR":
			case "DunkeyHatU":
				if (!progressive)
				{
					return 436L;
				}
				return 416L;
			case "PastryHatN":
			case "PastryHatR":
			case "PastryHatU":
				if (!progressive)
				{
					return 425L;
				}
				return 405L;
			case "RabbitHatN":
			case "RabbitHatR":
			case "RabbitHatU":
				if (!progressive)
				{
					return 431L;
				}
				return 411L;
			default:
				return -1L;
			}
		}

		public static List<long> GetSpoilerLocs(int cupId, Difficulty difficulty)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Expected I4, but got Unknown
			int num = (int)difficulty;
			List<long> list = new List<long>();
			switch (cupId)
			{
			case 0:
				list.Add(301L);
				list.Add(311L);
				if (num >= 0)
				{
					list.Add(321L);
					list.Add(331L);
				}
				if (num >= 1)
				{
					list.Add(341L);
					list.Add(351L);
				}
				if (num >= 2)
				{
					list.Add(361L);
					list.Add(371L);
				}
				break;
			case 1:
				list.Add(302L);
				list.Add(312L);
				if (num >= 0)
				{
					list.Add(322L);
					list.Add(332L);
				}
				if (num >= 1)
				{
					list.Add(342L);
					list.Add(352L);
				}
				if (num >= 2)
				{
					list.Add(362L);
					list.Add(372L);
				}
				break;
			case 2:
				list.Add(303L);
				list.Add(313L);
				if (num >= 0)
				{
					list.Add(323L);
					list.Add(333L);
				}
				if (num >= 1)
				{
					list.Add(343L);
					list.Add(353L);
				}
				if (num >= 2)
				{
					list.Add(363L);
					list.Add(373L);
				}
				break;
			case 3:
				list.Add(304L);
				list.Add(314L);
				if (num >= 0)
				{
					list.Add(324L);
					list.Add(334L);
				}
				if (num >= 1)
				{
					list.Add(344L);
					list.Add(354L);
				}
				if (num >= 2)
				{
					list.Add(364L);
					list.Add(374L);
				}
				break;
			}
			return list;
		}

		public static long GetSpoilerItemId(string custom, bool progressive)
		{
			switch (custom)
			{
			case "KGC_ManiabilityN":
			case "KGC_ManiabilityR":
			case "KGC_ManiabilityU":
				if (!progressive)
				{
					return 435L;
				}
				return 415L;
			case "KJC_SpeedN":
			case "KJC_SpeedR":
			case "KJC_SpeedU":
				if (!progressive)
				{
					return 522L;
				}
				return 502L;
			case "KLC_AccelerationN":
			case "KLC_AccelerationR":
			case "KLC_AccelerationU":
				if (!progressive)
				{
					return 523L;
				}
				return 503L;
			case "KOC_AccelerationN":
			case "KOC_AccelerationR":
			case "KOC_AccelerationU":
				if (!progressive)
				{
					return 524L;
				}
				return 504L;
			case "KAC_AccelerationN":
			case "KAC_AccelerationR":
			case "KAC_AccelerationU":
				if (!progressive)
				{
					return 525L;
				}
				return 505L;
			case "KNC_AccelerationN":
			case "KNC_AccelerationR":
			case "KNC_AccelerationU":
				if (!progressive)
				{
					return 526L;
				}
				return 506L;
			case "KSC_ManiabilityN":
			case "KSC_ManiabilityR":
			case "KSC_ManiabilityU":
				if (!progressive)
				{
					return 527L;
				}
				return 507L;
			case "KHC_SpeedN":
			case "KHC_SpeedR":
			case "KHC_SpeedU":
				if (!progressive)
				{
					return 528L;
				}
				return 508L;
			default:
				return -1L;
			}
		}
	}
	public class ArchipelagoItemTracker
	{
		private static readonly ConcurrentDictionary<long, int> receivedItems = new ConcurrentDictionary<long, int>();

		private static readonly ConcurrentDictionary<long, byte> checkedLocations = new ConcurrentDictionary<long, byte>();

		public static void Initialize()
		{
			Log.Message("Initializing Archipelago Item Tracker");
		}

		public static void AddReceivedItem(long itemId)
		{
			receivedItems.AddOrUpdate(itemId, 1, (long _, int existing) => existing + 1);
		}

		public static bool HasItem(long itemId)
		{
			return receivedItems.ContainsKey(itemId);
		}

		public static int AmountOfItem(long itemId)
		{
			return CollectionExtensions.GetValueOrDefault<long, int>((IReadOnlyDictionary<long, int>)receivedItems, itemId, 0);
		}

		public static void AddCheckedLocation(long locationId)
		{
			checkedLocations.TryAdd(locationId, 0);
		}

		public static bool HasLocation(long locationId)
		{
			return checkedLocations.ContainsKey(locationId);
		}

		public static int GetCheckedLocationCount()
		{
			return checkedLocations.Count;
		}

		public static void Clear()
		{
			receivedItems.Clear();
			checkedLocations.Clear();
			Log.Message("[AP] Cleared all received items and checked locations");
		}

		public static void LoadFromServer()
		{
			try
			{
				ArchipelagoSession session = GarfieldKartAPMod.APClient.GetSession();
				if (session == null)
				{
					return;
				}
				Clear();
				List<ItemInfo> list = session.Items.AllItemsReceived?.ToList();
				if (list != null)
				{
					Log.Message($"[AP] Loading {list.Count} items from server");
					foreach (ItemInfo item in list)
					{
						Log.Message($"[AP] Item: {item.ItemName} (ID: {item.ItemId})");
						receivedItems.AddOrUpdate(item.ItemId, 1, (long _, int existing) => existing + 1);
					}
				}
				List<long> list2 = session.Locations.AllLocationsChecked?.ToList();
				if (list2 == null)
				{
					return;
				}
				Log.Message($"[AP] Loading {list2.Count} checked locations from server");
				foreach (long item2 in list2)
				{
					Log.Message($"[AP] Location checked: {item2}");
					checkedLocations.TryAdd(item2, 0);
				}
			}
			catch (Exception arg)
			{
				Log.Error($"[AP] LoadFromServer exception: {arg}");
			}
		}

		public static void ResyncFromServer()
		{
			Log.Message("[AP] Resyncing Archipelago state from server");
			LoadFromServer();
		}

		public static int GetCupVictoryCount()
		{
			return checkedLocations.Keys.Count((long loc) => loc >= 101 && loc <= 104);
		}

		public static int GetRaceVictoryCount()
		{
			int num = 0;
			for (int i = 0; i < 16; i++)
			{
				if (HasLocation(1L + (long)i))
				{
					num++;
				}
			}
			return num;
		}

		public static int GetTimeTrialVictoryCount()
		{
			try
			{
				ArchipelagoSession val = GarfieldKartAPMod.APClient?.GetSession();
				if (val == null)
				{
					return 0;
				}
				string seed = val.RoomState.Seed;
				if (string.IsNullOrWhiteSpace(seed))
				{
					return 0;
				}
				string path = Application.persistentDataPath + "/" + seed + "_timetrials.txt";
				if (!File.Exists(path))
				{
					return 0;
				}
				return (from l in File.ReadAllLines(path)
					where !string.IsNullOrWhiteSpace(l)
					select l.Trim()).Distinct().Count();
			}
			catch (Exception ex)
			{
				Log.Error("Failed to read time-trial file: " + ex.Message);
				return 0;
			}
		}

		public static List<long> GetAvailableCups()
		{
			List<long> list = new List<long>();
			for (int i = 0; i < 4; i++)
			{
				if (HasCup(i))
				{
					list.Add(i);
				}
			}
			return list;
		}

		public static bool HasRace(int raceId)
		{
			int cupId = raceId / 4;
			bool flag = ArchipelagoHelper.IsRacesRandomized();
			if (ArchipelagoHelper.IsCupsRandomized() && !flag)
			{
				return HasCup(cupId);
			}
			return HasItem(101L + (long)raceId);
		}

		public static bool HasCup(int cupId)
		{
			bool flag = ArchipelagoHelper.IsCupsRandomized();
			if (ArchipelagoHelper.IsRacesRandomized() && !flag)
			{
				return HasAllRacesInCup(cupId);
			}
			if (flag)
			{
				if (ArchipelagoHelper.IsProgressiveCupsEnabled())
				{
					return AmountOfItem(200L) >= cupId;
				}
				return HasItem(201L + (long)cupId);
			}
			return true;
		}

		public static bool CanAccessCup(int cupId)
		{
			if (!HasCup(cupId))
			{
				return false;
			}
			return HasAllRacesInCup(cupId);
		}

		public static bool HasRaceInCup(int cupId)
		{
			int num = cupId * 4;
			for (int i = 0; i < 4; i++)
			{
				if (HasRace(num + i))
				{
					return true;
				}
			}
			return false;
		}

		public static bool HasAllRacesInCup(int cupId)
		{
			int num = cupId * 4;
			for (int i = 0; i < 4; i++)
			{
				if (!HasRace(num + i))
				{
					return false;
				}
			}
			return true;
		}

		public static int GetPuzzlePieceCount(string startScene)
		{
			long puzzlePieceLoc = ArchipelagoConstants.GetPuzzlePieceLoc(startScene, 0);
			if (puzzlePieceLoc == -1)
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < 3; i++)
			{
				if (HasLocation(puzzlePieceLoc + i))
				{
					num++;
				}
			}
			return num;
		}

		public static int GetOverallPuzzlePieceCount()
		{
			int num = 0;
			for (int i = 0; i < 48; i++)
			{
				if (HasItem(1L + (long)i))
				{
					num++;
				}
			}
			return num;
		}

		public static int GetCheckedPuzzlePieceCount()
		{
			List<string> obj = new List<string>
			{
				"E2C1", "E4C1", "E3C1", "E1C1", "E3C2", "E2C2", "E1C2", "E4C2", "E1C3", "E3C3",
				"E4C3", "E2C3", "E4C4", "E1C4", "E2C4", "E3C4"
			};
			int num = 0;
			foreach (string item in obj)
			{
				num += GetPuzzlePieceCount(item);
			}
			return num;
		}

		public static bool HasBonusAvailable(BonusCategory bonus)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected I4, but got Unknown
			if (!ArchipelagoHelper.IsItemRandomizerEnabled())
			{
				return true;
			}
			return (bonus - 1) switch
			{
				0 => HasItem(901L), 
				1 => HasItem(902L), 
				3 => HasItem(906L), 
				2 => HasItem(909L), 
				4 => HasItem(903L), 
				5 => HasItem(907L), 
				6 => HasItem(908L), 
				7 => HasItem(905L), 
				8 => HasItem(904L), 
				_ => true, 
			};
		}

		public static void LogAllReceivedItems()
		{
			int num = receivedItems.Sum((KeyValuePair<long, int> kv) => kv.Value);
			Log.Message($"[AP Debug] === All Received Items ({num} total entries) ===");
			foreach (KeyValuePair<long, int> item in receivedItems.OrderBy((KeyValuePair<long, int> kv) => kv.Key))
			{
				Log.Message($"[AP Debug] Item ID: {item.Key} Count: {item.Value}");
			}
		}

		public static void LogAllCheckedLocations()
		{
			Log.Message($"[AP Debug] === All Checked Locations ({checkedLocations.Count} total) ===");
			foreach (long item in checkedLocations.Keys.OrderBy((long x) => x))
			{
				Log.Message($"[AP Debug] Location ID: {item}");
			}
		}
	}
	public class ConnectionUI : MonoBehaviour
	{
		private bool showUI = true;

		private string hostname = "archipelago.gg";

		private string slotName = "";

		private string port = "38281";

		private string password = "";

		private string statusMessage = "";

		private Rect windowRect = new Rect((float)(Screen.width / 2 - 300), (float)(Screen.height / 2 - 250), 800f, 700f);

		private ArchipelagoClient apClient;

		private bool originalCursorVisible;

		private CursorLockMode originalLockMode;

		public void Initialize(ArchipelagoClient client)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			apClient = client;
			apClient.OnConnected += delegate
			{
				statusMessage = "Connected successfully!";
			};
			apClient.OnConnectionFailed += delegate(string error)
			{
				statusMessage = "Failed: " + error;
			};
			apClient.OnDisconnected += delegate
			{
				statusMessage = "Disconnected";
			};
			apClient.OnConnected += delegate
			{
				FileWriter fileWriter = Object.FindObjectOfType<FileWriter>();
				if (!((Object)(object)fileWriter == (Object)null))
				{
					int.TryParse(port, out var result);
					fileWriter.WriteLastConnection(hostname, result, slotName, password);
				}
			};
			(string, string, string, string) tuple = FileWriter.ReadLastConnection();
			if (!string.IsNullOrEmpty(tuple.Item1))
			{
				(hostname, _, _, _) = tuple;
			}
			if (!string.IsNullOrEmpty(tuple.Item2))
			{
				port = tuple.Item2;
			}
			if (!string.IsNullOrEmpty(tuple.Item3))
			{
				slotName = tuple.Item3;
			}
			if (!string.IsNullOrEmpty(tuple.Item4))
			{
				password = tuple.Item4;
			}
			originalCursorVisible = Cursor.visible;
			originalLockMode = Cursor.lockState;
			Cursor.visible = true;
			Cursor.lockState = (CursorLockMode)0;
		}

		public void ToggleUI()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			showUI = !showUI;
			if (showUI)
			{
				originalCursorVisible = Cursor.visible;
				originalLockMode = Cursor.lockState;
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
			}
			else
			{
				Cursor.visible = originalCursorVisible;
				Cursor.lockState = originalLockMode;
			}
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)282))
			{
				ToggleUI();
			}
		}

		private void OnGUI()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (showUI)
			{
				GUI.skin.label.fontSize = 24;
				GUI.skin.button.fontSize = 24;
				GUI.skin.textField.fontSize = 24;
				windowRect = GUI.Window(0, windowRect, new WindowFunction(DrawWindow), "Archipelago Connection");
			}
		}

		private void DrawWindow(int windowID)
		{
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Press F1 to toggle this menu", Array.Empty<GUILayoutOption>());
			GUILayout.Space(15f);
			GUILayout.Label("Hostname:", Array.Empty<GUILayoutOption>());
			hostname = GUILayout.TextField(hostname, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
			GUILayout.Space(10f);
			GUILayout.Label("Port:", Array.Empty<GUILayoutOption>());
			port = GUILayout.TextField(port, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
			GUILayout.Space(10f);
			GUILayout.Label("Slot Name:", Array.Empty<GUILayoutOption>());
			slotName = GUILayout.TextField(slotName, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
			GUILayout.Space(10f);
			GUILayout.Label("Password (optional):", Array.Empty<GUILayoutOption>());
			password = GUILayout.PasswordField(password, '*', (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
			GUILayout.Space(15f);
			ArchipelagoClient archipelagoClient = apClient;
			if (archipelagoClient != null && archipelagoClient.IsConnected)
			{
				if (GUILayout.Button("Disconnect", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
				{
					apClient.Disconnect();
				}
			}
			else if (GUILayout.Button("Connect", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
			{
				int result;
				if (string.IsNullOrEmpty(slotName))
				{
					statusMessage = "Please enter a slot name!";
				}
				else if (int.TryParse(port, out result))
				{
					statusMessage = "Connecting...";
					apClient?.Connect(hostname, result, slotName, password);
				}
				else
				{
					statusMessage = "Invalid port number!";
				}
			}
			GUILayout.Space(15f);
			if (!string.IsNullOrEmpty(statusMessage))
			{
				GUILayout.Label("Status: " + statusMessage, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndVertical();
			GUI.DragWindow();
		}
	}
	public class FileWriter : MonoBehaviour
	{
		private const string LastConnectionFileName = "last_connection.txt";

		public void WriteTimeTrialData(string track)
		{
			if (GarfieldKartAPMod.APClient == null || !GarfieldKartAPMod.APClient.IsConnected)
			{
				return;
			}
			ArchipelagoSession session = GarfieldKartAPMod.APClient.GetSession();
			if (session == null)
			{
				return;
			}
			string seed = session.RoomState.Seed;
			string text = Application.persistentDataPath + "/" + seed + "_timetrials.txt";
			HashSet<string> hashSet = new HashSet<string>();
			if (File.Exists(text))
			{
				hashSet = new HashSet<string>(File.ReadAllLines(text));
			}
			if (!hashSet.Contains(track))
			{
				using (StreamWriter streamWriter = new StreamWriter(text, append: true))
				{
					streamWriter.WriteLine(track);
				}
				Debug.Log((object)("AP TimeTrial file written to: " + text));
			}
		}

		public void WriteFillerData(string data)
		{
			if (GarfieldKartAPMod.APClient == null || !GarfieldKartAPMod.APClient.IsConnected)
			{
				return;
			}
			ArchipelagoSession session = GarfieldKartAPMod.APClient.GetSession();
			if (session == null)
			{
				return;
			}
			string seed = session.RoomState.Seed;
			string text = Application.persistentDataPath + "/" + seed + "_filler.txt";
			try
			{
				File.WriteAllText(text, data);
				Debug.Log((object)("AP Filler file written to: " + text));
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Failed to write filler data: " + ex.Message));
			}
		}

		public string ReadFillerData()
		{
			if (GarfieldKartAPMod.APClient == null || !GarfieldKartAPMod.APClient.IsConnected)
			{
				return string.Empty;
			}
			ArchipelagoSession session = GarfieldKartAPMod.APClient.GetSession();
			if (session == null)
			{
				return string.Empty;
			}
			string seed = session.RoomState.Seed;
			string path = Application.persistentDataPath + "/" + seed + "_filler.txt";
			if (!File.Exists(path))
			{
				return string.Empty;
			}
			try
			{
				return File.ReadAllText(path);
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Failed to read filler data: " + ex.Message));
				return string.Empty;
			}
		}

		public void WriteLastConnection(string host, int port, string slotName, string password)
		{
			try
			{
				string path = Application.persistentDataPath + "/last_connection.txt";
				List<string> contents = new List<string>
				{
					host ?? "",
					port.ToString(),
					slotName ?? "",
					password ?? ""
				};
				File.WriteAllLines(path, contents);
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Failed to write last connection info: " + ex.Message));
			}
		}

		public static (string host, string port, string slotName, string password) ReadLastConnection()
		{
			try
			{
				string path = Application.persistentDataPath + "/last_connection.txt";
				if (!File.Exists(path))
				{
					return (null, null, null, null);
				}
				string[] array = File.ReadAllLines(path);
				string item = ((array.Length != 0) ? array[0] : null);
				string item2 = ((array.Length > 1) ? array[1] : null);
				string item3 = ((array.Length > 2) ? array[2] : null);
				string item4 = ((array.Length > 3) ? array[3] : null);
				return (item, item2, item3, item4);
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("Failed to read last connection info: " + ex.Message));
				return (null, null, null, null);
			}
		}
	}
	[BepInPlugin("Jeffdev.GarfieldKartAPMod", "GarfieldKartAPMod", "0.4.2")]
	public class GarfieldKartAPMod : BaseUnityPlugin
	{
		private const string PluginGuid = "Jeffdev.GarfieldKartAPMod";

		private const string PluginAuthor = "Jeffdev";

		private const string PluginName = "GarfieldKartAPMod";

		private const string PluginVersion = "0.4.2";

		public static ConfigEntry<int> notificationTime;

		private Harmony harmony;

		public static Dictionary<string, object> sessionSlotData;

		private static GameObject uiObject;

		private static bool uiCreated;

		private static NotificationDisplay notificationDisplay;

		private FileWriter fileWriter;

		public static ArchipelagoClient APClient { get; private set; }

		public void Awake()
		{
			notificationTime = ((BaseUnityPlugin)this).Config.Bind<int>("Archipelago", "Server Message On-Screen Time", 3, "How long to show archipelago server messages and checks on the screen, in seconds.");
			InitializeLogging();
			InitializeAssemblyResolution();
			InitializeComponents();
			ApplyPatches();
			Log.Info("GarfieldKartAPMod loaded successfully!");
		}

		private void InitializeLogging()
		{
			Log.Init(((BaseUnityPlugin)this).Logger);
		}

		private void InitializeAssemblyResolution()
		{
			ForceLoadNewtonsoftJson();
			AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
			CheckSystemNumericsAvailability();
		}

		private void ForceLoadNewtonsoftJson()
		{
			try
			{
				Type typeFromHandle = typeof(JsonConvert);
				Log.Message($"Loaded Newtonsoft.Json version: {typeFromHandle.Assembly.GetName().Version}");
			}
			catch (Exception ex)
			{
				Log.Error("Failed to preload Newtonsoft.Json: " + ex.Message);
			}
		}

		private void CheckSystemNumericsAvailability()
		{
			try
			{
				Type type = Type.GetType("System.Numerics.BigInteger, System.Numerics");
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"BigInteger available: {type != null}");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("BigInteger check failed: " + ex.Message));
			}
		}

		private void InitializeComponents()
		{
			UITextureSwapper.Initialize();
			fileWriter = ((Component)this).gameObject.AddComponent<FileWriter>();
			APClient = new ArchipelagoClient();
			APClient.OnConnected += OnArchipelagoConnected;
			APClient.OnDisconnected += OnArchipelagoDisconnected;
		}

		private void ApplyPatches()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			harmony = new Harmony("Jeffdev.GarfieldKartAPMod");
			harmony.PatchAll(Assembly.GetExecutingAssembly());
		}

		public void Update()
		{
			if (APClient != null && APClient.HasPendingNotifications())
			{
				string message = APClient.DequeuePendingNotification();
				notificationDisplay.ShowNotification(message);
			}
		}

		private void OnArchipelagoConnected()
		{
			Log.Message("Connected to Archipelago - loading items");
			uiObject.GetComponent<ConnectionUI>().ToggleUI();
			PopupManager.OpenPopup("Connected to Archipelago!", (POPUP_TYPE)2, (POPUP_PRIORITY)0, (Relay)null, (Action<CLOSE_REASON>)null, 0f, (string)null);
		}

		private void OnArchipelagoDisconnected()
		{
			Log.Message("Disconnected from Archipelago");
			ArchipelagoItemTracker.Clear();
		}

		private Assembly OnAssemblyResolve(object sender, ResolveEventArgs args)
		{
			if (new AssemblyName(args.Name).Name != "Newtonsoft.Json")
			{
				return null;
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (!(assembly.GetName().Name != "Newtonsoft.Json"))
				{
					Log.Message($"Resolved Newtonsoft.Json to version {assembly.GetName().Version}");
					return assembly;
				}
			}
			return null;
		}

		public static void CreateUI()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			if (!uiCreated)
			{
				Log.Message("Creating Archipelago UI...");
				uiObject = new GameObject("ArchipelagoUI");
				Object.DontDestroyOnLoad((Object)(object)uiObject);
				uiObject.AddComponent<ConnectionUI>().Initialize(APClient);
				notificationDisplay = uiObject.AddComponent<NotificationDisplay>();
				notificationDisplay.Initialize();
				uiCreated = true;
			}
		}

		public void OnDestroy()
		{
			APClient?.Disconnect();
			if ((Object)(object)uiObject != (Object)null)
			{
				Object.Destroy((Object)(object)uiObject);
			}
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
	internal static class Log
	{
		private static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	public class NotificationDisplay : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <DisplayNextNotification>d__5 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public NotificationDisplay <>4__this;

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

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

			[DebuggerHidden]
			public <DisplayNextNotification>d__5(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Expected O, but got Unknown
				int num = <>1__state;
				NotificationDisplay notificationDisplay = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					notificationDisplay.isDisplaying = true;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (notificationDisplay.notificationQueue.Count > 0)
				{
					string text = notificationDisplay.notificationQueue.Dequeue();
					((TMP_Text)notificationDisplay.notificationText).text = text;
					<>2__current = (object)new WaitForSeconds((float)GarfieldKartAPMod.notificationTime.Value);
					<>1__state = 1;
					return true;
				}
				((TMP_Text)notificationDisplay.notificationText).text = "";
				notificationDisplay.isDisplaying = false;
				return false;
			}

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

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

		private TextMeshProUGUI notificationText;

		private readonly Queue<string> notificationQueue = new Queue<string>();

		private bool isDisplaying;

		public void Initialize()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			Canvas obj = ((Component)this).gameObject.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 1000;
			GameObject val = new GameObject("NotificationText");
			val.transform.SetParent(((Component)this).transform);
			notificationText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)notificationText).fontSize = 48f;
			((TMP_Text)notificationText).alignment = (TextAlignmentOptions)258;
			((TMP_Text)notificationText).autoSizeTextContainer = true;
			((TMP_Text)notificationText).enableWordWrapping = true;
			((Graphic)notificationText).color = Color.white;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.anchoredPosition = new Vector2(0f, -20f);
			component.sizeDelta = new Vector2(-40f, 100f);
			((TMP_Text)notificationText).text = "";
		}

		public void ShowNotification(string message)
		{
			notificationQueue.Enqueue(message);
			if (!isDisplaying)
			{
				((MonoBehaviour)this).StartCoroutine(DisplayNextNotification());
			}
		}

		[IteratorStateMachine(typeof(<DisplayNextNotification>d__5))]
		private IEnumerator DisplayNextNotification()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DisplayNextNotification>d__5(0)
			{
				<>4__this = this
			};
		}
	}
	[Serializable]
	public class SlotDataException : ApplicationException
	{
		public SlotDataException()
		{
		}

		public SlotDataException(string message)
			: base(message)
		{
		}

		public SlotDataException(string message, Exception innerException)
			: base(message, innerException)
		{
		}
	}
	public static class UITextureSwapper
	{
		public static string spriteFolder = "Resources/Sprites";

		private static Sprite baseArchipelagoSprite;

		public static Sprite puzzlePieceFilledSprite;

		public static Sprite puzzlePieceEmptySprite;

		private static bool initialized;

		private static bool hasSwappedThisMenu;

		public static void Initialize()
		{
			if (!initialized)
			{
				Log.Message("Initializing UI texture swapper...");
				if (TryLoadSprite("archipelago_logo.png", out baseArchipelagoSprite) && TryLoadSprite("garfkart_ap_puzzle_filled.png", out puzzlePieceFilledSprite) && TryLoadSprite("garfkart_ap_puzzle_empty.png", out puzzlePieceEmptySprite))
				{
					initialized = true;
				}
			}
		}

		private static bool TryLoadSprite(string path, out Sprite targetSprite)
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			_ = typeof(UITextureSwapper).Namespace;
			targetSprite = null;
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
				string text = null;
				string[] array = manifestResourceNames;
				foreach (string text2 in array)
				{
					if (!(text2 != path) || text2.EndsWith("." + path))
					{
						if (text != null)
						{
							throw new ApplicationException("Duplicate resource name found, unable to load the correct texture: " + text2);
						}
						text = text2;
					}
				}
				if (text == null)
				{
					Log.Warning("Couldn't find " + path + " in embedded resources, loading default sprite instead.");
					targetSprite = CreateDefaultSprite();
					return false;
				}
				Log.Message("Loading embedded resource: " + text);
				using Stream stream = executingAssembly.GetManifestResourceStream(text);
				if (stream == null)
				{
					Log.Error("Failed to load " + path + " for unknown reasons :)");
					targetSprite = CreateDefaultSprite();
					return false;
				}
				byte[] array2 = new byte[stream.Length];
				stream.Read(array2, 0, (int)stream.Length);
				Texture2D val = new Texture2D(2, 2);
				ImageConversion.LoadImage(val, array2);
				val.Apply();
				targetSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
				Log.Message($"Successfully loaded {path} ({((Texture)val).width}x{((Texture)val).height})");
				return true;
			}
			catch (Exception ex)
			{
				Log.Error("Failed to load " + path + ": " + ex.Message + "\n" + ex.StackTrace);
				targetSprite = CreateDefaultSprite();
				return false;
			}
		}

		private static Sprite CreateDefaultSprite()
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(64, 64);
			Color[] array = (Color[])(object)new Color[4096];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = Color.red;
			}
			val.SetPixels(array);
			val.Apply();
			Log.Message("Created default red placeholder sprite");
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f);
		}

		public static void ResetSwapFlag()
		{
			hasSwappedThisMenu = false;
		}

		public static void SwapPuzzlePieceIcons(GameObject menu)
		{
			if (hasSwappedThisMenu)
			{
				return;
			}
			if ((Object)(object)baseArchipelagoSprite == (Object)null)
			{
				Log.Error("Cannot swap - Archipelago sprite not loaded");
			}
			else
			{
				if (!GarfieldKartAPMod.APClient.IsConnected)
				{
					return;
				}
				try
				{
					int num = 0;
					Image[] componentsInChildren = menu.GetComponentsInChildren<Image>(true);
					foreach (Image val in componentsInChildren)
					{
						if (!((Object)(object)val.sprite == (Object)null))
						{
							string text = ((Object)val.sprite).name.ToLower();
							string text2 = ((Object)((Component)val).gameObject).name.ToLower();
							if (text.Contains("icnpuzzle") || text2.Contains("icnpuzzle") || text.Contains("icnpuzzlefull") || text2.Contains("icnpuzzlefull"))
							{
								val.sprite = baseArchipelagoSprite;
								num++;
								Log.Message("Swapped UI.Image on: " + ((Object)((Component)val).gameObject).name);
							}
						}
					}
					Log.Message($"Swapped {num} puzzle piece icons");
					hasSwappedThisMenu = true;
				}
				catch (Exception ex)
				{
					Log.Error("Failed to swap puzzle icons: " + ex.Message);
				}
			}
		}
	}
}
namespace GarfieldKartAPMod.Helpers
{
	public static class ArchipelagoGoalManager
	{
		public static long GetGoalId()
		{
			long.TryParse(GarfieldKartAPMod.APClient.GetSlotDataValue("goal"), out var result);
			return result;
		}

		public static void CheckAndCompleteGoal()
		{
			if (!ArchipelagoHelper.IsConnectedAndEnabled)
			{
				return;
			}
			long goalId = GetGoalId();
			if ((ulong)goalId <= 3uL)
			{
				switch (goalId)
				{
				case 0L:
					CheckGrandPrixGoal();
					return;
				case 3L:
					CheckPuzzlePieceGoal();
					return;
				case 1L:
					CheckRacesGoal();
					return;
				case 2L:
					CheckTimeTrialsGoal();
					return;
				}
			}
			Log.Debug($"Unknown goal ID: {goalId}");
		}

		private static void CheckGrandPrixGoal()
		{
			if (ArchipelagoItemTracker.GetCupVictoryCount() == 4)
			{
				CompleteGoal();
			}
		}

		private static void CheckPuzzlePieceGoal()
		{
			long num = ArchipelagoHelper.GetPuzzlePieceCount();
			if (ArchipelagoItemTracker.GetOverallPuzzlePieceCount() >= num)
			{
				CompleteGoal();
			}
		}

		private static void CheckRacesGoal()
		{
			if (ArchipelagoItemTracker.GetRaceVictoryCount() == 16)
			{
				CompleteGoal();
			}
		}

		private static void CheckTimeTrialsGoal()
		{
			if (ArchipelagoItemTracker.GetTimeTrialVictoryCount() == 16)
			{
				CompleteGoal();
			}
		}

		private static void CompleteGoal()
		{
			GarfieldKartAPMod.APClient.GetSession().SetGoalAchieved();
		}
	}
	public static class ArchipelagoHelper
	{
		public static bool IsConnectedAndEnabled => GarfieldKartAPMod.APClient?.IsConnected ?? false;

		private static bool IsTrue(string str)
		{
			if (str == "true" || str == "1")
			{
				return true;
			}
			return false;
		}

		public static bool IsPuzzleRandomizationEnabled()
		{
			return IsTrue(GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_puzzle_pieces"));
		}

		public static bool IsProgressiveCupsEnabled()
		{
			return IsTrue(GarfieldKartAPMod.APClient.GetSlotDataValue("progressive_cups"));
		}

		public static bool IsCharRandomizerEnabled()
		{
			return IsTrue(GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_characters"));
		}

		public static bool IsKartRandomizerEnabled()
		{
			return IsTrue(GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_karts"));
		}

		public static bool IsHatRandomizerEnabled()
		{
			return (long)int.Parse(GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_hats")) != 0;
		}

		public static bool IsProgressiveHatEnabled()
		{
			return (long)int.Parse(GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_hats")) == 1;
		}

		public static bool IsSpoilerRandomizerEnabled()
		{
			return (long)int.Parse(GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_spoilers")) != 0;
		}

		public static bool IsProgressiveSpoilerEnabled()
		{
			return (long)int.Parse(GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_spoilers")) == 1;
		}

		public static bool IsItemRandomizerEnabled()
		{
			return IsTrue(GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_items"));
		}

		public static bool IsRacesRandomized()
		{
			int.TryParse(GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_races"), out var result);
			if ((long)result != 1)
			{
				return (long)result == 2;
			}
			return true;
		}

		public static bool IsCupsRandomized()
		{
			int.TryParse(GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_races"), out var result);
			if (result != 0L)
			{
				return (long)result == 2;
			}
			return true;
		}

		public static bool IsRacesAndCupsRandomized()
		{
			int.TryParse(GarfieldKartAPMod.APClient.GetSlotDataValue("randomize_races"), out var result);
			return (long)result == 2;
		}

		public static bool IsSpringsOnly()
		{
			return IsTrue(GarfieldKartAPMod.APClient.GetSlotDataValue("springs_only"));
		}

		public static bool IsCPUItemsDisabled()
		{
			return IsTrue(GarfieldKartAPMod.APClient.GetSlotDataValue("disable_cpu_items"));
		}

		public static string GetTimeTrialGoalGrade()
		{
			return GarfieldKartAPMod.APClient.GetSlotDataValue("time_trial_goal_grade");
		}

		public static string GetCCRequirement()
		{
			return GarfieldKartAPMod.APClient.GetSlotDataValue("cc_requirement");
		}

		public static int GetPuzzlePieceCount()
		{
			string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("puzzle_piece_count");
			if (int.TryParse(slotDataValue, out var result))
			{
				return result;
			}
			throw new SlotDataException("Invalid puzzle piece goal value passed from slot data: " + slotDataValue);
		}

		internal static int GetLapCount()
		{
			string slotDataValue = GarfieldKartAPMod.APClient.GetSlotDataValue("lap_count");
			if (slotDataValue == null)
			{
				return 3;
			}
			if (int.TryParse(slotDataValue, out var result))
			{
				return result;
			}
			throw new SlotDataException("Invalid puzzle piece goal value passed from slot data: " + slotDataValue);
		}
	}
	internal class Utils
	{
		private static readonly Random rng = new Random();

		public static void Shuffle<T>(List<T> list)
		{
			int num = list.Count;
			while (num > 1)
			{
				num--;
				int num2 = rng.Next(num + 1);
				int index = num;
				int index2 = num2;
				T value = list[num2];
				T value2 = list[num];
				list[index] = value;
				list[index2] = value2;
			}
		}
	}
}
namespace GarfieldKartAPMod.Patches
{
	public static class ButtonHelper
	{
		public static void DisableButtonsByIndices(object buttonsArray, params int[] indices)
		{
			try
			{
				Type type = buttonsArray.GetType();
				PropertyInfo property = type.GetProperty("Length");
				PropertyInfo property2 = type.GetProperty("Item", new Type[1] { typeof(int) });
				if (property == null)
				{
					return;
				}
				int num = (int)property.GetValue(buttonsArray);
				foreach (int num2 in indices)
				{
					if (num2 < num && !(property2 == null))
					{
						object? value = property2.GetValue(buttonsArray, new object[1] { num2 });
						BetterButton val = (BetterButton)((value is BetterButton) ? value : null);
						if (!((Object)(object)val == (Object)null))
						{
							((Selectable)val).interactable = false;
							Log.Info($"Disabled button at index {num2}");
						}
					}
				}
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to disable buttons: {arg}");
			}
		}

		public static void DisableLockedRaceButtons(object instance, object m_buttons, int currentCupId)
		{
			try
			{
				Type type = m_buttons.GetType();
				PropertyInfo property = type.GetProperty("Length");
				if (property == null)
				{
					return;
				}
				int num = (int)property.GetValue(m_buttons);
				PropertyInfo property2 = type.GetProperty("Item", new Type[1] { typeof(int) });
				for (int i = 0; i < num; i++)
				{
					if (property2 != null)
					{
						object? value = property2.GetValue(m_buttons, new object[1] { i });
						BetterButton val = (BetterButton)((value is BetterButton) ? value : null);
						if ((Object)(object)val == (Object)null)
						{
							continue;
						}
						if (i == 4)
						{
							((Component)val).gameObject.SetActive(false);
							continue;
						}
						if (!ArchipelagoItemTracker.HasRace(4 * currentCupId + i))
						{
							((Selectable)val).interactable = false;
							continue;
						}
						((Selectable)val).interactable = true;
						GkEventSystem.Current.SelectButton((Selectable)(object)val, 0);
					}
					MenuHDTrackSelection val2 = (MenuHDTrackSelection)((instance is MenuHDTrackSelection) ? instance : null);
					if (val2 != null)
					{
						val2.UpdateRacesButtons(currentCupId);
					}
				}
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to disable race buttons: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(MenuHDMain), "Enter")]
	public class MenuHDMain_Enter_Patch
	{
		private static void Postfix()
		{
			Log.Message("Main menu started, creating UI...");
			GarfieldKartAPMod.CreateUI();
		}
	}
	[HarmonyPatch(typeof(MenuHDGameMode), "Enter")]
	public class MenuHDGameMode_Enter_Patch
	{
		private static void Postfix(MenuHDGameMode __instance, object ___m_buttons)
		{
			if (ArchipelagoHelper.IsConnectedAndEnabled && ArchipelagoItemTracker.GetAvailableCups().Count == 0)
			{
				ButtonHelper.DisableButtonsByIndices(___m_buttons, 1);
			}
		}
	}
	[HarmonyPatch(typeof(MenuHDGameMode), "OnSubmitChampionShip")]
	public class MenuHDModeSelect_OnSubmitChampionShip_Patch
	{
		private static bool Prefix(MenuHDGameMode __instance)
		{
			if (!ArchipelagoHelper.IsConnectedAndEnabled)
			{
				return true;
			}
			if (ArchipelagoItemTracker.GetAvailableCups().Count != 0)
			{
				return true;
			}
			PopupManager.OpenPopup("You haven't unlocked any cups!", (POPUP_TYPE)3, (POPUP_PRIORITY)0, (Relay)null, (Action<CLOSE_REASON>)null, 0f, (string)null);
			return false;
		}
	}
	[HarmonyPatch(typeof(MenuHDGameType), "Enter")]
	public class MenuHDGameType_Enter_Patch
	{
		private static void Prefix()
		{
			ArchipelagoItemTracker.ResyncFromServer();
		}

		private static void Postfix(MenuHDGameType __instance, object ___m_buttons)
		{
			if (ArchipelagoHelper.IsConnectedAndEnabled)
			{
				ButtonHelper.DisableButtonsByIndices(___m_buttons, 1, 2);
			}
		}
	}
	[HarmonyPatch(typeof(MenuHDTrackSelection), "Enter")]
	public class MenuHDTrackSelection_Enter_Patch
	{
		private static void Postfix(MenuHDTrackSelection __instance, EnumArray<TAB, BetterToggle> ___m_tabs, object ___m_buttons, ref int ___m_currentChampionshipIndex)
		{
			Log.Message("Track Selection Menu opened");
			ArchipelagoItemTracker.ResyncFromServer();
			if (ArchipelagoHelper.IsConnectedAndEnabled)
			{
				if (ArchipelagoHelper.IsPuzzleRandomizationEnabled())
				{
					UITextureSwapper.SwapPuzzlePieceIcons(((Component)__instance).gameObject);
				}
				int num = SetupCupTabs(___m_tabs, ___m_currentChampionshipIndex);
				ButtonHelper.DisableLockedRaceButtons(__instance, ___m_buttons, (num != -1) ? num : ___m_currentChampionshipIndex);
			}
		}

		private static int SetupCupTabs(EnumArray<TAB, BetterToggle> tabs, int currentChampionshipId)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			int num = -1;
			E_GameModeType gameModeType = Singleton<GameConfigurator>.Instance.GameModeType;
			for (int i = 0; i < tabs.Length; i++)
			{
				bool flag = false;
				bool flag2 = ArchipelagoItemTracker.HasRaceInCup(i);
				if ((int)gameModeType == 3 && ArchipelagoItemTracker.CanAccessCup(i))
				{
					flag = true;
				}
				else if (((int)gameModeType == 2 || (int)gameModeType == 4) && flag2)
				{
					flag = true;
				}
				if (!flag)
				{
					((Component)tabs[i]).gameObject.SetActive(false);
					continue;
				}
				if (num == -1)
				{
					GkEventSystem.Current.SelectTab((Toggle)(object)tabs[i], 0);
					num = i;
				}
				((Component)tabs[i]).gameObject.SetActive(true);
			}
			return num;
		}
	}
	[HarmonyPatch(typeof(MenuHDTrackSelection), "OnSelectChampionship")]
	public class MenuHDTrackSelection_OnSelectChampionship_Patch
	{
		private static void Postfix(MenuHDTrackSelection __instance, object ___m_buttons, int iId)
		{
			ButtonHelper.DisableLockedRaceButtons(__instance, ___m_buttons, iId);
		}
	}
	[HarmonyPatch(typeof(MenuHDTrackSelection), "UpdateRacesButtons")]
	public class MenuHDTrackSelection_UpdateRacesButtons_Patch
	{
		private static bool Prefix(MenuHDTrackSelection __instance, int cup, List<HD_TrackSelection_Item> ___m_itemsButtons, int ___m_maxPuzzleNumber, int ___m_currentSelectedButton, bool ___m_hasFinishedEntering, TextMeshProUGUI ___m_textCupCircuit)
		{
			if (!ArchipelagoHelper.IsConnectedAndEnabled || !ArchipelagoHelper.IsPuzzleRandomizationEnabled())
			{
				return true;
			}
			for (int i = 0; i < ___m_itemsButtons.Count - 1; i++)
			{
				___m_itemsButtons[i].ChangeBackground(PlayerGameEntities.ChampionShipDataList[cup].Sprites[i]);
				string text = Singleton<GameConfigurator>.Instance.ChampionShipData.Tracks[i];
				int puzzlePieceCount = ArchipelagoItemTracker.GetPuzzlePieceCount(text);
				___m_itemsButtons[i].UpdatePuzzleText(puzzlePieceCount);
				___m_itemsButtons[i].UpdateTimeTrialText(text);
			}
			if (___m_currentSelectedButton != 4 && ___m_hasFinishedEntering)
			{
				AccessTools.Method(typeof(MenuHDTrackSelection), "UpdateTimeTrialValues", (Type[])null, (Type[])null).Invoke(__instance, new object[1] { ___m_currentSelectedButton });
			}
			if (___m_currentSelectedButton < Singleton<GameConfigurator>.Instance.ChampionShipData.TracksName.Length)
			{
				((TMP_Text)___m_textCupCircuit).text = Singleton<GameConfigurator>.Instance.ChampionShipData.ChampionShipName + " - " + Singleton<GameConfigurator>.Instance.ChampionShipData.TracksName[___m_currentSelectedButton];
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(MenuHDTrackPresentation), "InitPuzzlePieces")]
	public class MenuHDTrackPresentation_InitPuzzlePieces_Patch
	{
		private static bool Prefix(Image[] puzzlePiecesImages, string trackName, bool isTimeTrial)
		{
			if (!ArchipelagoHelper.IsConnectedAndEnabled)
			{
				return true;
			}
			if (!ArchipelagoHelper.IsPuzzleRandomizationEnabled())
			{
				return true;
			}
			if (GkNetMgr.Instance.IsConnected)
			{
				((Component)((Component)puzzlePiecesImages[0]).transform.parent).gameObject.SetActive(false);
				return false;
			}
			((Component)((Component)puzzlePiecesImages[0]).transform.parent).gameObject.SetActive(true);
			for (int i = 0; i < puzzlePiecesImages.Length; i++)
			{
				((Component)puzzlePiecesImages[i]).gameObject.SetActive(!isTimeTrial);
				bool flag = ArchipelagoItemTracker.HasLocation(ArchipelagoConstants.GetPuzzlePieceLoc(trackName, i));
				puzzlePiecesImages[i].sprite = (flag ? UITextureSwapper.puzzlePieceFilledSprite : UITextureSwapper.puzzlePieceEmptySprite);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(GkEventSystem), "OnSecondaryMove")]
	public class GkEventSystem_OnSecondaryMove_Patch
	{
		private static Exception Finalizer(Exception __exception)
		{
			if (!(__exception is InvalidCastException))
			{
				return __exception;
			}
			Log.Debug("Suppressed InvalidCastException in OnSecondaryMove (navigating to disabled tab)");
			return null;
		}
	}
	[HarmonyPatch(typeof(RcRace), "StartRace")]
	public class RcRace_StartRace_Patch
	{
		private static void Prefix(RcRace __instance)
		{
			if (ArchipelagoHelper.IsConnectedAndEnabled)
			{
				int lapCount = ArchipelagoHelper.GetLapCount();
				__instance.SetRaceNbLap(lapCount);
			}
		}
	}
	[HarmonyPatch(typeof(KartBonusMgr), "SetItem")]
	public class KartBonusMgr_SetItem_Patch
	{
		private static bool Prefix(KartBonusMgr __instance, Kart ___m_kart, ref BonusCategory bonus, ref int iQuantity, int byPassSlot = -1, bool isFromCheat = false)
		{
			if (!ArchipelagoHelper.IsConnectedAndEnabled)
			{
				return true;
			}
			if (!___m_kart.Driver.IsHuman)
			{
				return !ArchipelagoHelper.IsCPUItemsDisabled();
			}
			if (ArchipelagoHelper.IsSpringsOnly())
			{
				bonus = (BonusCategory)3;
			}
			return ArchipelagoItemTracker.HasBonusAvailable(bonus);
		}

		private static void Postfix(KartBonusMgr __instance, Kart ___m_kart, BonusCategory bonus, int iQuantity, int byPassSlot = -1, bool isFromCheat = false)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected I4, but got Unknown
			if (ArchipelagoHelper.IsConnectedAndEnabled && ___m_kart.Driver.IsHuman && ArchipelagoItemTracker.HasBonusAvailable(bonus))
			{
				switch (bonus - 1)
				{
				case 0:
					GarfieldKartAPMod.APClient.SendLocation(1101L);
					break;
				case 1:
					GarfieldKartAPMod.APClient.SendLocation(1102L);
					break;
				case 3:
					GarfieldKartAPMod.APClient.SendLocation(1106L);
					break;
				case 2:
					GarfieldKartAPMod.APClient.SendLocation(1109L);
					break;
				case 4:
					GarfieldKartAPMod.APClient.SendLocation(1103L);
					break;
				case 8:
					GarfieldKartAPMod.APClient.SendLocation(1104L);
					break;
				case 6:
					GarfieldKartAPMod.APClient.SendLocation(1108L);
					break;
				case 7:
					GarfieldKartAPMod.APClient.SendLocation(1105L);
					break;
				case 5:
					GarfieldKartAPMod.APClient.SendLocation(1107L);
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(RacePuzzlePiece), "DoTrigger")]
	public class RacePuzzlePiece_DoTrigger_Patch
	{
		private static void Postfix(RacePuzzlePiece __instance, RcVehicle pVehicle)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (ArchipelagoHelper.IsConnectedAndEnabled && Object.op_Implicit((Object)(object)pVehicle) && (int)pVehicle.GetControlType() == 0)
			{
				long puzzlePieceLoc = ArchipelagoConstants.GetPuzzlePieceLoc(Singleton<GameConfigurator>.Instance.StartScene, __instance.Index);
				GarfieldKartAPMod.APClient.SendLocation(puzzlePieceLoc);
				Log.Message($"Sending Puzzle Piece {Singleton<GameConfigurator>.Instance.StartScene}_{__instance.Index}");
			}
		}
	}
	[HarmonyPatch(typeof(RacePuzzlePiece), "Awake")]
	public class RacePuzzlePiece_Awake_Patch
	{
		private static void Postfix(RacePuzzlePiece __instance)
		{
			if (!ArchipelagoHelper.IsConnectedAndEnabled || !ArchipelagoHelper.IsPuzzleRandomizationEnabled())
			{
				return;
			}
			((Component)__instance).GetComponent<Renderer>().materials[0] = null;
			if (ArchipelagoItemTracker.HasLocation(ArchipelagoConstants.GetPuzzlePieceLoc(Singleton<GameConfigurator>.Instance.StartScene, __instance.Index)))
			{
				Material[] materials = ((Component)__instance).GetComponent<Renderer>().materials;
				if (materials.Length == 1)
				{
					materials[0] = __instance.TransparentMaterial;
				}
				((Component)__instance).GetComponent<Renderer>().materials = materials;
			}
		}
	}
	[HarmonyPatch(typeof(HUDPositionHD), "TakePuzzlePiece")]
	public class HUDPositionHD_TakePuzzlePiece_Patch
	{
		private static bool Prefix(HUDPositionHD __instance, int iIndex, List<Animation> ___m_puzzlesAnimation, List<Image> ___m_puzzleImages, int ___m_iLogPuzzle)
		{
			if ((iIndex < 0 || iIndex >= 3) ? true : false)
			{
				return false;
			}
			bool flag = true;
			for (int i = 0; i < 2; i++)
			{
				if (i != iIndex && !ArchipelagoItemTracker.HasLocation(ArchipelagoConstants.GetPuzzlePieceLoc(Singleton<GameConfigurator>.Instance.StartScene, i)))
				{
					flag = false;
					break;
				}
			}
			if (flag)
			{
				foreach (Animation item in ___m_puzzlesAnimation)
				{
					item.Play("PuzzlePiece_Turn");
				}
			}
			else if ((Object)(object)___m_puzzlesAnimation[iIndex] != (Object)null)
			{
				___m_puzzlesAnimation[iIndex].Play("PuzzlePiece_Turn");
			}
			if ((Object)(object)___m_puzzleImages[iIndex] == (Object)null)
			{
				return false;
			}
			___m_puzzleImages[iIndex].sprite = UITextureSwapper.puzzlePieceFilledSprite;
			if (LogManager.Instance != null)
			{
				___m_iLogPuzzle++;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(GameSaveManager), "IsPuzzlePieceUnlocked")]
	public class GameSaveManager_IsPuzzlePieceUnlocked_Patch
	{
		private static bool Prefix(GameSaveManager __instance, string piece, Dictionary<string, bool> ___m_puzzlePieces, ref bool __result)
		{
			if (!ArchipelagoHelper.IsConnectedAndEnabled || !ArchipelagoHelper.IsPuzzleRandomizationEnabled())
			{
				return true;
			}
			string[] array = piece.Split(new char[1] { '_' });
			int.TryParse(array[1], out var result);
			__result = ArchipelagoItemTracker.HasItem(ArchipelagoConstants.GetPuzzlePiece(array[0], result));
			return false;
		}
	}
	[HarmonyPatch(typeof(HD_TrackSelection_Item), "UpdatePuzzleText")]
	public class HD_TrackSelection_Item_UpdatePuzzleText_Patch
	{
		private static bool Prefix(HD_TrackSelection_Item __instance, int value, TextMeshProUGUI ___m_puzzleText, GameObject ___m_boardPuzzle, GameObject ___m_boardPuzzleFull, int ___m_maxPuzzleValue)
		{
			if (!ArchipelagoHelper.IsConnectedAndEnabled || !ArchipelagoHelper.IsPuzzleRandomizationEnabled())
			{
				return true;
			}
			((TMP_Text)___m_puzzleText).text = $"{value}/{___m_maxPuzzleValue}";
			if (value == ___m_maxPuzzleValue)
			{
				if (___m_boardPuzzle.activeSelf)
				{
					___m_boardPuzzle.SetActive(false);
				}
				___m_boardPuzzleFull.SetActive(true);
			}
			else
			{
				if (___m_boardPuzzleFull.activeSelf)
				{
					___m_boardPuzzleFull.SetActive(false);
				}
				___m_boardPuzzle.SetActive(true);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(KartSelectionNavigation), "Enter")]
	public class KartSelectionNavigation_Enter_Patch
	{
		private static bool Prefix(KartSelectionNavigation __instance, EnumArray<KARTSELECT_TYPE, KartSelectionItem[]> ___m_items)
		{
			if (!ArchipelagoHelper.IsConnectedAndEnabled)
			{
				return true;
			}
			UpdateCharacterUnlocks(__instance, ___m_items);
			UpdateKartUnlocks(__instance, ___m_items);
			return true;
		}

		private static void UpdateCharacterUnlocks(KartSelectionNavigation instance, EnumArray<KARTSELECT_TYPE, KartSelectionItem[]> items)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Invalid comparison between Unknown and I4
			if (items == null)
			{
				return;
			}
			MethodInfo method = ((object)items).GetType().GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(int) }, null);
			if (!(method == null))
			{
				KartSelectionItem[] array = (KartSelectionItem[])method.Invoke(items, new object[1] { 0 });
				foreach (KartSelectionItem val in array)
				{
					CharacterCarac val2 = (CharacterCarac)val.IconCarac;
					UnlockableItemSate characterState = Singleton<GameSaveManager>.Instance.GetCharacterState(((DrivingCarac)val2).Owner);
					bool flag = characterState - 3 <= 1;
					bool flag2 = flag;
					val.SetLock(!flag2);
				}
			}
		}

		private static void UpdateKartUnlocks(KartSelectionNavigation instance, EnumArray<KARTSELECT_TYPE, KartSelectionItem[]> items)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Invalid comparison between Unknown and I4
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Invalid comparison between Unknown and I4
			if (items == null)
			{
				return;
			}
			MethodInfo method = ((object)items).GetType().GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(int) }, null);
			if (!(method == null))
			{
				KartSelectionItem[] array = (KartSelectionItem[])method.Invoke(items, new object[1] { 1 });
				foreach (KartSelectionItem obj in array)
				{
					KartCarac val = (KartCarac)obj.IconCarac;
					UnlockableItemSate kartState = Singleton<GameSaveManager>.Instance.GetKartState(((DrivingCarac)val).Owner);
					bool flag = (int)kartState == 4 || (int)kartState == 3;
					obj.SetLock(!flag);
				}
			}
		}
	}
	[HarmonyPatch(typeof(GameSaveManager), "GetCha

Newtonsoft.Json.dll

Decompiled 3 weeks ago
#define DEBUG
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq.JsonPath;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Schema")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")]
[assembly: CLSCompliant(true)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyCompany("Newtonsoft")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyCopyright("Copyright © James Newton-King 2008")]
[assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")]
[assembly: AssemblyFileVersion("11.0.1")]
[assembly: AssemblyInformationalVersion("11.0.1-beta2+0eb477a285cdf06aa7bf5e103583768eba37fed6")]
[assembly: AssemblyProduct("Json.NET")]
[assembly: AssemblyTitle("Json.NET")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ArchipelagoMW/Archipelago.MultiClient.Net.git")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyVersion("11.0.0.0")]
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.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;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
}
namespace Newtonsoft.Json
{
	public enum ConstructorHandling
	{
		Default,
		AllowNonPublicDefaultConstructor
	}
	public enum DateFormatHandling
	{
		IsoDateFormat,
		MicrosoftDateFormat
	}
	public enum DateParseHandling
	{
		None,
		DateTime,
		DateTimeOffset
	}
	public enum DateTimeZoneHandling
	{
		Local,
		Utc,
		Unspecified,
		RoundtripKind
	}
	public class DefaultJsonNameTable : JsonNameTable
	{
		private class Entry
		{
			internal readonly string Value;

			internal readonly int HashCode;

			internal Entry Next;

			internal Entry(string value, int hashCode, Entry next)
			{
				Value = value;
				HashCode = hashCode;
				Next = next;
			}
		}

		private static readonly int HashCodeRandomizer;

		private int _count;

		private Entry[] _entries;

		private int _mask = 31;

		static DefaultJsonNameTable()
		{
			HashCodeRandomizer = Environment.TickCount;
		}

		public DefaultJsonNameTable()
		{
			_entries = new Entry[_mask + 1];
		}

		public override string? Get(char[] key, int start, int length)
		{
			if (length == 0)
			{
				return string.Empty;
			}
			int num = length + HashCodeRandomizer;
			num += (num << 7) ^ key[start];
			int num2 = start + length;
			for (int i = start + 1; i < num2; i++)
			{
				num += (num << 7) ^ key[i];
			}
			num -= num >> 17;
			num -= num >> 11;
			num -= num >> 5;
			int num3 = num & _mask;
			Entry[] entries = _entries;
			for (Entry entry = entries[num3]; entry != null; entry = entry.Next)
			{
				if (entry.HashCode == num && TextEquals(entry.Value, key, start, length))
				{
					return entry.Value;
				}
			}
			return null;
		}

		public string Add(string key)
		{
			if (key == null)
			{
				throw new ArgumentNullException("key");
			}
			int length = key.Length;
			if (length == 0)
			{
				return string.Empty;
			}
			int num = length + HashCodeRandomizer;
			for (int i = 0; i < key.Length; i++)
			{
				num += (num << 7) ^ key[i];
			}
			num -= num >> 17;
			num -= num >> 11;
			num -= num >> 5;
			for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.Next)
			{
				if (entry.HashCode == num && entry.Value.Equals(key, StringComparison.Ordinal))
				{
					return entry.Value;
				}
			}
			return AddEntry(key, num);
		}

		private string AddEntry(string str, int hashCode)
		{
			int num = hashCode & _mask;
			Entry entry = new Entry(str, hashCode, _entries[num]);
			_entries[num] = entry;
			if (_count++ == _mask)
			{
				Grow();
			}
			return entry.Value;
		}

		private void Grow()
		{
			Entry[] entries = _entries;
			int num = _mask * 2 + 1;
			Entry[] array = new Entry[num + 1];
			for (int i = 0; i < entries.Length; i++)
			{
				Entry entry = entries[i];
				while (entry != null)
				{
					int num2 = entry.HashCode & num;
					Entry next = entry.Next;
					entry.Next = array[num2];
					array[num2] = entry;
					entry = next;
				}
			}
			_entries = array;
			_mask = num;
		}

		private static bool TextEquals(string str1, char[] str2, int str2Start, int str2Length)
		{
			if (str1.Length != str2Length)
			{
				return false;
			}
			for (int i = 0; i < str1.Length; i++)
			{
				if (str1[i] != str2[str2Start + i])
				{
					return false;
				}
			}
			return true;
		}
	}
	[Flags]
	public enum DefaultValueHandling
	{
		Include = 0,
		Ignore = 1,
		Populate = 2,
		IgnoreAndPopulate = 3
	}
	public enum FloatFormatHandling
	{
		String,
		Symbol,
		DefaultValue
	}
	public enum FloatParseHandling
	{
		Double,
		Decimal
	}
	public enum Formatting
	{
		None,
		Indented
	}
	public interface IArrayPool<T>
	{
		T[] Rent(int minimumLength);

		void Return(T[]? array);
	}
	public interface IJsonLineInfo
	{
		int LineNumber { get; }

		int LinePosition { get; }

		bool HasLineInfo();
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonArrayAttribute : JsonContainerAttribute
	{
		private bool _allowNullItems;

		public bool AllowNullItems
		{
			get
			{
				return _allowNullItems;
			}
			set
			{
				_allowNullItems = value;
			}
		}

		public JsonArrayAttribute()
		{
		}

		public JsonArrayAttribute(bool allowNullItems)
		{
			_allowNullItems = allowNullItems;
		}

		public JsonArrayAttribute(string id)
			: base(id)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)]
	public sealed class JsonConstructorAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public abstract class JsonContainerAttribute : Attribute
	{
		internal bool? _isReference;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		private Type? _namingStrategyType;

		private object[]? _namingStrategyParameters;

		public string? Id { get; set; }

		public string? Title { get; set; }

		public string? Description { get; set; }

		public Type? ItemConverterType { get; set; }

		public object[]? ItemConverterParameters { get; set; }

		public Type? NamingStrategyType
		{
			get
			{
				return _namingStrategyType;
			}
			set
			{
				_namingStrategyType = value;
				NamingStrategyInstance = null;
			}
		}

		public object[]? NamingStrategyParameters
		{
			get
			{
				return _namingStrategyParameters;
			}
			set
			{
				_namingStrategyParameters = value;
				NamingStrategyInstance = null;
			}
		}

		internal NamingStrategy? NamingStrategyInstance { get; set; }

		public bool IsReference
		{
			get
			{
				return _isReference.GetValueOrDefault();
			}
			set
			{
				_isReference = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference.GetValueOrDefault();
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling.GetValueOrDefault();
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		protected JsonContainerAttribute()
		{
		}

		protected JsonContainerAttribute(string id)
		{
			Id = id;
		}
	}
	public static class JsonConvert
	{
		public static readonly string True = "true";

		public static readonly string False = "false";

		public static readonly string Null = "null";

		public static readonly string Undefined = "undefined";

		public static readonly string PositiveInfinity = "Infinity";

		public static readonly string NegativeInfinity = "-Infinity";

		public static readonly string NaN = "NaN";

		public static Func<JsonSerializerSettings>? DefaultSettings { get; set; }

		public static string ToString(DateTime value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind);
		}

		public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling)
		{
			DateTime value2 = DateTimeUtils.EnsureDateTime(value, timeZoneHandling);
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeString(stringWriter, value2, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(DateTimeOffset value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat);
		}

		public static string ToString(DateTimeOffset value, DateFormatHandling format)
		{
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(bool value)
		{
			return value ? True : False;
		}

		public static string ToString(char value)
		{
			return ToString(char.ToString(value));
		}

		public static string ToString(Enum value)
		{
			return value.ToString("D");
		}

		public static string ToString(int value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(short value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ushort value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(uint value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(long value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		private static string ToStringInternal(BigInteger value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ulong value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(float value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			if (floatFormatHandling == FloatFormatHandling.Symbol || (!double.IsInfinity(value) && !double.IsNaN(value)))
			{
				return text;
			}
			if (floatFormatHandling == FloatFormatHandling.DefaultValue)
			{
				return (!nullable) ? "0.0" : Null;
			}
			return quoteChar + text + quoteChar;
		}

		public static string ToString(double value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureDecimalPlace(double value, string text)
		{
			if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1 || text.IndexOf('e') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		private static string EnsureDecimalPlace(string text)
		{
			if (text.IndexOf('.') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		public static string ToString(byte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(sbyte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(decimal value)
		{
			return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
		}

		public static string ToString(Guid value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(Guid value, char quoteChar)
		{
			string text = value.ToString("D", CultureInfo.InvariantCulture);
			string text2 = quoteChar.ToString(CultureInfo.InvariantCulture);
			return text2 + text + text2;
		}

		public static string ToString(TimeSpan value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(TimeSpan value, char quoteChar)
		{
			return ToString(value.ToString(), quoteChar);
		}

		public static string ToString(Uri? value)
		{
			if (value == null)
			{
				return Null;
			}
			return ToString(value, '"');
		}

		internal static string ToString(Uri value, char quoteChar)
		{
			return ToString(value.OriginalString, quoteChar);
		}

		public static string ToString(string? value)
		{
			return ToString(value, '"');
		}

		public static string ToString(string? value, char delimiter)
		{
			return ToString(value, delimiter, StringEscapeHandling.Default);
		}

		public static string ToString(string? value, char delimiter, StringEscapeHandling stringEscapeHandling)
		{
			if (delimiter != '"' && delimiter != '\'')
			{
				throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter");
			}
			return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, appendDelimiters: true, stringEscapeHandling);
		}

		public static string ToString(object? value)
		{
			if (value == null)
			{
				return Null;
			}
			return ConvertUtils.GetTypeCode(value.GetType()) switch
			{
				PrimitiveTypeCode.String => ToString((string)value), 
				PrimitiveTypeCode.Char => ToString((char)value), 
				PrimitiveTypeCode.Boolean => ToString((bool)value), 
				PrimitiveTypeCode.SByte => ToString((sbyte)value), 
				PrimitiveTypeCode.Int16 => ToString((short)value), 
				PrimitiveTypeCode.UInt16 => ToString((ushort)value), 
				PrimitiveTypeCode.Int32 => ToString((int)value), 
				PrimitiveTypeCode.Byte => ToString((byte)value), 
				PrimitiveTypeCode.UInt32 => ToString((uint)value), 
				PrimitiveTypeCode.Int64 => ToString((long)value), 
				PrimitiveTypeCode.UInt64 => ToString((ulong)value), 
				PrimitiveTypeCode.Single => ToString((float)value), 
				PrimitiveTypeCode.Double => ToString((double)value), 
				PrimitiveTypeCode.DateTime => ToString((DateTime)value), 
				PrimitiveTypeCode.Decimal => ToString((decimal)value), 
				PrimitiveTypeCode.DBNull => Null, 
				PrimitiveTypeCode.DateTimeOffset => ToString((DateTimeOffset)value), 
				PrimitiveTypeCode.Guid => ToString((Guid)value), 
				PrimitiveTypeCode.Uri => ToString((Uri)value), 
				PrimitiveTypeCode.TimeSpan => ToString((TimeSpan)value), 
				PrimitiveTypeCode.BigInteger => ToStringInternal((BigInteger)value), 
				_ => throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())), 
			};
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value)
		{
			return SerializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting)
		{
			return SerializeObject(value, formatting, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, formatting, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, JsonSerializerSettings? settings)
		{
			return SerializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Type? type, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Formatting formatting, JsonSerializerSettings? settings)
		{
			return SerializeObject(value, null, formatting, settings);
		}

		[DebuggerStepThrough]
		public static string SerializeObject(object? value, Type? type, Formatting formatting, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			jsonSerializer.Formatting = formatting;
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		private static string SerializeObjectInternal(object? value, Type? type, JsonSerializer jsonSerializer)
		{
			StringBuilder sb = new StringBuilder(256);
			StringWriter stringWriter = new StringWriter(sb, CultureInfo.InvariantCulture);
			using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter))
			{
				jsonTextWriter.Formatting = jsonSerializer.Formatting;
				jsonSerializer.Serialize(jsonTextWriter, value, type);
			}
			return stringWriter.ToString();
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value)
		{
			return DeserializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, JsonSerializerSettings settings)
		{
			return DeserializeObject(value, null, settings);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, Type type)
		{
			return DeserializeObject(value, type, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value)
		{
			return JsonConvert.DeserializeObject<T>(value, (JsonSerializerSettings?)null);
		}

		[DebuggerStepThrough]
		public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
		{
			return DeserializeObject<T>(value);
		}

		[DebuggerStepThrough]
		public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings)
		{
			return DeserializeObject<T>(value, settings);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value, params JsonConverter[] converters)
		{
			return (T)DeserializeObject(value, typeof(T), converters);
		}

		[DebuggerStepThrough]
		public static T? DeserializeObject<T>(string value, JsonSerializerSettings? settings)
		{
			return (T)DeserializeObject(value, typeof(T), settings);
		}

		[DebuggerStepThrough]
		public static object? DeserializeObject(string value, Type type, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return DeserializeObject(value, type, settings);
		}

		public static object? DeserializeObject(string value, Type? type, JsonSerializerSettings? settings)
		{
			ValidationUtils.ArgumentNotNull(value, "value");
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			if (!jsonSerializer.IsCheckAdditionalContentSet())
			{
				jsonSerializer.CheckAdditionalContent = true;
			}
			using JsonTextReader reader = new JsonTextReader(new StringReader(value));
			return jsonSerializer.Deserialize(reader, type);
		}

		[DebuggerStepThrough]
		public static void PopulateObject(string value, object target)
		{
			PopulateObject(value, target, null);
		}

		public static void PopulateObject(string value, object target, JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			using JsonReader jsonReader = new JsonTextReader(new StringReader(value));
			jsonSerializer.Populate(jsonReader, target);
			if (settings == null || !settings.CheckAdditionalContent)
			{
				return;
			}
			while (jsonReader.Read())
			{
				if (jsonReader.TokenType != JsonToken.Comment)
				{
					throw JsonSerializationException.Create(jsonReader, "Additional text found in JSON string after finishing deserializing object.");
				}
			}
		}

		public static string SerializeXmlNode(XmlNode? node)
		{
			return SerializeXmlNode(node, Formatting.None);
		}

		public static string SerializeXmlNode(XmlNode? node, Formatting formatting)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static string SerializeXmlNode(XmlNode? node, Formatting formatting, bool omitRootObject)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
			{
				OmitRootObject = omitRootObject
			};
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static XmlDocument? DeserializeXmlNode(string value)
		{
			return DeserializeXmlNode(value, null);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName)
		{
			return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute: false);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
		{
			return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
		}

		public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
			xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
			xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
			return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), xmlNodeConverter);
		}

		public static string SerializeXNode(XObject? node)
		{
			return SerializeXNode(node, Formatting.None);
		}

		public static string SerializeXNode(XObject? node, Formatting formatting)
		{
			return SerializeXNode(node, formatting, omitRootObject: false);
		}

		public static string SerializeXNode(XObject? node, Formatting formatting, bool omitRootObject)
		{
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
			{
				OmitRootObject = omitRootObject
			};
			return SerializeObject(node, formatting, xmlNodeConverter);
		}

		public static XDocument? DeserializeXNode(string value)
		{
			return DeserializeXNode(value, null);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName)
		{
			return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute: false);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
		{
			return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
		}

		public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
			xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
			xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
			xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
			return (XDocument)DeserializeObject(value, typeof(XDocument), xmlNodeConverter);
		}
	}
	public abstract class JsonConverter
	{
		public virtual bool CanRead => true;

		public virtual bool CanWrite => true;

		public abstract void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer);

		public abstract object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer);

		public abstract bool CanConvert(Type objectType);
	}
	public abstract class JsonConverter<T> : JsonConverter
	{
		public sealed override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
		{
			if (!((value != null) ? (value is T) : ReflectionUtils.IsNullable(typeof(T))))
			{
				throw new JsonSerializationException("Converter cannot write specified value to JSON. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
			}
			WriteJson(writer, (T)value, serializer);
		}

		public abstract void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer);

		public sealed override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
		{
			bool flag = existingValue == null;
			if (!flag && !(existingValue is T))
			{
				throw new JsonSerializationException("Converter cannot read JSON with the specified existing value. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
			}
			return ReadJson(reader, objectType, flag ? default(T) : ((T)existingValue), !flag, serializer);
		}

		public abstract T? ReadJson(JsonReader reader, Type objectType, T? existingValue, bool hasExistingValue, JsonSerializer serializer);

		public sealed override bool CanConvert(Type objectType)
		{
			return typeof(T).IsAssignableFrom(objectType);
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonConverterAttribute : Attribute
	{
		private readonly Type _converterType;

		public Type ConverterType => _converterType;

		public object[]? ConverterParameters { get; }

		public JsonConverterAttribute(Type converterType)
		{
			if (converterType == null)
			{
				throw new ArgumentNullException("converterType");
			}
			_converterType = converterType;
		}

		public JsonConverterAttribute(Type converterType, params object[] converterParameters)
			: this(converterType)
		{
			ConverterParameters = converterParameters;
		}
	}
	public class JsonConverterCollection : Collection<JsonConverter>
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonDictionaryAttribute : JsonContainerAttribute
	{
		public JsonDictionaryAttribute()
		{
		}

		public JsonDictionaryAttribute(string id)
			: base(id)
		{
		}
	}
	[Serializable]
	public class JsonException : Exception
	{
		public JsonException()
		{
		}

		public JsonException(string message)
			: base(message)
		{
		}

		public JsonException(string message, Exception? innerException)
			: base(message, innerException)
		{
		}

		public JsonException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			return new JsonException(message);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public class JsonExtensionDataAttribute : Attribute
	{
		public bool WriteData { get; set; }

		public bool ReadData { get; set; }

		public JsonExtensionDataAttribute()
		{
			WriteData = true;
			ReadData = true;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonIgnoreAttribute : Attribute
	{
	}
	public abstract class JsonNameTable
	{
		public abstract string? Get(char[] key, int start, int length);
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonObjectAttribute : JsonContainerAttribute
	{
		private MemberSerialization _memberSerialization = MemberSerialization.OptOut;

		internal MissingMemberHandling? _missingMemberHandling;

		internal Required? _itemRequired;

		internal NullValueHandling? _itemNullValueHandling;

		public MemberSerialization MemberSerialization
		{
			get
			{
				return _memberSerialization;
			}
			set
			{
				_memberSerialization = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling.GetValueOrDefault();
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public NullValueHandling ItemNullValueHandling
		{
			get
			{
				return _itemNullValueHandling.GetValueOrDefault();
			}
			set
			{
				_itemNullValueHandling = value;
			}
		}

		public Required ItemRequired
		{
			get
			{
				return _itemRequired.GetValueOrDefault();
			}
			set
			{
				_itemRequired = value;
			}
		}

		public JsonObjectAttribute()
		{
		}

		public JsonObjectAttribute(MemberSerialization memberSerialization)
		{
			MemberSerialization = memberSerialization;
		}

		public JsonObjectAttribute(string id)
			: base(id)
		{
		}
	}
	internal enum JsonContainerType
	{
		None,
		Object,
		Array,
		Constructor
	}
	internal struct JsonPosition
	{
		private static readonly char[] SpecialCharacters = new char[18]
		{
			'.', ' ', '\'', '/', '"', '[', ']', '(', ')', '\t',
			'\n', '\r', '\f', '\b', '\\', '\u0085', '\u2028', '\u2029'
		};

		internal JsonContainerType Type;

		internal int Position;

		internal string? PropertyName;

		internal bool HasIndex;

		public JsonPosition(JsonContainerType type)
		{
			Type = type;
			HasIndex = TypeHasIndex(type);
			Position = -1;
			PropertyName = null;
		}

		internal int CalculateLength()
		{
			switch (Type)
			{
			case JsonContainerType.Object:
				return PropertyName.Length + 5;
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				return MathUtils.IntLength((ulong)Position) + 2;
			default:
				throw new ArgumentOutOfRangeException("Type");
			}
		}

		internal void WriteTo(StringBuilder sb, ref StringWriter? writer, ref char[]? buffer)
		{
			switch (Type)
			{
			case JsonContainerType.Object:
			{
				string propertyName = PropertyName;
				if (propertyName.IndexOfAny(SpecialCharacters) != -1)
				{
					sb.Append("['");
					if (writer == null)
					{
						writer = new StringWriter(sb);
					}
					JavaScriptUtils.WriteEscapedJavaScriptString(writer, propertyName, '\'', appendDelimiters: false, JavaScriptUtils.SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, null, ref buffer);
					sb.Append("']");
				}
				else
				{
					if (sb.Length > 0)
					{
						sb.Append('.');
					}
					sb.Append(propertyName);
				}
				break;
			}
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				sb.Append('[');
				sb.Append(Position);
				sb.Append(']');
				break;
			}
		}

		internal static bool TypeHasIndex(JsonContainerType type)
		{
			return type == JsonContainerType.Array || type == JsonContainerType.Constructor;
		}

		internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition)
		{
			int num = 0;
			if (positions != null)
			{
				for (int i = 0; i < positions.Count; i++)
				{
					num += positions[i].CalculateLength();
				}
			}
			if (currentPosition.HasValue)
			{
				num += currentPosition.GetValueOrDefault().CalculateLength();
			}
			StringBuilder stringBuilder = new StringBuilder(num);
			StringWriter writer = null;
			char[] buffer = null;
			if (positions != null)
			{
				foreach (JsonPosition position in positions)
				{
					position.WriteTo(stringBuilder, ref writer, ref buffer);
				}
			}
			currentPosition?.WriteTo(stringBuilder, ref writer, ref buffer);
			return stringBuilder.ToString();
		}

		internal static string FormatMessage(IJsonLineInfo? lineInfo, string path, string message)
		{
			if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal))
			{
				message = message.Trim();
				if (!StringUtils.EndsWith(message, '.'))
				{
					message += ".";
				}
				message += " ";
			}
			message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path);
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition);
			}
			message += ".";
			return message;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonPropertyAttribute : Attribute
	{
		internal NullValueHandling? _nullValueHandling;

		internal DefaultValueHandling? _defaultValueHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal bool? _isReference;

		internal int? _order;

		internal Required? _required;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		public Type? ItemConverterType { get; set; }

		public object[]? ItemConverterParameters { get; set; }

		public Type? NamingStrategyType { get; set; }

		public object[]? NamingStrategyParameters { get; set; }

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling.GetValueOrDefault();
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling.GetValueOrDefault();
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling.GetValueOrDefault();
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling.GetValueOrDefault();
			}
			set
			{
				_typeNameHandling = value;
			}
		}

		public bool IsReference
		{
			get
			{
				return _isReference.GetValueOrDefault();
			}
			set
			{
				_isReference = value;
			}
		}

		public int Order
		{
			get
			{
				return _order.GetValueOrDefault();
			}
			set
			{
				_order = value;
			}
		}

		public Required Required
		{
			get
			{
				return _required.GetValueOrDefault();
			}
			set
			{
				_required = value;
			}
		}

		public string? PropertyName { get; set; }

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling.GetValueOrDefault();
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference.GetValueOrDefault();
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public JsonPropertyAttribute()
		{
		}

		public JsonPropertyAttribute(string propertyName)
		{
			PropertyName = propertyName;
		}
	}
	public abstract class JsonReader : IDisposable
	{
		protected internal enum State
		{
			Start,
			Complete,
			Property,
			ObjectStart,
			Object,
			ArrayStart,
			Array,
			Closed,
			PostValue,
			ConstructorStart,
			Constructor,
			Error,
			Finished
		}

		private JsonToken _tokenType;

		private object? _value;

		internal char _quoteChar;

		internal State _currentState;

		private JsonPosition _currentPosition;

		private CultureInfo? _culture;

		private DateTimeZoneHandling _dateTimeZoneHandling;

		private int? _maxDepth;

		private bool _hasExceededMaxDepth;

		internal DateParseHandling _dateParseHandling;

		internal FloatParseHandling _floatParseHandling;

		private string? _dateFormatString;

		private List<JsonPosition>? _stack;

		protected State CurrentState => _currentState;

		public bool CloseInput { get; set; }

		public bool SupportMultipleContent { get; set; }

		public virtual char QuoteChar
		{
			get
			{
				return _quoteChar;
			}
			protected internal set
			{
				_quoteChar = value;
			}
		}

		public DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling;
			}
			set
			{
				if (value < DateTimeZoneHandling.Local || value > DateTimeZoneHandling.RoundtripKind)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateTimeZoneHandling = value;
			}
		}

		public DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling;
			}
			set
			{
				if (value < DateParseHandling.None || value > DateParseHandling.DateTimeOffset)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateParseHandling = value;
			}
		}

		public FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling;
			}
			set
			{
				if (value < FloatParseHandling.Double || value > FloatParseHandling.Decimal)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_floatParseHandling = value;
			}
		}

		public string? DateFormatString
		{
			get
			{
				return _dateFormatString;
			}
			set
			{
				_dateFormatString = value;
			}
		}

		public int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
			}
		}

		public virtual JsonToken TokenType => _tokenType;

		public virtual object? Value => _value;

		public virtual Type? ValueType => _value?.GetType();

		public virtual int Depth
		{
			get
			{
				int num = _stack?.Count ?? 0;
				if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None)
				{
					return num;
				}
				return num + 1;
			}
		}

		public virtual string Path
		{
			get
			{
				if (_currentPosition.Type == JsonContainerType.None)
				{
					return string.Empty;
				}
				JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : null);
				return JsonPosition.BuildPath(_stack, currentPosition);
			}
		}

		public CultureInfo Culture
		{
			get
			{
				return _culture ?? CultureInfo.InvariantCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual Task<bool> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<bool>() ?? Read().ToAsync();
		}

		public async Task SkipAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			if (TokenType == JsonToken.PropertyName)
			{
				await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false) && depth < Depth)
				{
				}
			}
		}

		internal async Task ReaderReadAndAssertAsync(CancellationToken cancellationToken)
		{
			if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
			{
				throw CreateUnexpectedEndException();
			}
		}

		public virtual Task<bool?> ReadAsBooleanAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<bool?>() ?? Task.FromResult(ReadAsBoolean());
		}

		public virtual Task<byte[]?> ReadAsBytesAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<byte[]>() ?? Task.FromResult(ReadAsBytes());
		}

		internal async Task<byte[]?> ReadArrayIntoByteArrayAsync(CancellationToken cancellationToken)
		{
			List<byte> buffer = new List<byte>();
			do
			{
				if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					SetToken(JsonToken.None);
				}
			}
			while (!ReadArrayElementIntoByteArrayReportDone(buffer));
			byte[] d = buffer.ToArray();
			SetToken(JsonToken.Bytes, d, updateIndex: false);
			return d;
		}

		public virtual Task<DateTime?> ReadAsDateTimeAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<DateTime?>() ?? Task.FromResult(ReadAsDateTime());
		}

		public virtual Task<DateTimeOffset?> ReadAsDateTimeOffsetAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<DateTimeOffset?>() ?? Task.FromResult(ReadAsDateTimeOffset());
		}

		public virtual Task<decimal?> ReadAsDecimalAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<decimal?>() ?? Task.FromResult(ReadAsDecimal());
		}

		public virtual Task<double?> ReadAsDoubleAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return Task.FromResult(ReadAsDouble());
		}

		public virtual Task<int?> ReadAsInt32Async(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<int?>() ?? Task.FromResult(ReadAsInt32());
		}

		public virtual Task<string?> ReadAsStringAsync(CancellationToken cancellationToken = default(CancellationToken))
		{
			return cancellationToken.CancelIfRequestedAsync<string>() ?? Task.FromResult(ReadAsString());
		}

		internal async Task<bool> ReadAndMoveToContentAsync(CancellationToken cancellationToken)
		{
			bool flag = await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			if (flag)
			{
				flag = await MoveToContentAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
			}
			return flag;
		}

		internal Task<bool> MoveToContentAsync(CancellationToken cancellationToken)
		{
			JsonToken tokenType = TokenType;
			JsonToken jsonToken = tokenType;
			if (jsonToken == JsonToken.None || jsonToken == JsonToken.Comment)
			{
				return MoveToContentFromNonContentAsync(cancellationToken);
			}
			return AsyncUtils.True;
		}

		private async Task<bool> MoveToContentFromNonContentAsync(CancellationToken cancellationToken)
		{
			JsonToken jsonToken2;
			do
			{
				if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
				{
					return false;
				}
				JsonToken tokenType = TokenType;
				JsonToken jsonToken = tokenType;
				jsonToken2 = jsonToken;
			}
			while (jsonToken2 == JsonToken.None || jsonToken2 == JsonToken.Comment);
			return true;
		}

		internal JsonPosition GetPosition(int depth)
		{
			if (_stack != null && depth < _stack.Count)
			{
				return _stack[depth];
			}
			return _currentPosition;
		}

		protected JsonReader()
		{
			_currentState = State.Start;
			_dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
			_dateParseHandling = DateParseHandling.DateTime;
			_floatParseHandling = FloatParseHandling.Double;
			_maxDepth = 64;
			CloseInput = true;
		}

		private void Push(JsonContainerType value)
		{
			UpdateScopeWithFinishedValue();
			if (_currentPosition.Type == JsonContainerType.None)
			{
				_currentPosition = new JsonPosition(value);
				return;
			}
			if (_stack == null)
			{
				_stack = new List<JsonPosition>();
			}
			_stack.Add(_currentPosition);
			_currentPosition = new JsonPosition(value);
			if (!_maxDepth.HasValue || !(Depth + 1 > _maxDepth) || _hasExceededMaxDepth)
			{
				return;
			}
			_hasExceededMaxDepth = true;
			throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth));
		}

		private JsonContainerType Pop()
		{
			JsonPosition currentPosition;
			if (_stack != null && _stack.Count > 0)
			{
				currentPosition = _currentPosition;
				_currentPosition = _stack[_stack.Count - 1];
				_stack.RemoveAt(_stack.Count - 1);
			}
			else
			{
				currentPosition = _currentPosition;
				_currentPosition = default(JsonPosition);
			}
			if (_maxDepth.HasValue && Depth <= _maxDepth)
			{
				_hasExceededMaxDepth = false;
			}
			return currentPosition.Type;
		}

		private JsonContainerType Peek()
		{
			return _currentPosition.Type;
		}

		public abstract bool Read();

		public virtual int? ReadAsInt32()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is int value2)
				{
					return value2;
				}
				int num;
				if (value is BigInteger bigInteger)
				{
					num = (int)bigInteger;
				}
				else
				{
					try
					{
						num = Convert.ToInt32(value, CultureInfo.InvariantCulture);
					}
					catch (Exception ex)
					{
						throw JsonReaderException.Create(this, "Could not convert to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
					}
				}
				SetToken(JsonToken.Integer, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadInt32String(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal int? ReadInt32String(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (int.TryParse(s, NumberStyles.Integer, Culture, out var result))
			{
				SetToken(JsonToken.Integer, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual string? ReadAsString()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.String:
				return (string)Value;
			default:
				if (JsonTokenUtils.IsPrimitiveToken(contentToken))
				{
					object value = Value;
					if (value != null)
					{
						string text = ((!(value is IFormattable formattable)) ? ((value is Uri uri) ? uri.OriginalString : value.ToString()) : formattable.ToString(null, Culture));
						SetToken(JsonToken.String, text, updateIndex: false);
						return text;
					}
				}
				throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		public virtual byte[]? ReadAsBytes()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.StartObject:
			{
				ReadIntoWrappedTypeObject();
				byte[] array3 = ReadAsBytes();
				ReaderReadAndAssert();
				if (TokenType != JsonToken.EndObject)
				{
					throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
				}
				SetToken(JsonToken.Bytes, array3, updateIndex: false);
				return array3;
			}
			case JsonToken.String:
			{
				string text = (string)Value;
				Guid g;
				byte[] array2 = ((text.Length == 0) ? CollectionUtils.ArrayEmpty<byte>() : ((!ConvertUtils.TryConvertGuid(text, out g)) ? Convert.FromBase64String(text) : g.ToByteArray()));
				SetToken(JsonToken.Bytes, array2, updateIndex: false);
				return array2;
			}
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Bytes:
				if (Value is Guid guid)
				{
					byte[] array = guid.ToByteArray();
					SetToken(JsonToken.Bytes, array, updateIndex: false);
					return array;
				}
				return (byte[])Value;
			case JsonToken.StartArray:
				return ReadArrayIntoByteArray();
			default:
				throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal byte[] ReadArrayIntoByteArray()
		{
			List<byte> list = new List<byte>();
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
				}
			}
			while (!ReadArrayElementIntoByteArrayReportDone(list));
			byte[] array = list.ToArray();
			SetToken(JsonToken.Bytes, array, updateIndex: false);
			return array;
		}

		private bool ReadArrayElementIntoByteArrayReportDone(List<byte> buffer)
		{
			switch (TokenType)
			{
			case JsonToken.None:
				throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
			case JsonToken.Integer:
				buffer.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
				return false;
			case JsonToken.EndArray:
				return true;
			case JsonToken.Comment:
				return false;
			default:
				throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		public virtual double? ReadAsDouble()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is double value2)
				{
					return value2;
				}
				double num = ((!(value is BigInteger bigInteger) || 1 == 0) ? Convert.ToDouble(value, CultureInfo.InvariantCulture) : ((double)bigInteger));
				SetToken(JsonToken.Float, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
				return ReadDoubleString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal double? ReadDoubleString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (double.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to double: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual bool? ReadAsBoolean()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				bool flag = ((!(Value is BigInteger bigInteger) || 1 == 0) ? Convert.ToBoolean(Value, CultureInfo.InvariantCulture) : (bigInteger != 0L));
				SetToken(JsonToken.Boolean, flag, updateIndex: false);
				return flag;
			}
			case JsonToken.String:
				return ReadBooleanString((string)Value);
			case JsonToken.Boolean:
				return (bool)Value;
			default:
				throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal bool? ReadBooleanString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (bool.TryParse(s, out var result))
			{
				SetToken(JsonToken.Boolean, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual decimal? ReadAsDecimal()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				object value = Value;
				if (value is decimal value2)
				{
					return value2;
				}
				decimal num;
				if (value is BigInteger bigInteger)
				{
					num = (decimal)bigInteger;
				}
				else
				{
					try
					{
						num = Convert.ToDecimal(value, CultureInfo.InvariantCulture);
					}
					catch (Exception ex)
					{
						throw JsonReaderException.Create(this, "Could not convert to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
					}
				}
				SetToken(JsonToken.Float, num, updateIndex: false);
				return num;
			}
			case JsonToken.String:
				return ReadDecimalString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal decimal? ReadDecimalString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (decimal.TryParse(s, NumberStyles.Number, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			if (ConvertUtils.DecimalTryParse(s.ToCharArray(), 0, s.Length, out result) == ParseResult.Success)
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTime? ReadAsDateTime()
		{
			switch (GetContentToken())
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTimeOffset dateTimeOffset)
				{
					SetToken(JsonToken.Date, dateTimeOffset.DateTime, updateIndex: false);
				}
				return (DateTime)Value;
			case JsonToken.String:
				return ReadDateTimeString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		internal DateTime? ReadDateTimeString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTime(s, DateTimeZoneHandling, _dateFormatString, Culture, out var dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTimeOffset? ReadAsDateTimeOffset()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTime dateTime)
				{
					SetToken(JsonToken.Date, new DateTimeOffset(dateTime), updateIndex: false);
				}
				return (DateTimeOffset)Value;
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadDateTimeOffsetString(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal DateTimeOffset? ReadDateTimeOffsetString(string? s)
		{
			if (StringUtils.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTimeOffset(s, _dateFormatString, Culture, out var dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		internal void ReaderReadAndAssert()
		{
			if (!Read())
			{
				throw CreateUnexpectedEndException();
			}
		}

		internal JsonReaderException CreateUnexpectedEndException()
		{
			return JsonReaderException.Create(this, "Unexpected end when reading JSON.");
		}

		internal void ReadIntoWrappedTypeObject()
		{
			ReaderReadAndAssert();
			if (Value != null && Value.ToString() == "$type")
			{
				ReaderReadAndAssert();
				if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal))
				{
					ReaderReadAndAssert();
					if (Value.ToString() == "$value")
					{
						return;
					}
				}
			}
			throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject));
		}

		public void Skip()
		{
			if (TokenType == JsonToken.PropertyName)
			{
				Read();
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (Read() && depth < Depth)
				{
				}
			}
		}

		protected void SetToken(JsonToken newToken)
		{
			SetToken(newToken, null, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object? value)
		{
			SetToken(newToken, value, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object? value, bool updateIndex)
		{
			_tokenType = newToken;
			_value = value;
			switch (newToken)
			{
			case JsonToken.StartObject:
				_currentState = State.ObjectStart;
				Push(JsonContainerType.Object);
				break;
			case JsonToken.StartArray:
				_currentState = State.ArrayStart;
				Push(JsonContainerType.Array);
				break;
			case JsonToken.StartConstructor:
				_currentState = State.ConstructorStart;
				Push(JsonContainerType.Constructor);
				break;
			case JsonToken.EndObject:
				ValidateEnd(JsonToken.EndObject);
				break;
			case JsonToken.EndArray:
				ValidateEnd(JsonToken.EndArray);
				break;
			case JsonToken.EndConstructor:
				ValidateEnd(JsonToken.EndConstructor);
				break;
			case JsonToken.PropertyName:
				_currentState = State.Property;
				_currentPosition.PropertyName = (string)value;
				break;
			case JsonToken.Raw:
			case JsonToken.Integer:
			case JsonToken.Float:
			case JsonToken.String:
			case JsonToken.Boolean:
			case JsonToken.Null:
			case JsonToken.Undefined:
			case JsonToken.Date:
			case JsonToken.Bytes:
				SetPostValueState(updateIndex);
				break;
			case JsonToken.Comment:
				break;
			}
		}

		internal void SetPostValueState(bool updateIndex)
		{
			if (Peek() != 0 || SupportMultipleContent)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
			if (updateIndex)
			{
				UpdateScopeWithFinishedValue();
			}
		}

		private void UpdateScopeWithFinishedValue()
		{
			if (_currentPosition.HasIndex)
			{
				_currentPosition.Position++;
			}
		}

		private void ValidateEnd(JsonToken endToken)
		{
			JsonContainerType jsonContainerType = Pop();
			if (GetTypeForCloseToken(endToken) != jsonContainerType)
			{
				throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jsonContainerType));
			}
			if (Peek() != 0 || SupportMultipleContent)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
		}

		protected void SetStateBasedOnCurrent()
		{
			JsonContainerType jsonContainerType = Peek();
			switch (jsonContainerType)
			{
			case JsonContainerType.Object:
				_currentState = State.Object;
				break;
			case JsonContainerType.Array:
				_currentState = State.Array;
				break;
			case JsonContainerType.Constructor:
				_currentState = State.Constructor;
				break;
			case JsonContainerType.None:
				SetFinished();
				break;
			default:
				throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContainerType));
			}
		}

		private void SetFinished()
		{
			_currentState = ((!SupportMultipleContent) ? State.Finished : State.Start);
		}

		private JsonContainerType GetTypeForCloseToken(JsonToken token)
		{
			return token switch
			{
				JsonToken.EndObject => JsonContainerType.Object, 
				JsonToken.EndArray => JsonContainerType.Array, 
				JsonToken.EndConstructor => JsonContainerType.Constructor, 
				_ => throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)), 
			};
		}

		void IDisposable.Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (_currentState != State.Closed && disposing)
			{
				Close();
			}
		}

		public virtual void Close()
		{
			_currentState = State.Closed;
			_tokenType = JsonToken.None;
			_value = null;
		}

		internal void ReadAndAssert()
		{
			if (!Read())
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal void ReadForTypeAndAssert(JsonContract? contract, bool hasConverter)
		{
			if (!ReadForType(contract, hasConverter))
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal bool ReadForType(JsonContract? contract, bool hasConverter)
		{
			if (hasConverter)
			{
				return Read();
			}
			switch (contract?.InternalReadType ?? ReadType.Read)
			{
			case ReadType.Read:
				return ReadAndMoveToContent();
			case ReadType.ReadAsInt32:
				ReadAsInt32();
				break;
			case ReadType.ReadAsInt64:
			{
				bool result = ReadAndMoveToContent();
				if (TokenType == JsonToken.Undefined)
				{
					throw JsonReaderException.Create(this, "An undefined token is not a valid {0}.".FormatWith(CultureInfo.InvariantCulture, contract?.UnderlyingType ?? typeof(long)));
				}
				return result;
			}
			case ReadType.ReadAsDecimal:
				ReadAsDecimal();
				break;
			case ReadType.ReadAsDouble:
				ReadAsDouble();
				break;
			case ReadType.ReadAsBytes:
				ReadAsBytes();
				break;
			case ReadType.ReadAsBoolean:
				ReadAsBoolean();
				break;
			case ReadType.ReadAsString:
				ReadAsString();
				break;
			case ReadType.ReadAsDateTime:
				ReadAsDateTime();
				break;
			case ReadType.ReadAsDateTimeOffset:
				ReadAsDateTimeOffset();
				break;
			default:
				throw new ArgumentOutOfRangeException();
			}
			return TokenType != JsonToken.None;
		}

		internal bool ReadAndMoveToContent()
		{
			return Read() && MoveToContent();
		}

		internal bool MoveToContent()
		{
			JsonToken tokenType = TokenType;
			while (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
			{
				if (!Read())
				{
					return false;
				}
				tokenType = TokenType;
			}
			return true;
		}

		private JsonToken GetContentToken()
		{
			JsonToken tokenType;
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
					return JsonToken.None;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.Comment);
			return tokenType;
		}
	}
	[Serializable]
	public class JsonReaderException : JsonException
	{
		public int LineNumber { get; }

		public int LinePosition { get; }

		public string? Path { get; }

		public JsonReaderException()
		{
		}

		public JsonReaderException(string message)
			: base(message)
		{
		}

		public JsonReaderException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonReaderException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonReaderException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonReaderException Create(JsonReader reader, string message, Exception? ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonReaderException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonReaderException(message, path, lineNumber, linePosition, ex);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonRequiredAttribute : Attribute
	{
	}
	[Serializable]
	public class JsonSerializationException : JsonException
	{
		public int LineNumber { get; }

		public int LinePosition { get; }

		public string? Path { get; }

		public JsonSerializationException()
		{
		}

		public JsonSerializationException(string message)
			: base(message)
		{
		}

		public JsonSerializationException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonSerializationException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		public JsonSerializationException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonSerializationException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonSerializationException Create(JsonReader reader, string message, Exception? ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonSerializationException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonSerializationException(message, path, lineNumber, linePosition, ex);
		}
	}
	public class JsonSerializer
	{
		internal TypeNameHandling _typeNameHandling;

		internal TypeNameAssemblyFormatHandling _typeNameAssemblyFormatHandling;

		internal PreserveReferencesHandling _preserveReferencesHandling;

		internal ReferenceLoopHandling _referenceLoopHandling;

		internal MissingMemberHandling _missingMemberHandling;

		internal ObjectCreationHandling _objectCreationHandling;

		internal NullValueHandling _nullValueHandling;

		internal DefaultValueHandling _defaultValueHandling;

		internal ConstructorHandling _constructorHandling;

		internal MetadataPropertyHandling _metadataPropertyHandling;

		internal JsonConverterCollection? _converters;

		internal IContractResolver _contractResolver;

		internal ITraceWriter? _traceWriter;

		internal IEqualityComparer? _equalityComparer;

		internal ISerializationBinder _serializationBinder;

		internal StreamingContext _context;

		private IReferenceResolver? _referenceResolver;

		private Formatting? _formatting;

		private DateFormatHandling? _dateFormatHandling;

		private DateTimeZoneHandling? _dateTimeZoneHandling;

		private DateParseHandling? _dateParseHandling;

		private FloatFormatHandling? _floatFormatHandling;

		private FloatParseHandling? _floatParseHandling;

		private StringEscapeHandling? _stringEscapeHandling;

		private CultureInfo _culture;

		private int? _maxDepth;

		private bool _maxDepthSet;

		private bool? _checkAdditionalContent;

		private string? _dateFormatString;

		private bool _dateFormatStringSet;

		public virtual IReferenceResolver? ReferenceResolver
		{
			get
			{
				return GetReferenceResolver();
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Reference resolver cannot be null.");
				}
				_referenceResolver = value;
			}
		}

		[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
		public virtual SerializationBinder Binder
		{
			get
			{
				if (_serializationBinder is SerializationBinder result)
				{
					return result;
				}
				if (_serializationBinder is SerializationBinderAdapter serializationBinderAdapter)
				{
					return serializationBinderAdapter.SerializationBinder;
				}
				throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_serializationBinder = (value as ISerializationBinder) ?? new SerializationBinderAdapter(value);
			}
		}

		public virtual ISerializationBinder SerializationBinder
		{
			get
			{
				return _serializationBinder;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_serializationBinder = value;
			}
		}

		public virtual ITraceWriter? TraceWriter
		{
			get
			{
				return _traceWriter;
			}
			set
			{
				_traceWriter = value;
			}
		}

		public virtual IEqualityComparer? EqualityComparer
		{
			get
			{
				return _equalityComparer;
			}
			set
			{
				_equalityComparer = value;
			}
		}

		public virtual TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling;
			}
			set
			{
				if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameHandling = value;
			}
		}

		[Obsolete("TypeNameAssemblyFormat is obsolete. Use TypeNameAssemblyFormatHandling instead.")]
		public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
		{
			get
			{
				return (FormatterAssemblyStyle)_typeNameAssemblyFormatHandling;
			}
			set
			{
				if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormatHandling = (TypeNameAssemblyFormatHandling)value;
			}
		}

		public virtual TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling
		{
			get
			{
				return _typeNameAssemblyFormatHandling;
			}
			set
			{
				if (value < TypeNameAssemblyFormatHandling.Simple || value > TypeNameAssemblyFormatHandling.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormatHandling = value;
			}
		}

		public virtual PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling;
			}
			set
			{
				if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_preserveReferencesHandling = value;
			}
		}

		public virtual ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling;
			}
			set
			{
				if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_referenceLoopHandling = value;
			}
		}

		public virtual MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling;
			}
			set
			{
				if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_missingMemberHandling = value;
			}
		}

		public virtual NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling;
			}
			set
			{
				if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_nullValueHandling = value;
			}
		}

		public virtual DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling;
			}
			set
			{
				if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_defaultValueHandling = value;
			}
		}

		public virtual ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling;
			}
			set
			{
				if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_objectCreationHandling = value;
			}
		}

		public virtual ConstructorHandling ConstructorHandling
		{
			get
			{
				return _constructorHandling;
			}
			set
			{
				if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_constructorHandling = value;
			}
		}

		public virtual MetadataPropertyHandling MetadataPropertyHandling
		{
			get
			{
				return _metadataPropertyHandling;
			}
			set
			{
				if (value < MetadataPropertyHandling.Default || value > MetadataPropertyHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_metadataPropertyHandling = value;
			}
		}

		public virtual JsonConverterCollection Converters
		{
			get
			{
				if (_converters == null)
				{
					_converters = new JsonConverterCollection();
				}
				return _converters;
			}
		}

		public virtual IContractResolver ContractResolver
		{
			get
			{
				return _contractResolver;
			}
			set
			{
				_contractResolver = value ?? DefaultContractResolver.Instance;
			}
		}

		public virtual StreamingContext Context
		{
			get
			{
				return _context;
			}
			set
			{
				_context = value;
			}
		}

		public virtual Formatting Formatting
		{
			get
			{
				return _formatting.GetValueOrDefault();
			}
			set
			{
				_formatting = value;
			}
		}

		public virtual DateFormatHandling DateFormatHandling
		{
			get
			{
				return _dateFormatHandling.GetValueOrDefault();
			}
			set
			{
				_dateFormatHandling = value;
			}
		}

		public virtual DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling ?? DateTimeZoneHandling.RoundtripKind;
			}
			set
			{
				_dateTimeZoneHandling = value;
			}
		}

		public virtual DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling ?? DateParseHandling.DateTime;
			}
			set
			{
				_dateParseHandling = value;
			}
		}

		public virtual FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling.GetValueOrDefault();
			}
			set
			{
				_floatParseHandling = value;
			}
		}

		public virtual FloatFormatHandling FloatFormatHandling
		{
			get
			{
				return _floatFormatHandling.GetValueOrDefault();
			}
			set
			{
				_floatFormatHandling = value;
			}
		}

		public virtual StringEscapeHandling StringEscapeHandling
		{
			get
			{
				return _stringEscapeHandling.GetValueOrDefault();
			}
			set
			{
				_stringEscapeHandling = value;
			}
		}

		public virtual string DateFormatString
		{
			get
			{
				return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
			}
			set
			{
				_dateFormatString = value;
				_dateFormatStringSet = true;
			}
		}

		public virtual CultureInfo Culture
		{
			get
			{
				return _culture ?? JsonSerializerSettings.DefaultCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
				_maxDepthSet = true;
			}
		}

		public virtual bool CheckAdditionalContent
		{
			get
			{
				return _checkAdditionalContent.GetValueOrDefault();
			}
			set
			{
				_checkAdditionalContent = value;
			}
		}

		public virtual event EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs>? Error;

		internal bool IsCheckAdditionalContentSet()
		{
			return _checkAdditionalContent.HasValue;
		}

		public JsonSerializer()
		{
			_referenceLoopHandling = ReferenceLoopHandling.Error;
			_missingMemberHandling = MissingMemberHandling.Ignore;
			_nullValueHandling = NullValueHandling.Include;
			_defaultValueHandling = DefaultValueHandling.Include;
			_objectCreationHandling = ObjectCreationHandling.Auto;
			_preserveReferencesHandling = PreserveReferencesHandling.None;
			_constructorHandling = ConstructorHandling.Default;
			_typeNameHandling = TypeNameHandling.None;
			_metadataPropertyHandling = MetadataPropertyHandling.Default;
			_context = JsonSerializerSettings.DefaultContext;
			_serializationBinder = DefaultSerializationBinder.Instance;
			_culture = JsonSerializerSettings.DefaultCulture;
			_contractResolver = DefaultContractResolver.Instance;
		}

		public static JsonSerializer Create()
		{
			return new JsonSerializer();
		}

		public static JsonSerializer Create(JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = Create();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		public static JsonSerializer CreateDefault()
		{
			JsonSerializerSettings settings = JsonConvert.DefaultSettings?.Invoke();
			return Create(settings);
		}

		public static JsonSerializer CreateDefault(JsonSerializerSettings? settings)
		{
			JsonSerializer jsonSerializer = CreateDefault();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings)
		{
			if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
			{
				for (int i = 0; i < settings.Converters.Count; i++)
				{
					serializer.Converters.Insert(i, settings.Converters[i]);
				}
			}
			if (settings._typeNameHandling.HasValue)
			{
				serializer.TypeNameHandling = settings.TypeNameHandling;
			}
			if (settings._metadataPropertyHandling.HasValue)
			{
				serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling;
			}
			if (settings._typeNameAssemblyFormatHandling.HasValue)
			{
				serializer.TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling;
			}
			if (settings._preserveReferencesHandling.HasValue)
			{
				serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
			}
			if (settings._referenceLoopHandling.HasValue)
			{
				serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
			}
			if (settings._missingMemberHandling.HasValue)
			{
				serializer.MissingMemberHandling = settings.MissingMemberHandling;
			}
			if (settings._objectCreationHandling.HasValue)
			{
				serializer.ObjectCreationHandling = settings.ObjectCreationHandling;
			}
			if (settings._nullValueHandling.HasValue)
			{
				serializer.NullValueHandling = settings.NullValueHandling;
			}
			if (settings._defaultValueHandling.HasValue)
			{
				serializer.DefaultValueHandling = settings.DefaultValueHandling;
			}
			if (settings._constructorHandling.HasValue)
			{
				serializer.ConstructorHandling = settings.ConstructorHandling;
			}
			if (settings._context.HasValue)
			{
				serializer.Context = settings.Context;
			}
			if (settings._checkAdditionalContent.HasValue)
			{
				serializer._checkAdditionalContent = settings._checkAdditionalContent;
			}
			if (settings.Error != null)
			{
				serializer.Error += settings.Error;
			}
			if (settings.ContractResolver != null)
			{
				serializer.ContractResolver = settings.ContractResolver;
			}
			if (settings.ReferenceResolverProvider != null)
			{
				serializer.ReferenceResolver = settings.ReferenceResolverProvider();
			}
			if (settings.TraceWriter != null)
			{
				serializer.TraceWriter = settings.TraceWriter;
			}
			if (settings.EqualityComparer != null)
			{
				serializer.EqualityComparer = settings.EqualityComparer;
			}
			if (settings.SerializationBinder != null)
			{
				serializer.SerializationBinder = settings.SerializationBinder;
			}
			if (settings._formatting.HasValue)
			{
				serializer._formatting = settings._formatting;
			}
			if (settings._dateFormatHandling.HasValue)
			{
				serializer._dateFormatHandling = settings._dateFormatHandling;
			}
			if (settings._dateTimeZoneHandling.HasValue)
			{
				serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling;
			}
			if (settings._dateParseHandling.HasValue)
			{
				serializer._dateParseHandling = settings._dateParseHandling;
			}
			if (settings._dateFormatStringSet)
			{
				serializer._dateFormatString = settings._dateFormatString;
				serializer._dateFormatStringSet = settings._dateFormatStringSet;
			}
			if (settings._floatFormatHandling.HasValue)
			{
				serializer._floatFormatHandling = settings._floatFormatHandling;
			}
			if (settings._floatParseHandling.HasValue)
			{
				serializer._floatParseHandling = settings._floatParseHandling;
			}
			if (settings._stringEscapeHandling.HasValue)
			{
				serializer._stringEscapeHandling = settings._stringEscapeHandling;
			}
			if (settings._culture != null)
			{
				serializer._culture = settings._culture;
			}
			if (settings._maxDepthSet)
			{
				serializer._maxDepth = settings._maxDepth;
				serializer._maxDepthSet = settings._maxDepthSet;
			}
		}

		[DebuggerStepThrough]
		public void Populate(TextReader reader, object target)
		{
			Populate(new JsonTextReader(reader), target);
		}

		[DebuggerStepThrough]
		public void Populate(JsonReader reader, object target)
		{
			PopulateInternal(reader, target);
		}

		internal virtual void PopulateInternal(JsonReader reader, object target)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			ValidationUtils.ArgumentNotNull(target, "target");
			SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
			JsonSerializerInternalReader jsonSerializerInternalReader = new JsonSerializerInternalReader(this);
			jsonSerializerInternalReader.Populate(traceJsonReader ?? reader, target);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
		}

		[DebuggerStepThrough]
		public object? Deserialize(JsonReader reader)
		{
			return Deserialize(reader, null);
		}

		[DebuggerStepThrough]
		public object? Deserialize(TextReader reader, Type objectType)
		{
			return Deserialize(new JsonTextReader(reader), objectType);
		}

		[DebuggerStepThrough]
		public T? Deserialize<T>(JsonReader reader)
		{
			return (T)Deserialize(reader, typeof(T));
		}

		[DebuggerStepThrough]
		public object? Deserialize(JsonReader reader, Type? objectType)
		{
			return DeserializeInternal(reader, objectType);
		}

		internal virtual object? DeserializeInternal(JsonReader reader, Type? objectType)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
			JsonSerializerInternalReader jsonSerializerInternalReader = new JsonSerializerInternalReader(this);
			object result = jsonSerializerInternalReader.Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
			return result;
		}

		internal void SetupReader(JsonReader reader, out CultureInfo? previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string? previousDateFormatString)
		{
			if (_culture != null && !_culture.Equals(reader.Culture))
			{
				previousCulture = reader.Culture;
				reader.Culture = _culture;
			}
			else
			{
				previousCulture = null;
			}
			if (_dateTimeZoneHandling.HasValue && reader.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				previousDateTimeZoneHandling = reader.DateTimeZoneHandling;
				reader.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			else
			{
				previousDateTimeZoneHandling = null;
			}
			if (_dateParseHandling.HasValue && reader.DateParseHandling != _dateParseHandling)
			{
				previousDateParseHandling = reader.DateParseHandling;
				reader.DateParseHandling = _dateParseHandling.GetValueOrDefault();
			}
			else
			{
				previousDateParseHandling = null;
			}
			if (_floatParseHandling.HasValue && reader.FloatParseHandling != _floatParseHandling)
			{
				previousFloatParseHandling = reader.FloatParseHandling;
				reader.FloatParseHandling = _floatParseHandling.GetValueOrDefault();
			}
			else
			{
				previousFloatParseHandling = null;
			}
			if (_maxDepthSet && reader.MaxDepth != _maxDepth)
			{
				previousMaxDepth = reader.MaxDepth;
				reader.MaxDepth = _maxDepth;
			}
			else
			{
				previousMaxDepth = null;
			}
			if (_dateFormatStringSet && reader.DateFormatString != _dateFormatString)
			{
				previousDateFormatString = reader.DateFormatString;
				reader.DateFormatString = _dateFormatString;
			}
			else
			{
				previousDateFormatString = null;
			}
			if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable == null && _contractResolver is DefaultContractResolver defaultContractResolver)
			{
				jsonTextReader.PropertyNameTable = defaultContractResolver.GetNameTable();
			}
		}

		private void ResetReader(JsonReader reader, CultureInfo? previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string? previousDateFormatString)
		{
			if (previousCulture != null)
			{
				reader.Culture = previousCulture;
			}
			if (previousDateTimeZoneHandling.HasValue)
			{
				reader.DateTimeZoneHandling = previousDateTimeZoneHandling.GetValueOrDefault();
			}
			if (previousDateParseHandling.HasValue)
			{
				reader.DateParseHandling = previousDateParseHandling.GetValueOrDefault();
			}
			if (previousFloatParseHandling.HasValue)
			{
				reader.FloatParseHandling = previousFloatParseHandling.GetValueOrDefault();
			}
			if (_maxDepthSet)
			{
				reader.MaxDepth = previousMaxDepth;
			}
			if (_dateFormatStringSet)
			{
				reader.DateFormatString = previousDateFormatString;
			}
			if (reader is JsonTextReader jsonTextReader && jsonTextReader.PropertyNameTable != null && _contractResolver is DefaultContractResolver defaultContractResolver && jsonTextReader.PropertyNameTable == defaultContractResolver.GetNameTable())
			{
				jsonTextReader.PropertyNameTable = null;
			}
		}

		public void Serialize(TextWriter textWriter, object? value)
		{
			Serialize(new JsonTextWriter(textWriter), value);
		}

		public void Serialize(JsonWriter jsonWriter, object? value, Type? objectType)
		{
			SerializeInternal(jsonWriter, value, objectType);
		}

		public void Serialize(TextWriter textWriter, object? value, Type objectType)
		{
			Serialize(new JsonTextWriter(textWriter), value, objectType);
		}

		public void Serialize(JsonWriter jsonWriter, object? value)
		{
			SerializeInternal(jsonWriter, value, null);
		}

		private TraceJsonReader CreateTraceJsonReader(JsonReader reader)
		{
			TraceJsonReader traceJsonReader = new TraceJsonReader(reader);
			if (reader.TokenType != 0)
			{
				traceJsonReader.WriteCurrentToken();
			}
			return traceJsonReader;
		}

		internal virtual void SerializeInternal(JsonWriter jsonWriter, object? value, Type? objectType)
		{
			ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");
			Formatting? formatting = null;
			if (_formatting.HasValue && jsonWriter.Formatting != _formatting)
			{
				formatting = jsonWriter.Formatting;
				jsonWriter.Formatting = _formatting.GetValueOrDefault();
			}
			DateFormatHandling? dateFormatHandling = null;
			if (_dateFormatHandling.HasValue && jsonWriter.DateFormatHandling != _dateFormatHandling)
			{
				dateFormatHandling = jsonWriter.DateFormatHandling;
				jsonWriter.DateFormatHandling = _dateFormatHandling.GetValueOrDefault();
			}
			DateTimeZoneHandling? dateTimeZoneHandling = null;
			if (_dateTimeZoneHandling.HasValue && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				dateTimeZoneHandling = jsonWriter.DateTimeZoneHandling;
				jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			FloatFormatHandling? floatFormatHandling = null;
			if (_floatFormatHandling.HasValue && jsonWriter.FloatFormatHandling != _floatFormatHandling)
			{
				floatFormatHandling = jsonWriter.FloatFormatHandling;
				jsonWriter.FloatFormatHandling = _floatFormatHandling.GetValueOrDefault();
			}
			StringEscapeHandling? stringEscapeHandling = null;
			if (_stringEscapeHandling.HasValue && jsonWriter.StringEscapeHandling != _stringEscapeHandling)
			{
				stringEscapeHandling = jsonWriter.StringEscapeHandling;
				jsonWriter.StringEscapeHandling = _stringEscapeHandling.GetValueOrDefault();
			}
			CultureInfo cultureInfo = null;
			if (_culture != null && !_culture.Equals(jsonWriter.Culture))
			{
				cultureInfo = jsonWriter.Culture;
				jsonWriter.Culture = _culture;
			}
			string dateFormatString = null;
			if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString)
			{
				dateFormatString = jsonWriter.DateFormatString;
				jsonWriter.DateFormatString = _dateFormatString;
			}
			TraceJsonWriter traceJsonWriter = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonWriter(jsonWriter) : null);
			JsonSerializerInternalWriter jsonSerializerInternalWriter = new JsonSerializerInternalWriter(this);
			jsonSerializerInternalWriter.Serialize(traceJsonWriter ?? jsonWriter, value, objectType);
			if (traceJsonWriter != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonWriter.GetSerializedJsonMessage(), null);
			}
			if (formatting.HasValue)
			{
				jsonWriter.Formatting = formatting.GetValueOrDefault();
			}
			if (dateFormatHandling.HasValue)
			{
				jsonWriter.DateFormatHandling = dateFormatHandling.GetValueOrDefault();
			}
			if (dateTimeZoneHandling.HasValue)
			{
				jsonWriter.DateTimeZoneHandling = dateTimeZoneHandling.GetValueOrDefault();
			}
			if (floatFormatHandling.HasValue)
			{
				jsonWriter.FloatFormatHandling = floatFormatHandling.GetValueOrDefault();
			}
			if (stringEscapeHandling.HasValue)
			{
				jsonWriter.StringEscapeHandling = stringEscapeHandling.GetValueOrDefault();
			}
			if (_dateFormatStringSet)
			{
				jsonWriter.DateFormatString = dateFormatString;
			}
			if (cultureInfo != null)
			{
				jsonWriter.Culture = cultureInfo;
			}
		}

		internal IReferenceResolver GetReferenceResolver()
		{
			if (_referenceResolver == null)
			{
				_referenceResolver = new DefaultReferenceResolver();
			}
			return _referenceResolver;
		}

		internal JsonConverter? GetMatchingConverter(Type type)
		{
			return GetMatchingConverter(_converters, type);
		}

		internal static JsonConverter? GetMatchingConverter(IList<JsonConverter>? converters, Type objectType)
		{
			ValidationUtils.ArgumentNotNull(objectType, "objectType");
			if (converters != null)
			{
				for (int i = 0; i < converters.Count; i++)
				{
					JsonConverter jsonConverter = converters[i];
					if (jsonConverter.CanConvert(objectType))
					{
						return jsonConverter;
					}
				}
			}
			return null;
		}

		internal void OnError(Newtonsoft.Json.Serialization.ErrorEventArgs e)
		{
			this.Error?.Invoke(this, e);
		}
	}
	public class JsonSerializerSettings
	{
		internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error;

		internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore;

		internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include;

		internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include;

		internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto;

		internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None;

		internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default;

		internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None;

		internal const MetadataPropertyHandling DefaultMetadataPropertyHandling = MetadataPropertyHandling.Default;

		internal static readonly StreamingContext DefaultContext;

		internal const Formatting DefaultFormatting = Formatting.None;

		internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat;

		internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;

		internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime;

		internal const FloatParseHandling DefaultFloatParseHandling = FloatParseHandling.Double;

		internal const FloatFormatHandling DefaultFloatFormatHandling = FloatFormatHandling.String;

		internal const StringEscapeHandling DefaultStringEscapeHandling = StringEscapeHandling.Default;

		internal const TypeNameAssemblyFormatHandling DefaultTypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple;

		internal static readonly CultureInfo DefaultCulture;

		internal const bool DefaultCheckAdditionalContent = false;

		internal const string DefaultDateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";

		internal const int DefaultMaxDepth = 64;

		internal Formatting? _formatting;

		internal DateFormatHandling? _dateFormatHandling;

		internal DateTimeZoneHandling? _dateTimeZoneHandling;

		internal DateParseHandling? _dateParseHandling;

		internal FloatFormatHandling? _floatFormatHandling;

		internal FloatParseHandling? _floatParseHandling;

		internal StringEscapeHandling? _stringEscapeHandling;

		internal CultureInfo? _culture;

		internal bool? _checkAdditionalContent;

		internal int? _maxDepth;

		internal bool _maxDepthSet;

		internal string? _dateFormatString;

		internal bool _dateFormatStringSet;

		internal TypeNameAssemblyFormatHandling? _typeNameAssemblyFormatHandling;

		internal DefaultValueHandling? _defaultValueHandling;

		internal PreserveReferencesHandling? _preserveReferencesHandling;

		internal NullValueHandling? _nullValueHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal MissingMemberHandling? _missingMemberHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal StreamingContext? _context;

		internal ConstructorHandling? _constructorHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal MetadataPropertyHandling? _metadataPropertyHandling;

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling.GetValueOrDefault();
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling.GetValueOrDefault();
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling.GetValueOrDefault();
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling.GetValueOrDefault();
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling.GetValueOrDefault();
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public IList<JsonConverter> Converters { get; set; }

		public PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling.GetValueOrDefault();
			}
			set
			{
				_preserveReferencesHandling = value;
			}
		}

		public TypeNameHandling TypeName

System.Configuration.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration.Internal;
using System.Configuration.Provider;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using Unity;

[assembly: ComCompatibleVersion(1, 0, 3300, 0)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("System.Configuration.dll")]
[assembly: AssemblyDescription("System.Configuration.dll")]
[assembly: AssemblyDefaultAlias("System.Configuration.dll")]
[assembly: AssemblyCompany("Mono development team")]
[assembly: AssemblyProduct("Mono Common Language Infrastructure")]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyCopyright("(c) Various Mono authors")]
[assembly: AssemblyInformationalVersion("4.6.57.0")]
[assembly: CLSCompliant(true)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: ComVisible(false)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: AssemblyDelaySign(true)]
[assembly: InternalsVisibleTo("System.Web, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
[assembly: SatelliteContractVersion("4.0.0.0")]
[assembly: AssemblyFileVersion("4.6.57.0")]
[assembly: AssemblyVersion("4.0.0.0")]
internal static class Consts
{
	public const string MonoVersion = "5.11.0.0";

	public const string MonoCompany = "Mono development team";

	public const string MonoProduct = "Mono Common Language Infrastructure";

	public const string MonoCopyright = "(c) Various Mono authors";

	public const int MonoCorlibVersion = 1051100001;

	public const string FxVersion = "4.0.0.0";

	public const string FxFileVersion = "4.6.57.0";

	public const string EnvironmentVersion = "4.0.30319.42000";

	public const string VsVersion = "0.0.0.0";

	public const string VsFileVersion = "11.0.0.0";

	private const string PublicKeyToken = "b77a5c561934e089";

	public const string AssemblyI18N = "I18N, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMicrosoft_JScript = "Microsoft.JScript, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMicrosoft_VisualStudio = "Microsoft.VisualStudio, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMicrosoft_VisualStudio_Web = "Microsoft.VisualStudio.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMicrosoft_VSDesigner = "Microsoft.VSDesigner, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMono_Http = "Mono.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMono_Posix = "Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMono_Security = "Mono.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMono_Messaging_RabbitMQ = "Mono.Messaging.RabbitMQ, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyCorlib = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem = "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_Data = "System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_Design = "System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_DirectoryServices = "System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Drawing = "System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Drawing_Design = "System.Drawing.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Messaging = "System.Messaging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Security = "System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_ServiceProcess = "System.ServiceProcess, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Web = "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Windows_Forms = "System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_2_0 = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystemCore_3_5 = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_Core = "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string WindowsBase_3_0 = "WindowsBase, Version=3.0.0.0, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyWindowsBase = "WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyPresentationCore_3_5 = "PresentationCore, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyPresentationCore_4_0 = "PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyPresentationFramework_3_5 = "PresentationFramework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblySystemServiceModel_3_0 = "System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
}
internal sealed class Locale
{
	private Locale()
	{
	}

	public static string GetText(string msg)
	{
		return msg;
	}

	public static string GetText(string fmt, params object[] args)
	{
		return string.Format(fmt, args);
	}
}
internal class ConfigXmlTextReader : XmlTextReader, IConfigErrorInfo
{
	private readonly string fileName;

	public string Filename => fileName;

	public ConfigXmlTextReader(Stream s, string fileName)
		: base(s)
	{
		if (fileName == null)
		{
			throw new ArgumentNullException("fileName");
		}
		this.fileName = fileName;
	}

	public ConfigXmlTextReader(TextReader input, string fileName)
		: base(input)
	{
		if (fileName == null)
		{
			throw new ArgumentNullException("fileName");
		}
		this.fileName = fileName;
	}
}
namespace System
{
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	internal class MonoTODOAttribute : Attribute
	{
		private string comment;

		public string Comment => comment;

		public MonoTODOAttribute()
		{
		}

		public MonoTODOAttribute(string comment)
		{
			this.comment = comment;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	internal class MonoDocumentationNoteAttribute : MonoTODOAttribute
	{
		public MonoDocumentationNoteAttribute(string comment)
			: base(comment)
		{
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	internal class MonoExtensionAttribute : MonoTODOAttribute
	{
		public MonoExtensionAttribute(string comment)
			: base(comment)
		{
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	internal class MonoInternalNoteAttribute : MonoTODOAttribute
	{
		public MonoInternalNoteAttribute(string comment)
			: base(comment)
		{
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	internal class MonoLimitationAttribute : MonoTODOAttribute
	{
		public MonoLimitationAttribute(string comment)
			: base(comment)
		{
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	internal class MonoNotSupportedAttribute : MonoTODOAttribute
	{
		public MonoNotSupportedAttribute(string comment)
			: base(comment)
		{
		}
	}
}
namespace System.Configuration
{
	public sealed class AppSettingsSection : ConfigurationSection
	{
		private static ConfigurationPropertyCollection _properties;

		private static readonly ConfigurationProperty _propFile;

		private static readonly ConfigurationProperty _propSettings;

		[ConfigurationProperty("file", DefaultValue = "")]
		public string File
		{
			get
			{
				return (string)base[_propFile];
			}
			set
			{
				base[_propFile] = value;
			}
		}

		[ConfigurationProperty("", Options = ConfigurationPropertyOptions.IsDefaultCollection)]
		public KeyValueConfigurationCollection Settings => (KeyValueConfigurationCollection)base[_propSettings];

		protected internal override ConfigurationPropertyCollection Properties => _properties;

		static AppSettingsSection()
		{
			_propFile = new ConfigurationProperty("file", typeof(string), "", new StringConverter(), null, ConfigurationPropertyOptions.None);
			_propSettings = new ConfigurationProperty("", typeof(KeyValueConfigurationCollection), null, null, null, ConfigurationPropertyOptions.IsDefaultCollection);
			_properties = new ConfigurationPropertyCollection();
			_properties.Add(_propFile);
			_properties.Add(_propSettings);
		}

		protected internal override bool IsModified()
		{
			return Settings.IsModified();
		}

		[MonoInternalNote("file path?  do we use a System.Configuration api for opening it?  do we keep it open?  do we open it writable?")]
		protected internal override void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
		{
			base.DeserializeElement(reader, serializeCollectionKey);
			if (!(File != ""))
			{
				return;
			}
			try
			{
				string text = File;
				if (!Path.IsPathRooted(text))
				{
					text = Path.Combine(Path.GetDirectoryName(base.Configuration.FilePath), text);
				}
				FileStream fileStream = System.IO.File.OpenRead(text);
				XmlReader reader2 = new ConfigXmlTextReader(fileStream, text);
				base.DeserializeElement(reader2, serializeCollectionKey);
				fileStream.Close();
			}
			catch
			{
			}
		}

		protected internal override void Reset(ConfigurationElement parentSection)
		{
			if (parentSection is AppSettingsSection appSettingsSection)
			{
				Settings.Reset(appSettingsSection.Settings);
			}
		}

		[MonoTODO]
		protected internal override string SerializeSection(ConfigurationElement parentElement, string name, ConfigurationSaveMode saveMode)
		{
			if (File == "")
			{
				return base.SerializeSection(parentElement, name, saveMode);
			}
			throw new NotImplementedException();
		}

		protected internal override object GetRuntimeObject()
		{
			KeyValueInternalCollection keyValueInternalCollection = new KeyValueInternalCollection();
			string[] allKeys = Settings.AllKeys;
			foreach (string key in allKeys)
			{
				KeyValueConfigurationElement keyValueConfigurationElement = Settings[key];
				keyValueInternalCollection.Add(keyValueConfigurationElement.Key, keyValueConfigurationElement.Value);
			}
			if (!ConfigurationManager.ConfigurationSystem.SupportsUserConfig)
			{
				keyValueInternalCollection.SetReadOnly();
			}
			return keyValueInternalCollection;
		}
	}
	public sealed class CallbackValidator : ConfigurationValidatorBase
	{
		private Type type;

		private ValidatorCallback callback;

		public CallbackValidator(Type type, ValidatorCallback callback)
		{
			this.type = type;
			this.callback = callback;
		}

		public override bool CanValidate(Type type)
		{
			return type == this.type;
		}

		public override void Validate(object value)
		{
			callback(value);
		}
	}
	[AttributeUsage(AttributeTargets.Property)]
	public sealed class CallbackValidatorAttribute : ConfigurationValidatorAttribute
	{
		private string callbackMethodName = "";

		private Type type;

		private ConfigurationValidatorBase instance;

		public string CallbackMethodName
		{
			get
			{
				return callbackMethodName;
			}
			set
			{
				callbackMethodName = value;
				instance = null;
			}
		}

		public Type Type
		{
			get
			{
				return type;
			}
			set
			{
				type = value;
				instance = null;
			}
		}

		public override ConfigurationValidatorBase ValidatorInstance => instance;
	}
	internal class ClientConfigurationSystem : IInternalConfigSystem
	{
		private Configuration cfg;

		private Configuration Configuration
		{
			get
			{
				if (cfg == null)
				{
					Assembly entryAssembly = Assembly.GetEntryAssembly();
					try
					{
						cfg = ConfigurationManager.OpenExeConfigurationInternal(ConfigurationUserLevel.None, entryAssembly, null);
					}
					catch (Exception inner)
					{
						throw new ConfigurationErrorsException("Error Initializing the configuration system.", inner);
					}
				}
				return cfg;
			}
		}

		bool IInternalConfigSystem.SupportsUserConfig => false;

		object IInternalConfigSystem.GetSection(string configKey)
		{
			return Configuration.GetSection(configKey)?.GetRuntimeObject();
		}

		void IInternalConfigSystem.RefreshConfig(string sectionName)
		{
		}
	}
	public sealed class CommaDelimitedStringCollection : StringCollection
	{
		private bool modified;

		private bool readOnly;

		private int originalStringHash;

		public bool IsModified
		{
			get
			{
				if (modified)
				{
					return true;
				}
				string text = ToString();
				if (text == null)
				{
					return false;
				}
				return text.GetHashCode() != originalStringHash;
			}
		}

		public new bool IsReadOnly => readOnly;

		public new string this[int index]
		{
			get
			{
				return base[index];
			}
			set
			{
				if (readOnly)
				{
					throw new ConfigurationErrorsException("The configuration is read only");
				}
				base[index] = value;
				modified = true;
			}
		}

		public new void Add(string value)
		{
			if (readOnly)
			{
				throw new ConfigurationErrorsException("The configuration is read only");
			}
			base.Add(value);
			modified = true;
		}

		public new void AddRange(string[] range)
		{
			if (readOnly)
			{
				throw new ConfigurationErrorsException("The configuration is read only");
			}
			base.AddRange(range);
			modified = true;
		}

		public new void Clear()
		{
			if (readOnly)
			{
				throw new ConfigurationErrorsException("The configuration is read only");
			}
			base.Clear();
			modified = true;
		}

		public CommaDelimitedStringCollection Clone()
		{
			CommaDelimitedStringCollection commaDelimitedStringCollection = new CommaDelimitedStringCollection();
			string[] array = new string[base.Count];
			CopyTo(array, 0);
			commaDelimitedStringCollection.AddRange(array);
			commaDelimitedStringCollection.originalStringHash = originalStringHash;
			return commaDelimitedStringCollection;
		}

		public new void Insert(int index, string value)
		{
			if (readOnly)
			{
				throw new ConfigurationErrorsException("The configuration is read only");
			}
			base.Insert(index, value);
			modified = true;
		}

		public new void Remove(string value)
		{
			if (readOnly)
			{
				throw new ConfigurationErrorsException("The configuration is read only");
			}
			base.Remove(value);
			modified = true;
		}

		public void SetReadOnly()
		{
			readOnly = true;
		}

		public override string ToString()
		{
			if (base.Count == 0)
			{
				return null;
			}
			string[] array = new string[base.Count];
			CopyTo(array, 0);
			return string.Join(",", array);
		}

		internal void UpdateStringHash()
		{
			string text = ToString();
			if (text == null)
			{
				originalStringHash = 0;
			}
			else
			{
				originalStringHash = text.GetHashCode();
			}
		}
	}
	public sealed class CommaDelimitedStringCollectionConverter : ConfigurationConverterBase
	{
		public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data)
		{
			CommaDelimitedStringCollection commaDelimitedStringCollection = new CommaDelimitedStringCollection();
			string[] array = ((string)data).Split(new char[1] { ',' });
			foreach (string text in array)
			{
				commaDelimitedStringCollection.Add(text.Trim());
			}
			commaDelimitedStringCollection.UpdateStringHash();
			return commaDelimitedStringCollection;
		}

		public override object ConvertTo(ITypeDescriptorContext ctx, CultureInfo ci, object value, Type type)
		{
			if (value == null)
			{
				return null;
			}
			if (!typeof(StringCollection).IsAssignableFrom(value.GetType()))
			{
				throw new ArgumentException();
			}
			return value.ToString();
		}
	}
	internal class ConfigNameValueCollection : NameValueCollection
	{
		private bool modified;

		public bool IsModified => modified;

		public ConfigNameValueCollection()
		{
		}

		public ConfigNameValueCollection(ConfigNameValueCollection col)
			: base(col.Count, col)
		{
		}

		public void ResetModified()
		{
			modified = false;
		}

		public override void Set(string name, string value)
		{
			base.Set(name, value);
			modified = true;
		}
	}
	internal abstract class ConfigInfo
	{
		public string Name;

		public string TypeName;

		protected Type Type;

		private string streamName;

		public ConfigInfo Parent;

		public IInternalConfigHost ConfigHost;

		public string XPath
		{
			get
			{
				StringBuilder stringBuilder = new StringBuilder(Name);
				for (ConfigInfo parent = Parent; parent != null; parent = parent.Parent)
				{
					stringBuilder.Insert(0, parent.Name + "/");
				}
				return stringBuilder.ToString();
			}
		}

		public string StreamName
		{
			get
			{
				return streamName;
			}
			set
			{
				streamName = value;
			}
		}

		public virtual object CreateInstance()
		{
			if (Type == null)
			{
				Type = ConfigHost.GetConfigType(TypeName, throwOnError: true);
			}
			return Activator.CreateInstance(Type, nonPublic: true);
		}

		public abstract bool HasConfigContent(Configuration cfg);

		public abstract bool HasDataContent(Configuration cfg);

		protected void ThrowException(string text, XmlReader reader)
		{
			throw new ConfigurationErrorsException(text, reader);
		}

		public abstract void ReadConfig(Configuration cfg, string streamName, XmlReader reader);

		public abstract void WriteConfig(Configuration cfg, XmlWriter writer, ConfigurationSaveMode mode);

		public abstract void ReadData(Configuration config, XmlReader reader, bool overrideAllowed);

		public abstract void WriteData(Configuration config, XmlWriter writer, ConfigurationSaveMode mode);

		internal abstract void Merge(ConfigInfo data);

		internal abstract bool HasValues(Configuration config, ConfigurationSaveMode mode);

		internal abstract void ResetModified(Configuration config);
	}
	internal class ConfigurationXmlDocument : XmlDocument
	{
		public override XmlElement CreateElement(string prefix, string localName, string namespaceURI)
		{
			if (namespaceURI == "http://schemas.microsoft.com/.NetConfiguration/v2.0")
			{
				return base.CreateElement(string.Empty, localName, string.Empty);
			}
			return base.CreateElement(prefix, localName, namespaceURI);
		}
	}
	public sealed class Configuration
	{
		private Configuration parent;

		private Hashtable elementData;

		private string streamName;

		private ConfigurationSectionGroup rootSectionGroup;

		private ConfigurationLocationCollection locations;

		private SectionGroupInfo rootGroup;

		private IConfigSystem system;

		private bool hasFile;

		private string rootNamespace;

		private string configPath;

		private string locationConfigPath;

		private string locationSubPath;

		private ContextInformation evaluationContext;

		internal Configuration Parent
		{
			get
			{
				return parent;
			}
			set
			{
				parent = value;
			}
		}

		internal string FileName => streamName;

		internal IInternalConfigHost ConfigHost => system.Host;

		internal string LocationConfigPath => locationConfigPath;

		internal string ConfigPath => configPath;

		public AppSettingsSection AppSettings => (AppSettingsSection)GetSection("appSettings");

		public ConnectionStringsSection ConnectionStrings => (ConnectionStringsSection)GetSection("connectionStrings");

		public string FilePath
		{
			get
			{
				if (streamName == null && parent != null)
				{
					return parent.FilePath;
				}
				return streamName;
			}
		}

		public bool HasFile => hasFile;

		public ContextInformation EvaluationContext
		{
			get
			{
				if (evaluationContext == null)
				{
					object ctx = system.Host.CreateConfigurationContext(configPath, GetLocationSubPath());
					evaluationContext = new ContextInformation(this, ctx);
				}
				return evaluationContext;
			}
		}

		public ConfigurationLocationCollection Locations
		{
			get
			{
				if (locations == null)
				{
					locations = new ConfigurationLocationCollection();
				}
				return locations;
			}
		}

		public bool NamespaceDeclared
		{
			get
			{
				return rootNamespace != null;
			}
			set
			{
				rootNamespace = (value ? "http://schemas.microsoft.com/.NetConfiguration/v2.0" : null);
			}
		}

		public ConfigurationSectionGroup RootSectionGroup
		{
			get
			{
				if (rootSectionGroup == null)
				{
					rootSectionGroup = new ConfigurationSectionGroup();
					rootSectionGroup.Initialize(this, rootGroup);
				}
				return rootSectionGroup;
			}
		}

		public ConfigurationSectionGroupCollection SectionGroups => RootSectionGroup.SectionGroups;

		public ConfigurationSectionCollection Sections => RootSectionGroup.Sections;

		public Func<string, string> AssemblyStringTransformer
		{
			get
			{
				//IL_0007: Expected O, but got I4
				ThrowStub.ThrowNotSupportedException();
				return (Func<string, string>)0;
			}
			[ConfigurationPermission(SecurityAction.Demand, Unrestricted = true)]
			set
			{
				ThrowStub.ThrowNotSupportedException();
			}
		}

		public FrameworkName TargetFramework
		{
			get
			{
				ThrowStub.ThrowNotSupportedException();
				return null;
			}
			[ConfigurationPermission(SecurityAction.Demand, Unrestricted = true)]
			set
			{
				ThrowStub.ThrowNotSupportedException();
			}
		}

		public Func<string, string> TypeStringTransformer
		{
			get
			{
				//IL_0007: Expected O, but got I4
				ThrowStub.ThrowNotSupportedException();
				return (Func<string, string>)0;
			}
			[ConfigurationPermission(SecurityAction.Demand, Unrestricted = true)]
			set
			{
				ThrowStub.ThrowNotSupportedException();
			}
		}

		internal static event ConfigurationSaveEventHandler SaveStart;

		internal static event ConfigurationSaveEventHandler SaveEnd;

		internal Configuration(Configuration parent, string locationSubPath)
		{
			elementData = new Hashtable();
			base..ctor();
			this.parent = parent;
			system = parent.system;
			rootGroup = parent.rootGroup;
			this.locationSubPath = locationSubPath;
			configPath = parent.ConfigPath;
		}

		internal Configuration(InternalConfigurationSystem system, string locationSubPath)
		{
			elementData = new Hashtable();
			base..ctor();
			hasFile = true;
			this.system = system;
			system.InitForConfiguration(ref locationSubPath, out configPath, out locationConfigPath);
			Configuration configuration = null;
			if (locationSubPath != null)
			{
				configuration = new Configuration(system, locationSubPath);
				if (locationConfigPath != null)
				{
					configuration = configuration.FindLocationConfiguration(locationConfigPath, configuration);
				}
			}
			Init(system, configPath, configuration);
		}

		internal Configuration FindLocationConfiguration(string relativePath, Configuration defaultConfiguration)
		{
			Configuration configuration = defaultConfiguration;
			if (!string.IsNullOrEmpty(LocationConfigPath))
			{
				Configuration parentWithFile = GetParentWithFile();
				if (parentWithFile != null)
				{
					string configPathFromLocationSubPath = system.Host.GetConfigPathFromLocationSubPath(configPath, relativePath);
					configuration = parentWithFile.FindLocationConfiguration(configPathFromLocationSubPath, defaultConfiguration);
				}
			}
			string text = configPath.Substring(1) + "/";
			if (relativePath.StartsWith(text, StringComparison.Ordinal))
			{
				relativePath = relativePath.Substring(text.Length);
			}
			ConfigurationLocation configurationLocation = Locations.FindBest(relativePath);
			if (configurationLocation == null)
			{
				return configuration;
			}
			configurationLocation.SetParentConfiguration(configuration);
			return configurationLocation.OpenConfiguration();
		}

		internal void Init(IConfigSystem system, string configPath, Configuration parent)
		{
			this.system = system;
			this.configPath = configPath;
			streamName = system.Host.GetStreamName(configPath);
			this.parent = parent;
			if (parent != null)
			{
				rootGroup = parent.rootGroup;
			}
			else
			{
				rootGroup = new SectionGroupInfo();
				rootGroup.StreamName = streamName;
			}
			try
			{
				if (streamName != null)
				{
					Load();
				}
			}
			catch (XmlException ex)
			{
				throw new ConfigurationErrorsException(ex.Message, ex, streamName, 0);
			}
		}

		internal Configuration GetParentWithFile()
		{
			Configuration configuration = Parent;
			while (configuration != null && !configuration.HasFile)
			{
				configuration = configuration.Parent;
			}
			return configuration;
		}

		internal string GetLocationSubPath()
		{
			Configuration configuration = parent;
			string text = null;
			while (configuration != null)
			{
				text = configuration.locationSubPath;
				if (!string.IsNullOrEmpty(text))
				{
					return text;
				}
				configuration = configuration.parent;
			}
			return text;
		}

		public ConfigurationSection GetSection(string sectionName)
		{
			string[] array = sectionName.Split(new char[1] { '/' });
			if (array.Length == 1)
			{
				return Sections[array[0]];
			}
			ConfigurationSectionGroup configurationSectionGroup = SectionGroups[array[0]];
			int num = 1;
			while (configurationSectionGroup != null && num < array.Length - 1)
			{
				configurationSectionGroup = configurationSectionGroup.SectionGroups[array[num]];
				num++;
			}
			return configurationSectionGroup?.Sections[array[^1]];
		}

		public ConfigurationSectionGroup GetSectionGroup(string sectionGroupName)
		{
			string[] array = sectionGroupName.Split(new char[1] { '/' });
			ConfigurationSectionGroup configurationSectionGroup = SectionGroups[array[0]];
			int num = 1;
			while (configurationSectionGroup != null && num < array.Length)
			{
				configurationSectionGroup = configurationSectionGroup.SectionGroups[array[num]];
				num++;
			}
			return configurationSectionGroup;
		}

		internal ConfigurationSection GetSectionInstance(SectionInfo config, bool createDefaultInstance)
		{
			object obj = elementData[config];
			ConfigurationSection configurationSection = obj as ConfigurationSection;
			if (configurationSection != null || !createDefaultInstance)
			{
				return configurationSection;
			}
			object obj2 = config.CreateInstance();
			configurationSection = obj2 as ConfigurationSection;
			if (configurationSection == null)
			{
				configurationSection = new DefaultSection
				{
					SectionHandler = (IConfigurationSectionHandler)((obj2 is IConfigurationSectionHandler) ? obj2 : null)
				};
			}
			configurationSection.Configuration = this;
			ConfigurationSection configurationSection2 = null;
			if (parent != null)
			{
				configurationSection2 = parent.GetSectionInstance(config, createDefaultInstance: true);
				configurationSection.SectionInformation.SetParentSection(configurationSection2);
			}
			configurationSection.SectionInformation.ConfigFilePath = FilePath;
			configurationSection.ConfigContext = system.Host.CreateDeprecatedConfigContext(configPath);
			string text2 = (configurationSection.RawXml = obj as string);
			configurationSection.Reset(configurationSection2);
			if (text2 != null)
			{
				XmlTextReader xmlTextReader = new ConfigXmlTextReader(new StringReader(text2), FilePath);
				configurationSection.DeserializeSection(xmlTextReader);
				xmlTextReader.Close();
				if (!string.IsNullOrEmpty(configurationSection.SectionInformation.ConfigSource) && !string.IsNullOrEmpty(FilePath))
				{
					configurationSection.DeserializeConfigSource(Path.GetDirectoryName(FilePath));
				}
			}
			elementData[config] = configurationSection;
			return configurationSection;
		}

		internal ConfigurationSectionGroup GetSectionGroupInstance(SectionGroupInfo group)
		{
			ConfigurationSectionGroup configurationSectionGroup = group.CreateInstance() as ConfigurationSectionGroup;
			configurationSectionGroup?.Initialize(this, group);
			return configurationSectionGroup;
		}

		internal void SetConfigurationSection(SectionInfo config, ConfigurationSection sec)
		{
			elementData[config] = sec;
		}

		internal void SetSectionXml(SectionInfo config, string data)
		{
			elementData[config] = data;
		}

		internal string GetSectionXml(SectionInfo config)
		{
			return elementData[config] as string;
		}

		internal void CreateSection(SectionGroupInfo group, string name, ConfigurationSection sec)
		{
			if (group.HasChild(name))
			{
				throw new ConfigurationErrorsException("Cannot add a ConfigurationSection. A section or section group already exists with the name '" + name + "'");
			}
			if (!HasFile && !sec.SectionInformation.AllowLocation)
			{
				throw new ConfigurationErrorsException("The configuration section <" + name + "> cannot be defined inside a <location> element.");
			}
			if (!system.Host.IsDefinitionAllowed(configPath, sec.SectionInformation.AllowDefinition, sec.SectionInformation.AllowExeDefinition))
			{
				object obj = ((sec.SectionInformation.AllowExeDefinition != ConfigurationAllowExeDefinition.MachineToApplication) ? ((object)sec.SectionInformation.AllowExeDefinition) : ((object)sec.SectionInformation.AllowDefinition));
				throw new ConfigurationErrorsException(string.Concat("The section <", name, "> can't be defined in this configuration file (the allowed definition context is '", obj, "')."));
			}
			if (sec.SectionInformation.Type == null)
			{
				sec.SectionInformation.Type = system.Host.GetConfigTypeName(sec.GetType());
			}
			SectionInfo sectionInfo = new SectionInfo(name, sec.SectionInformation);
			sectionInfo.StreamName = streamName;
			sectionInfo.ConfigHost = system.Host;
			group.AddChild(sectionInfo);
			elementData[sectionInfo] = sec;
			sec.Configuration = this;
		}

		internal void CreateSectionGroup(SectionGroupInfo parentGroup, string name, ConfigurationSectionGroup sec)
		{
			if (parentGroup.HasChild(name))
			{
				throw new ConfigurationErrorsException("Cannot add a ConfigurationSectionGroup. A section or section group already exists with the name '" + name + "'");
			}
			if (sec.Type == null)
			{
				sec.Type = system.Host.GetConfigTypeName(sec.GetType());
			}
			sec.SetName(name);
			SectionGroupInfo sectionGroupInfo = new SectionGroupInfo(name, sec.Type);
			sectionGroupInfo.StreamName = streamName;
			sectionGroupInfo.ConfigHost = system.Host;
			parentGroup.AddChild(sectionGroupInfo);
			elementData[sectionGroupInfo] = sec;
			sec.Initialize(this, sectionGroupInfo);
		}

		internal void RemoveConfigInfo(ConfigInfo config)
		{
			elementData.Remove(config);
		}

		public void Save()
		{
			Save(ConfigurationSaveMode.Modified, forceSaveAll: false);
		}

		public void Save(ConfigurationSaveMode saveMode)
		{
			Save(saveMode, forceSaveAll: false);
		}

		public void Save(ConfigurationSaveMode saveMode, bool forceSaveAll)
		{
			if (!forceSaveAll && saveMode != ConfigurationSaveMode.Full && !HasValues(saveMode))
			{
				ResetModified();
				return;
			}
			ConfigurationSaveEventHandler saveStart = Configuration.SaveStart;
			ConfigurationSaveEventHandler saveEnd = Configuration.SaveEnd;
			object writeContext = null;
			Exception ex = null;
			Stream stream = system.Host.OpenStreamForWrite(streamName, null, ref writeContext);
			try
			{
				saveStart?.Invoke(this, new ConfigurationSaveEventArgs(streamName, start: true, null, writeContext));
				Save(stream, saveMode, forceSaveAll);
				system.Host.WriteCompleted(streamName, success: true, writeContext);
			}
			catch (Exception ex2)
			{
				ex = ex2;
				system.Host.WriteCompleted(streamName, success: false, writeContext);
				throw;
			}
			finally
			{
				stream.Close();
				saveEnd?.Invoke(this, new ConfigurationSaveEventArgs(streamName, start: false, ex, writeContext));
			}
		}

		public void SaveAs(string filename)
		{
			SaveAs(filename, ConfigurationSaveMode.Modified, forceSaveAll: false);
		}

		public void SaveAs(string filename, ConfigurationSaveMode saveMode)
		{
			SaveAs(filename, saveMode, forceSaveAll: false);
		}

		[MonoInternalNote("Detect if file has changed")]
		public void SaveAs(string filename, ConfigurationSaveMode saveMode, bool forceSaveAll)
		{
			if (!forceSaveAll && saveMode != ConfigurationSaveMode.Full && !HasValues(saveMode))
			{
				ResetModified();
				return;
			}
			string directoryName = Path.GetDirectoryName(Path.GetFullPath(filename));
			if (!Directory.Exists(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			Save(new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write), saveMode, forceSaveAll);
		}

		private void Save(Stream stream, ConfigurationSaveMode mode, bool forceUpdateAll)
		{
			XmlTextWriter xmlTextWriter = new XmlTextWriter(new StreamWriter(stream));
			xmlTextWriter.Formatting = Formatting.Indented;
			try
			{
				xmlTextWriter.WriteStartDocument();
				if (rootNamespace != null)
				{
					xmlTextWriter.WriteStartElement("configuration", rootNamespace);
				}
				else
				{
					xmlTextWriter.WriteStartElement("configuration");
				}
				if (rootGroup.HasConfigContent(this))
				{
					rootGroup.WriteConfig(this, xmlTextWriter, mode);
				}
				foreach (ConfigurationLocation location in Locations)
				{
					if (location.OpenedConfiguration == null)
					{
						xmlTextWriter.WriteRaw("\n");
						xmlTextWriter.WriteRaw(location.XmlContent);
						continue;
					}
					xmlTextWriter.WriteStartElement("location");
					xmlTextWriter.WriteAttributeString("path", location.Path);
					if (!location.AllowOverride)
					{
						xmlTextWriter.WriteAttributeString("allowOverride", "false");
					}
					location.OpenedConfiguration.SaveData(xmlTextWriter, mode, forceUpdateAll);
					xmlTextWriter.WriteEndElement();
				}
				SaveData(xmlTextWriter, mode, forceUpdateAll);
				xmlTextWriter.WriteEndElement();
				ResetModified();
			}
			finally
			{
				xmlTextWriter.Flush();
				xmlTextWriter.Close();
			}
		}

		private void SaveData(XmlTextWriter tw, ConfigurationSaveMode mode, bool forceUpdateAll)
		{
			rootGroup.WriteRootData(tw, this, mode);
		}

		private bool HasValues(ConfigurationSaveMode mode)
		{
			foreach (ConfigurationLocation location in Locations)
			{
				if (location.OpenedConfiguration != null && location.OpenedConfiguration.HasValues(mode))
				{
					return true;
				}
			}
			return rootGroup.HasValues(this, mode);
		}

		private void ResetModified()
		{
			foreach (ConfigurationLocation location in Locations)
			{
				if (location.OpenedConfiguration != null)
				{
					location.OpenedConfiguration.ResetModified();
				}
			}
			rootGroup.ResetModified(this);
		}

		private bool Load()
		{
			if (string.IsNullOrEmpty(streamName))
			{
				return true;
			}
			Stream stream = null;
			try
			{
				stream = system.Host.OpenStreamForRead(streamName);
				if (stream == null)
				{
					return false;
				}
			}
			catch
			{
				return false;
			}
			using (XmlTextReader reader = new ConfigXmlTextReader(stream, streamName))
			{
				ReadConfigFile(reader, streamName);
			}
			ResetModified();
			return true;
		}

		private void ReadConfigFile(XmlReader reader, string fileName)
		{
			reader.MoveToContent();
			if (reader.NodeType != XmlNodeType.Element || reader.Name != "configuration")
			{
				ThrowException("Configuration file does not have a valid root element", reader);
			}
			if (reader.HasAttributes)
			{
				while (reader.MoveToNextAttribute())
				{
					if (reader.LocalName == "xmlns")
					{
						rootNamespace = reader.Value;
					}
					else
					{
						ThrowException($"Unrecognized attribute '{reader.LocalName}' in root element", reader);
					}
				}
			}
			reader.MoveToElement();
			if (reader.IsEmptyElement)
			{
				reader.Skip();
				return;
			}
			reader.ReadStartElement();
			reader.MoveToContent();
			if (reader.LocalName == "configSections")
			{
				if (reader.HasAttributes)
				{
					ThrowException("Unrecognized attribute in <configSections>.", reader);
				}
				rootGroup.ReadConfig(this, fileName, reader);
			}
			rootGroup.ReadRootData(reader, this, overrideAllowed: true);
		}

		internal void ReadData(XmlReader reader, bool allowOverride)
		{
			rootGroup.ReadData(this, reader, allowOverride);
		}

		private void ThrowException(string text, XmlReader reader)
		{
			throw new ConfigurationErrorsException(text, streamName, (reader as IXmlLineInfo)?.LineNumber ?? 0);
		}

		internal Configuration()
		{
			ThrowStub.ThrowNotSupportedException();
		}
	}
	public enum ConfigurationAllowDefinition
	{
		MachineOnly = 0,
		MachineToWebRoot = 100,
		MachineToApplication = 200,
		Everywhere = 300
	}
	public enum ConfigurationAllowExeDefinition
	{
		MachineOnly = 0,
		MachineToApplication = 100,
		MachineToLocalUser = 300,
		MachineToRoamingUser = 200
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)]
	public sealed class ConfigurationCollectionAttribute : Attribute
	{
		private string addItemName = "add";

		private string clearItemsName = "clear";

		private string removeItemName = "remove";

		private ConfigurationElementCollectionType collectionType;

		private Type itemType;

		public string AddItemName
		{
			get
			{
				return addItemName;
			}
			set
			{
				addItemName = value;
			}
		}

		public string ClearItemsName
		{
			get
			{
				return clearItemsName;
			}
			set
			{
				clearItemsName = value;
			}
		}

		public string RemoveItemName
		{
			get
			{
				return removeItemName;
			}
			set
			{
				removeItemName = value;
			}
		}

		public ConfigurationElementCollectionType CollectionType
		{
			get
			{
				return collectionType;
			}
			set
			{
				collectionType = value;
			}
		}

		[MonoInternalNote("Do something with this in ConfigurationElementCollection")]
		public Type ItemType => itemType;

		public ConfigurationCollectionAttribute(Type itemType)
		{
			this.itemType = itemType;
		}
	}
	public abstract class ConfigurationConverterBase : TypeConverter
	{
		public override bool CanConvertFrom(ITypeDescriptorContext ctx, Type type)
		{
			if (type == typeof(string))
			{
				return true;
			}
			return base.CanConvertFrom(ctx, type);
		}

		public override bool CanConvertTo(ITypeDescriptorContext ctx, Type type)
		{
			if (type == typeof(string))
			{
				return true;
			}
			return base.CanConvertTo(ctx, type);
		}
	}
	public abstract class ConfigurationElement
	{
		private class SaveContext
		{
			public readonly ConfigurationElement Element;

			public readonly ConfigurationElement Parent;

			public readonly ConfigurationSaveMode Mode;

			public SaveContext(ConfigurationElement element, ConfigurationElement parent, ConfigurationSaveMode mode)
			{
				Element = element;
				Parent = parent;
				Mode = mode;
			}

			public bool HasValues()
			{
				if (Mode == ConfigurationSaveMode.Full)
				{
					return true;
				}
				return Element.HasValues(Parent, Mode);
			}

			public bool HasValue(PropertyInformation prop)
			{
				if (Mode == ConfigurationSaveMode.Full)
				{
					return true;
				}
				return Element.HasValue(Parent, prop, Mode);
			}
		}

		private string rawXml;

		private bool modified;

		private ElementMap map;

		private ConfigurationPropertyCollection keyProps;

		private ConfigurationElementCollection defaultCollection;

		private bool readOnly;

		private ElementInformation elementInfo;

		private ConfigurationElementProperty elementProperty;

		private Configuration _configuration;

		private bool elementPresent;

		private ConfigurationLockCollection lockAllAttributesExcept;

		private ConfigurationLockCollection lockAllElementsExcept;

		private ConfigurationLockCollection lockAttributes;

		private ConfigurationLockCollection lockElements;

		private bool lockItem;

		private SaveContext saveContext;

		internal Configuration Configuration
		{
			get
			{
				return _configuration;
			}
			set
			{
				_configuration = value;
			}
		}

		public ElementInformation ElementInformation
		{
			get
			{
				if (elementInfo == null)
				{
					elementInfo = new ElementInformation(this, null);
				}
				return elementInfo;
			}
		}

		internal string RawXml
		{
			get
			{
				return rawXml;
			}
			set
			{
				if (rawXml == null || value != null)
				{
					rawXml = value;
				}
			}
		}

		protected internal virtual ConfigurationElementProperty ElementProperty
		{
			get
			{
				if (elementProperty == null)
				{
					elementProperty = new ConfigurationElementProperty(ElementInformation.Validator);
				}
				return elementProperty;
			}
		}

		protected ContextInformation EvaluationContext
		{
			get
			{
				if (Configuration != null)
				{
					return Configuration.EvaluationContext;
				}
				throw new ConfigurationErrorsException("This element is not currently associated with any context.");
			}
		}

		public ConfigurationLockCollection LockAllAttributesExcept
		{
			get
			{
				if (lockAllAttributesExcept == null)
				{
					lockAllAttributesExcept = new ConfigurationLockCollection(this, ConfigurationLockType.Attribute | ConfigurationLockType.Exclude);
				}
				return lockAllAttributesExcept;
			}
		}

		public ConfigurationLockCollection LockAllElementsExcept
		{
			get
			{
				if (lockAllElementsExcept == null)
				{
					lockAllElementsExcept = new ConfigurationLockCollection(this, ConfigurationLockType.Element | ConfigurationLockType.Exclude);
				}
				return lockAllElementsExcept;
			}
		}

		public ConfigurationLockCollection LockAttributes
		{
			get
			{
				if (lockAttributes == null)
				{
					lockAttributes = new ConfigurationLockCollection(this, ConfigurationLockType.Attribute);
				}
				return lockAttributes;
			}
		}

		public ConfigurationLockCollection LockElements
		{
			get
			{
				if (lockElements == null)
				{
					lockElements = new ConfigurationLockCollection(this, ConfigurationLockType.Element);
				}
				return lockElements;
			}
		}

		public bool LockItem
		{
			get
			{
				return lockItem;
			}
			set
			{
				lockItem = value;
			}
		}

		protected internal object this[ConfigurationProperty prop]
		{
			get
			{
				return this[prop.Name];
			}
			set
			{
				this[prop.Name] = value;
			}
		}

		protected internal object this[string propertyName]
		{
			get
			{
				return (ElementInformation.Properties[propertyName] ?? throw new InvalidOperationException("Property '" + propertyName + "' not found in configuration element")).Value;
			}
			set
			{
				PropertyInformation propertyInformation = ElementInformation.Properties[propertyName];
				if (propertyInformation == null)
				{
					throw new InvalidOperationException("Property '" + propertyName + "' not found in configuration element");
				}
				SetPropertyValue(propertyInformation.Property, value, ignoreLocks: false);
				propertyInformation.Value = value;
				modified = true;
			}
		}

		protected internal virtual ConfigurationPropertyCollection Properties
		{
			get
			{
				if (map == null)
				{
					map = ElementMap.GetMap(GetType());
				}
				return map.Properties;
			}
		}

		internal bool IsElementPresent => elementPresent;

		public Configuration CurrentConfiguration
		{
			get
			{
				ThrowStub.ThrowNotSupportedException();
				return null;
			}
		}

		protected bool HasContext
		{
			get
			{
				ThrowStub.ThrowNotSupportedException();
				return default(bool);
			}
		}

		internal virtual void InitFromProperty(PropertyInformation propertyInfo)
		{
			elementInfo = new ElementInformation(this, propertyInfo);
			Init();
		}

		protected internal virtual void Init()
		{
		}

		[MonoTODO]
		protected virtual void ListErrors(IList errorList)
		{
			throw new NotImplementedException();
		}

		[MonoTODO]
		protected void SetPropertyValue(ConfigurationProperty prop, object value, bool ignoreLocks)
		{
			try
			{
				if (value != null)
				{
					prop.Validate(value);
				}
			}
			catch (Exception inner)
			{
				throw new ConfigurationErrorsException($"The value for the property '{prop.Name}' on type {ElementInformation.Type} is not valid.", inner);
			}
		}

		internal ConfigurationPropertyCollection GetKeyProperties()
		{
			if (keyProps != null)
			{
				return keyProps;
			}
			ConfigurationPropertyCollection configurationPropertyCollection = new ConfigurationPropertyCollection();
			foreach (ConfigurationProperty property in Properties)
			{
				if (property.IsKey)
				{
					configurationPropertyCollection.Add(property);
				}
			}
			return keyProps = configurationPropertyCollection;
		}

		internal ConfigurationElementCollection GetDefaultCollection()
		{
			if (defaultCollection != null)
			{
				return defaultCollection;
			}
			ConfigurationProperty configurationProperty = null;
			foreach (ConfigurationProperty property in Properties)
			{
				if (property.IsDefaultCollection)
				{
					configurationProperty = property;
					break;
				}
			}
			if (configurationProperty != null)
			{
				defaultCollection = this[configurationProperty] as ConfigurationElementCollection;
			}
			return defaultCollection;
		}

		public override bool Equals(object compareTo)
		{
			if (!(compareTo is ConfigurationElement configurationElement))
			{
				return false;
			}
			if (GetType() != configurationElement.GetType())
			{
				return false;
			}
			foreach (ConfigurationProperty property in Properties)
			{
				if (!object.Equals(this[property], configurationElement[property]))
				{
					return false;
				}
			}
			return true;
		}

		public override int GetHashCode()
		{
			int num = 0;
			foreach (ConfigurationProperty property in Properties)
			{
				object obj = this[property];
				if (obj != null)
				{
					num += obj.GetHashCode();
				}
			}
			return num;
		}

		internal virtual bool HasLocalModifications()
		{
			foreach (PropertyInformation property in ElementInformation.Properties)
			{
				if (property.ValueOrigin == PropertyValueOrigin.SetHere && property.IsModified)
				{
					return true;
				}
			}
			return false;
		}

		protected internal virtual void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
		{
			Hashtable hashtable = new Hashtable();
			reader.MoveToContent();
			elementPresent = true;
			while (reader.MoveToNextAttribute())
			{
				PropertyInformation propertyInformation = ElementInformation.Properties[reader.LocalName];
				if (propertyInformation == null || (serializeCollectionKey && !propertyInformation.IsKey))
				{
					if (reader.LocalName == "lockAllAttributesExcept")
					{
						LockAllAttributesExcept.SetFromList(reader.Value);
					}
					else if (reader.LocalName == "lockAllElementsExcept")
					{
						LockAllElementsExcept.SetFromList(reader.Value);
					}
					else if (reader.LocalName == "lockAttributes")
					{
						LockAttributes.SetFromList(reader.Value);
					}
					else if (reader.LocalName == "lockElements")
					{
						LockElements.SetFromList(reader.Value);
					}
					else if (reader.LocalName == "lockItem")
					{
						LockItem = reader.Value.ToLowerInvariant() == "true";
					}
					else if (!(reader.LocalName == "xmlns") && (!(this is ConfigurationSection) || !(reader.LocalName == "configSource")) && !OnDeserializeUnrecognizedAttribute(reader.LocalName, reader.Value))
					{
						throw new ConfigurationErrorsException("Unrecognized attribute '" + reader.LocalName + "'.", reader);
					}
					continue;
				}
				if (hashtable.ContainsKey(propertyInformation))
				{
					throw new ConfigurationErrorsException("The attribute '" + propertyInformation.Name + "' may only appear once in this element.", reader);
				}
				string text = null;
				try
				{
					text = reader.Value;
					ValidateValue(propertyInformation.Property, text);
					propertyInformation.SetStringValue(text);
				}
				catch (ConfigurationErrorsException)
				{
					throw;
				}
				catch (ConfigurationException)
				{
					throw;
				}
				catch (Exception ex2)
				{
					throw new ConfigurationErrorsException($"The value for the property '{propertyInformation.Name}' is not valid. The error is: {ex2.Message}", reader);
				}
				hashtable[propertyInformation] = propertyInformation.Name;
				if (reader is ConfigXmlTextReader configXmlTextReader)
				{
					propertyInformation.Source = configXmlTextReader.Filename;
					propertyInformation.LineNumber = configXmlTextReader.LineNumber;
				}
			}
			reader.MoveToElement();
			if (reader.IsEmptyElement)
			{
				reader.Skip();
			}
			else
			{
				int depth = reader.Depth;
				reader.ReadStartElement();
				reader.MoveToContent();
				do
				{
					if (reader.NodeType != XmlNodeType.Element)
					{
						reader.Skip();
						continue;
					}
					PropertyInformation propertyInformation2 = ElementInformation.Properties[reader.LocalName];
					if (propertyInformation2 == null || (serializeCollectionKey && !propertyInformation2.IsKey))
					{
						if (OnDeserializeUnrecognizedElement(reader.LocalName, reader))
						{
							continue;
						}
						if (propertyInformation2 == null)
						{
							ConfigurationElementCollection configurationElementCollection = GetDefaultCollection();
							if (configurationElementCollection != null && configurationElementCollection.OnDeserializeUnrecognizedElement(reader.LocalName, reader))
							{
								continue;
							}
						}
						throw new ConfigurationErrorsException("Unrecognized element '" + reader.LocalName + "'.", reader);
					}
					if (!propertyInformation2.IsElement)
					{
						throw new ConfigurationErrorsException("Property '" + propertyInformation2.Name + "' is not a ConfigurationElement.");
					}
					if (hashtable.Contains(propertyInformation2))
					{
						throw new ConfigurationErrorsException("The element <" + propertyInformation2.Name + "> may only appear once in this section.", reader);
					}
					((ConfigurationElement)propertyInformation2.Value).DeserializeElement(reader, serializeCollectionKey);
					hashtable[propertyInformation2] = propertyInformation2.Name;
					if (depth == reader.Depth)
					{
						reader.Read();
					}
				}
				while (depth < reader.Depth);
			}
			modified = false;
			foreach (PropertyInformation property in ElementInformation.Properties)
			{
				if (!string.IsNullOrEmpty(property.Name) && property.IsRequired && !hashtable.ContainsKey(property) && ElementInformation.Properties[property.Name] == null)
				{
					object obj = OnRequiredPropertyNotFound(property.Name);
					if (!object.Equals(obj, property.DefaultValue))
					{
						property.Value = obj;
						property.IsModified = false;
					}
				}
			}
			PostDeserialize();
		}

		protected virtual bool OnDeserializeUnrecognizedAttribute(string name, string value)
		{
			return false;
		}

		protected virtual bool OnDeserializeUnrecognizedElement(string elementName, XmlReader reader)
		{
			return false;
		}

		protected virtual object OnRequiredPropertyNotFound(string name)
		{
			throw new ConfigurationErrorsException("Required attribute '" + name + "' not found.");
		}

		protected virtual void PreSerialize(XmlWriter writer)
		{
		}

		protected virtual void PostDeserialize()
		{
		}

		protected internal virtual void InitializeDefault()
		{
		}

		protected internal virtual bool IsModified()
		{
			if (modified)
			{
				return true;
			}
			foreach (PropertyInformation property in ElementInformation.Properties)
			{
				if (property.IsElement && property.Value is ConfigurationElement configurationElement && configurationElement.IsModified())
				{
					modified = true;
					break;
				}
			}
			return modified;
		}

		protected internal virtual void SetReadOnly()
		{
			readOnly = true;
		}

		public virtual bool IsReadOnly()
		{
			return readOnly;
		}

		protected internal virtual void Reset(ConfigurationElement parentElement)
		{
			elementPresent = false;
			if (parentElement != null)
			{
				ElementInformation.Reset(parentElement.ElementInformation);
			}
			else
			{
				InitializeDefault();
			}
		}

		protected internal virtual void ResetModified()
		{
			modified = false;
			foreach (PropertyInformation property in ElementInformation.Properties)
			{
				property.IsModified = false;
				if (property.Value is ConfigurationElement configurationElement)
				{
					configurationElement.ResetModified();
				}
			}
		}

		protected internal virtual bool SerializeElement(XmlWriter writer, bool serializeCollectionKey)
		{
			PreSerialize(writer);
			if (serializeCollectionKey)
			{
				ConfigurationPropertyCollection keyProperties = GetKeyProperties();
				foreach (ConfigurationProperty item in keyProperties)
				{
					writer.WriteAttributeString(item.Name, item.ConvertToString(this[item.Name]));
				}
				return keyProperties.Count > 0;
			}
			bool flag = false;
			foreach (PropertyInformation property in ElementInformation.Properties)
			{
				if (!property.IsElement)
				{
					if (saveContext == null)
					{
						throw new InvalidOperationException();
					}
					if (saveContext.HasValue(property))
					{
						writer.WriteAttributeString(property.Name, property.GetStringValue());
						flag = true;
					}
				}
			}
			foreach (PropertyInformation property2 in ElementInformation.Properties)
			{
				if (property2.IsElement)
				{
					ConfigurationElement configurationElement = (ConfigurationElement)property2.Value;
					if (configurationElement != null)
					{
						flag = configurationElement.SerializeToXmlElement(writer, property2.Name) || flag;
					}
				}
			}
			return flag;
		}

		protected internal virtual bool SerializeToXmlElement(XmlWriter writer, string elementName)
		{
			if (saveContext == null)
			{
				throw new InvalidOperationException();
			}
			if (!saveContext.HasValues())
			{
				return false;
			}
			if (elementName != null && elementName != "")
			{
				writer.WriteStartElement(elementName);
			}
			bool result = SerializeElement(writer, serializeCollectionKey: false);
			if (elementName != null && elementName != "")
			{
				writer.WriteEndElement();
			}
			return result;
		}

		protected internal virtual void Unmerge(ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
		{
			if (parentElement != null && sourceElement.GetType() != parentElement.GetType())
			{
				throw new ConfigurationErrorsException("Can't unmerge two elements of different type");
			}
			bool flag = saveMode == ConfigurationSaveMode.Minimal || saveMode == ConfigurationSaveMode.Modified;
			foreach (PropertyInformation property in sourceElement.ElementInformation.Properties)
			{
				if (property.ValueOrigin == PropertyValueOrigin.Default)
				{
					continue;
				}
				PropertyInformation propertyInformation2 = ElementInformation.Properties[property.Name];
				object value = property.Value;
				if (parentElement == null || !parentElement.HasValue(property.Name))
				{
					propertyInformation2.Value = value;
				}
				else
				{
					if (value == null)
					{
						continue;
					}
					object obj = parentElement[property.Name];
					if (!property.IsElement)
					{
						if (!object.Equals(value, obj) || saveMode == ConfigurationSaveMode.Full || (saveMode == ConfigurationSaveMode.Modified && property.ValueOrigin == PropertyValueOrigin.SetHere))
						{
							propertyInformation2.Value = value;
						}
						continue;
					}
					ConfigurationElement configurationElement = (ConfigurationElement)value;
					if (!flag || configurationElement.IsModified())
					{
						if (obj == null)
						{
							propertyInformation2.Value = value;
							continue;
						}
						ConfigurationElement parentElement2 = (ConfigurationElement)obj;
						((ConfigurationElement)propertyInformation2.Value).Unmerge(configurationElement, parentElement2, saveMode);
					}
				}
			}
		}

		internal bool HasValue(string propName)
		{
			PropertyInformation propertyInformation = ElementInformation.Properties[propName];
			if (propertyInformation != null)
			{
				return propertyInformation.ValueOrigin != PropertyValueOrigin.Default;
			}
			return false;
		}

		internal bool IsReadFromConfig(string propName)
		{
			PropertyInformation propertyInformation = ElementInformation.Properties[propName];
			if (propertyInformation != null)
			{
				return propertyInformation.ValueOrigin == PropertyValueOrigin.SetHere;
			}
			return false;
		}

		private void ValidateValue(ConfigurationProperty p, string value)
		{
			ConfigurationValidatorBase validator;
			if (p != null && (validator = p.Validator) != null)
			{
				if (!validator.CanValidate(p.Type))
				{
					throw new ConfigurationErrorsException($"Validator does not support type {p.Type}");
				}
				validator.Validate(p.ConvertFromString(value));
			}
		}

		internal bool HasValue(ConfigurationElement parent, PropertyInformation prop, ConfigurationSaveMode mode)
		{
			if (prop.ValueOrigin == PropertyValueOrigin.Default)
			{
				return false;
			}
			if (mode == ConfigurationSaveMode.Modified && prop.ValueOrigin == PropertyValueOrigin.SetHere && prop.IsModified)
			{
				return true;
			}
			object obj = ((parent != null && parent.HasValue(prop.Name)) ? parent[prop.Name] : prop.DefaultValue);
			if (!prop.IsElement)
			{
				return !object.Equals(prop.Value, obj);
			}
			ConfigurationElement obj2 = (ConfigurationElement)prop.Value;
			ConfigurationElement parent2 = (ConfigurationElement)obj;
			return obj2.HasValues(parent2, mode);
		}

		internal virtual bool HasValues(ConfigurationElement parent, ConfigurationSaveMode mode)
		{
			if (mode == ConfigurationSaveMode.Full)
			{
				return true;
			}
			if (modified && mode == ConfigurationSaveMode.Modified)
			{
				return true;
			}
			foreach (PropertyInformation property in ElementInformation.Properties)
			{
				if (HasValue(parent, property, mode))
				{
					return true;
				}
			}
			return false;
		}

		internal virtual void PrepareSave(ConfigurationElement parent, ConfigurationSaveMode mode)
		{
			saveContext = new SaveContext(this, parent, mode);
			foreach (PropertyInformation property in ElementInformation.Properties)
			{
				if (property.IsElement)
				{
					ConfigurationElement configurationElement = (ConfigurationElement)property.Value;
					if (parent == null || !parent.HasValue(property.Name))
					{
						configurationElement.PrepareSave(null, mode);
						continue;
					}
					ConfigurationElement parent2 = (ConfigurationElement)parent[property.Name];
					configurationElement.PrepareSave(parent2, mode);
				}
			}
		}

		protected virtual string GetTransformedAssemblyString(string assemblyName)
		{
			ThrowStub.ThrowNotSupportedException();
			return null;
		}

		protected virtual string GetTransformedTypeString(string typeName)
		{
			ThrowStub.ThrowNotSupportedException();
			return null;
		}
	}
	internal class ElementMap
	{
		private static readonly Hashtable elementMaps = Hashtable.Synchronized(new Hashtable());

		private readonly ConfigurationPropertyCollection properties;

		private readonly ConfigurationCollectionAttribute collectionAttribute;

		public ConfigurationCollectionAttribute CollectionAttribute => collectionAttribute;

		public bool HasProperties => properties.Count > 0;

		public ConfigurationPropertyCollection Properties => properties;

		public static ElementMap GetMap(Type t)
		{
			if (elementMaps[t] is ElementMap result)
			{
				return result;
			}
			ElementMap elementMap = new ElementMap(t);
			elementMaps[t] = elementMap;
			return elementMap;
		}

		public ElementMap(Type t)
		{
			properties = new ConfigurationPropertyCollection();
			collectionAttribute = Attribute.GetCustomAttribute(t, typeof(ConfigurationCollectionAttribute)) as ConfigurationCollectionAttribute;
			PropertyInfo[] array = t.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (PropertyInfo propertyInfo in array)
			{
				if (Attribute.GetCustomAttribute(propertyInfo, typeof(ConfigurationPropertyAttribute)) is ConfigurationPropertyAttribute configurationPropertyAttribute)
				{
					string name = ((configurationPropertyAttribute.Name != null) ? configurationPropertyAttribute.Name : propertyInfo.Name);
					ConfigurationValidatorBase validator = ((Attribute.GetCustomAttribute(propertyInfo, typeof(ConfigurationValidatorAttribute)) is ConfigurationValidatorAttribute configurationValidatorAttribute) ? configurationValidatorAttribute.ValidatorInstance : null);
					TypeConverterAttribute typeConverterAttribute = (TypeConverterAttribute)Attribute.GetCustomAttribute(propertyInfo, typeof(TypeConverterAttribute));
					ConfigurationProperty property = new ConfigurationProperty(typeConverter: (typeConverterAttribute != null) ? ((TypeConverter)Activator.CreateInstance(Type.GetType(typeConverterAttribute.ConverterTypeName), nonPublic: true)) : null, name: name, type: propertyInfo.PropertyType, defaultValue: configurationPropertyAttribute.DefaultValue, validator: validator, options: configurationPropertyAttribute.Options)
					{
						CollectionAttribute = (Attribute.GetCustomAttribute(propertyInfo, typeof(ConfigurationCollectionAttribute)) as ConfigurationCollectionAttribute)
					};
					properties.Add(property);
				}
			}
		}
	}
	[DebuggerDisplay("Count = {Count}")]
	public abstract class ConfigurationElementCollection : ConfigurationElement, ICollection, IEnumerable
	{
		private sealed class ConfigurationRemoveElement : ConfigurationElement
		{
			private readonly ConfigurationPropertyCollection properties = new ConfigurationPropertyCollection();

			private readonly ConfigurationElement _origElement;

			private readonly ConfigurationElementCollection _origCollection;

			internal object KeyValue
			{
				get
				{
					foreach (ConfigurationProperty property in Properties)
					{
						_origElement[property] = base[property];
					}
					return _origCollection.GetElementKey(_origElement);
				}
			}

			protected internal override ConfigurationPropertyCollection Properties => properties;

			internal ConfigurationRemoveElement(ConfigurationElement origElement, ConfigurationElementCollection origCollection)
			{
				_origElement = origElement;
				_origCollection = origCollection;
				foreach (ConfigurationProperty property in origElement.Properties)
				{
					if (property.IsKey)
					{
						properties.Add(property);
					}
				}
			}
		}

		private ArrayList list = new ArrayList();

		private ArrayList removed;

		private ArrayList inherited;

		private bool emitClear;

		private bool modified;

		private IComparer comparer;

		private int inheritedLimitIndex;

		private string addElementName = "add";

		private string clearElementName = "clear";

		private string removeElementName = "remove";

		public virtual ConfigurationElementCollectionType CollectionType => ConfigurationElementCollectionType.AddRemoveClearMap;

		private bool IsBasic
		{
			get
			{
				if (CollectionType != 0)
				{
					return CollectionType == ConfigurationElementCollectionType.BasicMapAlternate;
				}
				return true;
			}
		}

		private bool IsAlternate
		{
			get
			{
				if (CollectionType != ConfigurationElementCollectionType.AddRemoveClearMapAlternate)
				{
					return CollectionType == ConfigurationElementCollectionType.BasicMapAlternate;
				}
				return true;
			}
		}

		public int Count => list.Count;

		protected virtual string ElementName => string.Empty;

		public bool EmitClear
		{
			get
			{
				return emitClear;
			}
			set
			{
				emitClear = value;
			}
		}

		public bool IsSynchronized => false;

		public object SyncRoot => this;

		protected virtual bool ThrowOnDuplicate
		{
			get
			{
				if (CollectionType != ConfigurationElementCollectionType.AddRemoveClearMap && CollectionType != ConfigurationElementCollectionType.AddRemoveClearMapAlternate)
				{
					return false;
				}
				return true;
			}
		}

		protected internal string AddElementName
		{
			get
			{
				return addElementName;
			}
			set
			{
				addElementName = value;
			}
		}

		protected internal string ClearElementName
		{
			get
			{
				return clearElementName;
			}
			set
			{
				clearElementName = value;
			}
		}

		protected internal string RemoveElementName
		{
			get
			{
				return removeElementName;
			}
			set
			{
				removeElementName = value;
			}
		}

		protected ConfigurationElementCollection()
		{
		}

		protected ConfigurationElementCollection(IComparer comparer)
		{
			this.comparer = comparer;
		}

		internal override void InitFromProperty(PropertyInformation propertyInfo)
		{
			ConfigurationCollectionAttribute configurationCollectionAttribute = propertyInfo.Property.CollectionAttribute;
			if (configurationCollectionAttribute == null)
			{
				configurationCollectionAttribute = Attribute.GetCustomAttribute(propertyInfo.Type, typeof(ConfigurationCollectionAttribute)) as ConfigurationCollectionAttribute;
			}
			if (configurationCollectionAttribute != null)
			{
				addElementName = configurationCollectionAttribute.AddItemName;
				clearElementName = configurationCollectionAttribute.ClearItemsName;
				removeElementName = configurationCollectionAttribute.RemoveItemName;
			}
			base.InitFromProperty(propertyInfo);
		}

		protected virtual void BaseAdd(ConfigurationElement element)
		{
			BaseAdd(element, ThrowOnDuplicate);
		}

		protected void BaseAdd(ConfigurationElement element, bool throwIfExists)
		{
			if (IsReadOnly())
			{
				throw new ConfigurationErrorsException("Collection is read only.");
			}
			if (IsAlternate)
			{
				list.Insert(inheritedLimitIndex, element);
				inheritedLimitIndex++;
			}
			else
			{
				int num = IndexOfKey(GetElementKey(element));
				if (num >= 0)
				{
					if (element.Equals(list[num]))
					{
						return;
					}
					if (throwIfExists)
					{
						throw new ConfigurationErrorsException("Duplicate element in collection");
					}
					list.RemoveAt(num);
				}
				list.Add(element);
			}
			modified = true;
		}

		protected virtual void BaseAdd(int index, ConfigurationElement element)
		{
			if (ThrowOnDuplicate && BaseIndexOf(element) != -1)
			{
				throw new ConfigurationErrorsException("Duplicate element in collection");
			}
			if (IsReadOnly())
			{
				throw new ConfigurationErrorsException("Collection is read only.");
			}
			if (IsAlternate && index > inheritedLimitIndex)
			{
				throw new ConfigurationErrorsException("Can't insert new elements below the inherited elements.");
			}
			if (!IsAlternate && index <= inheritedLimitIndex)
			{
				throw new ConfigurationErrorsException("Can't insert new elements above the inherited elements.");
			}
			list.Insert(index, element);
			modified = true;
		}

		protected internal void BaseClear()
		{
			if (IsReadOnly())
			{
				throw new ConfigurationErrorsException("Collection is read only.");
			}
			list.Clear();
			modified = true;
		}

		protected internal ConfigurationElement BaseGet(int index)
		{
			return (ConfigurationElement)list[index];
		}

		protected internal ConfigurationElement BaseGet(object key)
		{
			int num = IndexOfKey(key);
			if (num != -1)
			{
				return (ConfigurationElement)list[num];
			}
			return null;
		}

		protected internal object[] BaseGetAllKeys()
		{
			object[] array = new object[list.Count];
			for (int i = 0; i < list.Count; i++)
			{
				array[i] = BaseGetKey(i);
			}
			return array;
		}

		protected internal object BaseGetKey(int index)
		{
			if (index < 0 || index >= list.Count)
			{
				throw new ConfigurationErrorsException($"Index {index} is out of range");
			}
			return GetElementKey((ConfigurationElement)list[index]).ToString();
		}

		protected int BaseIndexOf(ConfigurationElement element)
		{
			return list.IndexOf(element);
		}

		private int IndexOfKey(object key)
		{
			for (int i = 0; i < list.Count; i++)
			{
				if (CompareKeys(GetElementKey((ConfigurationElement)list[i]), key))
				{
					return i;
				}
			}
			return -1;
		}

		protected internal bool BaseIsRemoved(object key)
		{
			if (removed == null)
			{
				return false;
			}
			foreach (ConfigurationElement item in removed)
			{
				if (CompareKeys(GetElementKey(item), key))
				{
					return true;
				}
			}
			return false;
		}

		protected internal void BaseRemove(object key)
		{
			if (IsReadOnly())
			{
				throw new ConfigurationErrorsException("Collection is read only.");
			}
			int num = IndexOfKey(key);
			if (num != -1)
			{
				BaseRemoveAt(num);
				modified = true;
			}
		}

		protected internal void BaseRemoveAt(int index)
		{
			if (IsReadOnly())
			{
				throw new ConfigurationErrorsException("Collection is read only.");
			}
			ConfigurationElement configurationElement = (ConfigurationElement)list[index];
			if (!IsElementRemovable(configurationElement))
			{
				throw new ConfigurationErrorsException("Element can't be removed from element collection.");
			}
			if (inherited != null && inherited.Contains(configurationElement))
			{
				throw new ConfigurationErrorsException("Inherited items can't be removed.");
			}
			list.RemoveAt(index);
			if (IsAlternate && inheritedLimitIndex > 0)
			{
				inheritedLimitIndex--;
			}
			modified = true;
		}

		private bool CompareKeys(object key1, object key2)
		{
			if (comparer != null)
			{
				return comparer.Compare(key1, key2) == 0;
			}
			return object.Equals(key1, key2);
		}

		public void CopyTo(ConfigurationElement[] array, int index)
		{
			list.CopyTo(array, index);
		}

		protected abstract ConfigurationElement CreateNewElement();

		protected virtual ConfigurationElement CreateNewElement(string elementName)
		{
			return CreateNewElement();
		}

		private ConfigurationElement CreateNewElementInternal(string elementName)
		{
			ConfigurationElement configurationElement = ((elementName != null) ? CreateNewElement(elementName) : CreateNewElement());
			configurationElement.Init();
			return configurationElement;
		}

		public override bool Equals(object compareTo)
		{
			if (!(compareTo is ConfigurationElementCollection configurationElementCollection))
			{
				return false;
			}
			if (GetType() != configurationElementCollection.GetType())
			{
				return false;
			}
			if (Count != configurationElementCollection.Count)
			{
				return false;
			}
			for (int i = 0; i < Count; i++)
			{
				if (!BaseGet(i).Equals(configurationElementCollection.BaseGet(i)))
				{
					return false;
				}
			}
			return true;
		}

		protected abstract object GetElementKey(ConfigurationElement element);

		public override int GetHashCode()
		{
			int num = 0;
			for (int i = 0; i < Count; i++)
			{
				num += BaseGet(i).GetHashCode();
			}
			return num;
		}

		void ICollection.CopyTo(Array arr, int index)
		{
			list.CopyTo(arr, index);
		}

		public IEnumerator GetEnumerator()
		{
			return list.GetEnumerator();
		}

		protected virtual bool IsElementName(string elementName)
		{
			return false;
		}

		protected virtual bool IsElementRemovable(ConfigurationElement element)
		{
			return !IsReadOnly();
		}

		protected internal override bool IsModified()
		{
			if (modified)
			{
				return true;
			}
			for (int i = 0; i < list.Count; i++)
			{
				if (((ConfigurationElement)list[i]).IsModified())
				{
					modified = true;
					break;
				}
			}
			return modified;
		}

		[MonoTODO]
		public override bool IsReadOnly()
		{
			return base.IsReadOnly();
		}

		internal override void PrepareSave(ConfigurationElement parentElement, ConfigurationSaveMode mode)
		{
			ConfigurationElementCollection configurationElementCollection = (ConfigurationElementCollection)parentElement;
			base.PrepareSave(parentElement, mode);
			for (int i = 0; i < list.Count; i++)
			{
				ConfigurationElement configurationElement = (ConfigurationElement)list[i];
				object elementKey = GetElementKey(configurationElement);
				ConfigurationElement parent = configurationElementCollection?.BaseGet(elementKey);
				configurationElement.PrepareSave(parent, mode);
			}
		}

		internal override bool HasValues(ConfigurationElement parentElement, ConfigurationSaveMode mode)
		{
			ConfigurationElementCollection configurationElementCollection = (ConfigurationElementCollection)parentElement;
			if (mode == ConfigurationSaveMode.Full)
			{
				return list.Count > 0;
			}
			for (int i = 0; i < list.Count; i++)
			{
				ConfigurationElement configurationElement = (ConfigurationElement)list[i];
				object elementKey = GetElementKey(configurationElement);
				ConfigurationElement parent = configurationElementCollection?.BaseGet(elementKey);
				if (configurationElement.HasValues(parent, mode))
				{
					return true;
				}
			}
			return false;
		}

		protected internal override void Reset(ConfigurationElement parentElement)
		{
			bool isBasic = IsBasic;
			ConfigurationElementCollection configurationElementCollection = (ConfigurationElementCollection)parentElement;
			for (int i = 0; i < configurationElementCollection.Count; i++)
			{
				ConfigurationElement parentElement2 = configurationElementCollection.BaseGet(i);
				ConfigurationElement configurationElement = CreateNewElementInternal(null);
				configurationElement.Reset(parentElement2);
				BaseAdd(configurationElement);
				if (isBasic)
				{
					if (inherited == null)
					{
						inherited = new ArrayList();
					}
					inherited.Add(configurationElement);
				}
			}
			if (IsAlternate)
			{
				inheritedLimitIndex = 0;
			}
			else
			{
				inheritedLimitIndex = Count - 1;
			}
			modified = false;
		}

		protected internal override void ResetModified()
		{
			modified = false;
			for (int i = 0; i < list.Count; i++)
			{
				((ConfigurationElement)list[i]).ResetModified();
			}
		}

		[MonoTODO]
		protected internal override void SetReadOnly()
		{
			base.SetReadOnly();
		}

		protected internal override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey)
		{
			if (serializeCollectionKey)
			{
				return base.SerializeElement(writer, serializeCollectionKey);
			}
			bool flag = false;
			if (IsBasic)
			{
				for (int i = 0; i < list.Count; i++)
				{
					ConfigurationElement configurationElement = (ConfigurationElement)list[i];
					flag = ((!(ElementName != string.Empty)) ? (configurationElement.SerializeElement(writer, serializeCollectionKey: false) || flag) : (configurationElement.SerializeToXmlElement(writer, ElementName) || flag));
				}
			}
			else
			{
				if (emitClear)
				{
					writer.WriteElementString(clearElementName, "");
					flag = true;
				}
				if (removed != null)
				{
					for (int j = 0; j < removed.Count; j++)
					{
						writer.WriteStartElement(removeElementName);
						((ConfigurationElement)removed[j]).SerializeElement(writer, serializeCollectionKey: true);
						writer.WriteEndElement();
					}
					flag = flag || removed.Count > 0;
				}
				for (int k = 0; k < list.Count; k++)
				{
					((ConfigurationElement)list[k]).SerializeToXmlElement(writer, addElementName);
				}
				flag = flag || list.Count > 0;
			}
			return flag;
		}

		protected override bool OnDeserializeUnrecognizedElement(string elementName, XmlReader reader)
		{
			if (IsBasic)
			{
				ConfigurationElement configurationElement = null;
				if (elementName == ElementName)
				{
					configurationElement = CreateNewElementInternal(null);
				}
				if (IsElementName(elementName))
				{
					configurationElement = CreateNewElementInternal(elementName);
				}
				if (configurationElement != null)
				{
					configurationElement.DeserializeElement(reader, serializeCollectionKey: false);
					BaseAdd(configurationElement);
					modified = false;
					return true;
				}
			}
			else
			{
				if (elementName == clearElementName)
				{
					reader.MoveToContent();
					if (reader.MoveToNextAttribute())
					{
						throw new ConfigurationErrorsException("Unrecognized attribute '" + reader.LocalName + "'.");
					}
					reader.MoveToElement();
					reader.Skip();
					BaseClear();
					emitClear = true;
					modified = false;
					return true;
				}
				if (elementName == removeElementName)
				{
					ConfigurationRemoveElement configurationRemoveElement = new ConfigurationRemoveElement(CreateNewElementInternal(null), this);
					configurationRemoveElement.DeserializeElement(reader, serializeCollectionKey: true);
					BaseRemove(configurationRemoveElement.KeyValue);
					modified = false;
					return true;
				}
				if (elementName == addElementName)
				{
					ConfigurationElement configurationElement2 = CreateNewElementInternal(null);
					configurationElement2.DeserializeElement(reader, serializeCollectionKey: false);
					BaseAdd(configurationElement2);
					modified = false;
					return true;
				}
			}
			return false;
		}

		protected internal override void Unmerge(ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
		{
			ConfigurationElementCollection configurationElementCollection = (ConfigurationElementCollection)sourceElement;
			ConfigurationElementCollection configurationElementCollection2 = (ConfigurationElementCollection)parentElement;
			for (int i = 0; i < configurationElementCollection.Count; i++)
			{
				ConfigurationElement configurationElement = configurationElementCollection.BaseGet(i);
				object elementKey = configurationElementCollection.GetElementKey(configurationElement);
				ConfigurationElement configurationElement2 = configurationElementCollection2?.BaseGet(elementKey);
				ConfigurationElement configurationElement3 = CreateNewElementInternal(null);
				if (configurationElement2 != null && saveMode != ConfigurationSaveMode.Full)
				{
					configurationElement3.Unmerge(configurationElement, configurationElement2, saveMode);
					if (configurationElement3.HasValues(configurationElement2, saveMode))
					{
						BaseAdd(configurationElement3);
					}
				}
				else
				{
					configurationElement3.Unmerge(configurationElement, null, ConfigurationSaveMode.Full);
					BaseAdd(configurationElement3);
				}
			}
			if (saveMode == ConfigurationSaveMode.Full)
			{
				EmitClear = true;
			}
			else
			{
				if (configurationElementCollection2 == null)
				{
					return;
				}
				for (int j = 0; j < configurationElementCollection2.Count; j++)
				{
					ConfigurationElement configurationElement4 = configurationElementCollection2.BaseGet(j);
					object elementKey2 = configurationElementCollection2.GetElementKey(configurationElement4);
					if (configurationElementCollection.IndexOfKey(elementKey2) == -1)
					{
						if (removed == null)
						{
							removed = new ArrayList();
						}
						removed.Add(configurationElement4);
					}
				}
			}
		}
	}
	public enum ConfigurationElementCollectionType
	{
		BasicMap,
		AddRemoveClearMap,
		BasicMapAlternate,
		AddRemoveClearMapAlternate
	}
	public sealed class ConfigurationElementProperty
	{
		private ConfigurationValidatorBase validator;

		public ConfigurationValidatorBase Validator => validator;

		public ConfigurationElementProperty(ConfigurationValidatorBase validator)
		{
			this.validator = validator;
		}
	}
	[Serializable]
	public class ConfigurationErrorsException : ConfigurationException
	{
		private readonly string filename;

		private readonly int line;

		public override string BareMessage => ((ConfigurationException)this).BareMessage;

		public ICollection Errors
		{
			get
			{
				throw new NotImplementedException();
			}
		}

		public override string Filename => filename;

		public override int Line => line;

		public override string Message
		{
			get
			{
				if (!string.IsNullOrEmpty(filename))
				{
					if (line != 0)
					{
						return ((ConfigurationException)this).BareMessage + " (" + filename + " line " + line + ")";
					}
					return ((ConfigurationException)this).BareMessage + " (" + filename + ")";
				}
				if (line != 0)
				{
					return ((ConfigurationException)this).BareMessage + " (line " + line + ")";
				}
				return ((ConfigurationException)this).BareMessage;
			}
		}

		public ConfigurationErrorsException()
		{
		}

		public ConfigurationErrorsException(string message)
			: base(message)
		{
		}

		protected ConfigurationErrorsException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
			filename = info.GetString("ConfigurationErrors_Filename");
			line = info.GetInt32("ConfigurationErrors_Line");
		}

		public ConfigurationErrorsException(string message, Exception inner)
			: base(message, inner)
		{
		}

		public ConfigurationErrorsException(string message, XmlNode node)
			: this(message, null, GetFilename(node), GetLineNumber(node))
		{
		}

		public ConfigurationErrorsException(string message, Exception inner, XmlNode node)
			: this(message, inner, GetFilename(node), GetLineNumber(node))
		{
		}

		public ConfigurationErrorsException(string message, XmlReader reader)
			: this(message, null, GetFilename(reader), GetLineNumber(reader))
		{
		}

		public ConfigurationErrorsException(string message, Exception inner, XmlReader reader)
			: this(message, inner, GetFilename(reader), GetLineNumber(reader))
		{
		}

		public ConfigurationErrorsException(string message, string filename, int line)
			: this(message, null, filename, line)
		{
		}

		public ConfigurationErrorsException(string message, Exception inner, string filename, int line)
			: base(message, inner)
		{
			this.filename = filename;
			this.line = line;
		}

		public static string GetFilename(XmlReader reader)
		{
			if (reader is IConfigErrorInfo)
			{
				return ((IConfigErrorInfo)reader).Filename;
			}
			return reader?.BaseURI;
		}

		public static int GetLineNumber(XmlReader reader)
		{
			if (reader is IConfigErrorInfo)
			{
				return ((IConfigErrorInfo)reader).LineNumber;
			}
			if (!(reader is IXmlLineInfo xmlLineInfo))
			{
				return 0;
			}
			return xmlLineInfo.LineNumber;
		}

		public static string GetFilename(XmlNode node)
		{
			if (!(node is IConfigErrorInfo))
			{
				return null;
			}
			return ((IConfigErrorInfo)node).Filename;
		}

		public static int GetLineNumber(XmlNode node)
		{
			if (!(node is IConfigErrorInfo))
			{
				return 0;
			}
			return ((IConfigErrorInfo)node).LineNumber;
		}

		[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
		public override void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			((ConfigurationException)this).GetObjectData(info, context);
			info.AddValue("ConfigurationErrors_Filename", filename);
			info.AddValue("ConfigurationErrors_Line", line);
		}
	}
	public class ConfigurationFileMap : ICloneable
	{
		private string machineConfigFilename;

		public string MachineConfigFilename
		{
			get
			{
				return machineConfigFilename;
			}
			set
			{
				machineConfigFilename = value;
			}
		}

		public ConfigurationFileMap()
		{
			machineConfigFilename = RuntimeEnvironment.SystemConfigurationFile;
		}

		public ConfigurationFileMap(string machineConfigFilename)
		{
			this.machineConfigFilename = machineConfigFilename;
		}

		public virtual object Clone()
		{
			return new ConfigurationFileMap(machineConfigFilename);
		}
	}
	public class ConfigurationLocation
	{
		private static readonly char[] pathTrimChars = new char[1] { '/' };

		private string path;

		private Configuration configuration;

		private Configuration parent;

		private string xmlContent;

		private bool parentResolved;

		private bool allowOverride;

		public string Path => path;

		internal bool AllowOverride => allowOverride;

		internal string XmlContent => xmlContent;

		internal Configuration OpenedConfiguration => configuration;

		internal ConfigurationLocation()
		{
		}

		internal ConfigurationLocation(string path, string xmlContent, Configuration parent, bool allowOverride)
		{
			if (!string.IsNullOrEmpty(path))
			{
				switch (path[0])
				{
				case ' ':
				case '.':
				case '/':
				case '\\':
					throw new ConfigurationErrorsException("<location> path attribute must be a relative virtual path.  It cannot start with any of ' ' '.' '/' or '\\'.");
				}
				path = path.TrimEnd(pathTrimChars);
			}
			this.path = path;
			this.xmlContent = xmlContent;
			this.parent = parent;
			this.allowOverride = allowOverride;
		}

		public Configuration OpenConfiguration()
		{
			if (configuration == null)
			{
				if (!parentResolved)
				{
					Configuration parentWithFile = parent.GetParentWithFile();
					if (parentWithFile != null)
					{
						string configPathFromLocationSubPath = parent.ConfigHost.GetConfigPathFromLocationSubPath(parent.LocationConfigPath, path);
						parent = parentWithFile.FindLocationConfiguration(configPathFromLocationSubPath, parent);
					}
				}
				configuration = new Configuration(parent, path);
				using (XmlTextReader reader = new ConfigXmlTextReader(new StringReader(xmlContent), path))
				{
					configuration.ReadData(reader, allowOverride);
				}
				xmlContent = null;
			}
			return configuration;
		}

		internal void SetParentConfiguration(Configuration parent)
		{
			if (!parentResolved)
			{
				parentResolved = true;
				this.parent = parent;
				if (configuration != null)
				{
					configuration.Parent = parent;
				}
			}
		}
	}
	public class ConfigurationLocationCollection : ReadOnlyCollectionBase
	{
		public ConfigurationLocation this[int index] => base.InnerList[index] as ConfigurationLocation;

		internal ConfigurationLocationCollection()
		{
		}

		internal void Add(ConfigurationLocation loc)
		{
			base.InnerList.Add(loc);
		}

		internal ConfigurationLocation Find(string location)
		{
			foreach (ConfigurationLocation inner in base.InnerList)
			{
				if (string.Compare(inner.Path, location, StringComparison.OrdinalIgnoreCase) == 0)
				{
					return inner;
				}
			}
			return null;
		}

		internal ConfigurationLocation FindBest(string location)
		{
			if (string.IsNullOrEmpty(location))
			{
				return null;
			}
			ConfigurationLocation configurationLocation = null;
			int length = location.Length;
			int num = 0;
			foreach (ConfigurationLocation inner in base.InnerList)
			{
				string path = inner.Path;
				if (string.IsNullOrEmpty(path))
				{
					continue;
				}
				int length2 = path.Length;
				if (!location.StartsWith(path, StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				if (length == length2)
				{
					return inner;
				}
				if (length <= length2 || location[length2] == '/')
				{
					if (configurationLocation == null)
					{
						configurationLocation = inner;
					}
					else if (num < length2)
					{
						configurationLocation = inner;
						num = length2;
					}
				}
			}
			return configurationLocation;
		}
	}
	[Flags]
	internal enum ConfigurationLockType
	{
		Attribute = 1,
		Element = 2,
		Exclude = 0x10
	}
	public sealed class ConfigurationLockCollection : ICollection, IEnumerable
	{
		private ArrayList names;

		private ConfigurationElement element;

		private ConfigurationLockType lockType;

		private bool is_modified;

		private Hashtable valid_name_hash;

		private string valid_names;

		public string AttributeList
		{
			get
			{
				string[] array = new string[names.Count];
				names.CopyTo(array, 0);
				return string.Join(",", array);
			}
		}

		public int Count => names.Count;

		[MonoTODO]
		public bool HasParentElements => false;

		[MonoTODO]
		public bool IsModified
		{
			get
			{
				return is_modified;
			}
			internal set
			{
				is_modified = value;
			}
		}

		[MonoTODO]
		public bool IsSynchronized => false;

		[MonoTODO]
		public object SyncRoot => this;

		internal ConfigurationLockCollection(ConfigurationElement element, ConfigurationLockType lockType)
		{
			names = new ArrayList();
			this.element = element;
			this.lockType = lockType;
		}

		private void CheckName(string name)
		{
			bool flag = (lockType & ConfigurationLockType.Attribute) == ConfigurationLockType.Attribute;
			if (valid_name_hash == null)
			{
				valid_name_hash = new Hashtable();
				foreach (ConfigurationProperty property in element.Properties)
				{
					if (flag != property.IsElement)
					{
						valid_name_hash.Add(property.Name, true);
					}
				}
				if (!flag)
				{
					ConfigurationElementCollection defaultCollection = element.GetDefaultCollection();
					valid_name_hash.Add(defaultCollection.AddElementName, true);
					valid_name_hash.Add(defaultCollection.ClearElementName, true);
					valid_name_hash.Add(defaultCollection.RemoveElementName, true);
				}
				string[] array = new string[valid_name_hash.Keys.Count];
				valid_name_hash.Keys.CopyTo(array, 0);
				valid_names = string.Join(",", array);
			}
			if (valid_name_hash[name] == null)
			{
				throw new ConfigurationErrorsException(string.Format("The {2} '{0}' is not valid in the locked list for this section.  The following {3} can be locked: '{1}'", name, valid_names, flag ? "attribute" : "element", flag ? "attributes" : "elements"));
			}
		}

		public void Add(string name)
		{
			CheckName(name);
			if (!names.Contains(name))
			{
				names.Add(name);
				is_modified = true;
			}
		}

		public void Clear()
		{
			names.Clear();
			is_modified = true;
		}

		public bool Contains(string name)
		{
			return names.Contains(name);
		}

		public void CopyTo(string[] array, int index)
		{
			names.CopyTo(array, index);
		}

		public IEnumerator GetEnumerator()
		{
			return names.GetEnumerator();
		}

		[MonoInternalNote("we can't possibly *always* return false here...")]
		public bool IsReadOnly(string name)
		{
			for (int i = 0; i < names.Count; i++)
			{
				if ((string)names[i] == name)
				{
					return false;
				}
			}
			throw new ConfigurationErrorsException($"The entry '{name}' is not in the collection.");
		}

		public void Remove(string name)
		{
			names.Remove(name);
			is_modified = true;
		}

		public void SetFromList(string attributeList)
		{
			Clear();
			char[] separator = new char[1] { ',' };
			string[] array = attributeList.Split(separator);
			foreach (string text in array)
			{
				Add(text.Trim());
			}
		}

		void ICollection.CopyTo(Array array, int index)
		{
			names.CopyTo(array, index);
		}

		internal ConfigurationLockCollection()
		{
			ThrowStub.ThrowNotSupportedException();
		}
	}
	public static class ConfigurationManager
	{
		private static InternalConfigurationFactory configFactory = new InternalConfigurationFactory();

		private static IInternalConfigSystem configSystem = new ClientConfigurationSystem();

		private static object lockobj = new object();

		internal static IInternalConfigConfigurationFactory ConfigurationFactory => configFactory;

		internal static IInternalConfigSystem ConfigurationSystem => configSystem;

		public static NameValueCollection AppSettings => (NameValueCollection)GetSection("appSettings");

		public static ConnectionStringSettingsCollection ConnectionStrings => ((ConnectionStringsSection)GetSection("connectionStrings")).ConnectionStrings;

		[MonoTODO("Evidence and version still needs work")]
		private static string GetAssemblyInfo(Assembly a)
		{
			object[] customAttributes = a.GetCustomAttributes(typeof(AssemblyProductAttribute), inherit: false);
			string arg = ((customAttributes == null || customAttributes.Length == 0) ? AppDomain.CurrentDomain.FriendlyName : ((AssemblyProductAttribute)customAttributes[0]).Product);
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("evidencehere");
			string arg2 = stringBuilder.ToString();
			customAttributes = a.GetCustomAttributes(typeof(AssemblyVersionAttribute), inherit: false);
			return Path.Combine(path2: (customAttributes == null || customAttributes.Length == 0) ? "1.0.0.0" : ((AssemblyVersionAttribute)customAttributes[0]).Version, path1: $"{arg}_{arg2}");
		}

		internal static Configuration OpenExeConfigurationInternal(ConfigurationUserLevel userLevel, Assembly calling_assembly, string exePath)
		{
			ExeConfigurationFileMap exeConfigurationFileMap = new ExeConfigurationFileMap();
			if (userLevel != 0)
			{
				if (userLevel != ConfigurationUserLevel.PerUserRoaming)
				{
					if (userLevel != ConfigurationUserLevel.PerUserRoamingAndLocal)
					{
						goto IL_00ea;
					}
					exeConfigurationFileMap.LocalUserConfigFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), GetAssemblyInfo(calling_assembly));
					exeConfigurationFileMap.LocalUserConfigFilename = Path.Combine(exeConfigurationFileMap.LocalUserConfigFilename, "user.config");
				}
				exeConfigurationFileMap.RoamingUserConfigFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), GetAssemblyInfo(calling_assembly));
				exeConfigurationFileMap.RoamingUserConfigFilename = Path.Combine(exeConfigurationFileMap.RoamingUserConfigFilename, "user.config");
			}
			if (exePath == null || exePath.Length == 0)
			{
				exeConfigurationFileMap.ExeConfigFilename = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
			}
			else
			{
				if (!Path.IsPathRooted(exePath))
				{
					exePath = Path.GetFullPath(exePath);
				}
				if (!File.Exists(exePath))
				{
					Exception inner = new ArgumentException("The specified path does not exist.", "exePath");
					throw new ConfigurationErrorsException("Error Initializing the configuration system:", inner);
				}
				exeConfigurationFileMap.ExeConfigFilename = exePath + ".config";
			}
			goto IL_00ea;
			IL_00ea:
			return ConfigurationFactory.Create(typeof(ExeConfigurationHost), exeConfigurationFileMap, userLevel);
		}

		public static Configuration OpenExeConfiguration(ConfigurationUserLevel userLevel)
		{
			return OpenExeConfigurationInternal(userLevel, Assembly.GetEntryAssembly() ?? Assembly.GetCallingAssembly(), null);
		}

		public static Configuration OpenExeConfiguration(string exePath)
		{
			return OpenExeConfigurationInternal(ConfigurationUserLevel.None, Assembly.GetEntryAssembly() ?? Assembly.GetCallingAssembly(), exePath);
		}

		[MonoLimitation("ConfigurationUserLevel parameter is not supported.")]
		public static Configuration OpenMappedExeConfiguration(ExeConfigurationFileMap fileMap, ConfigurationUserLevel userLevel)
		{
			return ConfigurationFactory.Create(typeof(ExeConfigurationHost), fileMap, userLevel);
		}

		public static Configuration OpenMachineConfiguration()
		{
			ConfigurationFileMap configurationFileMap = new ConfigurationFileMap();
			return ConfigurationFactory.Create(typeof(MachineConfigurationHost), configurationFileMap);
		}

		public static Configuration OpenMappedMachineConfiguration(ConfigurationFileMap fileMap)
		{
			return ConfigurationFactory.Create(typeof(MachineConfigurationHost), fileMap);
		}

		public static object GetSection(string sectionName)
		{
			object section = ConfigurationSystem.GetSection(sectionName);
			if (section is ConfigurationSection)
			{
				return ((ConfigurationSection)section).GetRuntimeObject();
			}
			return section;
		}

		public static void RefreshSection(string sectionName)
		{
			ConfigurationSystem.RefreshConfig(sectionName);
		}

		internal static IInternalConfigSystem ChangeConfigurationSystem(IInternalConfigSystem newSystem)
		{
			if (newSystem == null)
			{
				throw new ArgumentNullException("newSystem");
			}
			lock (lockobj)
			{
				IInternalConfigSystem result = configSystem;
				configSystem = newSystem;
				return result;
			}
		}

		public static Configuration OpenMappedExeConfiguration(ExeConfigurationFileMap fileMap, ConfigurationUserLevel userLevel, bool preLoad)
		{
			ThrowStub.ThrowNotSupportedException();
			return null;
		}
	}
	[Serializable]
	public sealed class ConfigurationPermission : CodeAccessPermission, IUnrestrictedPermission
	{
		private bool unrestricted;

		public ConfigurationPermission(PermissionState state)
		{
			unrestricted = state == PermissionState.Unrestricted;
		}

		public override IPermission Copy()
		{
			return (IPermission)(object)new ConfigurationPermission(unrestricted ? PermissionState.Unrestricted : PermissionState.None);
		}

		public override void FromXml(SecurityElement securityElement)
		{
			if (securityElement == null)
			{
				throw new ArgumentNullException("securityElement");
			}
			if (securityElement.Tag != "IPermission")
			{
				throw new ArgumentException("securityElement");
			}
			string text = securityElement.Attribute("Unrestricted");
			if (text != null)
			{
				unrestricted = string.Compare(text, "true", StringComparison.InvariantCultureIgnoreCase) == 0;
			}
		}

		public override IPermission Intersect(IPermission target)
		{
			if (target == null)
			{
				return null;
			}
			if (!(target is ConfigurationPermission configurationPermission))
			{
				throw new ArgumentException("target");
			}
			return (IPermission)(object)new ConfigurationPermission((unrestricted && configurationPermission.IsUnrestricted()) ? PermissionState.Unrestricted : PermissionState.None);
		}

		public override IPermission Union(IPermission target)
		{
			if (target == null)
			{
				return ((CodeAccessPermission)this).Copy();
			}
			if (!(target is ConfigurationPermission configurationPermission))
			{
				throw new ArgumentException("target");
			}
			return (IPermission)(object)new ConfigurationPermission((unrestricted || configurationPermission.IsUnrestricted()) ? PermissionState.Unrestricted : PermissionState.None);
		}

		public override bool IsSubsetOf(IPermission target)
		{
			if (target == null)
			{
				return !unrestricted;
			}
			if (!(target is ConfigurationPermission configurationPermission))
			{
				throw new ArgumentException("target");
			}
			if (unrestricted)
			{
				return configurationPermission.IsUnrestricted();
			}
			return true;
		}

		public bool IsUnrestricted()
		{
			return unrestricted;
		}

		public override SecurityElement ToXml()
		{
			SecurityElement securityElement = new SecurityElement("IPermission");
			securityElement.AddAttribute("class", ((object)this).GetType().AssemblyQualifiedName);
			securityElement.AddAttribute("version", "1");
			if (unrestricted)
			{
				securityElement.AddAttribute("Unrestricted", "true");
			}
			return securityElement;
		}
	}
	[Serializable]
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	public sealed class ConfigurationPermissionAttribute : CodeAccessSecurityAttribute
	{
		public ConfigurationPermissionAttribute(SecurityAction action)
			: base(action)
		{
		}

		public override IPermission CreatePermission()
		{
			return (IPermission)(object)new ConfigurationPermission(base.Unrestricted ? PermissionState.Unrestricted : PermissionState.None);
		}
	}
	public sealed class ConfigurationProperty
	{
		internal static readonly object NoDefaultValue = new object();

		private string name;

		private Type type;

		private object default_value;

		private TypeConverter converter;

		private ConfigurationValidatorBase validation;

		private ConfigurationPropertyOptions flags;

		private string description;

		private ConfigurationCollectionAttribute collectionAttribute;

		public TypeConverter Converter => converter;

		public object DefaultValue => default_value;

		public bool IsKey => (flags & ConfigurationPropertyOptions.IsKey) != 0;

		public bool IsRequired => (flags & ConfigurationPropertyOptions.IsRequired) != 0;

		public bool IsDefaultCollection => (flags & ConfigurationPropertyOptions.IsDefaultCollection) != 0;

		public string Name => name;

		public string Description => description;

		public Type Type => type;

		public ConfigurationValidatorBase Validator => validation;

		internal bool IsElement => typeof(ConfigurationElement).IsAssignableFrom(type);

		internal ConfigurationCollectionAttribute CollectionAttribute
		{
			get
			{
				return collectionAttribute;
			}
			set
			{
				collectionAttribute = value;
			}
		}

		public bool IsAssemblyStringTransformationRequired
		{
			get
			{
				ThrowStub.ThrowNotSupportedException();
				return default(bool);
			}
		}

		public bool IsTypeStringTransformationRequired
		{
			get
			{
				ThrowStub.ThrowNotSupportedException();
				return default(bool);
			}
		}

		public bool IsVersionCheckRequired
		{
			get
			{
				ThrowStub.ThrowNotSupportedException();
				return default(bool);
			}
		}

		public ConfigurationProperty(string name, Type type)
			: this(name, type, NoDefaultValue, TypeDescriptor.GetConverter(type), new DefaultValidator(), ConfigurationPropertyOptions.None, null)
		{
		}

		public ConfigurationProperty(string name, Type type, object defaultValue)
			: this(name, type, defaultValue, TypeDescriptor.GetConverter(type), new DefaultValidator(), ConfigurationPropertyOptions.None, null)
		{
		}

		public ConfigurationProperty(string name, Type type, object defaultValue, ConfigurationPropertyOptions options)
			: this(name, type, defaultValue, TypeDescriptor.GetConverter(type), new DefaultValidator(), options, null)
		{
		}

		public ConfigurationProperty(string name, Type type, object defaultValue, TypeConverter typeConverter, ConfigurationValidatorBase validator, ConfigurationPropertyOptions options)
			: this(name, type, defaultValue, typeConverter, validator, options, null)
		{
		}

		public ConfigurationProperty(string name, Type type, object defaultValue, TypeConverter typeConverter, ConfigurationValidatorBase validator, ConfigurationPropertyOptions options, string description)
		{
			this.name = name;
			converter = ((typeConverter != null) ? typeConverter : TypeDescriptor.GetConverter(type));
			if (defaultValue != null)
			{
				if (defaultValue == NoDefaultValue)
				{
					defaultValue 

System.Data.dll

Decompiled 3 weeks ago
using System;
using System.Buffers;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Data.Odbc;
using System.Data.OleDb;
using System.Data.ProviderBase;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.SqlClient.SNI;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Dynamic;
using System.EnterpriseServices;
using System.Globalization;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Numerics;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Transactions;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Xml.Serialization.Advanced;
using System.Xml.XPath;
using Microsoft.SqlServer.Server;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("System.Data.dll")]
[assembly: AssemblyDescription("System.Data.dll")]
[assembly: AssemblyDefaultAlias("System.Data.dll")]
[assembly: AssemblyCompany("Mono development team")]
[assembly: AssemblyProduct("Mono Common Language Infrastructure")]
[assembly: AssemblyCopyright("(c) Various Mono authors")]
[assembly: SatelliteContractVersion("4.0.0.0")]
[assembly: AssemblyInformationalVersion("4.6.57.0")]
[assembly: CLSCompliant(true)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: ComVisible(false)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: AssemblyDelaySign(true)]
[assembly: AssemblyFileVersion("4.6.57.0")]
[assembly: InternalsVisibleTo("System.Design, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
[assembly: InternalsVisibleTo("System.Web, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.0.0")]
[module: UnverifiableCode]
internal static class Interop
{
	internal static class Odbc
	{
		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLAllocHandle(ODBC32.SQL_HANDLE HandleType, IntPtr InputHandle, out IntPtr OutputHandle);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLAllocHandle(ODBC32.SQL_HANDLE HandleType, OdbcHandle InputHandle, out IntPtr OutputHandle);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLBindCol(OdbcStatementHandle StatementHandle, ushort ColumnNumber, ODBC32.SQL_C TargetType, HandleRef TargetValue, IntPtr BufferLength, IntPtr StrLen_or_Ind);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLBindCol(OdbcStatementHandle StatementHandle, ushort ColumnNumber, ODBC32.SQL_C TargetType, IntPtr TargetValue, IntPtr BufferLength, IntPtr StrLen_or_Ind);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLBindParameter(OdbcStatementHandle StatementHandle, ushort ParameterNumber, short ParamDirection, ODBC32.SQL_C SQLCType, short SQLType, IntPtr cbColDef, IntPtr ibScale, HandleRef rgbValue, IntPtr BufferLength, HandleRef StrLen_or_Ind);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLCancel(OdbcStatementHandle StatementHandle);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLCloseCursor(OdbcStatementHandle StatementHandle);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLColAttributeW(OdbcStatementHandle StatementHandle, short ColumnNumber, short FieldIdentifier, CNativeBuffer CharacterAttribute, short BufferLength, out short StringLength, out IntPtr NumericAttribute);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLColumnsW(OdbcStatementHandle StatementHandle, string CatalogName, short NameLen1, string SchemaName, short NameLen2, string TableName, short NameLen3, string ColumnName, short NameLen4);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLDisconnect(IntPtr ConnectionHandle);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLDriverConnectW(OdbcConnectionHandle hdbc, IntPtr hwnd, string connectionstring, short cbConnectionstring, IntPtr connectionstringout, short cbConnectionstringoutMax, out short cbConnectionstringout, short fDriverCompletion);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLEndTran(ODBC32.SQL_HANDLE HandleType, IntPtr Handle, short CompletionType);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLExecDirectW(OdbcStatementHandle StatementHandle, string StatementText, int TextLength);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLExecute(OdbcStatementHandle StatementHandle);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLFetch(OdbcStatementHandle StatementHandle);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLFreeHandle(ODBC32.SQL_HANDLE HandleType, IntPtr StatementHandle);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLFreeStmt(OdbcStatementHandle StatementHandle, ODBC32.STMT Option);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLGetConnectAttrW(OdbcConnectionHandle ConnectionHandle, ODBC32.SQL_ATTR Attribute, byte[] Value, int BufferLength, out int StringLength);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLGetData(OdbcStatementHandle StatementHandle, ushort ColumnNumber, ODBC32.SQL_C TargetType, CNativeBuffer TargetValue, IntPtr BufferLength, out IntPtr StrLen_or_Ind);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLGetDescFieldW(OdbcDescriptorHandle StatementHandle, short RecNumber, ODBC32.SQL_DESC FieldIdentifier, CNativeBuffer ValuePointer, int BufferLength, out int StringLength);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLGetDiagRecW(ODBC32.SQL_HANDLE HandleType, OdbcHandle Handle, short RecNumber, StringBuilder rchState, out int NativeError, StringBuilder MessageText, short BufferLength, out short TextLength);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLGetDiagFieldW(ODBC32.SQL_HANDLE HandleType, OdbcHandle Handle, short RecNumber, short DiagIdentifier, StringBuilder rchState, short BufferLength, out short StringLength);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLGetFunctions(OdbcConnectionHandle hdbc, ODBC32.SQL_API fFunction, out short pfExists);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLGetInfoW(OdbcConnectionHandle hdbc, ODBC32.SQL_INFO fInfoType, byte[] rgbInfoValue, short cbInfoValueMax, out short pcbInfoValue);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLGetInfoW(OdbcConnectionHandle hdbc, ODBC32.SQL_INFO fInfoType, byte[] rgbInfoValue, short cbInfoValueMax, IntPtr pcbInfoValue);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLGetStmtAttrW(OdbcStatementHandle StatementHandle, ODBC32.SQL_ATTR Attribute, out IntPtr Value, int BufferLength, out int StringLength);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLGetTypeInfo(OdbcStatementHandle StatementHandle, short fSqlType);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLMoreResults(OdbcStatementHandle StatementHandle);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLNumResultCols(OdbcStatementHandle StatementHandle, out short ColumnCount);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLPrepareW(OdbcStatementHandle StatementHandle, string StatementText, int TextLength);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLPrimaryKeysW(OdbcStatementHandle StatementHandle, string CatalogName, short NameLen1, string SchemaName, short NameLen2, string TableName, short NameLen3);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLProcedureColumnsW(OdbcStatementHandle StatementHandle, string CatalogName, short NameLen1, string SchemaName, short NameLen2, string ProcName, short NameLen3, string ColumnName, short NameLen4);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLProceduresW(OdbcStatementHandle StatementHandle, string CatalogName, short NameLen1, string SchemaName, short NameLen2, string ProcName, short NameLen3);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLRowCount(OdbcStatementHandle StatementHandle, out IntPtr RowCount);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLSetConnectAttrW(OdbcConnectionHandle ConnectionHandle, ODBC32.SQL_ATTR Attribute, IDtcTransaction Value, int StringLength);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLSetConnectAttrW(OdbcConnectionHandle ConnectionHandle, ODBC32.SQL_ATTR Attribute, string Value, int StringLength);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLSetConnectAttrW(OdbcConnectionHandle ConnectionHandle, ODBC32.SQL_ATTR Attribute, IntPtr Value, int StringLength);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLSetConnectAttrW(IntPtr ConnectionHandle, ODBC32.SQL_ATTR Attribute, IntPtr Value, int StringLength);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLSetDescFieldW(OdbcDescriptorHandle StatementHandle, short ColumnNumber, ODBC32.SQL_DESC FieldIdentifier, HandleRef CharacterAttribute, int BufferLength);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLSetDescFieldW(OdbcDescriptorHandle StatementHandle, short ColumnNumber, ODBC32.SQL_DESC FieldIdentifier, IntPtr CharacterAttribute, int BufferLength);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLSetEnvAttr(OdbcEnvironmentHandle EnvironmentHandle, ODBC32.SQL_ATTR Attribute, IntPtr Value, ODBC32.SQL_IS StringLength);

		[DllImport("odbc32.dll")]
		internal static extern ODBC32.RetCode SQLSetStmtAttrW(OdbcStatementHandle StatementHandle, int Attribute, IntPtr Value, int StringLength);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLSpecialColumnsW(OdbcStatementHandle StatementHandle, ODBC32.SQL_SPECIALCOLS IdentifierType, string CatalogName, short NameLen1, string SchemaName, short NameLen2, string TableName, short NameLen3, ODBC32.SQL_SCOPE Scope, ODBC32.SQL_NULLABILITY Nullable);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLStatisticsW(OdbcStatementHandle StatementHandle, string CatalogName, short NameLen1, string SchemaName, short NameLen2, string TableName, short NameLen3, short Unique, short Reserved);

		[DllImport("odbc32.dll", CharSet = CharSet.Unicode)]
		internal static extern ODBC32.RetCode SQLTablesW(OdbcStatementHandle StatementHandle, string CatalogName, short NameLen1, string SchemaName, short NameLen2, string TableName, short NameLen3, string TableType, short NameLen4);
	}

	internal static class Libraries
	{
		internal const string Advapi32 = "advapi32.dll";

		internal const string BCrypt = "BCrypt.dll";

		internal const string CoreComm_L1_1_1 = "api-ms-win-core-comm-l1-1-1.dll";

		internal const string Crypt32 = "crypt32.dll";

		internal const string Error_L1 = "api-ms-win-core-winrt-error-l1-1-0.dll";

		internal const string HttpApi = "httpapi.dll";

		internal const string IpHlpApi = "iphlpapi.dll";

		internal const string Kernel32 = "kernel32.dll";

		internal const string Memory_L1_3 = "api-ms-win-core-memory-l1-1-3.dll";

		internal const string Mswsock = "mswsock.dll";

		internal const string NCrypt = "ncrypt.dll";

		internal const string NtDll = "ntdll.dll";

		internal const string Odbc32 = "odbc32.dll";

		internal const string OleAut32 = "oleaut32.dll";

		internal const string PerfCounter = "perfcounter.dll";

		internal const string RoBuffer = "api-ms-win-core-winrt-robuffer-l1-1-0.dll";

		internal const string Secur32 = "secur32.dll";

		internal const string Shell32 = "shell32.dll";

		internal const string SspiCli = "sspicli.dll";

		internal const string User32 = "user32.dll";

		internal const string Version = "version.dll";

		internal const string WebSocket = "websocket.dll";

		internal const string WinHttp = "winhttp.dll";

		internal const string Ws2_32 = "ws2_32.dll";

		internal const string Wtsapi32 = "wtsapi32.dll";

		internal const string CompressionNative = "clrcompression.dll";
	}

	internal class Kernel32
	{
		public const int LOAD_LIBRARY_AS_DATAFILE = 2;

		public const int LOAD_LIBRARY_SEARCH_SYSTEM32 = 2048;

		[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
		public static extern bool FreeLibrary([In] IntPtr hModule);

		[DllImport("kernel32.dll", BestFitMapping = false, CharSet = CharSet.Ansi)]
		public static extern IntPtr GetProcAddress(SafeLibraryHandle hModule, string lpProcName);

		[DllImport("kernel32.dll", BestFitMapping = false, CharSet = CharSet.Ansi)]
		public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

		[DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
		public static extern SafeLibraryHandle LoadLibraryExW([In] string lpwLibFileName, [In] IntPtr hFile, [In] uint dwFlags);
	}
}
internal class SqlDependencyProcessDispatcher : MarshalByRefObject
{
	private class SqlConnectionContainer
	{
		private SqlConnection _con;

		private SqlCommand _com;

		private SqlParameter _conversationGuidParam;

		private SqlParameter _timeoutParam;

		private SqlConnectionContainerHashHelper _hashHelper;

		private string _queue;

		private string _receiveQuery;

		private string _beginConversationQuery;

		private string _endConversationQuery;

		private string _concatQuery;

		private readonly int _defaultWaitforTimeout = 60000;

		private string _escapedQueueName;

		private string _sprocName;

		private string _dialogHandle;

		private string _cachedServer;

		private string _cachedDatabase;

		private volatile bool _errorState;

		private volatile bool _stop;

		private volatile bool _stopped;

		private volatile bool _serviceQueueCreated;

		private int _startCount;

		private Timer _retryTimer;

		private Dictionary<string, int> _appDomainKeyHash;

		internal string Database
		{
			get
			{
				if (_cachedDatabase == null)
				{
					_cachedDatabase = _con.Database;
				}
				return _cachedDatabase;
			}
		}

		internal SqlConnectionContainerHashHelper HashHelper => _hashHelper;

		internal bool InErrorState => _errorState;

		internal string Queue => _queue;

		internal string Server => _cachedServer;

		internal SqlConnectionContainer(SqlConnectionContainerHashHelper hashHelper, string appDomainKey, bool useDefaults)
		{
			bool flag = false;
			try
			{
				_hashHelper = hashHelper;
				string text = null;
				if (useDefaults)
				{
					text = Guid.NewGuid().ToString();
					_queue = "SqlQueryNotificationService-" + text;
					_hashHelper.ConnectionStringBuilder.ApplicationName = _queue;
				}
				else
				{
					_queue = _hashHelper.Queue;
				}
				_con = new SqlConnection(_hashHelper.ConnectionStringBuilder.ConnectionString);
				_ = (SqlConnectionString)_con.ConnectionOptions;
				_con.Open();
				_cachedServer = _con.DataSource;
				_escapedQueueName = SqlConnection.FixupDatabaseTransactionName(_queue);
				_appDomainKeyHash = new Dictionary<string, int>();
				_com = new SqlCommand
				{
					Connection = _con,
					CommandText = "select is_broker_enabled from sys.databases where database_id=db_id()"
				};
				if (!(bool)_com.ExecuteScalar())
				{
					throw SQL.SqlDependencyDatabaseBrokerDisabled();
				}
				_conversationGuidParam = new SqlParameter("@p1", SqlDbType.UniqueIdentifier);
				_timeoutParam = new SqlParameter("@p2", SqlDbType.Int)
				{
					Value = 0
				};
				_com.Parameters.Add(_timeoutParam);
				flag = true;
				_receiveQuery = "WAITFOR(RECEIVE TOP (1) message_type_name, conversation_handle, cast(message_body AS XML) as message_body from " + _escapedQueueName + "), TIMEOUT @p2;";
				if (useDefaults)
				{
					_sprocName = SqlConnection.FixupDatabaseTransactionName("SqlQueryNotificationStoredProcedure-" + text);
					CreateQueueAndService(restart: false);
				}
				else
				{
					_com.CommandText = _receiveQuery;
					_endConversationQuery = "END CONVERSATION @p1; ";
					_concatQuery = _endConversationQuery + _receiveQuery;
				}
				IncrementStartCount(appDomainKey, out var _);
				SynchronouslyQueryServiceBrokerQueue();
				_timeoutParam.Value = _defaultWaitforTimeout;
				AsynchronouslyQueryServiceBrokerQueue();
			}
			catch (Exception e)
			{
				if (!ADP.IsCatchableExceptionType(e))
				{
					throw;
				}
				ADP.TraceExceptionWithoutRethrow(e);
				if (flag)
				{
					TearDownAndDispose();
				}
				else
				{
					if (_com != null)
					{
						_com.Dispose();
						_com = null;
					}
					if (_con != null)
					{
						_con.Dispose();
						_con = null;
					}
				}
				throw;
			}
		}

		internal bool AppDomainUnload(string appDomainKey)
		{
			lock (_appDomainKeyHash)
			{
				if (_appDomainKeyHash.ContainsKey(appDomainKey))
				{
					int num = _appDomainKeyHash[appDomainKey];
					bool appDomainStop = false;
					while (num > 0)
					{
						Stop(appDomainKey, out appDomainStop);
						num--;
					}
				}
			}
			return _stopped;
		}

		private void AsynchronouslyQueryServiceBrokerQueue()
		{
			AsyncCallback callback = AsyncResultCallback;
			_com.BeginExecuteReader(CommandBehavior.Default, callback, null);
		}

		private void AsyncResultCallback(IAsyncResult asyncResult)
		{
			try
			{
				using (SqlDataReader reader = _com.EndExecuteReader(asyncResult))
				{
					ProcessNotificationResults(reader);
				}
				if (!_stop)
				{
					AsynchronouslyQueryServiceBrokerQueue();
				}
				else
				{
					TearDownAndDispose();
				}
			}
			catch (Exception e)
			{
				if (!ADP.IsCatchableExceptionType(e))
				{
					_errorState = true;
					throw;
				}
				if (!_stop)
				{
					ADP.TraceExceptionWithoutRethrow(e);
				}
				if (_stop)
				{
					TearDownAndDispose();
					return;
				}
				_errorState = true;
				Restart(null);
			}
		}

		private void CreateQueueAndService(bool restart)
		{
			SqlCommand sqlCommand = new SqlCommand
			{
				Connection = _con
			};
			SqlTransaction sqlTransaction = null;
			try
			{
				sqlTransaction = (sqlCommand.Transaction = _con.BeginTransaction());
				string text = SqlServerEscapeHelper.MakeStringLiteral(_queue);
				sqlCommand.CommandText = "CREATE PROCEDURE " + _sprocName + " AS BEGIN BEGIN TRANSACTION; RECEIVE TOP(0) conversation_handle FROM " + _escapedQueueName + "; IF (SELECT COUNT(*) FROM " + _escapedQueueName + " WHERE message_type_name = 'http://schemas.microsoft.com/SQL/ServiceBroker/DialogTimer') > 0 BEGIN if ((SELECT COUNT(*) FROM sys.services WHERE name = " + text + ") > 0)   DROP SERVICE " + _escapedQueueName + "; if (OBJECT_ID(" + text + ", 'SQ') IS NOT NULL)   DROP QUEUE " + _escapedQueueName + "; DROP PROCEDURE " + _sprocName + "; END COMMIT TRANSACTION; END";
				if (!restart)
				{
					sqlCommand.ExecuteNonQuery();
				}
				else
				{
					try
					{
						sqlCommand.ExecuteNonQuery();
					}
					catch (Exception e)
					{
						if (!ADP.IsCatchableExceptionType(e))
						{
							throw;
						}
						ADP.TraceExceptionWithoutRethrow(e);
						try
						{
							if (sqlTransaction != null)
							{
								sqlTransaction.Rollback();
								sqlTransaction = null;
							}
						}
						catch (Exception e2)
						{
							if (!ADP.IsCatchableExceptionType(e2))
							{
								throw;
							}
							ADP.TraceExceptionWithoutRethrow(e2);
						}
					}
					if (sqlTransaction == null)
					{
						sqlTransaction = (sqlCommand.Transaction = _con.BeginTransaction());
					}
				}
				sqlCommand.CommandText = "IF OBJECT_ID(" + text + ", 'SQ') IS NULL BEGIN CREATE QUEUE " + _escapedQueueName + " WITH ACTIVATION (PROCEDURE_NAME=" + _sprocName + ", MAX_QUEUE_READERS=1, EXECUTE AS OWNER); END; IF (SELECT COUNT(*) FROM sys.services WHERE NAME=" + text + ") = 0 BEGIN CREATE SERVICE " + _escapedQueueName + " ON QUEUE " + _escapedQueueName + " ([http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification]); IF (SELECT COUNT(*) FROM sys.database_principals WHERE name='sql_dependency_subscriber' AND type='R') <> 0 BEGIN GRANT SEND ON SERVICE::" + _escapedQueueName + " TO sql_dependency_subscriber; END;  END; BEGIN DIALOG @dialog_handle FROM SERVICE " + _escapedQueueName + " TO SERVICE " + text;
				SqlParameter sqlParameter = new SqlParameter
				{
					ParameterName = "@dialog_handle",
					DbType = DbType.Guid,
					Direction = ParameterDirection.Output
				};
				sqlCommand.Parameters.Add(sqlParameter);
				sqlCommand.ExecuteNonQuery();
				_dialogHandle = ((Guid)sqlParameter.Value).ToString();
				_beginConversationQuery = "BEGIN CONVERSATION TIMER ('" + _dialogHandle + "') TIMEOUT = 120; " + _receiveQuery;
				_com.CommandText = _beginConversationQuery;
				_endConversationQuery = "END CONVERSATION @p1; ";
				_concatQuery = _endConversationQuery + _com.CommandText;
				sqlTransaction.Commit();
				sqlTransaction = null;
				_serviceQueueCreated = true;
			}
			finally
			{
				if (sqlTransaction != null)
				{
					try
					{
						sqlTransaction.Rollback();
						sqlTransaction = null;
					}
					catch (Exception e3)
					{
						if (!ADP.IsCatchableExceptionType(e3))
						{
							throw;
						}
						ADP.TraceExceptionWithoutRethrow(e3);
					}
				}
			}
		}

		internal void IncrementStartCount(string appDomainKey, out bool appDomainStart)
		{
			appDomainStart = false;
			Interlocked.Increment(ref _startCount);
			lock (_appDomainKeyHash)
			{
				if (_appDomainKeyHash.ContainsKey(appDomainKey))
				{
					_appDomainKeyHash[appDomainKey] += 1;
					return;
				}
				_appDomainKeyHash[appDomainKey] = 1;
				appDomainStart = true;
			}
		}

		private void ProcessNotificationResults(SqlDataReader reader)
		{
			Guid guid = Guid.Empty;
			try
			{
				if (_stop)
				{
					return;
				}
				while (reader.Read())
				{
					string @string = reader.GetString(0);
					guid = reader.GetGuid(1);
					if (string.Compare(@string, "http://schemas.microsoft.com/SQL/Notifications/QueryNotification", StringComparison.OrdinalIgnoreCase) == 0)
					{
						SqlXml sqlXml = reader.GetSqlXml(2);
						if (sqlXml == null)
						{
							continue;
						}
						SqlNotification sqlNotification = SqlNotificationParser.ProcessMessage(sqlXml);
						if (sqlNotification == null)
						{
							continue;
						}
						string key = sqlNotification.Key;
						int num = key.IndexOf(';');
						if (num < 0)
						{
							continue;
						}
						string key2 = key.Substring(0, num);
						SqlDependencyPerAppDomainDispatcher sqlDependencyPerAppDomainDispatcher;
						lock (s_staticInstance._sqlDependencyPerAppDomainDispatchers)
						{
							sqlDependencyPerAppDomainDispatcher = s_staticInstance._sqlDependencyPerAppDomainDispatchers[key2];
						}
						if (sqlDependencyPerAppDomainDispatcher == null)
						{
							continue;
						}
						try
						{
							sqlDependencyPerAppDomainDispatcher.InvalidateCommandID(sqlNotification);
						}
						catch (Exception e)
						{
							if (!ADP.IsCatchableExceptionType(e))
							{
								throw;
							}
							ADP.TraceExceptionWithoutRethrow(e);
						}
					}
					else
					{
						guid = Guid.Empty;
					}
				}
			}
			finally
			{
				if (guid == Guid.Empty)
				{
					_com.CommandText = _beginConversationQuery ?? _receiveQuery;
					if (_com.Parameters.Count > 1)
					{
						_com.Parameters.Remove(_conversationGuidParam);
					}
				}
				else
				{
					_com.CommandText = _concatQuery;
					_conversationGuidParam.Value = guid;
					if (_com.Parameters.Count == 1)
					{
						_com.Parameters.Add(_conversationGuidParam);
					}
				}
			}
		}

		private void Restart(object unused)
		{
			try
			{
				lock (this)
				{
					if (!_stop)
					{
						try
						{
							_con.Close();
						}
						catch (Exception e)
						{
							if (!ADP.IsCatchableExceptionType(e))
							{
								throw;
							}
							ADP.TraceExceptionWithoutRethrow(e);
						}
					}
				}
				lock (this)
				{
					if (!_stop)
					{
						_con.Open();
					}
				}
				lock (this)
				{
					if (!_stop && _serviceQueueCreated)
					{
						bool flag = false;
						try
						{
							CreateQueueAndService(restart: true);
						}
						catch (Exception e2)
						{
							if (!ADP.IsCatchableExceptionType(e2))
							{
								throw;
							}
							ADP.TraceExceptionWithoutRethrow(e2);
							flag = true;
						}
						if (flag)
						{
							s_staticInstance.Invalidate(Server, new SqlNotification(SqlNotificationInfo.Error, SqlNotificationSource.Client, SqlNotificationType.Change, null));
						}
					}
				}
				lock (this)
				{
					if (!_stop)
					{
						_timeoutParam.Value = 0;
						SynchronouslyQueryServiceBrokerQueue();
						_timeoutParam.Value = _defaultWaitforTimeout;
						AsynchronouslyQueryServiceBrokerQueue();
						_errorState = false;
						Timer retryTimer = _retryTimer;
						if (retryTimer != null)
						{
							_retryTimer = null;
							retryTimer.Dispose();
						}
					}
				}
				if (_stop)
				{
					TearDownAndDispose();
				}
			}
			catch (Exception e3)
			{
				if (!ADP.IsCatchableExceptionType(e3))
				{
					throw;
				}
				ADP.TraceExceptionWithoutRethrow(e3);
				try
				{
					s_staticInstance.Invalidate(Server, new SqlNotification(SqlNotificationInfo.Error, SqlNotificationSource.Client, SqlNotificationType.Change, null));
				}
				catch (Exception e4)
				{
					if (!ADP.IsCatchableExceptionType(e4))
					{
						throw;
					}
					ADP.TraceExceptionWithoutRethrow(e4);
				}
				try
				{
					_con.Close();
				}
				catch (Exception e5)
				{
					if (!ADP.IsCatchableExceptionType(e5))
					{
						throw;
					}
					ADP.TraceExceptionWithoutRethrow(e5);
				}
				if (!_stop)
				{
					_retryTimer = new Timer(Restart, null, _defaultWaitforTimeout, -1);
				}
			}
		}

		internal bool Stop(string appDomainKey, out bool appDomainStop)
		{
			appDomainStop = false;
			if (appDomainKey != null)
			{
				lock (_appDomainKeyHash)
				{
					if (_appDomainKeyHash.ContainsKey(appDomainKey))
					{
						int num = _appDomainKeyHash[appDomainKey];
						if (num > 0)
						{
							_appDomainKeyHash[appDomainKey] = num - 1;
						}
						if (1 == num)
						{
							_appDomainKeyHash.Remove(appDomainKey);
							appDomainStop = true;
						}
					}
				}
			}
			if (Interlocked.Decrement(ref _startCount) == 0)
			{
				lock (this)
				{
					try
					{
						_com.Cancel();
					}
					catch (Exception e)
					{
						if (!ADP.IsCatchableExceptionType(e))
						{
							throw;
						}
						ADP.TraceExceptionWithoutRethrow(e);
					}
					_stop = true;
				}
				Stopwatch stopwatch = Stopwatch.StartNew();
				while (true)
				{
					lock (this)
					{
						if (!_stopped)
						{
							if (!_errorState && stopwatch.Elapsed.Seconds < 30)
							{
								goto IL_0127;
							}
							Timer retryTimer = _retryTimer;
							_retryTimer = null;
							retryTimer?.Dispose();
							TearDownAndDispose();
						}
					}
					break;
					IL_0127:
					Thread.Sleep(1);
				}
			}
			return _stopped;
		}

		private void SynchronouslyQueryServiceBrokerQueue()
		{
			using SqlDataReader reader = _com.ExecuteReader();
			ProcessNotificationResults(reader);
		}

		private void TearDownAndDispose()
		{
			lock (this)
			{
				try
				{
					if (_con.State == ConnectionState.Closed || ConnectionState.Broken == _con.State)
					{
						return;
					}
					if (_com.Parameters.Count > 1)
					{
						try
						{
							_com.CommandText = _endConversationQuery;
							_com.Parameters.Remove(_timeoutParam);
							_com.ExecuteNonQuery();
						}
						catch (Exception e)
						{
							if (!ADP.IsCatchableExceptionType(e))
							{
								throw;
							}
							ADP.TraceExceptionWithoutRethrow(e);
						}
					}
					if (!_serviceQueueCreated || _errorState)
					{
						return;
					}
					_com.CommandText = "BEGIN TRANSACTION; DROP SERVICE " + _escapedQueueName + "; DROP QUEUE " + _escapedQueueName + "; DROP PROCEDURE " + _sprocName + "; COMMIT TRANSACTION;";
					try
					{
						_com.ExecuteNonQuery();
					}
					catch (Exception e2)
					{
						if (!ADP.IsCatchableExceptionType(e2))
						{
							throw;
						}
						ADP.TraceExceptionWithoutRethrow(e2);
					}
				}
				finally
				{
					_stopped = true;
					_con.Dispose();
				}
			}
		}
	}

	private class SqlNotificationParser
	{
		[Flags]
		private enum MessageAttributes
		{
			None = 0,
			Type = 1,
			Source = 2,
			Info = 4,
			All = 7
		}

		private const string RootNode = "QueryNotification";

		private const string MessageNode = "Message";

		private const string InfoAttribute = "info";

		private const string SourceAttribute = "source";

		private const string TypeAttribute = "type";

		internal static SqlNotification ProcessMessage(SqlXml xmlMessage)
		{
			using XmlReader xmlReader = xmlMessage.CreateReader();
			_ = string.Empty;
			MessageAttributes messageAttributes = MessageAttributes.None;
			SqlNotificationType type = SqlNotificationType.Unknown;
			SqlNotificationInfo info = SqlNotificationInfo.Unknown;
			SqlNotificationSource source = SqlNotificationSource.Unknown;
			string key = string.Empty;
			xmlReader.Read();
			if (XmlNodeType.Element == xmlReader.NodeType && "QueryNotification" == xmlReader.LocalName && 3 <= xmlReader.AttributeCount)
			{
				while (MessageAttributes.All != messageAttributes && xmlReader.MoveToNextAttribute())
				{
					try
					{
						switch (xmlReader.LocalName)
						{
						case "type":
							try
							{
								SqlNotificationType sqlNotificationType = (SqlNotificationType)Enum.Parse(typeof(SqlNotificationType), xmlReader.Value, ignoreCase: true);
								if (Enum.IsDefined(typeof(SqlNotificationType), sqlNotificationType))
								{
									type = sqlNotificationType;
								}
							}
							catch (Exception e2)
							{
								if (!ADP.IsCatchableExceptionType(e2))
								{
									throw;
								}
								ADP.TraceExceptionWithoutRethrow(e2);
							}
							messageAttributes |= MessageAttributes.Type;
							break;
						case "source":
							try
							{
								SqlNotificationSource sqlNotificationSource = (SqlNotificationSource)Enum.Parse(typeof(SqlNotificationSource), xmlReader.Value, ignoreCase: true);
								if (Enum.IsDefined(typeof(SqlNotificationSource), sqlNotificationSource))
								{
									source = sqlNotificationSource;
								}
							}
							catch (Exception e3)
							{
								if (!ADP.IsCatchableExceptionType(e3))
								{
									throw;
								}
								ADP.TraceExceptionWithoutRethrow(e3);
							}
							messageAttributes |= MessageAttributes.Source;
							break;
						case "info":
							try
							{
								string value = xmlReader.Value;
								switch (value)
								{
								case "set options":
									info = SqlNotificationInfo.Options;
									break;
								case "previous invalid":
									info = SqlNotificationInfo.PreviousFire;
									break;
								case "query template limit":
									info = SqlNotificationInfo.TemplateLimit;
									break;
								default:
								{
									SqlNotificationInfo sqlNotificationInfo = (SqlNotificationInfo)Enum.Parse(typeof(SqlNotificationInfo), value, ignoreCase: true);
									if (Enum.IsDefined(typeof(SqlNotificationInfo), sqlNotificationInfo))
									{
										info = sqlNotificationInfo;
									}
									break;
								}
								}
							}
							catch (Exception e)
							{
								if (!ADP.IsCatchableExceptionType(e))
								{
									throw;
								}
								ADP.TraceExceptionWithoutRethrow(e);
							}
							messageAttributes |= MessageAttributes.Info;
							break;
						}
					}
					catch (ArgumentException e4)
					{
						ADP.TraceExceptionWithoutRethrow(e4);
						return null;
					}
				}
				if (MessageAttributes.All != messageAttributes)
				{
					return null;
				}
				if (!xmlReader.Read())
				{
					return null;
				}
				if (XmlNodeType.Element != xmlReader.NodeType || string.Compare(xmlReader.LocalName, "Message", StringComparison.OrdinalIgnoreCase) != 0)
				{
					return null;
				}
				if (!xmlReader.Read())
				{
					return null;
				}
				if (xmlReader.NodeType != XmlNodeType.Text)
				{
					return null;
				}
				using (XmlTextReader xmlTextReader = new XmlTextReader(xmlReader.Value, XmlNodeType.Element, null))
				{
					if (!xmlTextReader.Read())
					{
						return null;
					}
					if (xmlTextReader.NodeType != XmlNodeType.Text)
					{
						return null;
					}
					key = xmlTextReader.Value;
					xmlTextReader.Close();
				}
				return new SqlNotification(info, source, type, key);
			}
			return null;
		}
	}

	private class SqlConnectionContainerHashHelper
	{
		private DbConnectionPoolIdentity _identity;

		private string _connectionString;

		private string _queue;

		private SqlConnectionStringBuilder _connectionStringBuilder;

		internal SqlConnectionStringBuilder ConnectionStringBuilder => _connectionStringBuilder;

		internal DbConnectionPoolIdentity Identity => _identity;

		internal string Queue => _queue;

		internal SqlConnectionContainerHashHelper(DbConnectionPoolIdentity identity, string connectionString, string queue, SqlConnectionStringBuilder connectionStringBuilder)
		{
			_identity = identity;
			_connectionString = connectionString;
			_queue = queue;
			_connectionStringBuilder = connectionStringBuilder;
		}

		public override bool Equals(object value)
		{
			SqlConnectionContainerHashHelper sqlConnectionContainerHashHelper = (SqlConnectionContainerHashHelper)value;
			bool flag = false;
			if (sqlConnectionContainerHashHelper == null)
			{
				return false;
			}
			if (this == sqlConnectionContainerHashHelper)
			{
				return true;
			}
			if ((_identity != null && sqlConnectionContainerHashHelper._identity == null) || (_identity == null && sqlConnectionContainerHashHelper._identity != null))
			{
				return false;
			}
			if (_identity == null && sqlConnectionContainerHashHelper._identity == null)
			{
				if (sqlConnectionContainerHashHelper._connectionString == _connectionString && string.Equals(sqlConnectionContainerHashHelper._queue, _queue, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
				return false;
			}
			if (sqlConnectionContainerHashHelper._identity.Equals(_identity) && sqlConnectionContainerHashHelper._connectionString == _connectionString && string.Equals(sqlConnectionContainerHashHelper._queue, _queue, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			return false;
		}

		public override int GetHashCode()
		{
			int num = 0;
			if (_identity != null)
			{
				num = _identity.GetHashCode();
			}
			if (_queue != null)
			{
				return _connectionString.GetHashCode() + _queue.GetHashCode() + num;
			}
			return _connectionString.GetHashCode() + num;
		}
	}

	private static SqlDependencyProcessDispatcher s_staticInstance = new SqlDependencyProcessDispatcher(null);

	private Dictionary<SqlConnectionContainerHashHelper, SqlConnectionContainer> _connectionContainers;

	private Dictionary<string, SqlDependencyPerAppDomainDispatcher> _sqlDependencyPerAppDomainDispatchers;

	internal static SqlDependencyProcessDispatcher SingletonProcessDispatcher => s_staticInstance;

	private SqlDependencyProcessDispatcher(object dummyVariable)
	{
		_connectionContainers = new Dictionary<SqlConnectionContainerHashHelper, SqlConnectionContainer>();
		_sqlDependencyPerAppDomainDispatchers = new Dictionary<string, SqlDependencyPerAppDomainDispatcher>();
	}

	public SqlDependencyProcessDispatcher()
	{
	}

	private static SqlConnectionContainerHashHelper GetHashHelper(string connectionString, out SqlConnectionStringBuilder connectionStringBuilder, out DbConnectionPoolIdentity identity, out string user, string queue)
	{
		connectionStringBuilder = new SqlConnectionStringBuilder(connectionString)
		{
			Pooling = false,
			Enlist = false,
			ConnectRetryCount = 0
		};
		if (queue != null)
		{
			connectionStringBuilder.ApplicationName = queue;
		}
		if (connectionStringBuilder.IntegratedSecurity)
		{
			identity = DbConnectionPoolIdentity.GetCurrent();
			user = null;
		}
		else
		{
			identity = null;
			user = connectionStringBuilder.UserID;
		}
		return new SqlConnectionContainerHashHelper(identity, connectionStringBuilder.ConnectionString, queue, connectionStringBuilder);
	}

	public override object InitializeLifetimeService()
	{
		return null;
	}

	private void Invalidate(string server, SqlNotification sqlNotification)
	{
		lock (_sqlDependencyPerAppDomainDispatchers)
		{
			foreach (KeyValuePair<string, SqlDependencyPerAppDomainDispatcher> sqlDependencyPerAppDomainDispatcher in _sqlDependencyPerAppDomainDispatchers)
			{
				SqlDependencyPerAppDomainDispatcher value = sqlDependencyPerAppDomainDispatcher.Value;
				try
				{
					value.InvalidateServer(server, sqlNotification);
				}
				catch (Exception e)
				{
					if (!ADP.IsCatchableExceptionType(e))
					{
						throw;
					}
					ADP.TraceExceptionWithoutRethrow(e);
				}
			}
		}
	}

	internal void QueueAppDomainUnloading(string appDomainKey)
	{
		ThreadPool.QueueUserWorkItem(AppDomainUnloading, appDomainKey);
	}

	private void AppDomainUnloading(object state)
	{
		string text = (string)state;
		lock (_connectionContainers)
		{
			List<SqlConnectionContainerHashHelper> list = new List<SqlConnectionContainerHashHelper>();
			foreach (KeyValuePair<SqlConnectionContainerHashHelper, SqlConnectionContainer> connectionContainer in _connectionContainers)
			{
				SqlConnectionContainer value = connectionContainer.Value;
				if (value.AppDomainUnload(text))
				{
					list.Add(value.HashHelper);
				}
			}
			foreach (SqlConnectionContainerHashHelper item in list)
			{
				_connectionContainers.Remove(item);
			}
		}
		lock (_sqlDependencyPerAppDomainDispatchers)
		{
			_sqlDependencyPerAppDomainDispatchers.Remove(text);
		}
	}

	internal bool StartWithDefault(string connectionString, out string server, out DbConnectionPoolIdentity identity, out string user, out string database, ref string service, string appDomainKey, SqlDependencyPerAppDomainDispatcher dispatcher, out bool errorOccurred, out bool appDomainStart)
	{
		return Start(connectionString, out server, out identity, out user, out database, ref service, appDomainKey, dispatcher, out errorOccurred, out appDomainStart, useDefaults: true);
	}

	internal bool Start(string connectionString, string queue, string appDomainKey, SqlDependencyPerAppDomainDispatcher dispatcher)
	{
		string server;
		DbConnectionPoolIdentity identity;
		bool errorOccurred;
		return Start(connectionString, out server, out identity, out server, out server, ref queue, appDomainKey, dispatcher, out errorOccurred, out errorOccurred, useDefaults: false);
	}

	private bool Start(string connectionString, out string server, out DbConnectionPoolIdentity identity, out string user, out string database, ref string queueService, string appDomainKey, SqlDependencyPerAppDomainDispatcher dispatcher, out bool errorOccurred, out bool appDomainStart, bool useDefaults)
	{
		server = null;
		identity = null;
		user = null;
		database = null;
		errorOccurred = false;
		appDomainStart = false;
		lock (_sqlDependencyPerAppDomainDispatchers)
		{
			if (!_sqlDependencyPerAppDomainDispatchers.ContainsKey(appDomainKey))
			{
				_sqlDependencyPerAppDomainDispatchers[appDomainKey] = dispatcher;
			}
		}
		SqlConnectionStringBuilder connectionStringBuilder;
		SqlConnectionContainerHashHelper hashHelper = GetHashHelper(connectionString, out connectionStringBuilder, out identity, out user, queueService);
		bool result = false;
		SqlConnectionContainer sqlConnectionContainer = null;
		lock (_connectionContainers)
		{
			if (!_connectionContainers.ContainsKey(hashHelper))
			{
				sqlConnectionContainer = new SqlConnectionContainer(hashHelper, appDomainKey, useDefaults);
				_connectionContainers.Add(hashHelper, sqlConnectionContainer);
				result = true;
				appDomainStart = true;
			}
			else
			{
				sqlConnectionContainer = _connectionContainers[hashHelper];
				if (sqlConnectionContainer.InErrorState)
				{
					errorOccurred = true;
				}
				else
				{
					sqlConnectionContainer.IncrementStartCount(appDomainKey, out appDomainStart);
				}
			}
		}
		if (useDefaults && !errorOccurred)
		{
			server = sqlConnectionContainer.Server;
			database = sqlConnectionContainer.Database;
			queueService = sqlConnectionContainer.Queue;
		}
		return result;
	}

	internal bool Stop(string connectionString, out string server, out DbConnectionPoolIdentity identity, out string user, out string database, ref string queueService, string appDomainKey, out bool appDomainStop)
	{
		server = null;
		identity = null;
		user = null;
		database = null;
		appDomainStop = false;
		SqlConnectionStringBuilder connectionStringBuilder;
		SqlConnectionContainerHashHelper hashHelper = GetHashHelper(connectionString, out connectionStringBuilder, out identity, out user, queueService);
		bool result = false;
		lock (_connectionContainers)
		{
			if (_connectionContainers.ContainsKey(hashHelper))
			{
				SqlConnectionContainer sqlConnectionContainer = _connectionContainers[hashHelper];
				server = sqlConnectionContainer.Server;
				database = sqlConnectionContainer.Database;
				queueService = sqlConnectionContainer.Queue;
				if (sqlConnectionContainer.Stop(appDomainKey, out appDomainStop))
				{
					result = true;
					_connectionContainers.Remove(hashHelper);
				}
			}
		}
		return result;
	}
}
internal static class AssemblyRef
{
	internal const string SystemConfiguration = "System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	internal const string System = "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string EcmaPublicKey = "b77a5c561934e089";

	public const string FrameworkPublicKeyFull = "00000000000000000400000000000000";

	public const string FrameworkPublicKeyFull2 = "00000000000000000400000000000000";

	public const string MicrosoftPublicKey = "b03f5f7f11d50a3a";

	public const string MicrosoftJScript = "Microsoft.JScript, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string MicrosoftVSDesigner = "Microsoft.VSDesigner, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string SystemData = "System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string SystemDesign = "System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string SystemDrawing = "System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string SystemWeb = "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string SystemWebExtensions = "System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string SystemWindowsForms = "System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
}
internal static class Consts
{
	public const string MonoCorlibVersion = "1A5E0066-58DC-428A-B21C-0AD6CDAE2789";

	public const string MonoVersion = "6.12.0.0";

	public const string MonoCompany = "Mono development team";

	public const string MonoProduct = "Mono Common Language Infrastructure";

	public const string MonoCopyright = "(c) Various Mono authors";

	public const string FxVersion = "4.0.0.0";

	public const string FxFileVersion = "4.6.57.0";

	public const string EnvironmentVersion = "4.0.30319.42000";

	public const string VsVersion = "0.0.0.0";

	public const string VsFileVersion = "11.0.0.0";

	private const string PublicKeyToken = "b77a5c561934e089";

	public const string AssemblyI18N = "I18N, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMicrosoft_JScript = "Microsoft.JScript, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMicrosoft_VisualStudio = "Microsoft.VisualStudio, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMicrosoft_VisualStudio_Web = "Microsoft.VisualStudio.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMicrosoft_VSDesigner = "Microsoft.VSDesigner, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMono_Http = "Mono.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMono_Posix = "Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMono_Security = "Mono.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMono_Messaging_RabbitMQ = "Mono.Messaging.RabbitMQ, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyCorlib = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem = "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_Data = "System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_Design = "System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_DirectoryServices = "System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Drawing = "System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Drawing_Design = "System.Drawing.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Messaging = "System.Messaging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Security = "System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_ServiceProcess = "System.ServiceProcess, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Web = "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Windows_Forms = "System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_2_0 = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystemCore_3_5 = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_Core = "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string WindowsBase_3_0 = "WindowsBase, Version=3.0.0.0, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyWindowsBase = "WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyPresentationCore_3_5 = "PresentationCore, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyPresentationCore_4_0 = "PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyPresentationFramework_3_5 = "PresentationFramework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblySystemServiceModel_3_0 = "System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
}
internal sealed class Locale
{
	private Locale()
	{
	}

	public static string GetText(string msg)
	{
		return msg;
	}

	public static string GetText(string fmt, params object[] args)
	{
		return string.Format(fmt, args);
	}
}
internal static class SR
{
	public const string ADP_CollectionIndexString = "An {0} with {1} '{2}' is not contained by this {3}.";

	public const string ADP_CollectionInvalidType = "The {0} only accepts non-null {1} type objects, not {2} objects.";

	public const string ADP_CollectionIsNotParent = "The {0} is already contained by another {1}.";

	public const string ADP_CollectionNullValue = "The {0} only accepts non-null {1} type objects.";

	public const string ADP_CollectionRemoveInvalidObject = "Attempted to remove an {0} that is not contained by this {1}.";

	public const string ADP_CollectionUniqueValue = "The {0}.{1} is required to be unique, '{2}' already exists in the collection.";

	public const string ADP_ConnectionStateMsg_Closed = "The connection's current state is closed.";

	public const string ADP_ConnectionStateMsg_Connecting = "The connection's current state is connecting.";

	public const string ADP_ConnectionStateMsg_Open = "The connection's current state is open.";

	public const string ADP_ConnectionStateMsg_OpenExecuting = "The connection's current state is executing.";

	public const string ADP_ConnectionStateMsg_OpenFetching = "The connection's current state is fetching.";

	public const string ADP_ConnectionStateMsg = "The connection's current state: {0}.";

	public const string ADP_ConnectionStringSyntax = "Format of the initialization string does not conform to specification starting at index {0}.";

	public const string ADP_DataReaderClosed = "Invalid attempt to call {0} when reader is closed.";

	public const string ADP_EmptyString = "Expecting non-empty string for '{0}' parameter.";

	public const string ADP_InvalidEnumerationValue = "The {0} enumeration value, {1}, is invalid.";

	public const string ADP_InvalidKey = "Invalid keyword, contain one or more of 'no characters', 'control characters', 'leading or trailing whitespace' or 'leading semicolons'.";

	public const string ADP_InvalidValue = "The value contains embedded nulls (\\\\u0000).";

	public const string Xml_SimpleTypeNotSupported = "DataSet doesn't support 'union' or 'list' as simpleType.";

	public const string Xml_MissingAttribute = "Invalid {0} syntax: missing required '{1}' attribute.";

	public const string Xml_ValueOutOfRange = "Value '{1}' is invalid for attribute '{0}'.";

	public const string Xml_AttributeValues = "The value of attribute '{0}' should be '{1}' or '{2}'.";

	public const string Xml_RelationParentNameMissing = "Parent table name is missing in relation '{0}'.";

	public const string Xml_RelationChildNameMissing = "Child table name is missing in relation '{0}'.";

	public const string Xml_RelationTableKeyMissing = "Parent table key is missing in relation '{0}'.";

	public const string Xml_RelationChildKeyMissing = "Child table key is missing in relation '{0}'.";

	public const string Xml_UndefinedDatatype = "Undefined data type: '{0}'.";

	public const string Xml_DatatypeNotDefined = "Data type not defined.";

	public const string Xml_InvalidField = "Invalid XPath selection inside field node. Cannot find: {0}.";

	public const string Xml_InvalidSelector = "Invalid XPath selection inside selector node: {0}.";

	public const string Xml_InvalidKey = "Invalid 'Key' node inside constraint named: {0}.";

	public const string Xml_DuplicateConstraint = "The constraint name {0} is already used in the schema.";

	public const string Xml_CannotConvert = " Cannot convert '{0}' to type '{1}'.";

	public const string Xml_MissingRefer = "Missing '{0}' part in '{1}' constraint named '{2}'.";

	public const string Xml_MismatchKeyLength = "Invalid Relation definition: different length keys.";

	public const string Xml_CircularComplexType = "DataSet doesn't allow the circular reference in the ComplexType named '{0}'.";

	public const string Xml_CannotInstantiateAbstract = "DataSet cannot instantiate an abstract ComplexType for the node {0}.";

	public const string Xml_MultipleTargetConverterError = "An error occurred with the multiple target converter while writing an Xml Schema.  See the inner exception for details.";

	public const string Xml_MultipleTargetConverterEmpty = "An error occurred with the multiple target converter while writing an Xml Schema.  A null or empty string was returned.";

	public const string Xml_MergeDuplicateDeclaration = "Duplicated declaration '{0}'.";

	public const string Xml_MissingTable = "Cannot load diffGram. Table '{0}' is missing in the destination dataset.";

	public const string Xml_MissingSQL = "Cannot load diffGram. The 'sql' node is missing.";

	public const string Xml_ColumnConflict = "Column name '{0}' is defined for different mapping types.";

	public const string Xml_InvalidPrefix = "Prefix '{0}' is not valid, because it contains special characters.";

	public const string Xml_NestedCircular = "Circular reference in self-nested table '{0}'.";

	public const string Xml_FoundEntity = "DataSet cannot expand entities. Use XmlValidatingReader and set the EntityHandling property accordingly.";

	public const string Xml_PolymorphismNotSupported = "Type '{0}' does not implement IXmlSerializable interface therefore can not proceed with serialization.";

	public const string Xml_CanNotDeserializeObjectType = "Unable to proceed with deserialization. Data does not implement IXMLSerializable, therefore polymorphism is not supported.";

	public const string Xml_DataTableInferenceNotSupported = "DataTable does not support schema inference from Xml.";

	public const string Xml_MultipleParentRows = "Cannot proceed with serializing DataTable '{0}'. It contains a DataRow which has multiple parent rows on the same Foreign Key.";

	public const string Xml_IsDataSetAttributeMissingInSchema = "IsDataSet attribute is missing in input Schema.";

	public const string Xml_TooManyIsDataSetAtributeInSchema = "Cannot determine the DataSet Element. IsDataSet attribute exist more than once.";

	public const string Xml_DynamicWithoutXmlSerializable = "DataSet will not serialize types that implement IDynamicMetaObjectProvider but do not also implement IXmlSerializable.";

	public const string Expr_NYI = "The feature not implemented. {0}.";

	public const string Expr_MissingOperand = "Syntax error: Missing operand after '{0}' operator.";

	public const string Expr_TypeMismatch = "Type mismatch in expression '{0}'.";

	public const string Expr_ExpressionTooComplex = "Expression is too complex.";

	public const string Expr_UnboundName = "Cannot find column [{0}].";

	public const string Expr_InvalidString = "The expression contains an invalid string constant: {0}.";

	public const string Expr_UndefinedFunction = "The expression contains undefined function call {0}().";

	public const string Expr_Syntax = "Syntax error in the expression.";

	public const string Expr_FunctionArgumentCount = "Invalid number of arguments: function {0}().";

	public const string Expr_MissingRightParen = "The expression is missing the closing parenthesis.";

	public const string Expr_UnknownToken = "Cannot interpret token '{0}' at position {1}.";

	public const string Expr_UnknownToken1 = "Expected {0}, but actual token at the position {2} is {1}.";

	public const string Expr_DatatypeConvertion = "Cannot convert from {0} to {1}.";

	public const string Expr_DatavalueConvertion = "Cannot convert value '{0}' to Type: {1}.";

	public const string Expr_InvalidName = "Invalid column name [{0}].";

	public const string Expr_InvalidDate = "The expression contains invalid date constant '{0}'.";

	public const string Expr_NonConstantArgument = "Only constant expressions are allowed in the expression list for the IN operator.";

	public const string Expr_InvalidPattern = "Error in Like operator: the string pattern '{0}' is invalid.";

	public const string Expr_InWithoutParentheses = "Syntax error: The items following the IN keyword must be separated by commas and be enclosed in parentheses.";

	public const string Expr_ArgumentType = "Type mismatch in function argument: {0}(), argument {1}, expected {2}.";

	public const string Expr_ArgumentTypeInteger = "Type mismatch in function argument: {0}(), argument {1}, expected one of the Integer types.";

	public const string Expr_TypeMismatchInBinop = "Cannot perform '{0}' operation on {1} and {2}.";

	public const string Expr_AmbiguousBinop = "Operator '{0}' is ambiguous on operands of type '{1}' and '{2}'. Cannot mix signed and unsigned types. Please use explicit Convert() function.";

	public const string Expr_InWithoutList = "Syntax error: The IN keyword must be followed by a non-empty list of expressions separated by commas, and also must be enclosed in parentheses.";

	public const string Expr_UnsupportedOperator = "The expression contains unsupported operator '{0}'.";

	public const string Expr_InvalidNameBracketing = "The expression contains invalid name: '{0}'.";

	public const string Expr_MissingOperandBefore = "Syntax error: Missing operand before '{0}' operator.";

	public const string Expr_TooManyRightParentheses = "The expression has too many closing parentheses.";

	public const string Expr_UnresolvedRelation = "The table [{0}] involved in more than one relation. You must explicitly mention a relation name in the expression '{1}'.";

	public const string Expr_AggregateArgument = "Syntax error in aggregate argument: Expecting a single column argument with possible 'Child' qualifier.";

	public const string Expr_AggregateUnbound = "Unbound reference in the aggregate expression '{0}'.";

	public const string Expr_EvalNoContext = "Cannot evaluate non-constant expression without current row.";

	public const string Expr_ExpressionUnbound = "Unbound reference in the expression '{0}'.";

	public const string Expr_ComputeNotAggregate = "Cannot evaluate. Expression '{0}' is not an aggregate.";

	public const string Expr_FilterConvertion = "Filter expression '{0}' does not evaluate to a Boolean term.";

	public const string Expr_InvalidType = "Invalid type name '{0}'.";

	public const string Expr_LookupArgument = "Syntax error in Lookup expression: Expecting keyword 'Parent' followed by a single column argument with possible relation qualifier: Parent[(<relation_name>)].<column_name>.";

	public const string Expr_InvokeArgument = "Need a row or a table to Invoke DataFilter.";

	public const string Expr_ArgumentOutofRange = "{0}() argument is out of range.";

	public const string Expr_IsSyntax = "Syntax error: Invalid usage of 'Is' operator. Correct syntax: <expression> Is [Not] Null.";

	public const string Expr_Overflow = "Value is either too large or too small for Type '{0}'.";

	public const string Expr_BindFailure = "Cannot find the parent relation '{0}'.";

	public const string Expr_InvalidHoursArgument = "'hours' argument is out of range. Value must be between -14 and +14.";

	public const string Expr_InvalidMinutesArgument = "'minutes' argument is out of range. Value must be between -59 and +59.";

	public const string Expr_InvalidTimeZoneRange = "Provided range for time one exceeds total of 14 hours.";

	public const string Expr_MismatchKindandTimeSpan = "Kind property of provided DateTime argument, does not match 'hours' and 'minutes' arguments.";

	public const string Expr_UnsupportedType = "A DataColumn of type '{0}' does not support expression.";

	public const string Data_EnforceConstraints = "Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.";

	public const string Data_CannotModifyCollection = "Collection itself is not modifiable.";

	public const string Data_CaseInsensitiveNameConflict = "The given name '{0}' matches at least two names in the collection object with different cases, but does not match either of them with the same case.";

	public const string Data_NamespaceNameConflict = "The given name '{0}' matches at least two names in the collection object with different namespaces.";

	public const string Data_InvalidOffsetLength = "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.";

	public const string Data_ArgumentOutOfRange = "'{0}' argument is out of range.";

	public const string Data_ArgumentNull = "'{0}' argument cannot be null.";

	public const string Data_ArgumentContainsNull = "'{0}' argument contains null value.";

	public const string DataColumns_OutOfRange = "Cannot find column {0}.";

	public const string DataColumns_Add1 = "Column '{0}' already belongs to this DataTable.";

	public const string DataColumns_Add2 = "Column '{0}' already belongs to another DataTable.";

	public const string DataColumns_Add3 = "Cannot have more than one SimpleContent columns in a DataTable.";

	public const string DataColumns_Add4 = "Cannot add a SimpleContent column to a table containing element columns or nested relations.";

	public const string DataColumns_AddDuplicate = "A column named '{0}' already belongs to this DataTable.";

	public const string DataColumns_AddDuplicate2 = "Cannot add a column named '{0}': a nested table with the same name already belongs to this DataTable.";

	public const string DataColumns_AddDuplicate3 = "A column named '{0}' already belongs to this DataTable: cannot set a nested table name to the same name.";

	public const string DataColumns_Remove = "Cannot remove a column that doesn't belong to this table.";

	public const string DataColumns_RemovePrimaryKey = "Cannot remove this column, because it's part of the primary key.";

	public const string DataColumns_RemoveChildKey = "Cannot remove this column, because it is part of the parent key for relationship {0}.";

	public const string DataColumns_RemoveConstraint = "Cannot remove this column, because it is a part of the constraint {0} on the table {1}.";

	public const string DataColumn_AutoIncrementAndExpression = "Cannot set AutoIncrement property for a computed column.";

	public const string DataColumn_AutoIncrementAndDefaultValue = "Cannot set AutoIncrement property for a column with DefaultValue set.";

	public const string DataColumn_DefaultValueAndAutoIncrement = "Cannot set a DefaultValue on an AutoIncrement column.";

	public const string DataColumn_AutoIncrementSeed = "AutoIncrementStep must be a non-zero value.";

	public const string DataColumn_NameRequired = "ColumnName is required when it is part of a DataTable.";

	public const string DataColumn_ChangeDataType = "Cannot change DataType of a column once it has data.";

	public const string DataColumn_NullDataType = "Column requires a valid DataType.";

	public const string DataColumn_DefaultValueDataType = "The DefaultValue for column {0} is of type {1} and cannot be converted to {2}.";

	public const string DataColumn_DefaultValueDataType1 = "The DefaultValue for the column is of type {0} and cannot be converted to {1}.";

	public const string DataColumn_DefaultValueColumnDataType = "The DefaultValue for column {0} is of type {1}, but the column is of type {2}.";

	public const string DataColumn_ReadOnlyAndExpression = "Cannot change ReadOnly property for the expression column.";

	public const string DataColumn_UniqueAndExpression = "Cannot change Unique property for the expression column.";

	public const string DataColumn_ExpressionAndUnique = "Cannot create an expression on a column that has AutoIncrement or Unique.";

	public const string DataColumn_ExpressionAndReadOnly = "Cannot set expression because column cannot be made ReadOnly.";

	public const string DataColumn_ExpressionAndConstraint = "Cannot set Expression property on column {0}, because it is a part of a constraint.";

	public const string DataColumn_ExpressionInConstraint = "Cannot create a constraint based on Expression column {0}.";

	public const string DataColumn_ExpressionCircular = "Cannot set Expression property due to circular reference in the expression.";

	public const string DataColumn_NullKeyValues = "Column '{0}' has null values in it.";

	public const string DataColumn_NullValues = "Column '{0}' does not allow nulls.";

	public const string DataColumn_ReadOnly = "Column '{0}' is read only.";

	public const string DataColumn_NonUniqueValues = "Column '{0}' contains non-unique values.";

	public const string DataColumn_NotInTheTable = "Column '{0}' does not belong to table {1}.";

	public const string DataColumn_NotInAnyTable = "Column must belong to a table.";

	public const string DataColumn_SetFailed = "Couldn't store <{0}> in {1} Column.  Expected type is {2}.";

	public const string DataColumn_CannotSetToNull = "Cannot set Column '{0}' to be null. Please use DBNull instead.";

	public const string DataColumn_LongerThanMaxLength = "Cannot set column '{0}'. The value violates the MaxLength limit of this column.";

	public const string DataColumn_HasToBeStringType = "MaxLength applies to string data type only. You cannot set Column '{0}' property MaxLength to be non-negative number.";

	public const string DataColumn_CannotSetMaxLength = "Cannot set Column '{0}' property MaxLength to '{1}'. There is at least one string in the table longer than the new limit.";

	public const string DataColumn_CannotSetMaxLength2 = "Cannot set Column '{0}' property MaxLength. The Column is SimpleContent.";

	public const string DataColumn_CannotSimpleContentType = "Cannot set Column '{0}' property DataType to {1}. The Column is SimpleContent.";

	public const string DataColumn_CannotSimpleContent = "Cannot set Column '{0}' property MappingType to SimpleContent. The Column DataType is {1}.";

	public const string DataColumn_ExceedMaxLength = "Column '{0}' exceeds the MaxLength limit.";

	public const string DataColumn_NotAllowDBNull = "Column '{0}' does not allow DBNull.Value.";

	public const string DataColumn_CannotChangeNamespace = "Cannot change the Column '{0}' property Namespace. The Column is SimpleContent.";

	public const string DataColumn_AutoIncrementCannotSetIfHasData = "Cannot change AutoIncrement of a DataColumn with type '{0}' once it has data.";

	public const string DataColumn_NotInTheUnderlyingTable = "Column '{0}' does not belong to underlying table '{1}'.";

	public const string DataColumn_InvalidDataColumnMapping = "DataColumn with type '{0}' is a complexType. Can not serialize value of a complex type as Attribute";

	public const string DataColumn_CannotSetDateTimeModeForNonDateTimeColumns = "The DateTimeMode can be set only on DataColumns of type DateTime.";

	public const string DataColumn_DateTimeMode = "Cannot change DateTimeMode from '{0}' to '{1}' once the table has data.";

	public const string DataColumn_INullableUDTwithoutStaticNull = "Type '{0}' does not contain static Null property or field.";

	public const string DataColumn_UDTImplementsIChangeTrackingButnotIRevertible = "Type '{0}' does not implement IRevertibleChangeTracking; therefore can not proceed with RejectChanges().";

	public const string DataColumn_SetAddedAndModifiedCalledOnNonUnchanged = "SetAdded and SetModified can only be called on DataRows with Unchanged DataRowState.";

	public const string DataColumn_OrdinalExceedMaximun = "Ordinal '{0}' exceeds the maximum number.";

	public const string DataColumn_NullableTypesNotSupported = "DataSet does not support System.Nullable<>.";

	public const string DataConstraint_NoName = "Cannot change the name of a constraint to empty string when it is in the ConstraintCollection.";

	public const string DataConstraint_Violation = "Cannot enforce constraints on constraint {0}.";

	public const string DataConstraint_ViolationValue = "Column '{0}' is constrained to be unique.  Value '{1}' is already present.";

	public const string DataConstraint_NotInTheTable = "Constraint '{0}' does not belong to this DataTable.";

	public const string DataConstraint_OutOfRange = "Cannot find constraint {0}.";

	public const string DataConstraint_Duplicate = "Constraint matches constraint named {0} already in collection.";

	public const string DataConstraint_DuplicateName = "A Constraint named '{0}' already belongs to this DataTable.";

	public const string DataConstraint_UniqueViolation = "These columns don't currently have unique values.";

	public const string DataConstraint_ForeignTable = "These columns don't point to this table.";

	public const string DataConstraint_ParentValues = "This constraint cannot be enabled as not all values have corresponding parent values.";

	public const string DataConstraint_AddFailed = "This constraint cannot be added since ForeignKey doesn't belong to table {0}.";

	public const string DataConstraint_RemoveFailed = "Cannot remove a constraint that doesn't belong to this table.";

	public const string DataConstraint_NeededForForeignKeyConstraint = "Cannot remove unique constraint '{0}'. Remove foreign key constraint '{1}' first.";

	public const string DataConstraint_CascadeDelete = "Cannot delete this row because constraints are enforced on relation {0}, and deleting this row will strand child rows.";

	public const string DataConstraint_CascadeUpdate = "Cannot make this change because constraints are enforced on relation {0}, and changing this value will strand child rows.";

	public const string DataConstraint_ClearParentTable = "Cannot clear table {0} because ForeignKeyConstraint {1} enforces constraints and there are child rows in {2}.";

	public const string DataConstraint_ForeignKeyViolation = "ForeignKeyConstraint {0} requires the child key values ({1}) to exist in the parent table.";

	public const string DataConstraint_BadObjectPropertyAccess = "Property not accessible because '{0}'.";

	public const string DataConstraint_RemoveParentRow = "Cannot remove this row because it has child rows, and constraints on relation {0} are enforced.";

	public const string DataConstraint_AddPrimaryKeyConstraint = "Cannot add primary key constraint since primary key is already set for the table.";

	public const string DataConstraint_CantAddConstraintToMultipleNestedTable = "Cannot add constraint to DataTable '{0}' which is a child table in two nested relations.";

	public const string DataKey_TableMismatch = "Cannot create a Key from Columns that belong to different tables.";

	public const string DataKey_NoColumns = "Cannot have 0 columns.";

	public const string DataKey_TooManyColumns = "Cannot have more than {0} columns.";

	public const string DataKey_DuplicateColumns = "Cannot create a Key when the same column is listed more than once: '{0}'";

	public const string DataKey_RemovePrimaryKey = "Cannot remove unique constraint since it's the primary key of a table.";

	public const string DataKey_RemovePrimaryKey1 = "Cannot remove unique constraint since it's the primary key of table {0}.";

	public const string DataRelation_ColumnsTypeMismatch = "Parent Columns and Child Columns don't have type-matching columns.";

	public const string DataRelation_KeyColumnsIdentical = "ParentKey and ChildKey are identical.";

	public const string DataRelation_KeyLengthMismatch = "ParentColumns and ChildColumns should be the same length.";

	public const string DataRelation_KeyZeroLength = "ParentColumns and ChildColumns must not be zero length.";

	public const string DataRelation_ForeignRow = "The row doesn't belong to the same DataSet as this relation.";

	public const string DataRelation_NoName = "RelationName is required when it is part of a DataSet.";

	public const string DataRelation_ForeignTable = "GetChildRows requires a row whose Table is {0}, but the specified row's Table is {1}.";

	public const string DataRelation_ForeignDataSet = "This relation should connect two tables in this DataSet to be added to this DataSet.";

	public const string DataRelation_GetParentRowTableMismatch = "GetParentRow requires a row whose Table is {0}, but the specified row's Table is {1}.";

	public const string DataRelation_SetParentRowTableMismatch = "SetParentRow requires a child row whose Table is {0}, but the specified row's Table is {1}.";

	public const string DataRelation_DataSetMismatch = "Cannot have a relationship between tables in different DataSets.";

	public const string DataRelation_TablesInDifferentSets = "Cannot create a relation between tables in different DataSets.";

	public const string DataRelation_AlreadyExists = "A relation already exists for these child columns.";

	public const string DataRelation_DoesNotExist = "This relation doesn't belong to this relation collection.";

	public const string DataRelation_AlreadyInOtherDataSet = "This relation already belongs to another DataSet.";

	public const string DataRelation_AlreadyInTheDataSet = "This relation already belongs to this DataSet.";

	public const string DataRelation_DuplicateName = "A Relation named '{0}' already belongs to this DataSet.";

	public const string DataRelation_NotInTheDataSet = "Relation {0} does not belong to this DataSet.";

	public const string DataRelation_OutOfRange = "Cannot find relation {0}.";

	public const string DataRelation_TableNull = "Cannot create a collection on a null table.";

	public const string DataRelation_TableWasRemoved = "The table this collection displays relations for has been removed from its DataSet.";

	public const string DataRelation_ChildTableMismatch = "Cannot add a relation to this table's ParentRelation collection where this table isn't the child table.";

	public const string DataRelation_ParentTableMismatch = "Cannot add a relation to this table's ChildRelation collection where this table isn't the parent table.";

	public const string DataRelation_RelationNestedReadOnly = "Cannot set the 'Nested' property to false for this relation.";

	public const string DataRelation_TableCantBeNestedInTwoTables = "The same table '{0}' cannot be the child table in two nested relations.";

	public const string DataRelation_LoopInNestedRelations = "The table ({0}) cannot be the child table to itself in nested relations.";

	public const string DataRelation_CaseLocaleMismatch = "Cannot add a DataRelation or Constraint that has different Locale or CaseSensitive settings between its parent and child tables.";

	public const string DataRelation_ParentOrChildColumnsDoNotHaveDataSet = "Cannot create a DataRelation if Parent or Child Columns are not in a DataSet.";

	public const string DataRelation_InValidNestedRelation = "Nested table '{0}' which inherits its namespace cannot have multiple parent tables in different namespaces.";

	public const string DataRelation_InValidNamespaceInNestedRelation = "Nested table '{0}' with empty namespace cannot have multiple parent tables in different namespaces.";

	public const string DataRow_NotInTheDataSet = "The row doesn't belong to the same DataSet as this relation.";

	public const string DataRow_NotInTheTable = "Cannot perform this operation on a row not in the table.";

	public const string DataRow_ParentRowNotInTheDataSet = "This relation and child row don't belong to same DataSet.";

	public const string DataRow_EditInRowChanging = "Cannot change a proposed value in the RowChanging event.";

	public const string DataRow_EndEditInRowChanging = "Cannot call EndEdit() inside an OnRowChanging event.";

	public const string DataRow_BeginEditInRowChanging = "Cannot call BeginEdit() inside the RowChanging event.";

	public const string DataRow_CancelEditInRowChanging = "Cannot call CancelEdit() inside an OnRowChanging event.  Throw an exception to cancel this update.";

	public const string DataRow_DeleteInRowDeleting = "Cannot call Delete inside an OnRowDeleting event.  Throw an exception to cancel this delete.";

	public const string DataRow_ValuesArrayLength = "Input array is longer than the number of columns in this table.";

	public const string DataRow_NoCurrentData = "There is no Current data to access.";

	public const string DataRow_NoOriginalData = "There is no Original data to access.";

	public const string DataRow_NoProposedData = "There is no Proposed data to access.";

	public const string DataRow_RemovedFromTheTable = "This row has been removed from a table and does not have any data.  BeginEdit() will allow creation of new data in this row.";

	public const string DataRow_DeletedRowInaccessible = "Deleted row information cannot be accessed through the row.";

	public const string DataRow_InvalidVersion = "Version must be Original, Current, or Proposed.";

	public const string DataRow_OutOfRange = "There is no row at position {0}.";

	public const string DataRow_RowInsertOutOfRange = "The row insert position {0} is invalid.";

	public const string DataRow_RowInsertMissing = "Values are missing in the rowOrder sequence for table '{0}'.";

	public const string DataRow_RowOutOfRange = "The given DataRow is not in the current DataRowCollection.";

	public const string DataRow_AlreadyInOtherCollection = "This row already belongs to another table.";

	public const string DataRow_AlreadyInTheCollection = "This row already belongs to this table.";

	public const string DataRow_AlreadyDeleted = "Cannot delete this row since it's already deleted.";

	public const string DataRow_Empty = "This row is empty.";

	public const string DataRow_AlreadyRemoved = "Cannot remove a row that's already been removed.";

	public const string DataRow_MultipleParents = "A child row has multiple parents.";

	public const string DataRow_InvalidRowBitPattern = "Unrecognized row state bit pattern.";

	public const string DataSet_SetNameToEmpty = "Cannot change the name of the DataSet to an empty string.";

	public const string DataSet_SetDataSetNameConflicting = "The name '{0}' is invalid. A DataSet cannot have the same name of the DataTable.";

	public const string DataSet_UnsupportedSchema = "The schema namespace is invalid. Please use this one instead: {0}.";

	public const string DataSet_CannotChangeCaseLocale = "Cannot change CaseSensitive or Locale property. This change would lead to at least one DataRelation or Constraint to have different Locale or CaseSensitive settings between its related tables.";

	public const string DataSet_CannotChangeSchemaSerializationMode = "SchemaSerializationMode property can be set only if it is overridden by derived DataSet.";

	public const string DataTable_ForeignPrimaryKey = "PrimaryKey columns do not belong to this table.";

	public const string DataTable_CannotAddToSimpleContent = "Cannot add a nested relation or an element column to a table containing a SimpleContent column.";

	public const string DataTable_NoName = "TableName is required when it is part of a DataSet.";

	public const string DataTable_MultipleSimpleContentColumns = "DataTable already has a simple content column.";

	public const string DataTable_MissingPrimaryKey = "Table doesn't have a primary key.";

	public const string DataTable_InvalidSortString = " {0} isn't a valid Sort string entry.";

	public const string DataTable_CanNotSerializeDataTableHierarchy = "Cannot serialize the DataTable. A DataTable being used in one or more DataColumn expressions is not a descendant of current DataTable.";

	public const string DataTable_CanNotRemoteDataTable = "This DataTable can only be remoted as part of DataSet. One or more Expression Columns has reference to other DataTable(s).";

	public const string DataTable_CanNotSetRemotingFormat = "Cannot have different remoting format property value for DataSet and DataTable.";

	public const string DataTable_CanNotSerializeDataTableWithEmptyName = "Cannot serialize the DataTable. DataTable name is not set.";

	public const string DataTable_DuplicateName = "A DataTable named '{0}' already belongs to this DataSet.";

	public const string DataTable_DuplicateName2 = "A DataTable named '{0}' with the same Namespace '{1}' already belongs to this DataSet.";

	public const string DataTable_SelfnestedDatasetConflictingName = "The table ({0}) cannot be the child table to itself in a nested relation: the DataSet name conflicts with the table name.";

	public const string DataTable_DatasetConflictingName = "The name '{0}' is invalid. A DataTable cannot have the same name of the DataSet.";

	public const string DataTable_AlreadyInOtherDataSet = "DataTable already belongs to another DataSet.";

	public const string DataTable_AlreadyInTheDataSet = "DataTable already belongs to this DataSet.";

	public const string DataTable_NotInTheDataSet = "Table {0} does not belong to this DataSet.";

	public const string DataTable_OutOfRange = "Cannot find table {0}.";

	public const string DataTable_InRelation = "Cannot remove a table that has existing relations.  Remove relations first.";

	public const string DataTable_InConstraint = "Cannot remove table {0}, because it referenced in ForeignKeyConstraint {1}.  Remove the constraint first.";

	public const string DataTable_TableNotFound = "DataTable '{0}' does not match to any DataTable in source.";

	public const string DataMerge_MissingDefinition = "Target DataSet missing definition for {0}.";

	public const string DataMerge_MissingConstraint = "Target DataSet missing {0} {1}.";

	public const string DataMerge_DataTypeMismatch = "<target>.{0} and <source>.{0} have conflicting properties: DataType property mismatch.";

	public const string DataMerge_PrimaryKeyMismatch = "<target>.PrimaryKey and <source>.PrimaryKey have different Length.";

	public const string DataMerge_PrimaryKeyColumnsMismatch = "Mismatch columns in the PrimaryKey : <target>.{0} versus <source>.{1}.";

	public const string DataMerge_ReltionKeyColumnsMismatch = "Relation {0} cannot be merged, because keys have mismatch columns.";

	public const string DataMerge_MissingColumnDefinition = "Target table {0} missing definition for column {1}.";

	public const string DataIndex_RecordStateRange = "The RowStates parameter must be set to a valid combination of values from the DataViewRowState enumeration.";

	public const string DataIndex_FindWithoutSortOrder = "Find finds a row based on a Sort order, and no Sort order is specified.";

	public const string DataIndex_KeyLength = "Expecting {0} value(s) for the key being indexed, but received {1} value(s).";

	public const string DataStorage_AggregateException = "Invalid usage of aggregate function {0}() and Type: {1}.";

	public const string DataStorage_InvalidStorageType = "Invalid storage type: {0}.";

	public const string DataStorage_ProblematicChars = "The DataSet Xml persistency does not support the value '{0}' as Char value, please use Byte storage instead.";

	public const string DataStorage_SetInvalidDataType = "Type of value has a mismatch with column type";

	public const string DataStorage_IComparableNotDefined = " Type '{0}' does not implement IComparable interface. Comparison cannot be done.";

	public const string DataView_SetFailed = "Cannot set {0}.";

	public const string DataView_SetDataSetFailed = "Cannot change DataSet on a DataViewManager that's already the default view for a DataSet.";

	public const string DataView_SetRowStateFilter = "RowStateFilter cannot show ModifiedOriginals and ModifiedCurrents at the same time.";

	public const string DataView_SetTable = "Cannot change Table property on a DefaultView or a DataView coming from a DataViewManager.";

	public const string DataView_CanNotSetDataSet = "Cannot change DataSet property once it is set.";

	public const string DataView_CanNotUseDataViewManager = "DataSet must be set prior to using DataViewManager.";

	public const string DataView_CanNotSetTable = "Cannot change Table property once it is set.";

	public const string DataView_CanNotUse = "DataTable must be set prior to using DataView.";

	public const string DataView_CanNotBindTable = "Cannot bind to DataTable with no name.";

	public const string DataView_SetIListObject = "Cannot set an object into this list.";

	public const string DataView_AddNewNotAllowNull = "Cannot call AddNew on a DataView where AllowNew is false.";

	public const string DataView_NotOpen = "DataView is not open.";

	public const string DataView_CreateChildView = "The relation is not parented to the table to which this DataView points.";

	public const string DataView_CanNotDelete = "Cannot delete on a DataSource where AllowDelete is false.";

	public const string DataView_CanNotEdit = "Cannot edit on a DataSource where AllowEdit is false.";

	public const string DataView_GetElementIndex = "Index {0} is either negative or above rows count.";

	public const string DataView_AddExternalObject = "Cannot add external objects to this list.";

	public const string DataView_CanNotClear = "Cannot clear this list.";

	public const string DataView_InsertExternalObject = "Cannot insert external objects to this list.";

	public const string DataView_RemoveExternalObject = "Cannot remove objects not in the list.";

	public const string DataROWView_PropertyNotFound = "{0} is neither a DataColumn nor a DataRelation for table {1}.";

	public const string Range_Argument = "Min ({0}) must be less than or equal to max ({1}) in a Range object.";

	public const string Range_NullRange = "This is a null range.";

	public const string RecordManager_MinimumCapacity = "MinimumCapacity must be non-negative.";

	public const string SqlConvert_ConvertFailed = " Cannot convert object of type '{0}' to object of type '{1}'.";

	public const string DataSet_DefaultDataException = "Data Exception.";

	public const string DataSet_DefaultConstraintException = "Constraint Exception.";

	public const string DataSet_DefaultDeletedRowInaccessibleException = "Deleted rows inaccessible.";

	public const string DataSet_DefaultDuplicateNameException = "Duplicate name not allowed.";

	public const string DataSet_DefaultInRowChangingEventException = "Operation not supported in the RowChanging event.";

	public const string DataSet_DefaultInvalidConstraintException = "Invalid constraint.";

	public const string DataSet_DefaultMissingPrimaryKeyException = "Missing primary key.";

	public const string DataSet_DefaultNoNullAllowedException = "Null not allowed.";

	public const string DataSet_DefaultReadOnlyException = "Column is marked read only.";

	public const string DataSet_DefaultRowNotInTableException = "Row not found in table.";

	public const string DataSet_DefaultVersionNotFoundException = "Version not found.";

	public const string Load_ReadOnlyDataModified = "ReadOnly Data is Modified.";

	public const string DataTableReader_InvalidDataTableReader = "DataTableReader is invalid for current DataTable '{0}'.";

	public const string DataTableReader_SchemaInvalidDataTableReader = "Schema of current DataTable '{0}' in DataTableReader has changed, DataTableReader is invalid.";

	public const string DataTableReader_CannotCreateDataReaderOnEmptyDataSet = "DataTableReader Cannot be created. There is no DataTable in DataSet.";

	public const string DataTableReader_DataTableReaderArgumentIsEmpty = "Cannot create DataTableReader. Argument is Empty.";

	public const string DataTableReader_ArgumentContainsNullValue = "Cannot create DataTableReader. Arguments contain null value.";

	public const string DataTableReader_InvalidRowInDataTableReader = "Current DataRow is either in Deleted or Detached state.";

	public const string DataTableReader_DataTableCleared = "Current DataTable '{0}' is empty. There is no DataRow in DataTable.";

	public const string RbTree_InvalidState = "DataTable internal index is corrupted: '{0}'.";

	public const string RbTree_EnumerationBroken = "Collection was modified; enumeration operation might not execute.";

	public const string NamedSimpleType_InvalidDuplicateNamedSimpleTypeDelaration = "Simple type '{0}' has already be declared with different '{1}'.";

	public const string DataDom_Foliation = "Invalid foliation.";

	public const string DataDom_TableNameChange = "Cannot change the table name once the associated DataSet is mapped to a loaded XML document.";

	public const string DataDom_TableNamespaceChange = "Cannot change the table namespace once the associated DataSet is mapped to a loaded XML document.";

	public const string DataDom_ColumnNameChange = "Cannot change the column name once the associated DataSet is mapped to a loaded XML document.";

	public const string DataDom_ColumnNamespaceChange = "Cannot change the column namespace once the associated DataSet is mapped to a loaded XML document.";

	public const string DataDom_ColumnMappingChange = "Cannot change the ColumnMapping property once the associated DataSet is mapped to a loaded XML document.";

	public const string DataDom_TableColumnsChange = "Cannot add or remove columns from the table once the DataSet is mapped to a loaded XML document.";

	public const string DataDom_DataSetTablesChange = "Cannot add or remove tables from the DataSet once the DataSet is mapped to a loaded XML document.";

	public const string DataDom_DataSetNestedRelationsChange = "Cannot add, remove, or change Nested relations from the DataSet once the DataSet is mapped to a loaded XML document.";

	public const string DataDom_DataSetNull = "The DataSet parameter is invalid. It cannot be null.";

	public const string DataDom_DataSetNameChange = "Cannot change the DataSet name once the DataSet is mapped to a loaded XML document.";

	public const string DataDom_CloneNode = "This type of node cannot be cloned: {0}.";

	public const string DataDom_MultipleLoad = "Cannot load XmlDataDocument if it already contains data. Please use a new XmlDataDocument.";

	public const string DataDom_MultipleDataSet = "DataSet can be associated with at most one XmlDataDocument. Cannot associate the DataSet with the current XmlDataDocument because the DataSet is already associated with another XmlDataDocument.";

	public const string DataDom_NotSupport_GetElementById = "GetElementById() is not supported on DataDocument.";

	public const string DataDom_NotSupport_EntRef = "Cannot create entity references on DataDocument.";

	public const string DataDom_NotSupport_Clear = "Clear function on DateSet and DataTable is not supported on XmlDataDocument.";

	public const string ADP_EmptyArray = "Expecting non-empty array for '{0}' parameter.";

	public const string SQL_WrongType = "Expecting argument of type {1}, but received type {0}.";

	public const string ADP_InvalidConnectionOptionValue = "Invalid value for key '{0}'.";

	public const string ADP_KeywordNotSupported = "Keyword not supported: '{0}'.";

	public const string ADP_InternalProviderError = "Internal .Net Framework Data Provider error {0}.";

	public const string ADP_NoQuoteChange = "The QuotePrefix and QuoteSuffix properties cannot be changed once an Insert, Update, or Delete command has been generated.";

	public const string ADP_MissingSourceCommand = "The DataAdapter.SelectCommand property needs to be initialized.";

	public const string ADP_MissingSourceCommandConnection = "The DataAdapter.SelectCommand.Connection property needs to be initialized;";

	public const string ADP_InvalidMultipartName = "{0} \"{1}\".";

	public const string ADP_InvalidMultipartNameQuoteUsage = "{0} \"{1}\", incorrect usage of quotes.";

	public const string ADP_InvalidMultipartNameToManyParts = "{0} \"{1}\", the current limit of \"{2}\" is insufficient.";

	public const string ADP_ColumnSchemaExpression = "The column mapping from SourceColumn '{0}' failed because the DataColumn '{1}' is a computed column.";

	public const string ADP_ColumnSchemaMismatch = "Inconvertible type mismatch between SourceColumn '{0}' of {1} and the DataColumn '{2}' of {3}.";

	public const string ADP_ColumnSchemaMissing1 = "Missing the DataColumn '{0}' for the SourceColumn '{2}'.";

	public const string ADP_ColumnSchemaMissing2 = "Missing the DataColumn '{0}' in the DataTable '{1}' for the SourceColumn '{2}'.";

	public const string ADP_InvalidSourceColumn = "SourceColumn is required to be a non-empty string.";

	public const string ADP_MissingColumnMapping = "Missing SourceColumn mapping for '{0}'.";

	public const string ADP_NotSupportedEnumerationValue = "The {0} enumeration value, {1}, is not supported by the {2} method.";

	public const string ADP_MissingTableSchema = "Missing the '{0}' DataTable for the '{1}' SourceTable.";

	public const string ADP_InvalidSourceTable = "SourceTable is required to be a non-empty string";

	public const string ADP_MissingTableMapping = "Missing SourceTable mapping: '{0}'";

	public const string ADP_ConnectionRequired_Insert = "Update requires the InsertCommand to have a connection object. The Connection property of the InsertCommand has not been initialized.";

	public const string ADP_ConnectionRequired_Update = "Update requires the UpdateCommand to have a connection object. The Connection property of the UpdateCommand has not been initialized.";

	public const string ADP_ConnectionRequired_Delete = "Update requires the DeleteCommand to have a connection object. The Connection property of the DeleteCommand has not been initialized.";

	public const string ADP_ConnectionRequired_Batch = "Update requires a connection object.  The Connection property has not been initialized.";

	public const string ADP_ConnectionRequired_Clone = "Update requires the command clone to have a connection object. The Connection property of the command clone has not been initialized.";

	public const string ADP_OpenConnectionRequired_Insert = "Update requires the {0}Command to have an open connection object. {1}";

	public const string ADP_OpenConnectionRequired_Update = "Update requires the {0}Command to have an open connection object. {1}";

	public const string ADP_OpenConnectionRequired_Delete = "Update requires the {0}Command to have an open connection object. {1}";

	public const string ADP_OpenConnectionRequired_Clone = "Update requires the updating command to have an open connection object. {1}";

	public const string ADP_MissingSelectCommand = "The SelectCommand property has not been initialized before calling '{0}'.";

	public const string ADP_UnwantedStatementType = "The StatementType {0} is not expected here.";

	public const string ADP_FillSchemaRequiresSourceTableName = "FillSchema: expected a non-empty string for the SourceTable name.";

	public const string ADP_FillRequiresSourceTableName = "Fill: expected a non-empty string for the SourceTable name.";

	public const string ADP_FillChapterAutoIncrement = "Hierarchical chapter columns must map to an AutoIncrement DataColumn.";

	public const string ADP_MissingDataReaderFieldType = "DataReader.GetFieldType({0}) returned null.";

	public const string ADP_OnlyOneTableForStartRecordOrMaxRecords = "Only specify one item in the dataTables array when using non-zero values for startRecords or maxRecords.";

	public const string ADP_UpdateRequiresSourceTable = "Update unable to find TableMapping['{0}'] or DataTable '{0}'.";

	public const string ADP_UpdateRequiresSourceTableName = "Update: expected a non-empty SourceTable name.";

	public const string ADP_UpdateRequiresCommandClone = "Update requires the command clone to be valid.";

	public const string ADP_UpdateRequiresCommandSelect = "Auto SQL generation during Update requires a valid SelectCommand.";

	public const string ADP_UpdateRequiresCommandInsert = "Update requires a valid InsertCommand when passed DataRow collection with new rows.";

	public const string ADP_UpdateRequiresCommandUpdate = "Update requires a valid UpdateCommand when passed DataRow collection with modified rows.";

	public const string ADP_UpdateRequiresCommandDelete = "Update requires a valid DeleteCommand when passed DataRow collection with deleted rows.";

	public const string ADP_UpdateMismatchRowTable = "DataRow[{0}] is from a different DataTable than DataRow[0].";

	public const string ADP_RowUpdatedErrors = "RowUpdatedEvent: Errors occurred; no additional is information available.";

	public const string ADP_RowUpdatingErrors = "RowUpdatingEvent: Errors occurred; no additional is information available.";

	public const string ADP_ResultsNotAllowedDuringBatch = "When batching, the command's UpdatedRowSource property value of UpdateRowSource.FirstReturnedRecord or UpdateRowSource.Both is invalid.";

	public const string ADP_UpdateConcurrencyViolation_Update = "Concurrency violation: the UpdateCommand affected {0} of the expected {1} records.";

	public const string ADP_UpdateConcurrencyViolation_Delete = "Concurrency violation: the DeleteCommand affected {0} of the expected {1} records.";

	public const string ADP_UpdateConcurrencyViolation_Batch = "Concurrency violation: the batched command affected {0} of the expected {1} records.";

	public const string ADP_InvalidSourceBufferIndex = "Invalid source buffer (size of {0}) offset: {1}";

	public const string ADP_InvalidDestinationBufferIndex = "Invalid destination buffer (size of {0}) offset: {1}";

	public const string ADP_StreamClosed = "Invalid attempt to {0} when stream is closed.";

	public const string ADP_InvalidSeekOrigin = "Specified SeekOrigin value is invalid.";

	public const string ADP_DynamicSQLJoinUnsupported = "Dynamic SQL generation is not supported against multiple base tables.";

	public const string ADP_DynamicSQLNoTableInfo = "Dynamic SQL generation is not supported against a SelectCommand that does not return any base table information.";

	public const string ADP_DynamicSQLNoKeyInfoDelete = "Dynamic SQL generation for the DeleteCommand is not supported against a SelectCommand that does not return any key column information.";

	public const string ADP_DynamicSQLNoKeyInfoUpdate = "Dynamic SQL generation for the UpdateCommand is not supported against a SelectCommand that does not return any key column information.";

	public const string ADP_DynamicSQLNoKeyInfoRowVersionDelete = "Dynamic SQL generation for the DeleteCommand is not supported against a SelectCommand that does not contain a row version column.";

	public const string ADP_DynamicSQLNoKeyInfoRowVersionUpdate = "Dynamic SQL generation for the UpdateCommand is not supported against a SelectCommand that does not contain a row version column.";

	public const string ADP_DynamicSQLNestedQuote = "Dynamic SQL generation not supported against table names '{0}' that contain the QuotePrefix or QuoteSuffix character '{1}'.";

	public const string SQL_InvalidBufferSizeOrIndex = "Buffer offset '{1}' plus the bytes available '{0}' is greater than the length of the passed in buffer.";

	public const string SQL_InvalidDataLength = "Data length '{0}' is less than 0.";

	public const string SqlMisc_NullString = "Null";

	public const string SqlMisc_MessageString = "Message";

	public const string SqlMisc_ArithOverflowMessage = "Arithmetic Overflow.";

	public const string SqlMisc_DivideByZeroMessage = "Divide by zero error encountered.";

	public const string SqlMisc_NullValueMessage = "Data is Null. This method or property cannot be called on Null values.";

	public const string SqlMisc_TruncationMessage = "Numeric arithmetic causes truncation.";

	public const string SqlMisc_DateTimeOverflowMessage = "SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.";

	public const string SqlMisc_ConcatDiffCollationMessage = "Two strings to be concatenated have different collation.";

	public const string SqlMisc_CompareDiffCollationMessage = "Two strings to be compared have different collation.";

	public const string SqlMisc_InvalidFlagMessage = "Invalid flag value.";

	public const string SqlMisc_NumeToDecOverflowMessage = "Conversion from SqlDecimal to Decimal overflows.";

	public const string SqlMisc_ConversionOverflowMessage = "Conversion overflows.";

	public const string SqlMisc_InvalidDateTimeMessage = "Invalid SqlDateTime.";

	public const string SqlMisc_TimeZoneSpecifiedMessage = "A time zone was specified. SqlDateTime does not support time zones.";

	public const string SqlMisc_InvalidArraySizeMessage = "Invalid array size.";

	public const string SqlMisc_InvalidPrecScaleMessage = "Invalid numeric precision/scale.";

	public const string SqlMisc_FormatMessage = "The input wasn't in a correct format.";

	public const string SqlMisc_SqlTypeMessage = "SqlType error.";

	public const string SqlMisc_NoBufferMessage = "There is no buffer. Read or write operation failed.";

	public const string SqlMisc_BufferInsufficientMessage = "The buffer is insufficient. Read or write operation failed.";

	public const string SqlMisc_WriteNonZeroOffsetOnNullMessage = "Cannot write to non-zero offset, because current value is Null.";

	public const string SqlMisc_WriteOff

System.Numerics.dll

Decompiled 3 weeks ago
using System;
using System.Buffers;
using System.Diagnostics;
using System.Globalization;
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;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("System.Numerics.dll")]
[assembly: AssemblyDescription("System.Numerics.dll")]
[assembly: AssemblyDefaultAlias("System.Numerics.dll")]
[assembly: AssemblyCompany("Mono development team")]
[assembly: AssemblyProduct("Mono Common Language Infrastructure")]
[assembly: AssemblyCopyright("(c) Various Mono authors")]
[assembly: SatelliteContractVersion("4.0.0.0")]
[assembly: AssemblyInformationalVersion("4.6.57.0")]
[assembly: AssemblyFileVersion("4.6.57.0")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyDelaySign(true)]
[assembly: SecurityCritical]
[assembly: ComVisible(false)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.0.0")]
[module: UnverifiableCode]
internal static class Consts
{
	public const string MonoCorlibVersion = "1A5E0066-58DC-428A-B21C-0AD6CDAE2789";

	public const string MonoVersion = "6.12.0.0";

	public const string MonoCompany = "Mono development team";

	public const string MonoProduct = "Mono Common Language Infrastructure";

	public const string MonoCopyright = "(c) Various Mono authors";

	public const string FxVersion = "4.0.0.0";

	public const string FxFileVersion = "4.6.57.0";

	public const string EnvironmentVersion = "4.0.30319.42000";

	public const string VsVersion = "0.0.0.0";

	public const string VsFileVersion = "11.0.0.0";

	private const string PublicKeyToken = "b77a5c561934e089";

	public const string AssemblyI18N = "I18N, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMicrosoft_JScript = "Microsoft.JScript, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMicrosoft_VisualStudio = "Microsoft.VisualStudio, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMicrosoft_VisualStudio_Web = "Microsoft.VisualStudio.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMicrosoft_VSDesigner = "Microsoft.VSDesigner, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMono_Http = "Mono.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMono_Posix = "Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMono_Security = "Mono.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMono_Messaging_RabbitMQ = "Mono.Messaging.RabbitMQ, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyCorlib = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem = "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_Data = "System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_Design = "System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_DirectoryServices = "System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Drawing = "System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Drawing_Design = "System.Drawing.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Messaging = "System.Messaging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Security = "System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_ServiceProcess = "System.ServiceProcess, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Web = "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Windows_Forms = "System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_2_0 = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystemCore_3_5 = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_Core = "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string WindowsBase_3_0 = "WindowsBase, Version=3.0.0.0, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyWindowsBase = "WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyPresentationCore_3_5 = "PresentationCore, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyPresentationCore_4_0 = "PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyPresentationFramework_3_5 = "PresentationFramework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblySystemServiceModel_3_0 = "System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
}
internal static class SR
{
	public const string Argument_BadFormatSpecifier = "Format specifier was invalid.";

	public const string Argument_InvalidNumberStyles = "An undefined NumberStyles value is being used.";

	public const string Argument_InvalidHexStyle = "With the AllowHexSpecifier bit set in the enum bit field, the only other valid bits that can be combined into the enum value must be a subset of those in HexNumber.";

	public const string Argument_MustBeBigInt = "The parameter must be a BigInteger.";

	public const string Format_TooLarge = "The value is too large to be represented by this format specifier.";

	public const string ArgumentOutOfRange_MustBeNonNeg = "The number must be greater than or equal to zero.";

	public const string Overflow_BigIntInfinity = "BigInteger cannot represent infinity.";

	public const string Overflow_NotANumber = "The value is not a number.";

	public const string Overflow_ParseBigInteger = "The value could not be parsed.";

	public const string Overflow_Int32 = "Value was either too large or too small for an Int32.";

	public const string Overflow_Int64 = "Value was either too large or too small for an Int64.";

	public const string Overflow_UInt32 = "Value was either too large or too small for a UInt32.";

	public const string Overflow_UInt64 = "Value was either too large or too small for a UInt64.";

	public const string Overflow_Decimal = "Value was either too large or too small for a Decimal.";

	public const string Arg_ArgumentOutOfRangeException = "Index was out of bounds:";

	public const string Arg_ElementsInSourceIsGreaterThanDestination = "Number of elements in source vector is greater than the destination array";

	public const string Arg_NullArgumentNullRef = "The method was called with a null array argument.";

	public const string Arg_TypeNotSupported = "Specified type is not supported";

	public const string ArgumentException_BufferNotFromPool = "The buffer is not associated with this pool and may not be returned to it.";

	public const string Overflow_Negative_Unsigned = "Negative values do not have an unsigned representation.";

	internal static string GetString(string name, params object[] args)
	{
		return GetString(CultureInfo.InvariantCulture, name, args);
	}

	internal static string GetString(CultureInfo culture, string name, params object[] args)
	{
		return string.Format(culture, name, args);
	}

	internal static string GetString(string name)
	{
		return name;
	}

	internal static string GetString(CultureInfo culture, string name)
	{
		return name;
	}

	internal static string Format(string resourceFormat, params object[] args)
	{
		if (args != null)
		{
			return string.Format(CultureInfo.InvariantCulture, resourceFormat, args);
		}
		return resourceFormat;
	}

	internal static string Format(string resourceFormat, object p1)
	{
		return string.Format(CultureInfo.InvariantCulture, resourceFormat, p1);
	}

	internal static string Format(string resourceFormat, object p1, object p2)
	{
		return string.Format(CultureInfo.InvariantCulture, resourceFormat, p1, p2);
	}

	internal static string Format(CultureInfo ci, string resourceFormat, object p1, object p2)
	{
		return string.Format(ci, resourceFormat, p1, p2);
	}

	internal static string Format(string resourceFormat, object p1, object p2, object p3)
	{
		return string.Format(CultureInfo.InvariantCulture, resourceFormat, p1, p2, p3);
	}

	internal static string GetResourceString(string str)
	{
		return str;
	}
}
namespace System.Numerics
{
	public struct Matrix3x2 : IEquatable<Matrix3x2>
	{
		public float M11;

		public float M12;

		public float M21;

		public float M22;

		public float M31;

		public float M32;

		private static readonly Matrix3x2 _identity = new Matrix3x2(1f, 0f, 0f, 1f, 0f, 0f);

		public static Matrix3x2 Identity => _identity;

		public bool IsIdentity
		{
			get
			{
				if (M11 == 1f && M22 == 1f && M12 == 0f && M21 == 0f && M31 == 0f)
				{
					return M32 == 0f;
				}
				return false;
			}
		}

		public Vector2 Translation
		{
			get
			{
				return new Vector2(M31, M32);
			}
			set
			{
				M31 = value.X;
				M32 = value.Y;
			}
		}

		public Matrix3x2(float m11, float m12, float m21, float m22, float m31, float m32)
		{
			M11 = m11;
			M12 = m12;
			M21 = m21;
			M22 = m22;
			M31 = m31;
			M32 = m32;
		}

		public static Matrix3x2 CreateTranslation(Vector2 position)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = 1f;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = 1f;
			result.M31 = position.X;
			result.M32 = position.Y;
			return result;
		}

		public static Matrix3x2 CreateTranslation(float xPosition, float yPosition)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = 1f;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = 1f;
			result.M31 = xPosition;
			result.M32 = yPosition;
			return result;
		}

		public static Matrix3x2 CreateScale(float xScale, float yScale)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = xScale;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = yScale;
			result.M31 = 0f;
			result.M32 = 0f;
			return result;
		}

		public static Matrix3x2 CreateScale(float xScale, float yScale, Vector2 centerPoint)
		{
			float m = centerPoint.X * (1f - xScale);
			float m2 = centerPoint.Y * (1f - yScale);
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = xScale;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = yScale;
			result.M31 = m;
			result.M32 = m2;
			return result;
		}

		public static Matrix3x2 CreateScale(Vector2 scales)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = scales.X;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = scales.Y;
			result.M31 = 0f;
			result.M32 = 0f;
			return result;
		}

		public static Matrix3x2 CreateScale(Vector2 scales, Vector2 centerPoint)
		{
			float m = centerPoint.X * (1f - scales.X);
			float m2 = centerPoint.Y * (1f - scales.Y);
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = scales.X;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = scales.Y;
			result.M31 = m;
			result.M32 = m2;
			return result;
		}

		public static Matrix3x2 CreateScale(float scale)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = scale;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = scale;
			result.M31 = 0f;
			result.M32 = 0f;
			return result;
		}

		public static Matrix3x2 CreateScale(float scale, Vector2 centerPoint)
		{
			float m = centerPoint.X * (1f - scale);
			float m2 = centerPoint.Y * (1f - scale);
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = scale;
			result.M12 = 0f;
			result.M21 = 0f;
			result.M22 = scale;
			result.M31 = m;
			result.M32 = m2;
			return result;
		}

		public static Matrix3x2 CreateSkew(float radiansX, float radiansY)
		{
			float m = MathF.Tan(radiansX);
			float m2 = MathF.Tan(radiansY);
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = 1f;
			result.M12 = m2;
			result.M21 = m;
			result.M22 = 1f;
			result.M31 = 0f;
			result.M32 = 0f;
			return result;
		}

		public static Matrix3x2 CreateSkew(float radiansX, float radiansY, Vector2 centerPoint)
		{
			float num = MathF.Tan(radiansX);
			float num2 = MathF.Tan(radiansY);
			float m = (0f - centerPoint.Y) * num;
			float m2 = (0f - centerPoint.X) * num2;
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = 1f;
			result.M12 = num2;
			result.M21 = num;
			result.M22 = 1f;
			result.M31 = m;
			result.M32 = m2;
			return result;
		}

		public static Matrix3x2 CreateRotation(float radians)
		{
			radians = MathF.IEEERemainder(radians, (float)Math.PI * 2f);
			float num;
			float num2;
			if (radians > -1.7453294E-05f && radians < 1.7453294E-05f)
			{
				num = 1f;
				num2 = 0f;
			}
			else if (radians > 1.570779f && radians < 1.5708138f)
			{
				num = 0f;
				num2 = 1f;
			}
			else if (radians < -3.1415753f || radians > 3.1415753f)
			{
				num = -1f;
				num2 = 0f;
			}
			else if (radians > -1.5708138f && radians < -1.570779f)
			{
				num = 0f;
				num2 = -1f;
			}
			else
			{
				num = MathF.Cos(radians);
				num2 = MathF.Sin(radians);
			}
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = num;
			result.M12 = num2;
			result.M21 = 0f - num2;
			result.M22 = num;
			result.M31 = 0f;
			result.M32 = 0f;
			return result;
		}

		public static Matrix3x2 CreateRotation(float radians, Vector2 centerPoint)
		{
			radians = MathF.IEEERemainder(radians, (float)Math.PI * 2f);
			float num;
			float num2;
			if (radians > -1.7453294E-05f && radians < 1.7453294E-05f)
			{
				num = 1f;
				num2 = 0f;
			}
			else if (radians > 1.570779f && radians < 1.5708138f)
			{
				num = 0f;
				num2 = 1f;
			}
			else if (radians < -3.1415753f || radians > 3.1415753f)
			{
				num = -1f;
				num2 = 0f;
			}
			else if (radians > -1.5708138f && radians < -1.570779f)
			{
				num = 0f;
				num2 = -1f;
			}
			else
			{
				num = MathF.Cos(radians);
				num2 = MathF.Sin(radians);
			}
			float m = centerPoint.X * (1f - num) + centerPoint.Y * num2;
			float m2 = centerPoint.Y * (1f - num) - centerPoint.X * num2;
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = num;
			result.M12 = num2;
			result.M21 = 0f - num2;
			result.M22 = num;
			result.M31 = m;
			result.M32 = m2;
			return result;
		}

		public float GetDeterminant()
		{
			return M11 * M22 - M21 * M12;
		}

		public static bool Invert(Matrix3x2 matrix, out Matrix3x2 result)
		{
			float num = matrix.M11 * matrix.M22 - matrix.M21 * matrix.M12;
			if (MathF.Abs(num) < float.Epsilon)
			{
				result = new Matrix3x2(float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN);
				return false;
			}
			float num2 = 1f / num;
			result.M11 = matrix.M22 * num2;
			result.M12 = (0f - matrix.M12) * num2;
			result.M21 = (0f - matrix.M21) * num2;
			result.M22 = matrix.M11 * num2;
			result.M31 = (matrix.M21 * matrix.M32 - matrix.M31 * matrix.M22) * num2;
			result.M32 = (matrix.M31 * matrix.M12 - matrix.M11 * matrix.M32) * num2;
			return true;
		}

		public static Matrix3x2 Lerp(Matrix3x2 matrix1, Matrix3x2 matrix2, float amount)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = matrix1.M11 + (matrix2.M11 - matrix1.M11) * amount;
			result.M12 = matrix1.M12 + (matrix2.M12 - matrix1.M12) * amount;
			result.M21 = matrix1.M21 + (matrix2.M21 - matrix1.M21) * amount;
			result.M22 = matrix1.M22 + (matrix2.M22 - matrix1.M22) * amount;
			result.M31 = matrix1.M31 + (matrix2.M31 - matrix1.M31) * amount;
			result.M32 = matrix1.M32 + (matrix2.M32 - matrix1.M32) * amount;
			return result;
		}

		public static Matrix3x2 Negate(Matrix3x2 value)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = 0f - value.M11;
			result.M12 = 0f - value.M12;
			result.M21 = 0f - value.M21;
			result.M22 = 0f - value.M22;
			result.M31 = 0f - value.M31;
			result.M32 = 0f - value.M32;
			return result;
		}

		public static Matrix3x2 Add(Matrix3x2 value1, Matrix3x2 value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 + value2.M11;
			result.M12 = value1.M12 + value2.M12;
			result.M21 = value1.M21 + value2.M21;
			result.M22 = value1.M22 + value2.M22;
			result.M31 = value1.M31 + value2.M31;
			result.M32 = value1.M32 + value2.M32;
			return result;
		}

		public static Matrix3x2 Subtract(Matrix3x2 value1, Matrix3x2 value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 - value2.M11;
			result.M12 = value1.M12 - value2.M12;
			result.M21 = value1.M21 - value2.M21;
			result.M22 = value1.M22 - value2.M22;
			result.M31 = value1.M31 - value2.M31;
			result.M32 = value1.M32 - value2.M32;
			return result;
		}

		public static Matrix3x2 Multiply(Matrix3x2 value1, Matrix3x2 value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21;
			result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22;
			result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21;
			result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22;
			result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value2.M31;
			result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value2.M32;
			return result;
		}

		public static Matrix3x2 Multiply(Matrix3x2 value1, float value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 * value2;
			result.M12 = value1.M12 * value2;
			result.M21 = value1.M21 * value2;
			result.M22 = value1.M22 * value2;
			result.M31 = value1.M31 * value2;
			result.M32 = value1.M32 * value2;
			return result;
		}

		public static Matrix3x2 operator -(Matrix3x2 value)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = 0f - value.M11;
			result.M12 = 0f - value.M12;
			result.M21 = 0f - value.M21;
			result.M22 = 0f - value.M22;
			result.M31 = 0f - value.M31;
			result.M32 = 0f - value.M32;
			return result;
		}

		public static Matrix3x2 operator +(Matrix3x2 value1, Matrix3x2 value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 + value2.M11;
			result.M12 = value1.M12 + value2.M12;
			result.M21 = value1.M21 + value2.M21;
			result.M22 = value1.M22 + value2.M22;
			result.M31 = value1.M31 + value2.M31;
			result.M32 = value1.M32 + value2.M32;
			return result;
		}

		public static Matrix3x2 operator -(Matrix3x2 value1, Matrix3x2 value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 - value2.M11;
			result.M12 = value1.M12 - value2.M12;
			result.M21 = value1.M21 - value2.M21;
			result.M22 = value1.M22 - value2.M22;
			result.M31 = value1.M31 - value2.M31;
			result.M32 = value1.M32 - value2.M32;
			return result;
		}

		public static Matrix3x2 operator *(Matrix3x2 value1, Matrix3x2 value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21;
			result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22;
			result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21;
			result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22;
			result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value2.M31;
			result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value2.M32;
			return result;
		}

		public static Matrix3x2 operator *(Matrix3x2 value1, float value2)
		{
			Matrix3x2 result = default(Matrix3x2);
			result.M11 = value1.M11 * value2;
			result.M12 = value1.M12 * value2;
			result.M21 = value1.M21 * value2;
			result.M22 = value1.M22 * value2;
			result.M31 = value1.M31 * value2;
			result.M32 = value1.M32 * value2;
			return result;
		}

		public static bool operator ==(Matrix3x2 value1, Matrix3x2 value2)
		{
			if (value1.M11 == value2.M11 && value1.M22 == value2.M22 && value1.M12 == value2.M12 && value1.M21 == value2.M21 && value1.M31 == value2.M31)
			{
				return value1.M32 == value2.M32;
			}
			return false;
		}

		public static bool operator !=(Matrix3x2 value1, Matrix3x2 value2)
		{
			if (value1.M11 == value2.M11 && value1.M12 == value2.M12 && value1.M21 == value2.M21 && value1.M22 == value2.M22 && value1.M31 == value2.M31)
			{
				return value1.M32 != value2.M32;
			}
			return true;
		}

		public bool Equals(Matrix3x2 other)
		{
			if (M11 == other.M11 && M22 == other.M22 && M12 == other.M12 && M21 == other.M21 && M31 == other.M31)
			{
				return M32 == other.M32;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is Matrix3x2)
			{
				return Equals((Matrix3x2)obj);
			}
			return false;
		}

		public override string ToString()
		{
			CultureInfo currentCulture = CultureInfo.CurrentCulture;
			return string.Format(currentCulture, "{{ {{M11:{0} M12:{1}}} {{M21:{2} M22:{3}}} {{M31:{4} M32:{5}}} }}", M11.ToString(currentCulture), M12.ToString(currentCulture), M21.ToString(currentCulture), M22.ToString(currentCulture), M31.ToString(currentCulture), M32.ToString(currentCulture));
		}

		public override int GetHashCode()
		{
			return M11.GetHashCode() + M12.GetHashCode() + M21.GetHashCode() + M22.GetHashCode() + M31.GetHashCode() + M32.GetHashCode();
		}
	}
	public struct Matrix4x4 : IEquatable<Matrix4x4>
	{
		private struct CanonicalBasis
		{
			public Vector3 Row0;

			public Vector3 Row1;

			public Vector3 Row2;
		}

		private struct VectorBasis
		{
			public unsafe Vector3* Element0;

			public unsafe Vector3* Element1;

			public unsafe Vector3* Element2;
		}

		public float M11;

		public float M12;

		public float M13;

		public float M14;

		public float M21;

		public float M22;

		public float M23;

		public float M24;

		public float M31;

		public float M32;

		public float M33;

		public float M34;

		public float M41;

		public float M42;

		public float M43;

		public float M44;

		private static readonly Matrix4x4 _identity = new Matrix4x4(1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f);

		public static Matrix4x4 Identity => _identity;

		public bool IsIdentity
		{
			get
			{
				if (M11 == 1f && M22 == 1f && M33 == 1f && M44 == 1f && M12 == 0f && M13 == 0f && M14 == 0f && M21 == 0f && M23 == 0f && M24 == 0f && M31 == 0f && M32 == 0f && M34 == 0f && M41 == 0f && M42 == 0f)
				{
					return M43 == 0f;
				}
				return false;
			}
		}

		public Vector3 Translation
		{
			get
			{
				return new Vector3(M41, M42, M43);
			}
			set
			{
				M41 = value.X;
				M42 = value.Y;
				M43 = value.Z;
			}
		}

		public Matrix4x4(float m11, float m12, float m13, float m14, float m21, float m22, float m23, float m24, float m31, float m32, float m33, float m34, float m41, float m42, float m43, float m44)
		{
			M11 = m11;
			M12 = m12;
			M13 = m13;
			M14 = m14;
			M21 = m21;
			M22 = m22;
			M23 = m23;
			M24 = m24;
			M31 = m31;
			M32 = m32;
			M33 = m33;
			M34 = m34;
			M41 = m41;
			M42 = m42;
			M43 = m43;
			M44 = m44;
		}

		public Matrix4x4(Matrix3x2 value)
		{
			M11 = value.M11;
			M12 = value.M12;
			M13 = 0f;
			M14 = 0f;
			M21 = value.M21;
			M22 = value.M22;
			M23 = 0f;
			M24 = 0f;
			M31 = 0f;
			M32 = 0f;
			M33 = 1f;
			M34 = 0f;
			M41 = value.M31;
			M42 = value.M32;
			M43 = 0f;
			M44 = 1f;
		}

		public static Matrix4x4 CreateBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 cameraUpVector, Vector3 cameraForwardVector)
		{
			Vector3 left = new Vector3(objectPosition.X - cameraPosition.X, objectPosition.Y - cameraPosition.Y, objectPosition.Z - cameraPosition.Z);
			float num = left.LengthSquared();
			left = ((!(num < 0.0001f)) ? Vector3.Multiply(left, 1f / MathF.Sqrt(num)) : (-cameraForwardVector));
			Vector3 vector = Vector3.Normalize(Vector3.Cross(cameraUpVector, left));
			Vector3 vector2 = Vector3.Cross(left, vector);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = vector.X;
			result.M12 = vector.Y;
			result.M13 = vector.Z;
			result.M14 = 0f;
			result.M21 = vector2.X;
			result.M22 = vector2.Y;
			result.M23 = vector2.Z;
			result.M24 = 0f;
			result.M31 = left.X;
			result.M32 = left.Y;
			result.M33 = left.Z;
			result.M34 = 0f;
			result.M41 = objectPosition.X;
			result.M42 = objectPosition.Y;
			result.M43 = objectPosition.Z;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateConstrainedBillboard(Vector3 objectPosition, Vector3 cameraPosition, Vector3 rotateAxis, Vector3 cameraForwardVector, Vector3 objectForwardVector)
		{
			Vector3 left = new Vector3(objectPosition.X - cameraPosition.X, objectPosition.Y - cameraPosition.Y, objectPosition.Z - cameraPosition.Z);
			float num = left.LengthSquared();
			left = ((!(num < 0.0001f)) ? Vector3.Multiply(left, 1f / MathF.Sqrt(num)) : (-cameraForwardVector));
			Vector3 vector = rotateAxis;
			Vector3 vector3;
			Vector3 vector2;
			if (MathF.Abs(Vector3.Dot(rotateAxis, left)) > 0.99825466f)
			{
				vector2 = objectForwardVector;
				if (MathF.Abs(Vector3.Dot(rotateAxis, vector2)) > 0.99825466f)
				{
					vector2 = ((MathF.Abs(rotateAxis.Z) > 0.99825466f) ? new Vector3(1f, 0f, 0f) : new Vector3(0f, 0f, -1f));
				}
				vector3 = Vector3.Normalize(Vector3.Cross(rotateAxis, vector2));
				vector2 = Vector3.Normalize(Vector3.Cross(vector3, rotateAxis));
			}
			else
			{
				vector3 = Vector3.Normalize(Vector3.Cross(rotateAxis, left));
				vector2 = Vector3.Normalize(Vector3.Cross(vector3, vector));
			}
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = vector3.X;
			result.M12 = vector3.Y;
			result.M13 = vector3.Z;
			result.M14 = 0f;
			result.M21 = vector.X;
			result.M22 = vector.Y;
			result.M23 = vector.Z;
			result.M24 = 0f;
			result.M31 = vector2.X;
			result.M32 = vector2.Y;
			result.M33 = vector2.Z;
			result.M34 = 0f;
			result.M41 = objectPosition.X;
			result.M42 = objectPosition.Y;
			result.M43 = objectPosition.Z;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateTranslation(Vector3 position)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 1f;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = 1f;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = 1f;
			result.M34 = 0f;
			result.M41 = position.X;
			result.M42 = position.Y;
			result.M43 = position.Z;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateTranslation(float xPosition, float yPosition, float zPosition)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 1f;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = 1f;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = 1f;
			result.M34 = 0f;
			result.M41 = xPosition;
			result.M42 = yPosition;
			result.M43 = zPosition;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateScale(float xScale, float yScale, float zScale)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = xScale;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = yScale;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = zScale;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateScale(float xScale, float yScale, float zScale, Vector3 centerPoint)
		{
			float m = centerPoint.X * (1f - xScale);
			float m2 = centerPoint.Y * (1f - yScale);
			float m3 = centerPoint.Z * (1f - zScale);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = xScale;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = yScale;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = zScale;
			result.M34 = 0f;
			result.M41 = m;
			result.M42 = m2;
			result.M43 = m3;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateScale(Vector3 scales)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = scales.X;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = scales.Y;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = scales.Z;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateScale(Vector3 scales, Vector3 centerPoint)
		{
			float m = centerPoint.X * (1f - scales.X);
			float m2 = centerPoint.Y * (1f - scales.Y);
			float m3 = centerPoint.Z * (1f - scales.Z);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = scales.X;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = scales.Y;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = scales.Z;
			result.M34 = 0f;
			result.M41 = m;
			result.M42 = m2;
			result.M43 = m3;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateScale(float scale)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = scale;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = scale;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = scale;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateScale(float scale, Vector3 centerPoint)
		{
			float m = centerPoint.X * (1f - scale);
			float m2 = centerPoint.Y * (1f - scale);
			float m3 = centerPoint.Z * (1f - scale);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = scale;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = scale;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = scale;
			result.M34 = 0f;
			result.M41 = m;
			result.M42 = m2;
			result.M43 = m3;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateRotationX(float radians)
		{
			float num = MathF.Cos(radians);
			float num2 = MathF.Sin(radians);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 1f;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = num;
			result.M23 = num2;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f - num2;
			result.M33 = num;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateRotationX(float radians, Vector3 centerPoint)
		{
			float num = MathF.Cos(radians);
			float num2 = MathF.Sin(radians);
			float m = centerPoint.Y * (1f - num) + centerPoint.Z * num2;
			float m2 = centerPoint.Z * (1f - num) - centerPoint.Y * num2;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 1f;
			result.M12 = 0f;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = num;
			result.M23 = num2;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f - num2;
			result.M33 = num;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = m;
			result.M43 = m2;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateRotationY(float radians)
		{
			float num = MathF.Cos(radians);
			float num2 = MathF.Sin(radians);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num;
			result.M12 = 0f;
			result.M13 = 0f - num2;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = 1f;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = num2;
			result.M32 = 0f;
			result.M33 = num;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateRotationY(float radians, Vector3 centerPoint)
		{
			float num = MathF.Cos(radians);
			float num2 = MathF.Sin(radians);
			float m = centerPoint.X * (1f - num) - centerPoint.Z * num2;
			float m2 = centerPoint.Z * (1f - num) + centerPoint.X * num2;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num;
			result.M12 = 0f;
			result.M13 = 0f - num2;
			result.M14 = 0f;
			result.M21 = 0f;
			result.M22 = 1f;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = num2;
			result.M32 = 0f;
			result.M33 = num;
			result.M34 = 0f;
			result.M41 = m;
			result.M42 = 0f;
			result.M43 = m2;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateRotationZ(float radians)
		{
			float num = MathF.Cos(radians);
			float num2 = MathF.Sin(radians);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num;
			result.M12 = num2;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f - num2;
			result.M22 = num;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = 1f;
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateRotationZ(float radians, Vector3 centerPoint)
		{
			float num = MathF.Cos(radians);
			float num2 = MathF.Sin(radians);
			float m = centerPoint.X * (1f - num) + centerPoint.Y * num2;
			float m2 = centerPoint.Y * (1f - num) - centerPoint.X * num2;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num;
			result.M12 = num2;
			result.M13 = 0f;
			result.M14 = 0f;
			result.M21 = 0f - num2;
			result.M22 = num;
			result.M23 = 0f;
			result.M24 = 0f;
			result.M31 = 0f;
			result.M32 = 0f;
			result.M33 = 1f;
			result.M34 = 0f;
			result.M41 = m;
			result.M42 = m2;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateFromAxisAngle(Vector3 axis, float angle)
		{
			float x = axis.X;
			float y = axis.Y;
			float z = axis.Z;
			float num = MathF.Sin(angle);
			float num2 = MathF.Cos(angle);
			float num3 = x * x;
			float num4 = y * y;
			float num5 = z * z;
			float num6 = x * y;
			float num7 = x * z;
			float num8 = y * z;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num3 + num2 * (1f - num3);
			result.M12 = num6 - num2 * num6 + num * z;
			result.M13 = num7 - num2 * num7 - num * y;
			result.M14 = 0f;
			result.M21 = num6 - num2 * num6 - num * z;
			result.M22 = num4 + num2 * (1f - num4);
			result.M23 = num8 - num2 * num8 + num * x;
			result.M24 = 0f;
			result.M31 = num7 - num2 * num7 + num * y;
			result.M32 = num8 - num2 * num8 - num * x;
			result.M33 = num5 + num2 * (1f - num5);
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance)
		{
			if (fieldOfView <= 0f || fieldOfView >= (float)Math.PI)
			{
				throw new ArgumentOutOfRangeException("fieldOfView");
			}
			if (nearPlaneDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("nearPlaneDistance");
			}
			if (farPlaneDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("farPlaneDistance");
			}
			if (nearPlaneDistance >= farPlaneDistance)
			{
				throw new ArgumentOutOfRangeException("nearPlaneDistance");
			}
			float num = 1f / MathF.Tan(fieldOfView * 0.5f);
			float m = num / aspectRatio;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = m;
			result.M12 = (result.M13 = (result.M14 = 0f));
			result.M22 = num;
			result.M21 = (result.M23 = (result.M24 = 0f));
			result.M31 = (result.M32 = 0f);
			float num2 = (result.M33 = (float.IsPositiveInfinity(farPlaneDistance) ? (-1f) : (farPlaneDistance / (nearPlaneDistance - farPlaneDistance))));
			result.M34 = -1f;
			result.M41 = (result.M42 = (result.M44 = 0f));
			result.M43 = nearPlaneDistance * num2;
			return result;
		}

		public static Matrix4x4 CreatePerspective(float width, float height, float nearPlaneDistance, float farPlaneDistance)
		{
			if (nearPlaneDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("nearPlaneDistance");
			}
			if (farPlaneDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("farPlaneDistance");
			}
			if (nearPlaneDistance >= farPlaneDistance)
			{
				throw new ArgumentOutOfRangeException("nearPlaneDistance");
			}
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 2f * nearPlaneDistance / width;
			result.M12 = (result.M13 = (result.M14 = 0f));
			result.M22 = 2f * nearPlaneDistance / height;
			result.M21 = (result.M23 = (result.M24 = 0f));
			float num = (result.M33 = (float.IsPositiveInfinity(farPlaneDistance) ? (-1f) : (farPlaneDistance / (nearPlaneDistance - farPlaneDistance))));
			result.M31 = (result.M32 = 0f);
			result.M34 = -1f;
			result.M41 = (result.M42 = (result.M44 = 0f));
			result.M43 = nearPlaneDistance * num;
			return result;
		}

		public static Matrix4x4 CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float nearPlaneDistance, float farPlaneDistance)
		{
			if (nearPlaneDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("nearPlaneDistance");
			}
			if (farPlaneDistance <= 0f)
			{
				throw new ArgumentOutOfRangeException("farPlaneDistance");
			}
			if (nearPlaneDistance >= farPlaneDistance)
			{
				throw new ArgumentOutOfRangeException("nearPlaneDistance");
			}
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 2f * nearPlaneDistance / (right - left);
			result.M12 = (result.M13 = (result.M14 = 0f));
			result.M22 = 2f * nearPlaneDistance / (top - bottom);
			result.M21 = (result.M23 = (result.M24 = 0f));
			result.M31 = (left + right) / (right - left);
			result.M32 = (top + bottom) / (top - bottom);
			float num = (result.M33 = (float.IsPositiveInfinity(farPlaneDistance) ? (-1f) : (farPlaneDistance / (nearPlaneDistance - farPlaneDistance))));
			result.M34 = -1f;
			result.M43 = nearPlaneDistance * num;
			result.M41 = (result.M42 = (result.M44 = 0f));
			return result;
		}

		public static Matrix4x4 CreateOrthographic(float width, float height, float zNearPlane, float zFarPlane)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 2f / width;
			result.M12 = (result.M13 = (result.M14 = 0f));
			result.M22 = 2f / height;
			result.M21 = (result.M23 = (result.M24 = 0f));
			result.M33 = 1f / (zNearPlane - zFarPlane);
			result.M31 = (result.M32 = (result.M34 = 0f));
			result.M41 = (result.M42 = 0f);
			result.M43 = zNearPlane / (zNearPlane - zFarPlane);
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNearPlane, float zFarPlane)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 2f / (right - left);
			result.M12 = (result.M13 = (result.M14 = 0f));
			result.M22 = 2f / (top - bottom);
			result.M21 = (result.M23 = (result.M24 = 0f));
			result.M33 = 1f / (zNearPlane - zFarPlane);
			result.M31 = (result.M32 = (result.M34 = 0f));
			result.M41 = (left + right) / (left - right);
			result.M42 = (top + bottom) / (bottom - top);
			result.M43 = zNearPlane / (zNearPlane - zFarPlane);
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector)
		{
			Vector3 vector = Vector3.Normalize(cameraPosition - cameraTarget);
			Vector3 vector2 = Vector3.Normalize(Vector3.Cross(cameraUpVector, vector));
			Vector3 vector3 = Vector3.Cross(vector, vector2);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = vector2.X;
			result.M12 = vector3.X;
			result.M13 = vector.X;
			result.M14 = 0f;
			result.M21 = vector2.Y;
			result.M22 = vector3.Y;
			result.M23 = vector.Y;
			result.M24 = 0f;
			result.M31 = vector2.Z;
			result.M32 = vector3.Z;
			result.M33 = vector.Z;
			result.M34 = 0f;
			result.M41 = 0f - Vector3.Dot(vector2, cameraPosition);
			result.M42 = 0f - Vector3.Dot(vector3, cameraPosition);
			result.M43 = 0f - Vector3.Dot(vector, cameraPosition);
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateWorld(Vector3 position, Vector3 forward, Vector3 up)
		{
			Vector3 vector = Vector3.Normalize(-forward);
			Vector3 vector2 = Vector3.Normalize(Vector3.Cross(up, vector));
			Vector3 vector3 = Vector3.Cross(vector, vector2);
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = vector2.X;
			result.M12 = vector2.Y;
			result.M13 = vector2.Z;
			result.M14 = 0f;
			result.M21 = vector3.X;
			result.M22 = vector3.Y;
			result.M23 = vector3.Z;
			result.M24 = 0f;
			result.M31 = vector.X;
			result.M32 = vector.Y;
			result.M33 = vector.Z;
			result.M34 = 0f;
			result.M41 = position.X;
			result.M42 = position.Y;
			result.M43 = position.Z;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateFromQuaternion(Quaternion quaternion)
		{
			float num = quaternion.X * quaternion.X;
			float num2 = quaternion.Y * quaternion.Y;
			float num3 = quaternion.Z * quaternion.Z;
			float num4 = quaternion.X * quaternion.Y;
			float num5 = quaternion.Z * quaternion.W;
			float num6 = quaternion.Z * quaternion.X;
			float num7 = quaternion.Y * quaternion.W;
			float num8 = quaternion.Y * quaternion.Z;
			float num9 = quaternion.X * quaternion.W;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 1f - 2f * (num2 + num3);
			result.M12 = 2f * (num4 + num5);
			result.M13 = 2f * (num6 - num7);
			result.M14 = 0f;
			result.M21 = 2f * (num4 - num5);
			result.M22 = 1f - 2f * (num3 + num);
			result.M23 = 2f * (num8 + num9);
			result.M24 = 0f;
			result.M31 = 2f * (num6 + num7);
			result.M32 = 2f * (num8 - num9);
			result.M33 = 1f - 2f * (num2 + num);
			result.M34 = 0f;
			result.M41 = 0f;
			result.M42 = 0f;
			result.M43 = 0f;
			result.M44 = 1f;
			return result;
		}

		public static Matrix4x4 CreateFromYawPitchRoll(float yaw, float pitch, float roll)
		{
			return CreateFromQuaternion(Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll));
		}

		public static Matrix4x4 CreateShadow(Vector3 lightDirection, Plane plane)
		{
			Plane plane2 = Plane.Normalize(plane);
			float num = plane2.Normal.X * lightDirection.X + plane2.Normal.Y * lightDirection.Y + plane2.Normal.Z * lightDirection.Z;
			float num2 = 0f - plane2.Normal.X;
			float num3 = 0f - plane2.Normal.Y;
			float num4 = 0f - plane2.Normal.Z;
			float num5 = 0f - plane2.D;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num2 * lightDirection.X + num;
			result.M21 = num3 * lightDirection.X;
			result.M31 = num4 * lightDirection.X;
			result.M41 = num5 * lightDirection.X;
			result.M12 = num2 * lightDirection.Y;
			result.M22 = num3 * lightDirection.Y + num;
			result.M32 = num4 * lightDirection.Y;
			result.M42 = num5 * lightDirection.Y;
			result.M13 = num2 * lightDirection.Z;
			result.M23 = num3 * lightDirection.Z;
			result.M33 = num4 * lightDirection.Z + num;
			result.M43 = num5 * lightDirection.Z;
			result.M14 = 0f;
			result.M24 = 0f;
			result.M34 = 0f;
			result.M44 = num;
			return result;
		}

		public static Matrix4x4 CreateReflection(Plane value)
		{
			value = Plane.Normalize(value);
			float x = value.Normal.X;
			float y = value.Normal.Y;
			float z = value.Normal.Z;
			float num = -2f * x;
			float num2 = -2f * y;
			float num3 = -2f * z;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = num * x + 1f;
			result.M12 = num2 * x;
			result.M13 = num3 * x;
			result.M14 = 0f;
			result.M21 = num * y;
			result.M22 = num2 * y + 1f;
			result.M23 = num3 * y;
			result.M24 = 0f;
			result.M31 = num * z;
			result.M32 = num2 * z;
			result.M33 = num3 * z + 1f;
			result.M34 = 0f;
			result.M41 = num * value.D;
			result.M42 = num2 * value.D;
			result.M43 = num3 * value.D;
			result.M44 = 1f;
			return result;
		}

		public float GetDeterminant()
		{
			float m = M11;
			float m2 = M12;
			float m3 = M13;
			float m4 = M14;
			float m5 = M21;
			float m6 = M22;
			float m7 = M23;
			float m8 = M24;
			float m9 = M31;
			float m10 = M32;
			float m11 = M33;
			float m12 = M34;
			float m13 = M41;
			float m14 = M42;
			float m15 = M43;
			float m16 = M44;
			float num = m11 * m16 - m12 * m15;
			float num2 = m10 * m16 - m12 * m14;
			float num3 = m10 * m15 - m11 * m14;
			float num4 = m9 * m16 - m12 * m13;
			float num5 = m9 * m15 - m11 * m13;
			float num6 = m9 * m14 - m10 * m13;
			return m * (m6 * num - m7 * num2 + m8 * num3) - m2 * (m5 * num - m7 * num4 + m8 * num5) + m3 * (m5 * num2 - m6 * num4 + m8 * num6) - m4 * (m5 * num3 - m6 * num5 + m7 * num6);
		}

		public static bool Invert(Matrix4x4 matrix, out Matrix4x4 result)
		{
			float m = matrix.M11;
			float m2 = matrix.M12;
			float m3 = matrix.M13;
			float m4 = matrix.M14;
			float m5 = matrix.M21;
			float m6 = matrix.M22;
			float m7 = matrix.M23;
			float m8 = matrix.M24;
			float m9 = matrix.M31;
			float m10 = matrix.M32;
			float m11 = matrix.M33;
			float m12 = matrix.M34;
			float m13 = matrix.M41;
			float m14 = matrix.M42;
			float m15 = matrix.M43;
			float m16 = matrix.M44;
			float num = m11 * m16 - m12 * m15;
			float num2 = m10 * m16 - m12 * m14;
			float num3 = m10 * m15 - m11 * m14;
			float num4 = m9 * m16 - m12 * m13;
			float num5 = m9 * m15 - m11 * m13;
			float num6 = m9 * m14 - m10 * m13;
			float num7 = m6 * num - m7 * num2 + m8 * num3;
			float num8 = 0f - (m5 * num - m7 * num4 + m8 * num5);
			float num9 = m5 * num2 - m6 * num4 + m8 * num6;
			float num10 = 0f - (m5 * num3 - m6 * num5 + m7 * num6);
			float num11 = m * num7 + m2 * num8 + m3 * num9 + m4 * num10;
			if (MathF.Abs(num11) < float.Epsilon)
			{
				result = new Matrix4x4(float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN);
				return false;
			}
			float num12 = 1f / num11;
			result.M11 = num7 * num12;
			result.M21 = num8 * num12;
			result.M31 = num9 * num12;
			result.M41 = num10 * num12;
			result.M12 = (0f - (m2 * num - m3 * num2 + m4 * num3)) * num12;
			result.M22 = (m * num - m3 * num4 + m4 * num5) * num12;
			result.M32 = (0f - (m * num2 - m2 * num4 + m4 * num6)) * num12;
			result.M42 = (m * num3 - m2 * num5 + m3 * num6) * num12;
			float num13 = m7 * m16 - m8 * m15;
			float num14 = m6 * m16 - m8 * m14;
			float num15 = m6 * m15 - m7 * m14;
			float num16 = m5 * m16 - m8 * m13;
			float num17 = m5 * m15 - m7 * m13;
			float num18 = m5 * m14 - m6 * m13;
			result.M13 = (m2 * num13 - m3 * num14 + m4 * num15) * num12;
			result.M23 = (0f - (m * num13 - m3 * num16 + m4 * num17)) * num12;
			result.M33 = (m * num14 - m2 * num16 + m4 * num18) * num12;
			result.M43 = (0f - (m * num15 - m2 * num17 + m3 * num18)) * num12;
			float num19 = m7 * m12 - m8 * m11;
			float num20 = m6 * m12 - m8 * m10;
			float num21 = m6 * m11 - m7 * m10;
			float num22 = m5 * m12 - m8 * m9;
			float num23 = m5 * m11 - m7 * m9;
			float num24 = m5 * m10 - m6 * m9;
			result.M14 = (0f - (m2 * num19 - m3 * num20 + m4 * num21)) * num12;
			result.M24 = (m * num19 - m3 * num22 + m4 * num23) * num12;
			result.M34 = (0f - (m * num20 - m2 * num22 + m4 * num24)) * num12;
			result.M44 = (m * num21 - m2 * num23 + m3 * num24) * num12;
			return true;
		}

		public unsafe static bool Decompose(Matrix4x4 matrix, out Vector3 scale, out Quaternion rotation, out Vector3 translation)
		{
			bool result = true;
			fixed (Vector3* ptr = &scale)
			{
				float* ptr2 = (float*)ptr;
				VectorBasis vectorBasis = default(VectorBasis);
				Vector3** ptr3 = (Vector3**)(&vectorBasis);
				Matrix4x4 identity = Identity;
				CanonicalBasis canonicalBasis = default(CanonicalBasis);
				Vector3* ptr4 = &canonicalBasis.Row0;
				canonicalBasis.Row0 = new Vector3(1f, 0f, 0f);
				canonicalBasis.Row1 = new Vector3(0f, 1f, 0f);
				canonicalBasis.Row2 = new Vector3(0f, 0f, 1f);
				translation = new Vector3(matrix.M41, matrix.M42, matrix.M43);
				*ptr3 = (Vector3*)(&identity.M11);
				ptr3[1] = (Vector3*)(&identity.M21);
				ptr3[2] = (Vector3*)(&identity.M31);
				*(*ptr3) = new Vector3(matrix.M11, matrix.M12, matrix.M13);
				*ptr3[1] = new Vector3(matrix.M21, matrix.M22, matrix.M23);
				*ptr3[2] = new Vector3(matrix.M31, matrix.M32, matrix.M33);
				scale.X = (*ptr3)->Length();
				scale.Y = ptr3[1]->Length();
				scale.Z = ptr3[2]->Length();
				float num = *ptr2;
				float num2 = ptr2[1];
				float num3 = ptr2[2];
				uint num4;
				uint num5;
				uint num6;
				if (num < num2)
				{
					if (num2 < num3)
					{
						num4 = 2u;
						num5 = 1u;
						num6 = 0u;
					}
					else
					{
						num4 = 1u;
						if (num < num3)
						{
							num5 = 2u;
							num6 = 0u;
						}
						else
						{
							num5 = 0u;
							num6 = 2u;
						}
					}
				}
				else if (num < num3)
				{
					num4 = 2u;
					num5 = 0u;
					num6 = 1u;
				}
				else
				{
					num4 = 0u;
					if (num2 < num3)
					{
						num5 = 2u;
						num6 = 1u;
					}
					else
					{
						num5 = 1u;
						num6 = 2u;
					}
				}
				if (ptr2[num4] < 0.0001f)
				{
					*ptr3[num4] = ptr4[num4];
				}
				*ptr3[num4] = Vector3.Normalize(*ptr3[num4]);
				if (ptr2[num5] < 0.0001f)
				{
					float num7 = MathF.Abs(ptr3[num4]->X);
					float num8 = MathF.Abs(ptr3[num4]->Y);
					float num9 = MathF.Abs(ptr3[num4]->Z);
					uint num10 = ((num7 < num8) ? ((!(num8 < num9)) ? ((!(num7 < num9)) ? 2u : 0u) : 0u) : ((num7 < num9) ? 1u : ((num8 < num9) ? 1u : 2u)));
					*ptr3[num5] = Vector3.Cross(*ptr3[num4], ptr4[num10]);
				}
				*ptr3[num5] = Vector3.Normalize(*ptr3[num5]);
				if (ptr2[num6] < 0.0001f)
				{
					*ptr3[num6] = Vector3.Cross(*ptr3[num4], *ptr3[num5]);
				}
				*ptr3[num6] = Vector3.Normalize(*ptr3[num6]);
				float num11 = identity.GetDeterminant();
				if (num11 < 0f)
				{
					ptr2[num4] = 0f - ptr2[num4];
					*ptr3[num4] = -(*ptr3[num4]);
					num11 = 0f - num11;
				}
				num11 -= 1f;
				num11 *= num11;
				if (0.0001f < num11)
				{
					rotation = Quaternion.Identity;
					result = false;
				}
				else
				{
					rotation = Quaternion.CreateFromRotationMatrix(identity);
				}
			}
			return result;
		}

		public static Matrix4x4 Transform(Matrix4x4 value, Quaternion rotation)
		{
			float num = rotation.X + rotation.X;
			float num2 = rotation.Y + rotation.Y;
			float num3 = rotation.Z + rotation.Z;
			float num4 = rotation.W * num;
			float num5 = rotation.W * num2;
			float num6 = rotation.W * num3;
			float num7 = rotation.X * num;
			float num8 = rotation.X * num2;
			float num9 = rotation.X * num3;
			float num10 = rotation.Y * num2;
			float num11 = rotation.Y * num3;
			float num12 = rotation.Z * num3;
			float num13 = 1f - num10 - num12;
			float num14 = num8 - num6;
			float num15 = num9 + num5;
			float num16 = num8 + num6;
			float num17 = 1f - num7 - num12;
			float num18 = num11 - num4;
			float num19 = num9 - num5;
			float num20 = num11 + num4;
			float num21 = 1f - num7 - num10;
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value.M11 * num13 + value.M12 * num14 + value.M13 * num15;
			result.M12 = value.M11 * num16 + value.M12 * num17 + value.M13 * num18;
			result.M13 = value.M11 * num19 + value.M12 * num20 + value.M13 * num21;
			result.M14 = value.M14;
			result.M21 = value.M21 * num13 + value.M22 * num14 + value.M23 * num15;
			result.M22 = value.M21 * num16 + value.M22 * num17 + value.M23 * num18;
			result.M23 = value.M21 * num19 + value.M22 * num20 + value.M23 * num21;
			result.M24 = value.M24;
			result.M31 = value.M31 * num13 + value.M32 * num14 + value.M33 * num15;
			result.M32 = value.M31 * num16 + value.M32 * num17 + value.M33 * num18;
			result.M33 = value.M31 * num19 + value.M32 * num20 + value.M33 * num21;
			result.M34 = value.M34;
			result.M41 = value.M41 * num13 + value.M42 * num14 + value.M43 * num15;
			result.M42 = value.M41 * num16 + value.M42 * num17 + value.M43 * num18;
			result.M43 = value.M41 * num19 + value.M42 * num20 + value.M43 * num21;
			result.M44 = value.M44;
			return result;
		}

		public static Matrix4x4 Transpose(Matrix4x4 matrix)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = matrix.M11;
			result.M12 = matrix.M21;
			result.M13 = matrix.M31;
			result.M14 = matrix.M41;
			result.M21 = matrix.M12;
			result.M22 = matrix.M22;
			result.M23 = matrix.M32;
			result.M24 = matrix.M42;
			result.M31 = matrix.M13;
			result.M32 = matrix.M23;
			result.M33 = matrix.M33;
			result.M34 = matrix.M43;
			result.M41 = matrix.M14;
			result.M42 = matrix.M24;
			result.M43 = matrix.M34;
			result.M44 = matrix.M44;
			return result;
		}

		public static Matrix4x4 Lerp(Matrix4x4 matrix1, Matrix4x4 matrix2, float amount)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = matrix1.M11 + (matrix2.M11 - matrix1.M11) * amount;
			result.M12 = matrix1.M12 + (matrix2.M12 - matrix1.M12) * amount;
			result.M13 = matrix1.M13 + (matrix2.M13 - matrix1.M13) * amount;
			result.M14 = matrix1.M14 + (matrix2.M14 - matrix1.M14) * amount;
			result.M21 = matrix1.M21 + (matrix2.M21 - matrix1.M21) * amount;
			result.M22 = matrix1.M22 + (matrix2.M22 - matrix1.M22) * amount;
			result.M23 = matrix1.M23 + (matrix2.M23 - matrix1.M23) * amount;
			result.M24 = matrix1.M24 + (matrix2.M24 - matrix1.M24) * amount;
			result.M31 = matrix1.M31 + (matrix2.M31 - matrix1.M31) * amount;
			result.M32 = matrix1.M32 + (matrix2.M32 - matrix1.M32) * amount;
			result.M33 = matrix1.M33 + (matrix2.M33 - matrix1.M33) * amount;
			result.M34 = matrix1.M34 + (matrix2.M34 - matrix1.M34) * amount;
			result.M41 = matrix1.M41 + (matrix2.M41 - matrix1.M41) * amount;
			result.M42 = matrix1.M42 + (matrix2.M42 - matrix1.M42) * amount;
			result.M43 = matrix1.M43 + (matrix2.M43 - matrix1.M43) * amount;
			result.M44 = matrix1.M44 + (matrix2.M44 - matrix1.M44) * amount;
			return result;
		}

		public static Matrix4x4 Negate(Matrix4x4 value)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 0f - value.M11;
			result.M12 = 0f - value.M12;
			result.M13 = 0f - value.M13;
			result.M14 = 0f - value.M14;
			result.M21 = 0f - value.M21;
			result.M22 = 0f - value.M22;
			result.M23 = 0f - value.M23;
			result.M24 = 0f - value.M24;
			result.M31 = 0f - value.M31;
			result.M32 = 0f - value.M32;
			result.M33 = 0f - value.M33;
			result.M34 = 0f - value.M34;
			result.M41 = 0f - value.M41;
			result.M42 = 0f - value.M42;
			result.M43 = 0f - value.M43;
			result.M44 = 0f - value.M44;
			return result;
		}

		public static Matrix4x4 Add(Matrix4x4 value1, Matrix4x4 value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 + value2.M11;
			result.M12 = value1.M12 + value2.M12;
			result.M13 = value1.M13 + value2.M13;
			result.M14 = value1.M14 + value2.M14;
			result.M21 = value1.M21 + value2.M21;
			result.M22 = value1.M22 + value2.M22;
			result.M23 = value1.M23 + value2.M23;
			result.M24 = value1.M24 + value2.M24;
			result.M31 = value1.M31 + value2.M31;
			result.M32 = value1.M32 + value2.M32;
			result.M33 = value1.M33 + value2.M33;
			result.M34 = value1.M34 + value2.M34;
			result.M41 = value1.M41 + value2.M41;
			result.M42 = value1.M42 + value2.M42;
			result.M43 = value1.M43 + value2.M43;
			result.M44 = value1.M44 + value2.M44;
			return result;
		}

		public static Matrix4x4 Subtract(Matrix4x4 value1, Matrix4x4 value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 - value2.M11;
			result.M12 = value1.M12 - value2.M12;
			result.M13 = value1.M13 - value2.M13;
			result.M14 = value1.M14 - value2.M14;
			result.M21 = value1.M21 - value2.M21;
			result.M22 = value1.M22 - value2.M22;
			result.M23 = value1.M23 - value2.M23;
			result.M24 = value1.M24 - value2.M24;
			result.M31 = value1.M31 - value2.M31;
			result.M32 = value1.M32 - value2.M32;
			result.M33 = value1.M33 - value2.M33;
			result.M34 = value1.M34 - value2.M34;
			result.M41 = value1.M41 - value2.M41;
			result.M42 = value1.M42 - value2.M42;
			result.M43 = value1.M43 - value2.M43;
			result.M44 = value1.M44 - value2.M44;
			return result;
		}

		public static Matrix4x4 Multiply(Matrix4x4 value1, Matrix4x4 value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21 + value1.M13 * value2.M31 + value1.M14 * value2.M41;
			result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22 + value1.M13 * value2.M32 + value1.M14 * value2.M42;
			result.M13 = value1.M11 * value2.M13 + value1.M12 * value2.M23 + value1.M13 * value2.M33 + value1.M14 * value2.M43;
			result.M14 = value1.M11 * value2.M14 + value1.M12 * value2.M24 + value1.M13 * value2.M34 + value1.M14 * value2.M44;
			result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21 + value1.M23 * value2.M31 + value1.M24 * value2.M41;
			result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22 + value1.M23 * value2.M32 + value1.M24 * value2.M42;
			result.M23 = value1.M21 * value2.M13 + value1.M22 * value2.M23 + value1.M23 * value2.M33 + value1.M24 * value2.M43;
			result.M24 = value1.M21 * value2.M14 + value1.M22 * value2.M24 + value1.M23 * value2.M34 + value1.M24 * value2.M44;
			result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value1.M33 * value2.M31 + value1.M34 * value2.M41;
			result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value1.M33 * value2.M32 + value1.M34 * value2.M42;
			result.M33 = value1.M31 * value2.M13 + value1.M32 * value2.M23 + value1.M33 * value2.M33 + value1.M34 * value2.M43;
			result.M34 = value1.M31 * value2.M14 + value1.M32 * value2.M24 + value1.M33 * value2.M34 + value1.M34 * value2.M44;
			result.M41 = value1.M41 * value2.M11 + value1.M42 * value2.M21 + value1.M43 * value2.M31 + value1.M44 * value2.M41;
			result.M42 = value1.M41 * value2.M12 + value1.M42 * value2.M22 + value1.M43 * value2.M32 + value1.M44 * value2.M42;
			result.M43 = value1.M41 * value2.M13 + value1.M42 * value2.M23 + value1.M43 * value2.M33 + value1.M44 * value2.M43;
			result.M44 = value1.M41 * value2.M14 + value1.M42 * value2.M24 + value1.M43 * value2.M34 + value1.M44 * value2.M44;
			return result;
		}

		public static Matrix4x4 Multiply(Matrix4x4 value1, float value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 * value2;
			result.M12 = value1.M12 * value2;
			result.M13 = value1.M13 * value2;
			result.M14 = value1.M14 * value2;
			result.M21 = value1.M21 * value2;
			result.M22 = value1.M22 * value2;
			result.M23 = value1.M23 * value2;
			result.M24 = value1.M24 * value2;
			result.M31 = value1.M31 * value2;
			result.M32 = value1.M32 * value2;
			result.M33 = value1.M33 * value2;
			result.M34 = value1.M34 * value2;
			result.M41 = value1.M41 * value2;
			result.M42 = value1.M42 * value2;
			result.M43 = value1.M43 * value2;
			result.M44 = value1.M44 * value2;
			return result;
		}

		public static Matrix4x4 operator -(Matrix4x4 value)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = 0f - value.M11;
			result.M12 = 0f - value.M12;
			result.M13 = 0f - value.M13;
			result.M14 = 0f - value.M14;
			result.M21 = 0f - value.M21;
			result.M22 = 0f - value.M22;
			result.M23 = 0f - value.M23;
			result.M24 = 0f - value.M24;
			result.M31 = 0f - value.M31;
			result.M32 = 0f - value.M32;
			result.M33 = 0f - value.M33;
			result.M34 = 0f - value.M34;
			result.M41 = 0f - value.M41;
			result.M42 = 0f - value.M42;
			result.M43 = 0f - value.M43;
			result.M44 = 0f - value.M44;
			return result;
		}

		public static Matrix4x4 operator +(Matrix4x4 value1, Matrix4x4 value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 + value2.M11;
			result.M12 = value1.M12 + value2.M12;
			result.M13 = value1.M13 + value2.M13;
			result.M14 = value1.M14 + value2.M14;
			result.M21 = value1.M21 + value2.M21;
			result.M22 = value1.M22 + value2.M22;
			result.M23 = value1.M23 + value2.M23;
			result.M24 = value1.M24 + value2.M24;
			result.M31 = value1.M31 + value2.M31;
			result.M32 = value1.M32 + value2.M32;
			result.M33 = value1.M33 + value2.M33;
			result.M34 = value1.M34 + value2.M34;
			result.M41 = value1.M41 + value2.M41;
			result.M42 = value1.M42 + value2.M42;
			result.M43 = value1.M43 + value2.M43;
			result.M44 = value1.M44 + value2.M44;
			return result;
		}

		public static Matrix4x4 operator -(Matrix4x4 value1, Matrix4x4 value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 - value2.M11;
			result.M12 = value1.M12 - value2.M12;
			result.M13 = value1.M13 - value2.M13;
			result.M14 = value1.M14 - value2.M14;
			result.M21 = value1.M21 - value2.M21;
			result.M22 = value1.M22 - value2.M22;
			result.M23 = value1.M23 - value2.M23;
			result.M24 = value1.M24 - value2.M24;
			result.M31 = value1.M31 - value2.M31;
			result.M32 = value1.M32 - value2.M32;
			result.M33 = value1.M33 - value2.M33;
			result.M34 = value1.M34 - value2.M34;
			result.M41 = value1.M41 - value2.M41;
			result.M42 = value1.M42 - value2.M42;
			result.M43 = value1.M43 - value2.M43;
			result.M44 = value1.M44 - value2.M44;
			return result;
		}

		public static Matrix4x4 operator *(Matrix4x4 value1, Matrix4x4 value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 * value2.M11 + value1.M12 * value2.M21 + value1.M13 * value2.M31 + value1.M14 * value2.M41;
			result.M12 = value1.M11 * value2.M12 + value1.M12 * value2.M22 + value1.M13 * value2.M32 + value1.M14 * value2.M42;
			result.M13 = value1.M11 * value2.M13 + value1.M12 * value2.M23 + value1.M13 * value2.M33 + value1.M14 * value2.M43;
			result.M14 = value1.M11 * value2.M14 + value1.M12 * value2.M24 + value1.M13 * value2.M34 + value1.M14 * value2.M44;
			result.M21 = value1.M21 * value2.M11 + value1.M22 * value2.M21 + value1.M23 * value2.M31 + value1.M24 * value2.M41;
			result.M22 = value1.M21 * value2.M12 + value1.M22 * value2.M22 + value1.M23 * value2.M32 + value1.M24 * value2.M42;
			result.M23 = value1.M21 * value2.M13 + value1.M22 * value2.M23 + value1.M23 * value2.M33 + value1.M24 * value2.M43;
			result.M24 = value1.M21 * value2.M14 + value1.M22 * value2.M24 + value1.M23 * value2.M34 + value1.M24 * value2.M44;
			result.M31 = value1.M31 * value2.M11 + value1.M32 * value2.M21 + value1.M33 * value2.M31 + value1.M34 * value2.M41;
			result.M32 = value1.M31 * value2.M12 + value1.M32 * value2.M22 + value1.M33 * value2.M32 + value1.M34 * value2.M42;
			result.M33 = value1.M31 * value2.M13 + value1.M32 * value2.M23 + value1.M33 * value2.M33 + value1.M34 * value2.M43;
			result.M34 = value1.M31 * value2.M14 + value1.M32 * value2.M24 + value1.M33 * value2.M34 + value1.M34 * value2.M44;
			result.M41 = value1.M41 * value2.M11 + value1.M42 * value2.M21 + value1.M43 * value2.M31 + value1.M44 * value2.M41;
			result.M42 = value1.M41 * value2.M12 + value1.M42 * value2.M22 + value1.M43 * value2.M32 + value1.M44 * value2.M42;
			result.M43 = value1.M41 * value2.M13 + value1.M42 * value2.M23 + value1.M43 * value2.M33 + value1.M44 * value2.M43;
			result.M44 = value1.M41 * value2.M14 + value1.M42 * value2.M24 + value1.M43 * value2.M34 + value1.M44 * value2.M44;
			return result;
		}

		public static Matrix4x4 operator *(Matrix4x4 value1, float value2)
		{
			Matrix4x4 result = default(Matrix4x4);
			result.M11 = value1.M11 * value2;
			result.M12 = value1.M12 * value2;
			result.M13 = value1.M13 * value2;
			result.M14 = value1.M14 * value2;
			result.M21 = value1.M21 * value2;
			result.M22 = value1.M22 * value2;
			result.M23 = value1.M23 * value2;
			result.M24 = value1.M24 * value2;
			result.M31 = value1.M31 * value2;
			result.M32 = value1.M32 * value2;
			result.M33 = value1.M33 * value2;
			result.M34 = value1.M34 * value2;
			result.M41 = value1.M41 * value2;
			result.M42 = value1.M42 * value2;
			result.M43 = value1.M43 * value2;
			result.M44 = value1.M44 * value2;
			return result;
		}

		public static bool operator ==(Matrix4x4 value1, Matrix4x4 value2)
		{
			if (value1.M11 == value2.M11 && value1.M22 == value2.M22 && value1.M33 == value2.M33 && value1.M44 == value2.M44 && value1.M12 == value2.M12 && value1.M13 == value2.M13 && value1.M14 == value2.M14 && value1.M21 == value2.M21 && value1.M23 == value2.M23 && value1.M24 == value2.M24 && value1.M31 == value2.M31 && value1.M32 == value2.M32 && value1.M34 == value2.M34 && value1.M41 == value2.M41 && value1.M42 == value2.M42)
			{
				return value1.M43 == value2.M43;
			}
			return false;
		}

		public static bool operator !=(Matrix4x4 value1, Matrix4x4 value2)
		{
			if (value1.M11 == value2.M11 && value1.M12 == value2.M12 && value1.M13 == value2.M13 && value1.M14 == value2.M14 && value1.M21 == value2.M21 && value1.M22 == value2.M22 && value1.M23 == value2.M23 && value1.M24 == value2.M24 && value1.M31 == value2.M31 && value1.M32 == value2.M32 && value1.M33 == value2.M33 && value1.M34 == value2.M34 && value1.M41 == value2.M41 && value1.M42 == value2.M42 && value1.M43 == value2.M43)
			{
				return value1.M44 != value2.M44;
			}
			return true;
		}

		public bool Equals(Matrix4x4 other)
		{
			if (M11 == other.M11 && M22 == other.M22 && M33 == other.M33 && M44 == other.M44 && M12 == other.M12 && M13 == other.M13 && M14 == other.M14 && M21 == other.M21 && M23 == other.M23 && M24 == other.M24 && M31 == other.M31 && M32 == other.M32 && M34 == other.M34 && M41 == other.M41 && M42 == other.M42)
			{
				return M43 == other.M43;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is Matrix4x4)
			{
				return Equals((Matrix4x4)obj);
			}
			return false;
		}

		public override string ToString()
		{
			CultureInfo currentCulture = CultureInfo.CurrentCulture;
			return string.Format(currentCulture, "{{ {{M11:{0} M12:{1} M13:{2} M14:{3}}} {{M21:{4} M22:{5} M23:{6} M24:{7}}} {{M31:{8} M32:{9} M33:{10} M34:{11}}} {{M41:{12} M42:{13} M43:{14} M44:{15}}} }}", M11.ToString(currentCulture), M12.ToString(currentCulture), M13.ToString(currentCulture), M14.ToString(currentCulture), M21.ToString(currentCulture), M22.ToString(currentCulture), M23.ToString(currentCulture), M24.ToString(currentCulture), M31.ToString(currentCulture), M32.ToString(currentCulture), M33.ToString(currentCulture), M34.ToString(currentCulture), M41.ToString(currentCulture), M42.ToString(currentCulture), M43.ToString(currentCulture), M44.ToString(currentCulture));
		}

		public override int GetHashCode()
		{
			return M11.GetHashCode() + M12.GetHashCode() + M13.GetHashCode() + M14.GetHashCode() + M21.GetHashCode() + M22.GetHashCode() + M23.GetHashCode() + M24.GetHashCode() + M31.GetHashCode() + M32.GetHashCode() + M33.GetHashCode() + M34.GetHashCode() + M41.GetHashCode() + M42.GetHashCode() + M43.GetHashCode() + M44.GetHashCode();
		}
	}
	public struct Plane : IEquatable<Plane>
	{
		public Vector3 Normal;

		public float D;

		public Plane(float x, float y, float z, float d)
		{
			Normal = new Vector3(x, y, z);
			D = d;
		}

		public Plane(Vector3 normal, float d)
		{
			Normal = normal;
			D = d;
		}

		public Plane(Vector4 value)
		{
			Normal = new Vector3(value.X, value.Y, value.Z);
			D = value.W;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Plane CreateFromVertices(Vector3 point1, Vector3 point2, Vector3 point3)
		{
			if (Vector.IsHardwareAccelerated)
			{
				Vector3 vector = point2 - point1;
				Vector3 vector2 = point3 - point1;
				Vector3 vector3 = Vector3.Normalize(Vector3.Cross(vector, vector2));
				float d = 0f - Vector3.Dot(vector3, point1);
				return new Plane(vector3, d);
			}
			float num = point2.X - point1.X;
			float num2 = point2.Y - point1.Y;
			float num3 = point2.Z - point1.Z;
			float num4 = point3.X - point1.X;
			float num5 = point3.Y - point1.Y;
			float num6 = point3.Z - point1.Z;
			float num7 = num2 * num6 - num3 * num5;
			float num8 = num3 * num4 - num * num6;
			float num9 = num * num5 - num2 * num4;
			float num10 = num7 * num7 + num8 * num8 + num9 * num9;
			float num11 = 1f / MathF.Sqrt(num10);
			Vector3 normal = new Vector3(num7 * num11, num8 * num11, num9 * num11);
			return new Plane(normal, 0f - (normal.X * point1.X + normal.Y * point1.Y + normal.Z * point1.Z));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Plane Normalize(Plane value)
		{
			if (Vector.IsHardwareAccelerated)
			{
				float num = value.Normal.LengthSquared();
				if (MathF.Abs(num - 1f) < 1.1920929E-07f)
				{
					return value;
				}
				float num2 = MathF.Sqrt(num);
				return new Plane(value.Normal / num2, value.D / num2);
			}
			float num3 = value.Normal.X * value.Normal.X + value.Normal.Y * value.Normal.Y + value.Normal.Z * value.Normal.Z;
			if (MathF.Abs(num3 - 1f) < 1.1920929E-07f)
			{
				return value;
			}
			float num4 = 1f / MathF.Sqrt(num3);
			return new Plane(value.Normal.X * num4, value.Normal.Y * num4, value.Normal.Z * num4, value.D * num4);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Plane Transform(Plane plane, Matrix4x4 matrix)
		{
			Matrix4x4.Invert(matrix, out var result);
			float x = plane.Normal.X;
			float y = plane.Normal.Y;
			float z = plane.Normal.Z;
			float d = plane.D;
			return new Plane(x * result.M11 + y * result.M12 + z * result.M13 + d * result.M14, x * result.M21 + y * result.M22 + z * result.M23 + d * result.M24, x * result.M31 + y * result.M32 + z * result.M33 + d * result.M34, x * result.M41 + y * result.M42 + z * result.M43 + d * result.M44);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Plane Transform(Plane plane, Quaternion rotation)
		{
			float num = rotation.X + rotation.X;
			float num2 = rotation.Y + rotation.Y;
			float num3 = rotation.Z + rotation.Z;
			float num4 = rotation.W * num;
			float num5 = rotation.W * num2;
			float num6 = rotation.W * num3;
			float num7 = rotation.X * num;
			float num8 = rotation.X * num2;
			float num9 = rotation.X * num3;
			float num10 = rotation.Y * num2;
			float num11 = rotation.Y * num3;
			float num12 = rotation.Z * num3;
			float num13 = 1f - num10 - num12;
			float num14 = num8 - num6;
			float num15 = num9 + num5;
			float num16 = num8 + num6;
			float num17 = 1f - num7 - num12;
			float num18 = num11 - num4;
			float num19 = num9 - num5;
			float num20 = num11 + num4;
			float num21 = 1f - num7 - num10;
			float x = plane.Normal.X;
			float y = plane.Normal.Y;
			float z = plane.Normal.Z;
			return new Plane(x * num13 + y * num14 + z * num15, x * num16 + y * num17 + z * num18, x * num19 + y * num20 + z * num21, plane.D);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Dot(Plane plane, Vector4 value)
		{
			return plane.Normal.X * value.X + plane.Normal.Y * value.Y + plane.Normal.Z * value.Z + plane.D * value.W;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float DotCoordinate(Plane plane, Vector3 value)
		{
			if (Vector.IsHardwareAccelerated)
			{
				return Vector3.Dot(plane.Normal, value) + plane.D;
			}
			return plane.Normal.X * value.X + plane.Normal.Y * value.Y + plane.Normal.Z * value.Z + plane.D;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float DotNormal(Plane plane, Vector3 value)
		{
			if (Vector.IsHardwareAccelerated)
			{
				return Vector3.Dot(plane.Normal, value);
			}
			return plane.Normal.X * value.X + plane.Normal.Y * value.Y + plane.Normal.Z * value.Z;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator ==(Plane value1, Plane value2)
		{
			if (value1.Normal.X == value2.Normal.X && value1.Normal.Y == value2.Normal.Y && value1.Normal.Z == value2.Normal.Z)
			{
				return value1.D == value2.D;
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator !=(Plane value1, Plane value2)
		{
			if (value1.Normal.X == value2.Normal.X && value1.Normal.Y == value2.Normal.Y && value1.Normal.Z == value2.Normal.Z)
			{
				return value1.D != value2.D;
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public bool Equals(Plane other)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (Normal.Equals(other.Normal))
				{
					return D == other.D;
				}
				return false;
			}
			if (Normal.X == other.Normal.X && Normal.Y == other.Normal.Y && Normal.Z == other.Normal.Z)
			{
				return D == other.D;
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public override bool Equals(object obj)
		{
			if (obj is Plane)
			{
				return Equals((Plane)obj);
			}
			return false;
		}

		public override string ToString()
		{
			CultureInfo currentCulture = CultureInfo.CurrentCulture;
			return string.Format(currentCulture, "{{Normal:{0} D:{1}}}", Normal.ToString(), D.ToString(currentCulture));
		}

		public override int GetHashCode()
		{
			return Normal.GetHashCode() + D.GetHashCode();
		}
	}
	public struct Quaternion : IEquatable<Quaternion>
	{
		public float X;

		public float Y;

		public float Z;

		public float W;

		public static Quaternion Identity => new Quaternion(0f, 0f, 0f, 1f);

		public bool IsIdentity
		{
			get
			{
				if (X == 0f && Y == 0f && Z == 0f)
				{
					return W == 1f;
				}
				return false;
			}
		}

		public Quaternion(float x, float y, float z, float w)
		{
			X = x;
			Y = y;
			Z = z;
			W = w;
		}

		public Quaternion(Vector3 vectorPart, float scalarPart)
		{
			X = vectorPart.X;
			Y = vectorPart.Y;
			Z = vectorPart.Z;
			W = scalarPart;
		}

		public float Length()
		{
			return MathF.Sqrt(X * X + Y * Y + Z * Z + W * W);
		}

		public float LengthSquared()
		{
			return X * X + Y * Y + Z * Z + W * W;
		}

		public static Quaternion Normalize(Quaternion value)
		{
			float num = value.X * value.X + value.Y * value.Y + value.Z * value.Z + value.W * value.W;
			float num2 = 1f / MathF.Sqrt(num);
			Quaternion result = default(Quaternion);
			result.X = value.X * num2;
			result.Y = value.Y * num2;
			result.Z = value.Z * num2;
			result.W = value.W * num2;
			return result;
		}

		public static Quaternion Conjugate(Quaternion value)
		{
			Quaternion result = default(Quaternion);
			result.X = 0f - value.X;
			result.Y = 0f - value.Y;
			result.Z = 0f - value.Z;
			result.W = value.W;
			return result;
		}

		public static Quaternion Inverse(Quaternion value)
		{
			float num = value.X * value.X + value.Y * value.Y + value.Z * value.Z + value.W * value.W;
			float num2 = 1f / num;
			Quaternion result = default(Quaternion);
			result.X = (0f - value.X) * num2;
			result.Y = (0f - value.Y) * num2;
			result.Z = (0f - value.Z) * num2;
			result.W = value.W * num2;
			return result;
		}

		public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle)
		{
			float num = angle * 0.5f;
			float num2 = MathF.Sin(num);
			float w = MathF.Cos(num);
			Quaternion result = default(Quaternion);
			result.X = axis.X * num2;
			result.Y = axis.Y * num2;
			result.Z = axis.Z * num2;
			result.W = w;
			return result;
		}

		public static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll)
		{
			float num = roll * 0.5f;
			float num2 = MathF.Sin(num);
			float num3 = MathF.Cos(num);
			float num4 = pitch * 0.5f;
			float num5 = MathF.Sin(num4);
			float num6 = MathF.Cos(num4);
			float num7 = yaw * 0.5f;
			float num8 = MathF.Sin(num7);
			float num9 = MathF.Cos(num7);
			Quaternion result = default(Quaternion);
			result.X = num9 * num5 * num3 + num8 * num6 * num2;
			result.Y = num8 * num6 * num3 - num9 * num5 * num2;
			result.Z = num9 * num6 * num2 - num8 * num5 * num3;
			result.W = num9 * num6 * num3 + num8 * num5 * num2;
			return result;
		}

		public static Quaternion CreateFromRotationMatrix(Matrix4x4 matrix)
		{
			float num = matrix.M11 + matrix.M22 + matrix.M33;
			Quaternion result = default(Quaternion);
			if (num > 0f)
			{
				float num2 = MathF.Sqrt(num + 1f);
				result.W = num2 * 0.5f;
				num2 = 0.5f / num2;
				result.X = (matrix.M23 - matrix.M32) * num2;
				result.Y = (matrix.M31 - matrix.M13) * num2;
				result.Z = (matrix.M12 - matrix.M21) * num2;
			}
			else if (matrix.M11 >= matrix.M22 && matrix.M11 >= matrix.M33)
			{
				float num3 = MathF.Sqrt(1f + matrix.M11 - matrix.M22 - matrix.M33);
				float num4 = 0.5f / num3;
				result.X = 0.5f * num3;
				result.Y = (matrix.M12 + matrix.M21) * num4;
				result.Z = (matrix.M13 + matrix.M31) * num4;
				result.W = (matrix.M23 - matrix.M32) * num4;
			}
			else if (matrix.M22 > matrix.M33)
			{
				float num5 = MathF.Sqrt(1f + matrix.M22 - matrix.M11 - matrix.M33);
				float num6 = 0.5f / num5;
				result.X = (matrix.M21 + matrix.M12) * num6;
				result.Y = 0.5f * num5;
				result.Z = (matrix.M32 + matrix.M23) * num6;
				result.W = (matrix.M31 - matrix.M13) * num6;
			}
			else
			{
				float num7 = MathF.Sqrt(1f + matrix.M33 - matrix.M11 - matrix.M22);
				float num8 = 0.5f / num7;
				result.X = (matrix.M31 + matrix.M13) * num8;
				result.Y = (matrix.M32 + matrix.M23) * num8;
				result.Z = 0.5f * num7;
				result.W = (matrix.M12 - matrix.M21) * num8;
			}
			return result;
		}

		public static float Dot(Quaternion quaternion1, Quaternion quaternion2)
		{
			return quaternion1.X * quaternion2.X + quaternion1.Y * quaternion2.Y + quaternion1.Z * quaternion2.Z + quaternion1.W * quaternion2.W;
		}

		public static Quaternion Slerp(Quaternion quaternion1, Quaternion quaternion2, float amount)
		{
			float num = quaternion1.X * quaternion2.X + quaternion1.Y * quaternion2.Y + quaternion1.Z * quaternion2.Z + quaternion1.W * quaternion2.W;
			bool flag = false;
			if (num < 0f)
			{
				flag = true;
				num = 0f - num;
			}
			float num2;
			float num3;
			if (num > 0.999999f)
			{
				num2 = 1f - amount;
				num3 = (flag ? (0f - amount) : amount);
			}
			else
			{
				float num4 = MathF.Acos(num);
				float num5 = 1f / MathF.Sin(num4);
				num2 = MathF.Sin((1f - amount) * num4) * num5;
				num3 = (flag ? ((0f - MathF.Sin(amount * num4)) * num5) : (MathF.Sin(amount * num4) * num5));
			}
			Quaternion result = default(Quaternion);
			result.X = num2 * quaternion1.X + num3 * quaternion2.X;
			result.Y = num2 * quaternion1.Y + num3 * quaternion2.Y;
			result.Z = num2 * quaternion1.Z + num3 * quaternion2.Z;
			result.W = num2 * quaternion1.W + num3 * quaternion2.W;
			return result;
		}

		public static Quaternion Lerp(Quaternion quaternion1, Quaternion quaternion2, float amount)
		{
			float num = 1f - amount;
			Quaternion result = default(Quaternion);
			if (quaternion1.X * quaternion2.X + quaternion1.Y * quaternion2.Y + quaternion1.Z * quaternion2.Z + quaternion1.W * quaternion2.W >= 0f)
			{
				result.X = num * quaternion1.X + amount * quaternion2.X;
				result.Y = num * quaternion1.Y + amount * quaternion2.Y;
				result.Z = num * quaternion1.Z + amount * quaternion2.Z;
				result.W = num * quaternion1.W + amount * quaternion2.W;
			}
			else
			{
				result.X = num * quaternion1.X - amount * quaternion2.X;
				result.Y = num * quaternion1.Y - amount * quaternion2.Y;
				result.Z = num * quaternion1.Z - amount * quaternion2.Z;
				result.W = num * quaternion1.W - amount * quaternion2.W;
			}
			float num2 = result.X * result.X + result.Y * result.Y + result.Z * result.Z + result.W * result.W;
			float num3 = 1f / MathF.Sqrt(num2);
			result.X *= num3;
			result.Y *= num3;
			result.Z *= num3;
			result.W *= num3;
			return result;
		}

		public static Quaternion Concatenate(Quaternion value1, Quaternion value2)
		{
			float x = value2.X;
			float y = value2.Y;
			float z = value2.Z;
			float w = value2.W;
			float x2 = value1.X;
			float y2 = value1.Y;
			float z2 = value1.Z;
			float w2 = value1.W;
			float num = y * z2 - z * y2;
			float num2 = z * x2 - x * z2;
			float num3 = x * y2 - y * x2;
			float num4 = x * x2 + y * y2 + z * z2;
			Quaternion result = default(Quaternion);
			result.X = x * w2 + x2 * w + num;
			result.Y = y * w2 + y2 * w + num2;
			result.Z = z * w2 + z2 * w + num3;
			result.W = w * w2 - num4;
			return result;
		}

		public static Quaternion Negate(Quaternion value)
		{
			Quaternion result = default(Quaternion);
			result.X = 0f - value.X;
			result.Y = 0f - value.Y;
			result.Z = 0f - value.Z;
			result.W = 0f - value.W;
			return result;
		}

		public static Quaternion Add(Quaternion value1, Quaternion value2)
		{
			Quaternion result = default(Quaternion);
			result.X = value1.X + value2.X;
			result.Y = value1.Y + value2.Y;
			result.Z = value1.Z + value2.Z;
			result.W = value1.W + value2.W;
			return result;
		}

		public static Quaternion Subtract(Quaternion value1, Quaternion value2)
		{
			Quaternion result = default(Quaternion);
			result.X = value1.X - value2.X;
			result.Y = value1.Y - value2.Y;
			result.Z = value1.Z - value2.Z;
			result.W = value1.W - value2.W;
			return result;
		}

		public static Quaternion Multiply(Quaternion value1, Quaternion value2)
		{
			float x = value1.X;
			float y = value1.Y;
			float z = value1.Z;
			float w = value1.W;
			float x2 = value2.X;
			float y2 = value2.Y;
			float z2 = value2.Z;
			float w2 = value2.W;
			float num = y * z2 - z * y2;
			float num2 = z * x2 - x * z2;
			float num3 = x * y2 - y * x2;
			float num4 = x * x2 + y * y2 + z * z2;
			Quaternion result = default(Quaternion);
			result.X = x * w2 + x2 * w + num;
			result.Y = y * w2 + y2 * w + num2;
			result.Z = z * w2 + z2 * w + num3;
			result.W = w * w2 - num4;
			return result;
		}

		public static Quaternion Multiply(Quaternion value1, float value2)
		{
			Quaternion result = default(Quaternion);
			result.X = value1.X * value2;
			result.Y = value1.Y * value2;
			result.Z = value1.Z * value2;
			result.W = value1.W * value2;
			return result;
		}

		public static Quaternion Divide(Quaternion value1, Quaternion value2)
		{
			float x = value1.X;
			float y = value1.Y;
			float z = value1.Z;
			float w = value1.W;
			float num = value2.X * value2.X + value2.Y * value2.Y + value2.Z * value2.Z + value2.W * value2.W;
			float num2 = 1f / num;
			float num3 = (0f - value2.X) * num2;
			float num4 = (0f - value2.Y) * num2;
			float num5 = (0f - value2.Z) * num2;
			float num6 = value2.W * num2;
			float num7 = y * num5 - z * num4;
			float num8 = z * num3 - x * num5;
			float num9 = x * num4 - y * num3;
			float num10 = x * num3 + y * num4 + z * num5;
			Quaternion result = default(Quaternion);
			result.X = x * num6 + num3 * w + num7;
			result.Y = y * num6 + num4 * w + num8;
			result.Z = z * num6 + num5 * w + num9;
			result.W = w * num6 - num10;
			return result;
		}

		public static Quaternion operator -(Quaternion value)
		{
			Quaternion result = default(Quaternion);
			result.X = 0f - value.X;
			result.Y = 0f - value.Y;
			result.Z = 0f - value.Z;
			result.W = 0f - value.W;
			return result;
		}

		public static Quaternion operator +(Quaternion value1, Quaternion value2)
		{
			Quaternion result = default(Quaternion);
			result.X = value1.X + value2.X;
			result.Y = value1.Y + value2.Y;
			result.Z = value1.Z + value2.Z;
			result.W = value1.W + value2.W;
			return result;
		}

		public static Quaternion operator -(Quaternion value1, Quaternion value2)
		{
			Quaternion result = default(Quaternion);
			result.X = value1.X - value2.X;
			result.Y = value1.Y - value2.Y;
			result.Z = value1.Z - value2.Z;
			result.W = value1.W - value2.W;
			return result;
		}

		public static Quaternion operator *(Quaternion value1, Quaternion value2)
		{
			float x = value1.X;
			float y = value1.Y;
			float z = value1.Z;
			float w = value1.W;
			float x2 = value2.X;
			float y2 = value2.Y;
			float z2 = value2.Z;
			float w2 = value2.W;
			float num = y * z2 - z * y2;
			float num2 = z * x2 - x * z2;
			float num3 = x * y2 - y * x2;
			float num4 = x * x2 + y * y2 + z * z2;
			Quaternion result = default(Quaternion);
			result.X = x * w2 + x2 * w + num;
			result.Y = y * w2 + y2 * w + num2;
			result.Z = z * w2 + z2 * w + num3;
			result.W = w * w2 - num4;
			return result;
		}

		public static Quaternion operator *(Quaternion value1, float value2)
		{
			Quaternion result = default(Quaternion);
			result.X = value1.X * value2;
			result.Y = value1.Y * value2;
			result.Z = value1.Z * value2;
			result.W = value1.W * value2;
			return result;
		}

		public static Quaternion operator /(Quaternion value1, Quaternion value2)
		{
			float x = value1.X;
			float y = value1.Y;
			float z = value1.Z;
			float w = value1.W;
			float num = value2.X * value2.X + value2.Y * value2.Y + value2.Z * value2.Z + value2.W * value2.W;
			float num2 = 1f / num;
			float num3 = (0f - value2.X) * num2;
			float num4 = (0f - value2.Y) * num2;
			float num5 = (0f - value2.Z) * num2;
			float num6 = value2.W * num2;
			float num7 = y * num5 - z * num4;
			float num8 = z * num3 - x * num5;
			float num9 = x * num4 - y * num3;
			float num10 = x * num3 + y * num4 + z * num5;
			Quaternion result = default(Quaternion);
			result.X = x * num6 + num3 * w + num7;
			result.Y = y * num6 + num4 * w + num8;
			result.Z = z * num6 + num5 * w + num9;
			result.W = w * num6 - num10;
			return result;
		}

		public static bool operator ==(Quaternion value1, Quaternion value2)
		{
			if (value1.X == value2.X && value1.Y == value2.Y && value1.Z == value2.Z)
			{
				return value1.W == value2.W;
			}
			return false;
		}

		public static bool operator !=(Quaternion value1, Quaternion value2)
		{
			if (value1.X == value2.X && value1.Y == value2.Y && value1.Z == value2.Z)
			{
				return value1.W != value2.W;
			}
			return true;
		}

		public bool Equals(Quaternion other)
		{
			if (X == other.X && Y == other.Y && Z == other.Z)
			{
				return W == other.W;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is Quaternion)
			{
				return Equals((Quaternion)obj);
			}
			return false;
		}

		public override string ToString()
		{
			CultureInfo currentCulture = CultureInfo.CurrentCulture;
			return string.Format(currentCulture, "{{X:{0} Y:{1} Z:{2} W:{3}}}", X.ToString(currentCulture), Y.ToString(currentCulture), Z.ToString(currentCulture), W.ToString(currentCulture));
		}

		public override int GetHashCode()
		{
			return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode();
		}
	}
	public struct Vector2 : IEquatable<Vector2>, IFormattable
	{
		public float X;

		public float Y;

		public static Vector2 Zero => default(Vector2);

		public static Vector2 One => new Vector2(1f, 1f);

		public static Vector2 UnitX => new Vector2(1f, 0f);

		public static Vector2 UnitY => new Vector2(0f, 1f);

		public override int GetHashCode()
		{
			return HashHelpers.Combine(X.GetHashCode(), Y.GetHashCode());
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public override bool Equals(object obj)
		{
			if (!(obj is Vector2))
			{
				return false;
			}
			return Equals((Vector2)obj);
		}

		public override string ToString()
		{
			return ToString("G", CultureInfo.CurrentCulture);
		}

		public string ToString(string format)
		{
			return ToString(format, CultureInfo.CurrentCulture);
		}

		public string ToString(string format, IFormatProvider formatProvider)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string numberGroupSeparator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator;
			stringBuilder.Append('<');
			stringBuilder.Append(X.ToString(format, formatProvider));
			stringBuilder.Append(numberGroupSeparator);
			stringBuilder.Append(' ');
			stringBuilder.Append(Y.ToString(format, formatProvider));
			stringBuilder.Append('>');
			return stringBuilder.ToString();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public float Length()
		{
			if (Vector.IsHardwareAccelerated)
			{
				return MathF.Sqrt(Dot(this, this));
			}
			return MathF.Sqrt(X * X + Y * Y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public float LengthSquared()
		{
			if (Vector.IsHardwareAccelerated)
			{
				return Dot(this, this);
			}
			return X * X + Y * Y;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Distance(Vector2 value1, Vector2 value2)
		{
			if (Vector.IsHardwareAccelerated)
			{
				Vector2 vector = value1 - value2;
				return MathF.Sqrt(Dot(vector, vector));
			}
			float num = value1.X - value2.X;
			float num2 = value1.Y - value2.Y;
			return MathF.Sqrt(num * num + num2 * num2);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float DistanceSquared(Vector2 value1, Vector2 value2)
		{
			if (Vector.IsHardwareAccelerated)
			{
				Vector2 vector = value1 - value2;
				return Dot(vector, vector);
			}
			float num = value1.X - value2.X;
			float num2 = value1.Y - value2.Y;
			return num * num + num2 * num2;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Normalize(Vector2 value)
		{
			if (Vector.IsHardwareAccelerated)
			{
				float num = value.Length();
				return value / num;
			}
			float num2 = value.X * value.X + value.Y * value.Y;
			float num3 = 1f / MathF.Sqrt(num2);
			return new Vector2(value.X * num3, value.Y * num3);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Reflect(Vector2 vector, Vector2 normal)
		{
			if (Vector.IsHardwareAccelerated)
			{
				float num = Dot(vector, normal);
				return vector - 2f * num * normal;
			}
			float num2 = vector.X * normal.X + vector.Y * normal.Y;
			return new Vector2(vector.X - 2f * num2 * normal.X, vector.Y - 2f * num2 * normal.Y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Clamp(Vector2 value1, Vector2 min, Vector2 max)
		{
			float x = value1.X;
			x = ((x > max.X) ? max.X : x);
			x = ((x < min.X) ? min.X : x);
			float y = value1.Y;
			y = ((y > max.Y) ? max.Y : y);
			y = ((y < min.Y) ? min.Y : y);
			return new Vector2(x, y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Lerp(Vector2 value1, Vector2 value2, float amount)
		{
			return new Vector2(value1.X + (value2.X - value1.X) * amount, value1.Y + (value2.Y - value1.Y) * amount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Transform(Vector2 position, Matrix3x2 matrix)
		{
			return new Vector2(position.X * matrix.M11 + position.Y * matrix.M21 + matrix.M31, position.X * matrix.M12 + position.Y * matrix.M22 + matrix.M32);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Transform(Vector2 position, Matrix4x4 matrix)
		{
			return new Vector2(position.X * matrix.M11 + position.Y * matrix.M21 + matrix.M41, position.X * matrix.M12 + position.Y * matrix.M22 + matrix.M42);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 TransformNormal(Vector2 normal, Matrix3x2 matrix)
		{
			return new Vector2(normal.X * matrix.M11 + normal.Y * matrix.M21, normal.X * matrix.M12 + normal.Y * matrix.M22);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 TransformNormal(Vector2 normal, Matrix4x4 matrix)
		{
			return new Vector2(normal.X * matrix.M11 + normal.Y * matrix.M21, normal.X * matrix.M12 + normal.Y * matrix.M22);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Transform(Vector2 value, Quaternion rotation)
		{
			float num = rotation.X + rotation.X;
			float num2 = rotation.Y + rotation.Y;
			float num3 = rotation.Z + rotation.Z;
			float num4 = rotation.W * num3;
			float num5 = rotation.X * num;
			float num6 = rotation.X * num2;
			float num7 = rotation.Y * num2;
			float num8 = rotation.Z * num3;
			return new Vector2(value.X * (1f - num7 - num8) + value.Y * (num6 - num4), value.X * (num6 + num4) + value.Y * (1f - num5 - num8));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Add(Vector2 left, Vector2 right)
		{
			return left + right;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Subtract(Vector2 left, Vector2 right)
		{
			return left - right;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Multiply(Vector2 left, Vector2 right)
		{
			return left * right;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Multiply(Vector2 left, float right)
		{
			return left * right;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Multiply(float left, Vector2 right)
		{
			return left * right;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Divide(Vector2 left, Vector2 right)
		{
			return left / right;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Divide(Vector2 left, float divisor)
		{
			return left / divisor;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 Negate(Vector2 value)
		{
			return -value;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public Vector2(float value)
			: this(value, value)
		{
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public Vector2(float x, float y)
		{
			X = x;
			Y = y;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public void CopyTo(float[] array)
		{
			CopyTo(array, 0);
		}

		public void CopyTo(float[] array, int index)
		{
			if (array == null)
			{
				throw new NullReferenceException("The method was called with a null array argument.");
			}
			if (index < 0 || index >= array.Length)
			{
				throw new ArgumentOutOfRangeException("index", SR.Format("Index was out of bounds:", index));
			}
			if (array.Length - index < 2)
			{
				throw new ArgumentException(SR.Format("Number of elements in source vector is greater than the destination array", index));
			}
			array[index] = X;
			array[index + 1] = Y;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public bool Equals(Vector2 other)
		{
			if (X == other.X)
			{
				return Y == other.Y;
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static float Dot(Vector2 value1, Vector2 value2)
		{
			return value1.X * value2.X + value1.Y * value2.Y;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static Vector2 Min(Vector2 value1, Vector2 value2)
		{
			return new Vector2((value1.X < value2.X) ? value1.X : value2.X, (value1.Y < value2.Y) ? value1.Y : value2.Y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static Vector2 Max(Vector2 value1, Vector2 value2)
		{
			return new Vector2((value1.X > value2.X) ? value1.X : value2.X, (value1.Y > value2.Y) ? value1.Y : value2.Y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static Vector2 Abs(Vector2 value)
		{
			return new Vector2(MathF.Abs(value.X), MathF.Abs(value.Y));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static Vector2 SquareRoot(Vector2 value)
		{
			return new Vector2(MathF.Sqrt(value.X), MathF.Sqrt(value.Y));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static Vector2 operator +(Vector2 left, Vector2 right)
		{
			return new Vector2(left.X + right.X, left.Y + right.Y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static Vector2 operator -(Vector2 left, Vector2 right)
		{
			return new Vector2(left.X - right.X, left.Y - right.Y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static Vector2 operator *(Vector2 left, Vector2 right)
		{
			return new Vector2(left.X * right.X, left.Y * right.Y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static Vector2 operator *(float left, Vector2 right)
		{
			return new Vector2(left, left) * right;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static Vector2 operator *(Vector2 left, float right)
		{
			return left * new Vector2(right, right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static Vector2 operator /(Vector2 left, Vector2 right)
		{
			return new Vector2(left.X / right.X, left.Y / right.Y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 operator /(Vector2 value1, float value2)
		{
			return value1 / new Vector2(value2);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector2 operator -(Vector2 value)
		{
			return Zero - value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator ==(Vector2 left, Vector2 right)
		{
			return left.Equals(right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator !=(Vector2 left, Vector2 right)
		{
			return !(left == right);
		}
	}
	public struct Vector3 : IEquatable<Vector3>, IFormattable
	{
		public float X;

		public float Y;

		public float Z;

		public static Vector3 Zero => default(Vector3);

		public static Vector3 One => new Vector3(1f, 1f, 1f);

		public static Vector3 UnitX => new Vector3(1f, 0f, 0f);

		public static Vector3 UnitY => new Vector3(0f, 1f, 0f);

		public static Vector3 UnitZ => new Vector3(0f, 0f, 1f);

		public override int GetHashCode()
		{
			return HashHelpers.Combine(HashHelpers.Combine(X.GetHashCode(), Y.GetHashCode()), Z.GetHashCode());
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public override bool Equals(object obj)
		{
			if (!(obj is Vector3))
			{
				return false;
			}
			return Equals((Vector3)obj);
		}

		public override string ToString()
		{
			return ToString("G", CultureInfo.CurrentCulture);
		}

		public string ToString(string format)
		{
			return ToString(format, CultureInfo.CurrentCulture);
		}

		public string ToString(string format, IFormatProvider formatProvider)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string numberGroupSeparator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator;
			stringBuilder.Append('<');
			stringBuilder.Append(((IFormattable)X).ToString(format, formatProvider));
			stringBuilder.Append(numberGroupSeparator);
			stringBuilder.Append(' ');
			stringBuilder.Append(((IFormattable)Y).ToString(format, formatProvider));
			stringBuilder.Append(numberGroupSeparator);
			stringBuilder.Append(' ');
			stringBuilder.Append(((IFormattable)Z).ToString(format, formatProvider));
			stringBuilder.Append('>');
			return stringBuilder.ToString();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public float Length()
		{
			if (Vector.IsHardwareAccelerated)
			{
				return MathF.Sqrt(Dot(this, this));
			}
			return MathF.Sqrt(X * X + Y * Y + Z * Z);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public float LengthSquared()
		{
			if (Vector.IsHardwareAccelerated)
			{
				return Dot(this, this);
			}
			return X * X + Y * Y + Z * Z;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Distance(Vector3 value1, Vector3 value2)
		{
			if (Vector.IsHardwareAccelerated)
			{
				Vector3 vector = value1 - value2;
				return MathF.Sqrt(Dot(vector, vector));
			}
			float num = value1.X - value2.X;
			float num2 = value1.Y - value2.Y;
			float num3 = value1.Z - value2.Z;
			return MathF.Sqrt(num * num + num2 * num2 + num3 * num3);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float DistanceSquared(Vector3 value1, Vector3 value2)
		{
			if (Vector.IsHardwareAccelerated)
			{
				Vector3 vector = value1 - value2;
				return Dot(vector, vector);
			}
			float num = value1.X - value2.X;
			float num2 = value1.Y - value2.Y;
			float num3 = value1.Z - value2.Z;
			return num * num + num2 * num2 + num3 * num3;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector3 Normalize(Vector3 value)
		{
			if (Vector.IsHardwareAccelerated)
			{
				float num = value.Length();
				return value / num;
			}
			float num2 = MathF.Sqrt(value.X * value.X + value.Y * value.Y + value.Z * value.Z);
			return new Vector3(value.X / num2, value.Y / num2, value.Z / num2);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector3 Cross(Vector3 vector1, Vector3 vector2)
		{
			return new Vector3(vector1.Y * vector2.Z - vector1.Z * vector2.Y, vector1.Z * vector2.X - vector1.X * vector2.Z, vector1.X * vector2.Y - vector1.Y * vector2.X);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector3 Reflect(Vector3 vector, Vector3 normal)
		{
			if (Vector.IsHardwareAccelerated)
			{
				float num = Dot(vector, normal);
				Vector3 vector2 = normal * num * 2f;
				return vector - vector2;
			}
			float num2 = vector.X * normal.X + vector.Y * normal.Y + vector.Z * normal.Z;
			float num3 = normal.X * num2 * 2f;
			float num4 = normal.Y * num2 * 2f;
			float num5 = normal.Z * num2 * 2f;
			return new Vector3(vector.X - num3, vector.Y - num4, vector.Z - num5);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector3 Clamp(Vector3 value1, Vector3 min, Vector3 max)
		{
			float x = value1.X;
			x = ((x > max.X) ? max.X : x);
			x = ((x < min.X) ? min.X : x);
			float y = value1.Y;
			y = ((y > max.Y) ? max.Y : y);
			y = ((y < min.Y) ? min.Y : y);
			float z = value1.Z;
			z = ((z > max.Z) ? max.Z : z);
			z = ((z < min.Z) ? min.Z : z);
			return new Vector3(x, y, z);
		}

		[MethodImpl(MethodImplOption

System.Runtime.Serialization.dll

Decompiled 3 weeks ago
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Configuration;
using System.Runtime.Serialization.Diagnostics;
using System.Runtime.Serialization.Diagnostics.Application;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Json;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Xml.XPath;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("System.Runtime.Serialization.dll")]
[assembly: AssemblyDescription("System.Runtime.Serialization.dll")]
[assembly: AssemblyDefaultAlias("System.Runtime.Serialization.dll")]
[assembly: AssemblyCompany("Mono development team")]
[assembly: AssemblyProduct("Mono Common Language Infrastructure")]
[assembly: AssemblyCopyright("(c) Various Mono authors")]
[assembly: SatelliteContractVersion("4.0.0.0")]
[assembly: AssemblyInformationalVersion("4.6.57.0")]
[assembly: AssemblyFileVersion("4.6.57.0")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyDelaySign(true)]
[assembly: AssemblyKeyFile("../ecma.pub")]
[assembly: AllowPartiallyTrustedCallers]
[assembly: ComCompatibleVersion(1, 0, 3300, 0)]
[assembly: SecurityCritical(SecurityCriticalScope.Explicit)]
[assembly: ComVisible(false)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.0.0")]
[module: UnverifiableCode]
internal static class SR
{
	internal static string GetString(string name, params object[] args)
	{
		return GetString(CultureInfo.InvariantCulture, name, args);
	}

	internal static string GetString(CultureInfo culture, string name, params object[] args)
	{
		return string.Format(culture, name, args);
	}

	internal static string GetString(string name)
	{
		return name;
	}

	internal static string GetString(CultureInfo culture, string name)
	{
		return name;
	}

	internal static string Format(string resourceFormat, params object[] args)
	{
		if (args != null)
		{
			return string.Format(CultureInfo.InvariantCulture, resourceFormat, args);
		}
		return resourceFormat;
	}

	internal static string Format(string resourceFormat, object p1)
	{
		return string.Format(CultureInfo.InvariantCulture, resourceFormat, p1);
	}

	internal static string Format(string resourceFormat, object p1, object p2)
	{
		return string.Format(CultureInfo.InvariantCulture, resourceFormat, p1, p2);
	}

	internal static string Format(CultureInfo ci, string resourceFormat, object p1, object p2)
	{
		return string.Format(ci, resourceFormat, p1, p2);
	}

	internal static string Format(string resourceFormat, object p1, object p2, object p3)
	{
		return string.Format(CultureInfo.InvariantCulture, resourceFormat, p1, p2, p3);
	}

	internal static string GetResourceString(string str)
	{
		return str;
	}
}
namespace System
{
	internal static class LocalAppContextSwitches
	{
		public static readonly bool DoNotUseTimeZoneInfo;

		public static readonly bool DoNotUseEcmaScriptV6EscapeControlCharacter;
	}
	internal static class NotImplemented
	{
		internal static Exception ByDesign => new NotImplementedException();

		internal static Exception ByDesignWithMessage(string message)
		{
			return new NotImplementedException(message);
		}
	}
}
namespace System.Xml
{
	internal abstract class ArrayHelper<TArgument, TArray>
	{
		public TArray[] ReadArray(XmlDictionaryReader reader, TArgument localName, TArgument namespaceUri, int maxArrayLength)
		{
			TArray[][] array = null;
			TArray[] array2 = null;
			int num = 0;
			int num2 = 0;
			if (reader.TryGetArrayLength(out var count))
			{
				if (count > maxArrayLength)
				{
					XmlExceptionHelper.ThrowMaxArrayLengthOrMaxItemsQuotaExceeded(reader, maxArrayLength);
				}
				if (count > 65535)
				{
					count = 65535;
				}
			}
			else
			{
				count = 32;
			}
			while (true)
			{
				array2 = new TArray[count];
				int i;
				int num3;
				for (i = 0; i < array2.Length; i += num3)
				{
					num3 = ReadArray(reader, localName, namespaceUri, array2, i, array2.Length - i);
					if (num3 == 0)
					{
						break;
					}
				}
				if (num2 > maxArrayLength - i)
				{
					XmlExceptionHelper.ThrowMaxArrayLengthOrMaxItemsQuotaExceeded(reader, maxArrayLength);
				}
				num2 += i;
				if (i < array2.Length || reader.NodeType == XmlNodeType.EndElement)
				{
					break;
				}
				if (array == null)
				{
					array = new TArray[32][];
				}
				array[num++] = array2;
				count *= 2;
			}
			if (num2 != array2.Length || num > 0)
			{
				TArray[] array3 = new TArray[num2];
				int num4 = 0;
				for (int j = 0; j < num; j++)
				{
					Array.Copy(array[j], 0, array3, num4, array[j].Length);
					num4 += array[j].Length;
				}
				Array.Copy(array2, 0, array3, num4, num2 - num4);
				array2 = array3;
			}
			return array2;
		}

		public void WriteArray(XmlDictionaryWriter writer, string prefix, TArgument localName, TArgument namespaceUri, XmlDictionaryReader reader)
		{
			int count = ((!reader.TryGetArrayLength(out count)) ? 256 : Math.Min(count, 256));
			TArray[] array = new TArray[count];
			while (true)
			{
				int num = ReadArray(reader, localName, namespaceUri, array, 0, array.Length);
				if (num != 0)
				{
					WriteArray(writer, prefix, localName, namespaceUri, array, 0, num);
					continue;
				}
				break;
			}
		}

		protected abstract int ReadArray(XmlDictionaryReader reader, TArgument localName, TArgument namespaceUri, TArray[] array, int offset, int count);

		protected abstract void WriteArray(XmlDictionaryWriter writer, string prefix, TArgument localName, TArgument namespaceUri, TArray[] array, int offset, int count);
	}
	internal class BooleanArrayHelperWithString : ArrayHelper<string, bool>
	{
		public static readonly BooleanArrayHelperWithString Instance = new BooleanArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, bool[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, bool[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class BooleanArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, bool>
	{
		public static readonly BooleanArrayHelperWithDictionaryString Instance = new BooleanArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, bool[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, bool[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class Int16ArrayHelperWithString : ArrayHelper<string, short>
	{
		public static readonly Int16ArrayHelperWithString Instance = new Int16ArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, short[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, short[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class Int16ArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, short>
	{
		public static readonly Int16ArrayHelperWithDictionaryString Instance = new Int16ArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, short[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, short[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class Int32ArrayHelperWithString : ArrayHelper<string, int>
	{
		public static readonly Int32ArrayHelperWithString Instance = new Int32ArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, int[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, int[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class Int32ArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, int>
	{
		public static readonly Int32ArrayHelperWithDictionaryString Instance = new Int32ArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, int[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, int[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class Int64ArrayHelperWithString : ArrayHelper<string, long>
	{
		public static readonly Int64ArrayHelperWithString Instance = new Int64ArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, long[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, long[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class Int64ArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, long>
	{
		public static readonly Int64ArrayHelperWithDictionaryString Instance = new Int64ArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, long[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, long[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class SingleArrayHelperWithString : ArrayHelper<string, float>
	{
		public static readonly SingleArrayHelperWithString Instance = new SingleArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, float[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, float[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class SingleArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, float>
	{
		public static readonly SingleArrayHelperWithDictionaryString Instance = new SingleArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, float[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, float[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class DoubleArrayHelperWithString : ArrayHelper<string, double>
	{
		public static readonly DoubleArrayHelperWithString Instance = new DoubleArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, double[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, double[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class DoubleArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, double>
	{
		public static readonly DoubleArrayHelperWithDictionaryString Instance = new DoubleArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, double[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, double[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class DecimalArrayHelperWithString : ArrayHelper<string, decimal>
	{
		public static readonly DecimalArrayHelperWithString Instance = new DecimalArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, decimal[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, decimal[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class DecimalArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, decimal>
	{
		public static readonly DecimalArrayHelperWithDictionaryString Instance = new DecimalArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, decimal[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, decimal[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class DateTimeArrayHelperWithString : ArrayHelper<string, DateTime>
	{
		public static readonly DateTimeArrayHelperWithString Instance = new DateTimeArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, DateTime[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, DateTime[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class DateTimeArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, DateTime>
	{
		public static readonly DateTimeArrayHelperWithDictionaryString Instance = new DateTimeArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, DateTime[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, DateTime[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class GuidArrayHelperWithString : ArrayHelper<string, Guid>
	{
		public static readonly GuidArrayHelperWithString Instance = new GuidArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, Guid[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, Guid[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class GuidArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, Guid>
	{
		public static readonly GuidArrayHelperWithDictionaryString Instance = new GuidArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Guid[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Guid[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class TimeSpanArrayHelperWithString : ArrayHelper<string, TimeSpan>
	{
		public static readonly TimeSpanArrayHelperWithString Instance = new TimeSpanArrayHelperWithString();

		protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, TimeSpan[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, TimeSpan[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class TimeSpanArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, TimeSpan>
	{
		public static readonly TimeSpanArrayHelperWithDictionaryString Instance = new TimeSpanArrayHelperWithDictionaryString();

		protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, TimeSpan[] array, int offset, int count)
		{
			return reader.ReadArray(localName, namespaceUri, array, offset, count);
		}

		protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, TimeSpan[] array, int offset, int count)
		{
			writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
		}
	}
	internal class EncodingStreamWrapper : Stream
	{
		private enum SupportedEncoding
		{
			UTF8,
			UTF16LE,
			UTF16BE,
			None
		}

		private static readonly UTF8Encoding SafeUTF8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: false);

		private static readonly UnicodeEncoding SafeUTF16 = new UnicodeEncoding(bigEndian: false, byteOrderMark: false, throwOnInvalidBytes: false);

		private static readonly UnicodeEncoding SafeBEUTF16 = new UnicodeEncoding(bigEndian: true, byteOrderMark: false, throwOnInvalidBytes: false);

		private static readonly UTF8Encoding ValidatingUTF8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);

		private static readonly UnicodeEncoding ValidatingUTF16 = new UnicodeEncoding(bigEndian: false, byteOrderMark: false, throwOnInvalidBytes: true);

		private static readonly UnicodeEncoding ValidatingBEUTF16 = new UnicodeEncoding(bigEndian: true, byteOrderMark: false, throwOnInvalidBytes: true);

		private const int BufferLength = 128;

		private static readonly byte[] encodingAttr = new byte[8] { 101, 110, 99, 111, 100, 105, 110, 103 };

		private static readonly byte[] encodingUTF8 = new byte[5] { 117, 116, 102, 45, 56 };

		private static readonly byte[] encodingUnicode = new byte[6] { 117, 116, 102, 45, 49, 54 };

		private static readonly byte[] encodingUnicodeLE = new byte[8] { 117, 116, 102, 45, 49, 54, 108, 101 };

		private static readonly byte[] encodingUnicodeBE = new byte[8] { 117, 116, 102, 45, 49, 54, 98, 101 };

		private SupportedEncoding encodingCode;

		private Encoding encoding;

		private Encoder enc;

		private Decoder dec;

		private bool isReading;

		private Stream stream;

		private char[] chars;

		private byte[] bytes;

		private int byteOffset;

		private int byteCount;

		private byte[] byteBuffer = new byte[1];

		public override bool CanRead
		{
			get
			{
				if (!isReading)
				{
					return false;
				}
				return stream.CanRead;
			}
		}

		public override bool CanSeek => false;

		public override bool CanWrite
		{
			get
			{
				if (isReading)
				{
					return false;
				}
				return stream.CanWrite;
			}
		}

		public override long Position
		{
			get
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
			}
			set
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
			}
		}

		public override bool CanTimeout => stream.CanTimeout;

		public override long Length => stream.Length;

		public override int ReadTimeout
		{
			get
			{
				return stream.ReadTimeout;
			}
			set
			{
				stream.ReadTimeout = value;
			}
		}

		public override int WriteTimeout
		{
			get
			{
				return stream.WriteTimeout;
			}
			set
			{
				stream.WriteTimeout = value;
			}
		}

		public EncodingStreamWrapper(Stream stream, Encoding encoding)
		{
			try
			{
				isReading = true;
				this.stream = new BufferedStream(stream);
				SupportedEncoding supportedEncoding = GetSupportedEncoding(encoding);
				SupportedEncoding supportedEncoding2 = ReadBOMEncoding(encoding == null);
				if (supportedEncoding != SupportedEncoding.None && supportedEncoding != supportedEncoding2)
				{
					ThrowExpectedEncodingMismatch(supportedEncoding, supportedEncoding2);
				}
				if (supportedEncoding2 == SupportedEncoding.UTF8)
				{
					FillBuffer(2);
					if (bytes[byteOffset + 1] == 63 && bytes[byteOffset] == 60)
					{
						FillBuffer(128);
						CheckUTF8DeclarationEncoding(bytes, byteOffset, byteCount, supportedEncoding2, supportedEncoding);
					}
					return;
				}
				EnsureBuffers();
				FillBuffer(254);
				SetReadDocumentEncoding(supportedEncoding2);
				CleanupCharBreak();
				int charCount = this.encoding.GetChars(bytes, byteOffset, byteCount, chars, 0);
				byteOffset = 0;
				byteCount = ValidatingUTF8.GetBytes(chars, 0, charCount, bytes, 0);
				if (bytes[1] == 63 && bytes[0] == 60)
				{
					CheckUTF8DeclarationEncoding(bytes, 0, byteCount, supportedEncoding2, supportedEncoding);
				}
				else if (supportedEncoding == SupportedEncoding.None)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("An XML declaration with an encoding is required for all non-UTF8 documents.")));
				}
			}
			catch (DecoderFallbackException innerException)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Invalid byte encoding."), innerException));
			}
		}

		private void SetReadDocumentEncoding(SupportedEncoding e)
		{
			EnsureBuffers();
			encodingCode = e;
			encoding = GetEncoding(e);
		}

		private static Encoding GetEncoding(SupportedEncoding e)
		{
			return e switch
			{
				SupportedEncoding.UTF8 => ValidatingUTF8, 
				SupportedEncoding.UTF16LE => ValidatingUTF16, 
				SupportedEncoding.UTF16BE => ValidatingBEUTF16, 
				_ => throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("XML encoding not supported."))), 
			};
		}

		private static Encoding GetSafeEncoding(SupportedEncoding e)
		{
			return e switch
			{
				SupportedEncoding.UTF8 => SafeUTF8, 
				SupportedEncoding.UTF16LE => SafeUTF16, 
				SupportedEncoding.UTF16BE => SafeBEUTF16, 
				_ => throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("XML encoding not supported."))), 
			};
		}

		private static string GetEncodingName(SupportedEncoding enc)
		{
			return enc switch
			{
				SupportedEncoding.UTF8 => "utf-8", 
				SupportedEncoding.UTF16LE => "utf-16LE", 
				SupportedEncoding.UTF16BE => "utf-16BE", 
				_ => throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("XML encoding not supported."))), 
			};
		}

		private static SupportedEncoding GetSupportedEncoding(Encoding encoding)
		{
			if (encoding == null)
			{
				return SupportedEncoding.None;
			}
			if (encoding.WebName == ValidatingUTF8.WebName)
			{
				return SupportedEncoding.UTF8;
			}
			if (encoding.WebName == ValidatingUTF16.WebName)
			{
				return SupportedEncoding.UTF16LE;
			}
			if (encoding.WebName == ValidatingBEUTF16.WebName)
			{
				return SupportedEncoding.UTF16BE;
			}
			throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("XML encoding not supported.")));
		}

		public EncodingStreamWrapper(Stream stream, Encoding encoding, bool emitBOM)
		{
			isReading = false;
			this.encoding = encoding;
			this.stream = new BufferedStream(stream);
			encodingCode = GetSupportedEncoding(encoding);
			if (encodingCode == SupportedEncoding.UTF8)
			{
				return;
			}
			EnsureBuffers();
			dec = ValidatingUTF8.GetDecoder();
			enc = this.encoding.GetEncoder();
			if (emitBOM)
			{
				byte[] preamble = this.encoding.GetPreamble();
				if (preamble.Length != 0)
				{
					this.stream.Write(preamble, 0, preamble.Length);
				}
			}
		}

		private SupportedEncoding ReadBOMEncoding(bool notOutOfBand)
		{
			int num = stream.ReadByte();
			int num2 = stream.ReadByte();
			int num3 = stream.ReadByte();
			int num4 = stream.ReadByte();
			if (num4 == -1)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Unexpected end of file.")));
			}
			int preserve;
			SupportedEncoding result = ReadBOMEncoding((byte)num, (byte)num2, (byte)num3, (byte)num4, notOutOfBand, out preserve);
			EnsureByteBuffer();
			switch (preserve)
			{
			case 1:
				bytes[0] = (byte)num4;
				break;
			case 2:
				bytes[0] = (byte)num3;
				bytes[1] = (byte)num4;
				break;
			case 4:
				bytes[0] = (byte)num;
				bytes[1] = (byte)num2;
				bytes[2] = (byte)num3;
				bytes[3] = (byte)num4;
				break;
			}
			byteCount = preserve;
			return result;
		}

		private static SupportedEncoding ReadBOMEncoding(byte b1, byte b2, byte b3, byte b4, bool notOutOfBand, out int preserve)
		{
			SupportedEncoding result = SupportedEncoding.UTF8;
			preserve = 0;
			if (b1 == 60 && b2 != 0)
			{
				result = SupportedEncoding.UTF8;
				preserve = 4;
			}
			else if (b1 == byte.MaxValue && b2 == 254)
			{
				result = SupportedEncoding.UTF16LE;
				preserve = 2;
			}
			else if (b1 == 254 && b2 == byte.MaxValue)
			{
				result = SupportedEncoding.UTF16BE;
				preserve = 2;
			}
			else if (b1 == 0 && b2 == 60)
			{
				result = SupportedEncoding.UTF16BE;
				if (notOutOfBand && (b3 != 0 || b4 != 63))
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("An XML declaration is required for all non-UTF8 documents.")));
				}
				preserve = 4;
			}
			else if (b1 == 60 && b2 == 0)
			{
				result = SupportedEncoding.UTF16LE;
				if (notOutOfBand && (b3 != 63 || b4 != 0))
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("An XML declaration is required for all non-UTF8 documents.")));
				}
				preserve = 4;
			}
			else if (b1 == 239 && b2 == 187)
			{
				if (notOutOfBand && b3 != 191)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Unrecognized Byte Order Mark.")));
				}
				preserve = 1;
			}
			else
			{
				preserve = 4;
			}
			return result;
		}

		private void FillBuffer(int count)
		{
			count -= byteCount;
			while (count > 0)
			{
				int num = stream.Read(bytes, byteOffset + byteCount, count);
				if (num != 0)
				{
					byteCount += num;
					count -= num;
					continue;
				}
				break;
			}
		}

		private void EnsureBuffers()
		{
			EnsureByteBuffer();
			if (chars == null)
			{
				chars = new char[128];
			}
		}

		private void EnsureByteBuffer()
		{
			if (bytes == null)
			{
				bytes = new byte[512];
				byteOffset = 0;
				byteCount = 0;
			}
		}

		private static void CheckUTF8DeclarationEncoding(byte[] buffer, int offset, int count, SupportedEncoding e, SupportedEncoding expectedEnc)
		{
			byte b = 0;
			int num = -1;
			int num2 = offset + Math.Min(count, 128);
			int num3 = 0;
			int num4 = 0;
			for (num3 = offset + 2; num3 < num2; num3++)
			{
				if (b != 0)
				{
					if (buffer[num3] == b)
					{
						b = 0;
					}
				}
				else if (buffer[num3] == 39 || buffer[num3] == 34)
				{
					b = buffer[num3];
				}
				else if (buffer[num3] == 61)
				{
					if (num4 == 1)
					{
						num = num3;
						break;
					}
					num4++;
				}
				else if (buffer[num3] == 63)
				{
					break;
				}
			}
			if (num == -1)
			{
				if (e != 0 && expectedEnc == SupportedEncoding.None)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("An XML declaration with an encoding is required for all non-UTF8 documents.")));
				}
				return;
			}
			if (num < 28)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Malformed XML declaration.")));
			}
			num3 = num - 1;
			while (IsWhitespace(buffer[num3]))
			{
				num3--;
			}
			if (!Compare(encodingAttr, buffer, num3 - encodingAttr.Length + 1))
			{
				if (e == SupportedEncoding.UTF8 || expectedEnc != SupportedEncoding.None)
				{
					return;
				}
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("An XML declaration with an encoding is required for all non-UTF8 documents.")));
			}
			for (num3 = num + 1; num3 < num2 && IsWhitespace(buffer[num3]); num3++)
			{
			}
			if (buffer[num3] != 39 && buffer[num3] != 34)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Malformed XML declaration.")));
			}
			b = buffer[num3];
			int num5 = num3++;
			for (; buffer[num3] != b && num3 < num2; num3++)
			{
			}
			if (buffer[num3] != b)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Malformed XML declaration.")));
			}
			int num6 = num5 + 1;
			int num7 = num3 - num6;
			SupportedEncoding supportedEncoding = e;
			if (num7 == encodingUTF8.Length && CompareCaseInsensitive(encodingUTF8, buffer, num6))
			{
				supportedEncoding = SupportedEncoding.UTF8;
			}
			else if (num7 == encodingUnicodeLE.Length && CompareCaseInsensitive(encodingUnicodeLE, buffer, num6))
			{
				supportedEncoding = SupportedEncoding.UTF16LE;
			}
			else if (num7 == encodingUnicodeBE.Length && CompareCaseInsensitive(encodingUnicodeBE, buffer, num6))
			{
				supportedEncoding = SupportedEncoding.UTF16BE;
			}
			else if (num7 == encodingUnicode.Length && CompareCaseInsensitive(encodingUnicode, buffer, num6))
			{
				if (e == SupportedEncoding.UTF8)
				{
					ThrowEncodingMismatch(SafeUTF8.GetString(buffer, num6, num7), SafeUTF8.GetString(encodingUTF8, 0, encodingUTF8.Length));
				}
			}
			else
			{
				ThrowEncodingMismatch(SafeUTF8.GetString(buffer, num6, num7), e);
			}
			if (e != supportedEncoding)
			{
				ThrowEncodingMismatch(SafeUTF8.GetString(buffer, num6, num7), e);
			}
		}

		private static bool CompareCaseInsensitive(byte[] key, byte[] buffer, int offset)
		{
			for (int i = 0; i < key.Length; i++)
			{
				if (key[i] != buffer[offset + i] && key[i] != char.ToLower((char)buffer[offset + i], CultureInfo.InvariantCulture))
				{
					return false;
				}
			}
			return true;
		}

		private static bool Compare(byte[] key, byte[] buffer, int offset)
		{
			for (int i = 0; i < key.Length; i++)
			{
				if (key[i] != buffer[offset + i])
				{
					return false;
				}
			}
			return true;
		}

		private static bool IsWhitespace(byte ch)
		{
			if (ch != 32 && ch != 10 && ch != 9)
			{
				return ch == 13;
			}
			return true;
		}

		internal static ArraySegment<byte> ProcessBuffer(byte[] buffer, int offset, int count, Encoding encoding)
		{
			if (count < 4)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Unexpected end of file.")));
			}
			try
			{
				SupportedEncoding supportedEncoding = GetSupportedEncoding(encoding);
				int preserve;
				SupportedEncoding supportedEncoding2 = ReadBOMEncoding(buffer[offset], buffer[offset + 1], buffer[offset + 2], buffer[offset + 3], encoding == null, out preserve);
				if (supportedEncoding != SupportedEncoding.None && supportedEncoding != supportedEncoding2)
				{
					ThrowExpectedEncodingMismatch(supportedEncoding, supportedEncoding2);
				}
				offset += 4 - preserve;
				count -= 4 - preserve;
				if (supportedEncoding2 == SupportedEncoding.UTF8)
				{
					if (buffer[offset + 1] != 63 || buffer[offset] != 60)
					{
						return new ArraySegment<byte>(buffer, offset, count);
					}
					CheckUTF8DeclarationEncoding(buffer, offset, count, supportedEncoding2, supportedEncoding);
					return new ArraySegment<byte>(buffer, offset, count);
				}
				Encoding safeEncoding = GetSafeEncoding(supportedEncoding2);
				int num = Math.Min(count, 256);
				char[] array = new char[safeEncoding.GetMaxCharCount(num)];
				int charCount = safeEncoding.GetChars(buffer, offset, num, array, 0);
				byte[] array2 = new byte[ValidatingUTF8.GetMaxByteCount(charCount)];
				int count2 = ValidatingUTF8.GetBytes(array, 0, charCount, array2, 0);
				if (array2[1] == 63 && array2[0] == 60)
				{
					CheckUTF8DeclarationEncoding(array2, 0, count2, supportedEncoding2, supportedEncoding);
				}
				else if (supportedEncoding == SupportedEncoding.None)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("An XML declaration with an encoding is required for all non-UTF8 documents.")));
				}
				return new ArraySegment<byte>(ValidatingUTF8.GetBytes(GetEncoding(supportedEncoding2).GetChars(buffer, offset, count)));
			}
			catch (DecoderFallbackException innerException)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Invalid byte encoding."), innerException));
			}
		}

		private static void ThrowExpectedEncodingMismatch(SupportedEncoding expEnc, SupportedEncoding actualEnc)
		{
			throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("The expected encoding '{0}' does not match the actual encoding '{1}'.", GetEncodingName(expEnc), GetEncodingName(actualEnc))));
		}

		private static void ThrowEncodingMismatch(string declEnc, SupportedEncoding enc)
		{
			ThrowEncodingMismatch(declEnc, GetEncodingName(enc));
		}

		private static void ThrowEncodingMismatch(string declEnc, string docEnc)
		{
			throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("The encoding in the declaration '{0}' does not match the encoding of the document '{1}'.", declEnc, docEnc)));
		}

		public override void Close()
		{
			Flush();
			base.Close();
			stream.Close();
		}

		public override void Flush()
		{
			stream.Flush();
		}

		public override int ReadByte()
		{
			if (byteCount == 0 && encodingCode == SupportedEncoding.UTF8)
			{
				return stream.ReadByte();
			}
			if (Read(byteBuffer, 0, 1) == 0)
			{
				return -1;
			}
			return byteBuffer[0];
		}

		public override int Read(byte[] buffer, int offset, int count)
		{
			try
			{
				if (byteCount == 0)
				{
					if (encodingCode == SupportedEncoding.UTF8)
					{
						return stream.Read(buffer, offset, count);
					}
					byteOffset = 0;
					byteCount = stream.Read(bytes, byteCount, (chars.Length - 1) * 2);
					if (byteCount == 0)
					{
						return 0;
					}
					CleanupCharBreak();
					int charCount = encoding.GetChars(bytes, 0, byteCount, chars, 0);
					byteCount = Encoding.UTF8.GetBytes(chars, 0, charCount, bytes, 0);
				}
				if (byteCount < count)
				{
					count = byteCount;
				}
				Buffer.BlockCopy(bytes, byteOffset, buffer, offset, count);
				byteOffset += count;
				byteCount -= count;
				return count;
			}
			catch (DecoderFallbackException innerException)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Invalid byte encoding."), innerException));
			}
		}

		private void CleanupCharBreak()
		{
			int num = byteOffset + byteCount;
			if (byteCount % 2 != 0)
			{
				int num2 = stream.ReadByte();
				if (num2 < 0)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Unexpected end of file.")));
				}
				bytes[num++] = (byte)num2;
				byteCount++;
			}
			int num3 = ((encodingCode != SupportedEncoding.UTF16LE) ? (bytes[num - 1] + (bytes[num - 2] << 8)) : (bytes[num - 2] + (bytes[num - 1] << 8)));
			if ((num3 & 0xDC00) != 56320 && num3 >= 55296 && num3 <= 56319)
			{
				int num4 = stream.ReadByte();
				int num5 = stream.ReadByte();
				if (num5 < 0)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(System.Runtime.Serialization.SR.GetString("Unexpected end of file.")));
				}
				bytes[num++] = (byte)num4;
				bytes[num++] = (byte)num5;
				byteCount += 2;
			}
		}

		public override long Seek(long offset, SeekOrigin origin)
		{
			throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
		}

		public override void WriteByte(byte b)
		{
			if (encodingCode == SupportedEncoding.UTF8)
			{
				stream.WriteByte(b);
				return;
			}
			byteBuffer[0] = b;
			Write(byteBuffer, 0, 1);
		}

		public override void Write(byte[] buffer, int offset, int count)
		{
			if (encodingCode == SupportedEncoding.UTF8)
			{
				stream.Write(buffer, offset, count);
				return;
			}
			while (count > 0)
			{
				int num = ((chars.Length < count) ? chars.Length : count);
				int charCount = dec.GetChars(buffer, offset, num, chars, 0, flush: false);
				byteCount = enc.GetBytes(chars, 0, charCount, bytes, 0, flush: false);
				stream.Write(bytes, 0, byteCount);
				offset += num;
				count -= num;
			}
		}

		public override void SetLength(long value)
		{
			throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
		}
	}
	public interface IFragmentCapableXmlDictionaryWriter
	{
		bool CanFragment { get; }

		void StartFragment(Stream stream, bool generateSelfContainedTextFragment);

		void EndFragment();

		void WriteFragment(byte[] buffer, int offset, int count);
	}
	public interface IStreamProvider
	{
		Stream GetStream();

		void ReleaseStream(Stream stream);
	}
	public interface IXmlDictionary
	{
		bool TryLookup(string value, out XmlDictionaryString result);

		bool TryLookup(int key, out XmlDictionaryString result);

		bool TryLookup(XmlDictionaryString value, out XmlDictionaryString result);
	}
	internal enum PrefixHandleType
	{
		Empty,
		A,
		B,
		C,
		D,
		E,
		F,
		G,
		H,
		I,
		J,
		K,
		L,
		M,
		N,
		O,
		P,
		Q,
		R,
		S,
		T,
		U,
		V,
		W,
		X,
		Y,
		Z,
		Buffer,
		Max
	}
	internal class PrefixHandle
	{
		private XmlBufferReader bufferReader;

		private PrefixHandleType type;

		private int offset;

		private int length;

		private static string[] prefixStrings = new string[27]
		{
			"", "a", "b", "c", "d", "e", "f", "g", "h", "i",
			"j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
			"t", "u", "v", "w", "x", "y", "z"
		};

		private static byte[] prefixBuffer = new byte[26]
		{
			97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
			107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
			117, 118, 119, 120, 121, 122
		};

		public bool IsEmpty => type == PrefixHandleType.Empty;

		public bool IsXmlns
		{
			get
			{
				if (type != PrefixHandleType.Buffer)
				{
					return false;
				}
				if (length != 5)
				{
					return false;
				}
				byte[] buffer = bufferReader.Buffer;
				int num = offset;
				if (buffer[num] == 120 && buffer[num + 1] == 109 && buffer[num + 2] == 108 && buffer[num + 3] == 110)
				{
					return buffer[num + 4] == 115;
				}
				return false;
			}
		}

		public bool IsXml
		{
			get
			{
				if (type != PrefixHandleType.Buffer)
				{
					return false;
				}
				if (length != 3)
				{
					return false;
				}
				byte[] buffer = bufferReader.Buffer;
				int num = offset;
				if (buffer[num] == 120 && buffer[num + 1] == 109)
				{
					return buffer[num + 2] == 108;
				}
				return false;
			}
		}

		public PrefixHandle(XmlBufferReader bufferReader)
		{
			this.bufferReader = bufferReader;
		}

		public void SetValue(PrefixHandleType type)
		{
			this.type = type;
		}

		public void SetValue(PrefixHandle prefix)
		{
			type = prefix.type;
			offset = prefix.offset;
			length = prefix.length;
		}

		public void SetValue(int offset, int length)
		{
			switch (length)
			{
			case 0:
				SetValue(PrefixHandleType.Empty);
				return;
			case 1:
			{
				byte @byte = bufferReader.GetByte(offset);
				if (@byte >= 97 && @byte <= 122)
				{
					SetValue(GetAlphaPrefix(@byte - 97));
					return;
				}
				break;
			}
			}
			type = PrefixHandleType.Buffer;
			this.offset = offset;
			this.length = length;
		}

		public bool TryGetShortPrefix(out PrefixHandleType type)
		{
			type = this.type;
			return type != PrefixHandleType.Buffer;
		}

		public static string GetString(PrefixHandleType type)
		{
			return prefixStrings[(int)type];
		}

		public static PrefixHandleType GetAlphaPrefix(int index)
		{
			return (PrefixHandleType)(1 + index);
		}

		public static byte[] GetString(PrefixHandleType type, out int offset, out int length)
		{
			if (type == PrefixHandleType.Empty)
			{
				offset = 0;
				length = 0;
			}
			else
			{
				length = 1;
				offset = (int)(type - 1);
			}
			return prefixBuffer;
		}

		public string GetString(XmlNameTable nameTable)
		{
			PrefixHandleType prefixHandleType = type;
			if (prefixHandleType != PrefixHandleType.Buffer)
			{
				return GetString(prefixHandleType);
			}
			return bufferReader.GetString(offset, length, nameTable);
		}

		public string GetString()
		{
			PrefixHandleType prefixHandleType = type;
			if (prefixHandleType != PrefixHandleType.Buffer)
			{
				return GetString(prefixHandleType);
			}
			return bufferReader.GetString(offset, length);
		}

		public byte[] GetString(out int offset, out int length)
		{
			PrefixHandleType prefixHandleType = type;
			if (prefixHandleType != PrefixHandleType.Buffer)
			{
				return GetString(prefixHandleType, out offset, out length);
			}
			offset = this.offset;
			length = this.length;
			return bufferReader.Buffer;
		}

		public int CompareTo(PrefixHandle that)
		{
			return GetString().CompareTo(that.GetString());
		}

		private bool Equals2(PrefixHandle prefix2)
		{
			PrefixHandleType prefixHandleType = type;
			PrefixHandleType prefixHandleType2 = prefix2.type;
			if (prefixHandleType != prefixHandleType2)
			{
				return false;
			}
			if (prefixHandleType != PrefixHandleType.Buffer)
			{
				return true;
			}
			if (bufferReader == prefix2.bufferReader)
			{
				return bufferReader.Equals2(offset, length, prefix2.offset, prefix2.length);
			}
			return bufferReader.Equals2(offset, length, prefix2.bufferReader, prefix2.offset, prefix2.length);
		}

		private bool Equals2(string prefix2)
		{
			PrefixHandleType prefixHandleType = type;
			if (prefixHandleType != PrefixHandleType.Buffer)
			{
				return GetString(prefixHandleType) == prefix2;
			}
			return bufferReader.Equals2(offset, length, prefix2);
		}

		private bool Equals2(XmlDictionaryString prefix2)
		{
			return Equals2(prefix2.Value);
		}

		public static bool operator ==(PrefixHandle prefix1, string prefix2)
		{
			return prefix1.Equals2(prefix2);
		}

		public static bool operator !=(PrefixHandle prefix1, string prefix2)
		{
			return !prefix1.Equals2(prefix2);
		}

		public static bool operator ==(PrefixHandle prefix1, XmlDictionaryString prefix2)
		{
			return prefix1.Equals2(prefix2);
		}

		public static bool operator !=(PrefixHandle prefix1, XmlDictionaryString prefix2)
		{
			return !prefix1.Equals2(prefix2);
		}

		public static bool operator ==(PrefixHandle prefix1, PrefixHandle prefix2)
		{
			return prefix1.Equals2(prefix2);
		}

		public static bool operator !=(PrefixHandle prefix1, PrefixHandle prefix2)
		{
			return !prefix1.Equals2(prefix2);
		}

		public override bool Equals(object obj)
		{
			if (!(obj is PrefixHandle prefixHandle))
			{
				return false;
			}
			return this == prefixHandle;
		}

		public override string ToString()
		{
			return GetString();
		}

		public override int GetHashCode()
		{
			return GetString().GetHashCode();
		}
	}
	internal enum StringHandleConstStringType
	{
		Type,
		Root,
		Item
	}
	internal class StringHandle
	{
		private enum StringHandleType
		{
			Dictionary,
			UTF8,
			EscapedUTF8,
			ConstString
		}

		private XmlBufferReader bufferReader;

		private StringHandleType type;

		private int key;

		private int offset;

		private int length;

		private static string[] constStrings = new string[3] { "type", "root", "item" };

		public bool IsEmpty
		{
			get
			{
				if (type == StringHandleType.UTF8)
				{
					return length == 0;
				}
				return Equals2(string.Empty);
			}
		}

		public bool IsXmlns
		{
			get
			{
				if (type == StringHandleType.UTF8)
				{
					if (length != 5)
					{
						return false;
					}
					byte[] buffer = bufferReader.Buffer;
					int num = offset;
					if (buffer[num] == 120 && buffer[num + 1] == 109 && buffer[num + 2] == 108 && buffer[num + 3] == 110)
					{
						return buffer[num + 4] == 115;
					}
					return false;
				}
				return Equals2("xmlns");
			}
		}

		public StringHandle(XmlBufferReader bufferReader)
		{
			this.bufferReader = bufferReader;
			SetValue(0, 0);
		}

		public void SetValue(int offset, int length)
		{
			type = StringHandleType.UTF8;
			this.offset = offset;
			this.length = length;
		}

		public void SetConstantValue(StringHandleConstStringType constStringType)
		{
			type = StringHandleType.ConstString;
			key = (int)constStringType;
		}

		public void SetValue(int offset, int length, bool escaped)
		{
			type = ((!escaped) ? StringHandleType.UTF8 : StringHandleType.EscapedUTF8);
			this.offset = offset;
			this.length = length;
		}

		public void SetValue(int key)
		{
			type = StringHandleType.Dictionary;
			this.key = key;
		}

		public void SetValue(StringHandle value)
		{
			type = value.type;
			key = value.key;
			offset = value.offset;
			length = value.length;
		}

		public void ToPrefixHandle(PrefixHandle prefix)
		{
			prefix.SetValue(offset, length);
		}

		public string GetString(XmlNameTable nameTable)
		{
			return type switch
			{
				StringHandleType.UTF8 => bufferReader.GetString(offset, length, nameTable), 
				StringHandleType.Dictionary => nameTable.Add(bufferReader.GetDictionaryString(key).Value), 
				StringHandleType.ConstString => nameTable.Add(constStrings[key]), 
				_ => bufferReader.GetEscapedString(offset, length, nameTable), 
			};
		}

		public string GetString()
		{
			return type switch
			{
				StringHandleType.UTF8 => bufferReader.GetString(offset, length), 
				StringHandleType.Dictionary => bufferReader.GetDictionaryString(key).Value, 
				StringHandleType.ConstString => constStrings[key], 
				_ => bufferReader.GetEscapedString(offset, length), 
			};
		}

		public byte[] GetString(out int offset, out int length)
		{
			switch (type)
			{
			case StringHandleType.UTF8:
				offset = this.offset;
				length = this.length;
				return bufferReader.Buffer;
			case StringHandleType.Dictionary:
			{
				byte[] array3 = bufferReader.GetDictionaryString(key).ToUTF8();
				offset = 0;
				length = array3.Length;
				return array3;
			}
			case StringHandleType.ConstString:
			{
				byte[] array2 = XmlConverter.ToBytes(constStrings[key]);
				offset = 0;
				length = array2.Length;
				return array2;
			}
			default:
			{
				byte[] array = XmlConverter.ToBytes(bufferReader.GetEscapedString(this.offset, this.length));
				offset = 0;
				length = array.Length;
				return array;
			}
			}
		}

		public bool TryGetDictionaryString(out XmlDictionaryString value)
		{
			if (type == StringHandleType.Dictionary)
			{
				value = bufferReader.GetDictionaryString(key);
				return true;
			}
			if (IsEmpty)
			{
				value = XmlDictionaryString.Empty;
				return true;
			}
			value = null;
			return false;
		}

		public override string ToString()
		{
			return GetString();
		}

		private bool Equals2(int key2, XmlBufferReader bufferReader2)
		{
			return type switch
			{
				StringHandleType.Dictionary => bufferReader.Equals2(key, key2, bufferReader2), 
				StringHandleType.UTF8 => bufferReader.Equals2(offset, length, bufferReader2.GetDictionaryString(key2).Value), 
				_ => GetString() == bufferReader.GetDictionaryString(key2).Value, 
			};
		}

		private bool Equals2(XmlDictionaryString xmlString2)
		{
			return type switch
			{
				StringHandleType.Dictionary => bufferReader.Equals2(key, xmlString2), 
				StringHandleType.UTF8 => bufferReader.Equals2(offset, length, xmlString2.ToUTF8()), 
				_ => GetString() == xmlString2.Value, 
			};
		}

		private bool Equals2(string s2)
		{
			return type switch
			{
				StringHandleType.Dictionary => bufferReader.GetDictionaryString(key).Value == s2, 
				StringHandleType.UTF8 => bufferReader.Equals2(offset, length, s2), 
				_ => GetString() == s2, 
			};
		}

		private bool Equals2(int offset2, int length2, XmlBufferReader bufferReader2)
		{
			return type switch
			{
				StringHandleType.Dictionary => bufferReader2.Equals2(offset2, length2, bufferReader.GetDictionaryString(key).Value), 
				StringHandleType.UTF8 => bufferReader.Equals2(offset, length, bufferReader2, offset2, length2), 
				_ => GetString() == bufferReader.GetString(offset2, length2), 
			};
		}

		private bool Equals2(StringHandle s2)
		{
			return s2.type switch
			{
				StringHandleType.Dictionary => Equals2(s2.key, s2.bufferReader), 
				StringHandleType.UTF8 => Equals2(s2.offset, s2.length, s2.bufferReader), 
				_ => Equals2(s2.GetString()), 
			};
		}

		public static bool operator ==(StringHandle s1, XmlDictionaryString xmlString2)
		{
			return s1.Equals2(xmlString2);
		}

		public static bool operator !=(StringHandle s1, XmlDictionaryString xmlString2)
		{
			return !s1.Equals2(xmlString2);
		}

		public static bool operator ==(StringHandle s1, string s2)
		{
			return s1.Equals2(s2);
		}

		public static bool operator !=(StringHandle s1, string s2)
		{
			return !s1.Equals2(s2);
		}

		public static bool operator ==(StringHandle s1, StringHandle s2)
		{
			return s1.Equals2(s2);
		}

		public static bool operator !=(StringHandle s1, StringHandle s2)
		{
			return !s1.Equals2(s2);
		}

		public int CompareTo(StringHandle that)
		{
			if (type == StringHandleType.UTF8 && that.type == StringHandleType.UTF8)
			{
				return bufferReader.Compare(offset, length, that.offset, that.length);
			}
			return string.Compare(GetString(), that.GetString(), StringComparison.Ordinal);
		}

		public override bool Equals(object obj)
		{
			if (!(obj is StringHandle stringHandle))
			{
				return false;
			}
			return this == stringHandle;
		}

		public override int GetHashCode()
		{
			return GetString().GetHashCode();
		}
	}
	public class UniqueId
	{
		private long idLow;

		private long idHigh;

		[SecurityCritical]
		private string s;

		private const int guidLength = 16;

		private const int uuidLength = 45;

		private static short[] char2val = new short[256]
		{
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 0, 16,
			32, 48, 64, 80, 96, 112, 128, 144, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 160, 176, 192,
			208, 224, 240, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 0, 1, 2, 3,
			4, 5, 6, 7, 8, 9, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 10, 11, 12, 13, 14,
			15, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
			256, 256, 256, 256, 256, 256
		};

		private const string val2char = "0123456789abcdef";

		public int CharArrayLength
		{
			[SecuritySafeCritical]
			get
			{
				if (s != null)
				{
					return s.Length;
				}
				return 45;
			}
		}

		public bool IsGuid => (idLow | idHigh) != 0;

		public UniqueId()
			: this(Guid.NewGuid())
		{
		}

		public UniqueId(Guid guid)
			: this(guid.ToByteArray())
		{
		}

		public UniqueId(byte[] guid)
			: this(guid, 0)
		{
		}

		[SecuritySafeCritical]
		public unsafe UniqueId(byte[] guid, int offset)
		{
			if (guid == null)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("guid"));
			}
			if (offset < 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The value of this argument must be non-negative.")));
			}
			if (offset > guid.Length)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The specified offset exceeds the buffer size ({0} bytes).", guid.Length)));
			}
			if (16 > guid.Length - offset)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.Runtime.Serialization.SR.GetString("Array too small.  Length of available data must be at least {0}.", 16), "guid"));
			}
			fixed (byte* ptr = &guid[offset])
			{
				idLow = UnsafeGetInt64(ptr);
				idHigh = UnsafeGetInt64(ptr + 8);
			}
		}

		[SecuritySafeCritical]
		public unsafe UniqueId(string value)
		{
			if (value == null)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
			}
			if (value.Length == 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(System.Runtime.Serialization.SR.GetString("UniqueId cannot be zero length.")));
			}
			fixed (char* chars = value)
			{
				UnsafeParse(chars, value.Length);
			}
			s = value;
		}

		[SecuritySafeCritical]
		public unsafe UniqueId(char[] chars, int offset, int count)
		{
			if (chars == null)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars"));
			}
			if (offset < 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The value of this argument must be non-negative.")));
			}
			if (offset > chars.Length)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The specified offset exceeds the buffer size ({0} bytes).", chars.Length)));
			}
			if (count < 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", System.Runtime.Serialization.SR.GetString("The value of this argument must be non-negative.")));
			}
			if (count > chars.Length - offset)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", System.Runtime.Serialization.SR.GetString("The specified size exceeds the remaining buffer space ({0} bytes).", chars.Length - offset)));
			}
			if (count == 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(System.Runtime.Serialization.SR.GetString("UniqueId cannot be zero length.")));
			}
			fixed (char* chars2 = &chars[offset])
			{
				UnsafeParse(chars2, count);
			}
			if (!IsGuid)
			{
				s = new string(chars, offset, count);
			}
		}

		[SecurityCritical]
		private unsafe int UnsafeDecode(short* char2val, char ch1, char ch2)
		{
			if ((ch1 | ch2) >= 128)
			{
				return 256;
			}
			return char2val[(int)ch1] | char2val[128 + ch2];
		}

		[SecurityCritical]
		private unsafe void UnsafeEncode(char* val2char, byte b, char* pch)
		{
			*pch = val2char[b >> 4];
			pch[1] = val2char[b & 0xF];
		}

		[SecurityCritical]
		private unsafe void UnsafeParse(char* chars, int charCount)
		{
			if (charCount != 45 || *chars != 'u' || chars[1] != 'r' || chars[2] != 'n' || chars[3] != ':' || chars[4] != 'u' || chars[5] != 'u' || chars[6] != 'i' || chars[7] != 'd' || chars[8] != ':' || chars[17] != '-' || chars[22] != '-' || chars[27] != '-' || chars[32] != '-')
			{
				return;
			}
			byte* ptr = stackalloc byte[16];
			int num = 0;
			fixed (short* ptr2 = char2val)
			{
				short* ptr3 = ptr2;
				num = UnsafeDecode(ptr3, chars[15], chars[16]);
				*ptr = (byte)num;
				int num2 = 0 | num;
				num = UnsafeDecode(ptr3, chars[13], chars[14]);
				ptr[1] = (byte)num;
				int num3 = num2 | num;
				num = UnsafeDecode(ptr3, chars[11], chars[12]);
				ptr[2] = (byte)num;
				int num4 = num3 | num;
				num = UnsafeDecode(ptr3, chars[9], chars[10]);
				ptr[3] = (byte)num;
				int num5 = num4 | num;
				num = UnsafeDecode(ptr3, chars[20], chars[21]);
				ptr[4] = (byte)num;
				int num6 = num5 | num;
				num = UnsafeDecode(ptr3, chars[18], chars[19]);
				ptr[5] = (byte)num;
				int num7 = num6 | num;
				num = UnsafeDecode(ptr3, chars[25], chars[26]);
				ptr[6] = (byte)num;
				int num8 = num7 | num;
				num = UnsafeDecode(ptr3, chars[23], chars[24]);
				ptr[7] = (byte)num;
				int num9 = num8 | num;
				num = UnsafeDecode(ptr3, chars[28], chars[29]);
				ptr[8] = (byte)num;
				int num10 = num9 | num;
				num = UnsafeDecode(ptr3, chars[30], chars[31]);
				ptr[9] = (byte)num;
				int num11 = num10 | num;
				num = UnsafeDecode(ptr3, chars[33], chars[34]);
				ptr[10] = (byte)num;
				int num12 = num11 | num;
				num = UnsafeDecode(ptr3, chars[35], chars[36]);
				ptr[11] = (byte)num;
				int num13 = num12 | num;
				num = UnsafeDecode(ptr3, chars[37], chars[38]);
				ptr[12] = (byte)num;
				int num14 = num13 | num;
				num = UnsafeDecode(ptr3, chars[39], chars[40]);
				ptr[13] = (byte)num;
				int num15 = num14 | num;
				num = UnsafeDecode(ptr3, chars[41], chars[42]);
				ptr[14] = (byte)num;
				int num16 = num15 | num;
				num = UnsafeDecode(ptr3, chars[43], chars[44]);
				ptr[15] = (byte)num;
				if ((num16 | num) >= 256)
				{
					return;
				}
				idLow = UnsafeGetInt64(ptr);
				idHigh = UnsafeGetInt64(ptr + 8);
			}
		}

		[SecuritySafeCritical]
		public unsafe int ToCharArray(char[] chars, int offset)
		{
			int charArrayLength = CharArrayLength;
			if (chars == null)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars"));
			}
			if (offset < 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The value of this argument must be non-negative.")));
			}
			if (offset > chars.Length)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The specified offset exceeds the buffer size ({0} bytes).", chars.Length)));
			}
			if (charArrayLength > chars.Length - offset)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("chars", System.Runtime.Serialization.SR.GetString("Array too small.  Must be able to hold at least {0}.", charArrayLength)));
			}
			if (s != null)
			{
				s.CopyTo(0, chars, offset, charArrayLength);
			}
			else
			{
				byte* ptr = stackalloc byte[16];
				UnsafeSetInt64(idLow, ptr);
				UnsafeSetInt64(idHigh, ptr + 8);
				fixed (char* ptr2 = &chars[offset])
				{
					*ptr2 = 'u';
					ptr2[1] = 'r';
					ptr2[2] = 'n';
					ptr2[3] = ':';
					ptr2[4] = 'u';
					ptr2[5] = 'u';
					ptr2[6] = 'i';
					ptr2[7] = 'd';
					ptr2[8] = ':';
					ptr2[17] = '-';
					ptr2[22] = '-';
					ptr2[27] = '-';
					ptr2[32] = '-';
					fixed (char* ptr3 = "0123456789abcdef")
					{
						char* ptr4 = ptr3;
						UnsafeEncode(ptr4, *ptr, ptr2 + 15);
						UnsafeEncode(ptr4, ptr[1], ptr2 + 13);
						UnsafeEncode(ptr4, ptr[2], ptr2 + 11);
						UnsafeEncode(ptr4, ptr[3], ptr2 + 9);
						UnsafeEncode(ptr4, ptr[4], ptr2 + 20);
						UnsafeEncode(ptr4, ptr[5], ptr2 + 18);
						UnsafeEncode(ptr4, ptr[6], ptr2 + 25);
						UnsafeEncode(ptr4, ptr[7], ptr2 + 23);
						UnsafeEncode(ptr4, ptr[8], ptr2 + 28);
						UnsafeEncode(ptr4, ptr[9], ptr2 + 30);
						UnsafeEncode(ptr4, ptr[10], ptr2 + 33);
						UnsafeEncode(ptr4, ptr[11], ptr2 + 35);
						UnsafeEncode(ptr4, ptr[12], ptr2 + 37);
						UnsafeEncode(ptr4, ptr[13], ptr2 + 39);
						UnsafeEncode(ptr4, ptr[14], ptr2 + 41);
						UnsafeEncode(ptr4, ptr[15], ptr2 + 43);
					}
				}
			}
			return charArrayLength;
		}

		public bool TryGetGuid(out Guid guid)
		{
			byte[] array = new byte[16];
			if (!TryGetGuid(array, 0))
			{
				guid = Guid.Empty;
				return false;
			}
			guid = new Guid(array);
			return true;
		}

		[SecuritySafeCritical]
		public unsafe bool TryGetGuid(byte[] buffer, int offset)
		{
			if (!IsGuid)
			{
				return false;
			}
			if (buffer == null)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer"));
			}
			if (offset < 0)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The value of this argument must be non-negative.")));
			}
			if (offset > buffer.Length)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString("The specified offset exceeds the buffer size ({0} bytes).", buffer.Length)));
			}
			if (16 > buffer.Length - offset)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("buffer", System.Runtime.Serialization.SR.GetString("Array too small.  Must be able to hold at least {0}.", 16)));
			}
			fixed (byte* ptr = &buffer[offset])
			{
				UnsafeSetInt64(idLow, ptr);
				UnsafeSetInt64(idHigh, ptr + 8);
			}
			return true;
		}

		[SecuritySafeCritical]
		public override string ToString()
		{
			if (s == null)
			{
				int charArrayLength = CharArrayLength;
				char[] array = new char[charArrayLength];
				ToCharArray(array, 0);
				s = new string(array, 0, charArrayLength);
			}
			return s;
		}

		public static bool operator ==(UniqueId id1, UniqueId id2)
		{
			if ((object)id1 == null && (object)id2 == null)
			{
				return true;
			}
			if ((object)id1 == null || (object)id2 == null)
			{
				return false;
			}
			if (id1.IsGuid && id2.IsGuid)
			{
				if (id1.idLow == id2.idLow)
				{
					return id1.idHigh == id2.idHigh;
				}
				return false;
			}
			return id1.ToString() == id2.ToString();
		}

		public static bool operator !=(UniqueId id1, UniqueId id2)
		{
			return !(id1 == id2);
		}

		public override bool Equals(object obj)
		{
			return this == obj as UniqueId;
		}

		public override int GetHashCode()
		{
			if (IsGuid)
			{
				long num = idLow ^ idHigh;
				return (int)(num >> 32) ^ (int)num;
			}
			return ToString().GetHashCode();
		}

		[SecurityCritical]
		private unsafe long UnsafeGetInt64(byte* pb)
		{
			int num = UnsafeGetInt32(pb);
			return ((long)UnsafeGetInt32(pb + 4) << 32) | (uint)num;
		}

		[SecurityCritical]
		private unsafe int UnsafeGetInt32(byte* pb)
		{
			return (((((pb[3] << 8) | pb[2]) << 8) | pb[1]) << 8) | *pb;
		}

		[SecurityCritical]
		private unsafe void UnsafeSetInt64(long value, byte* pb)
		{
			UnsafeSetInt32((int)value, pb);
			UnsafeSetInt32((int)(value >> 32), pb + 4);
		}

		[SecurityCritical]
		private unsafe void UnsafeSetInt32(int value, byte* pb)
		{
			*pb = (byte)value;
			value >>= 8;
			pb[1] = (byte)value;
			value >>= 8;
			pb[2] = (byte)value;
			value >>= 8;
			pb[3] = (byte)value;
		}
	}
	internal enum ValueHandleConstStringType
	{
		String,
		Number,
		Array,
		Object,
		Boolean,
		Null
	}
	internal static class ValueHandleLength
	{
		public const int Int8 = 1;

		public const int Int16 = 2;

		public const int Int32 = 4;

		public const int Int64 = 8;

		public const int UInt64 = 8;

		public const int Single = 4;

		public const int Double = 8;

		public const int Decimal = 16;

		public const int DateTime = 8;

		public const int TimeSpan = 8;

		public const int Guid = 16;

		public const int UniqueId = 16;
	}
	internal enum ValueHandleType
	{
		Empty,
		True,
		False,
		Zero,
		One,
		Int8,
		Int16,
		Int32,
		Int64,
		UInt64,
		Single,
		Double,
		Decimal,
		DateTime,
		TimeSpan,
		Guid,
		UniqueId,
		UTF8,
		EscapedUTF8,
		Base64,
		Dictionary,
		List,
		Char,
		Unicode,
		QName,
		ConstString
	}
	internal class ValueHandle
	{
		private XmlBufferReader bufferReader;

		private ValueHandleType type;

		private int offset;

		private int length;

		private static Base64Encoding base64Encoding;

		private static string[] constStrings = new string[6] { "string", "number", "array", "object", "boolean", "null" };

		private static Base64Encoding Base64Encoding
		{
			get
			{
				if (base64Encoding == null)
				{
					base64Encoding = new Base64Encoding();
				}
				return base64Encoding;
			}
		}

		public ValueHandle(XmlBufferReader bufferReader)
		{
			this.bufferReader = bufferReader;
			type = ValueHandleType.Empty;
		}

		public void SetConstantValue(ValueHandleConstStringType constStringType)
		{
			type = ValueHandleType.ConstString;
			offset = (int)constStringType;
		}

		public void SetValue(ValueHandleType type)
		{
			this.type = type;
		}

		public void SetDictionaryValue(int key)
		{
			SetValue(ValueHandleType.Dictionary, key, 0);
		}

		public void SetCharValue(int ch)
		{
			SetValue(ValueHandleType.Char, ch, 0);
		}

		public void SetQNameValue(int prefix, int key)
		{
			SetValue(ValueHandleType.QName, key, prefix);
		}

		public void SetValue(ValueHandleType type, int offset, int length)
		{
			this.type = type;
			this.offset = offset;
			this.length = length;
		}

		public bool IsWhitespace()
		{
			switch (type)
			{
			case ValueHandleType.UTF8:
				return bufferReader.IsWhitespaceUTF8(offset, length);
			case ValueHandleType.Dictionary:
				return bufferReader.IsWhitespaceKey(offset);
			case ValueHandleType.Char:
			{
				int @char = GetChar();
				if (@char > 65535)
				{
					return false;
				}
				return XmlConverter.IsWhitespace((char)@char);
			}
			case ValueHandleType.EscapedUTF8:
				return bufferReader.IsWhitespaceUTF8(offset, length);
			case ValueHandleType.Unicode:
				return bufferReader.IsWhitespaceUnicode(offset, length);
			case ValueHandleType.True:
			case ValueHandleType.False:
			case ValueHandleType.Zero:
			case ValueHandleType.One:
				return false;
			case ValueHandleType.ConstString:
				return constStrings[offset].Length == 0;
			default:
				return length == 0;
			}
		}

		public Type ToType()
		{
			switch (type)
			{
			case ValueHandleType.True:
			case ValueHandleType.False:
				return typeof(bool);
			case ValueHandleType.Zero:
			case ValueHandleType.One:
			case ValueHandleType.Int8:
			case ValueHandleType.Int16:
			case ValueHandleType.Int32:
				return typeof(int);
			case ValueHandleType.Int64:
				return typeof(long);
			case ValueHandleType.UInt64:
				return typeof(ulong);
			case ValueHandleType.Single:
				return typeof(float);
			case ValueHandleType.Double:
				return typeof(double);
			case ValueHandleType.Decimal:
				return typeof(decimal);
			case ValueHandleType.DateTime:
				return typeof(DateTime);
			case ValueHandleType.Empty:
			case ValueHandleType.UTF8:
			case ValueHandleType.EscapedUTF8:
			case ValueHandleType.Dictionary:
			case ValueHandleType.Char:
			case ValueHandleType.Unicode:
			case ValueHandleType.QName:
			case ValueHandleType.ConstString:
				return typeof(string);
			case ValueHandleType.Base64:
				return typeof(byte[]);
			case ValueHandleType.List:
				return typeof(object[]);
			case ValueHandleType.UniqueId:
				return typeof(UniqueId);
			case ValueHandleType.Guid:
				return typeof(Guid);
			case ValueHandleType.TimeSpan:
				return typeof(TimeSpan);
			default:
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException());
			}
		}

		public bool ToBoolean()
		{
			switch (type)
			{
			case ValueHandleType.False:
				return false;
			case ValueHandleType.True:
				return true;
			case ValueHandleType.UTF8:
				return XmlConverter.ToBoolean(bufferReader.Buffer, offset, length);
			case ValueHandleType.Int8:
				switch (GetInt8())
				{
				case 0:
					return false;
				case 1:
					return true;
				}
				break;
			}
			return XmlConverter.ToBoolean(GetString());
		}

		public int ToInt()
		{
			ValueHandleType valueHandleType = type;
			switch (valueHandleType)
			{
			case ValueHandleType.Zero:
				return 0;
			case ValueHandleType.One:
				return 1;
			case ValueHandleType.Int8:
				return GetInt8();
			case ValueHandleType.Int16:
				return GetInt16();
			case ValueHandleType.Int32:
				return GetInt32();
			case ValueHandleType.Int64:
			{
				long @int = GetInt64();
				if (@int >= int.MinValue && @int <= int.MaxValue)
				{
					return (int)@int;
				}
				break;
			}
			}
			if (valueHandleType == ValueHandleType.UInt64)
			{
				ulong uInt = GetUInt64();
				if (uInt <= int.MaxValue)
				{
					return (int)uInt;
				}
			}
			if (valueHandleType == ValueHandleType.UTF8)
			{
				return XmlConverter.ToInt32(bufferReader.Buffer, offset, length);
			}
			return XmlConverter.ToInt32(GetString());
		}

		public long ToLong()
		{
			ValueHandleType valueHandleType = type;
			switch (valueHandleType)
			{
			case ValueHandleType.Zero:
				return 0L;
			case ValueHandleType.One:
				return 1L;
			case ValueHandleType.Int8:
				return GetInt8();
			case ValueHandleType.Int16:
				return GetInt16();
			case ValueHandleType.Int32:
				return GetInt32();
			case ValueHandleType.Int64:
				return GetInt64();
			case ValueHandleType.UInt64:
			{
				ulong uInt = GetUInt64();
				if (uInt <= long.MaxValue)
				{
					return (long)uInt;
				}
				break;
			}
			}
			if (valueHandleType == ValueHandleType.UTF8)
			{
				return XmlConverter.ToInt64(bufferReader.Buffer, offset, length);
			}
			return XmlConverter.ToInt64(GetString());
		}

		public ulong ToULong()
		{
			ValueHandleType valueHandleType = type;
			switch (valueHandleType)
			{
			case ValueHandleType.Zero:
				return 0uL;
			case ValueHandleType.One:
				return 1uL;
			case ValueHandleType.Int8:
			case ValueHandleType.Int16:
			case ValueHandleType.Int32:
			case ValueHandleType.Int64:
			{
				long num = ToLong();
				if (num >= 0)
				{
					return (ulong)num;
				}
				break;
			}
			}
			return valueHandleType switch
			{
				ValueHandleType.UInt64 => GetUInt64(), 
				ValueHandleType.UTF8 => XmlConverter.ToUInt64(bufferReader.Buffer, offset, length), 
				_ => XmlConverter.ToUInt64(GetString()), 
			};
		}

		public float ToSingle()
		{
			ValueHandleType valueHandleType = type;
			switch (valueHandleType)
			{
			case ValueHandleType.Single:
				return GetSingle();
			case ValueHandleType.Double:
			{
				double @double = GetDouble();
				if ((@double >= -3.4028234663852886E+38 && @double <= 3.4028234663852886E+38) || double.IsInfinity(@double) || double.IsNaN(@double))
				{
					return (float)@double;
				}
				break;
			}
			}
			return valueHandleType switch
			{
				ValueHandleType.Zero => 0f, 
				ValueHandleType.One => 1f, 
				ValueHandleType.Int8 => GetInt8(), 
				ValueHandleType.Int16 => GetInt16(), 
				ValueHandleType.UTF8 => XmlConverter.ToSingle(bufferReader.Buffer, offset, length), 
				_ => XmlConverter.ToSingle(GetString()), 
			};
		}

		public double ToDouble()
		{
			return type switch
			{
				ValueHandleType.Double => GetDouble(), 
				ValueHandleType.Single => GetSingle(), 
				ValueHandleType.Zero => 0.0, 
				ValueHandleType.One => 1.0, 
				ValueHandleType.Int8 => GetInt8(), 
				ValueHandleType.Int16 => GetInt16(), 
				ValueHandleType.Int32 => GetInt32(), 
				ValueHandleType.UTF8 => XmlConverter.ToDouble(bufferReader.Buffer, offset, length), 
				_ => XmlConverter.ToDouble(GetString()), 
			};
		}

		public decimal ToDecimal()
		{
			ValueHandleType valueHandleType = type;
			switch (valueHandleType)
			{
			case ValueHandleType.Decimal:
				return GetDecimal();
			case ValueHandleType.Zero:
				return 0m;
			case ValueHandleType.One:
				return 1m;
			case ValueHandleType.Int8:
			case ValueHandleType.Int16:
			case ValueHandleType.Int32:
			case ValueHandleType.Int64:
				return ToLong();
			default:
				return valueHandleType switch
				{
					ValueHandleType.UInt64 => GetUInt64(), 
					ValueHandleType.UTF8 => XmlConverter.ToDecimal(bufferReader.Buffer, offset, length), 
					_ => XmlConverter.ToDecimal(GetString()), 
				};
			}
		}

		public DateTime ToDateTime()
		{
			if (type == ValueHandleType.DateTime)
			{
				return XmlConverter.ToDateTime(GetInt64());
			}
			if (type == ValueHandleType.UTF8)
			{
				return XmlConverter.ToDateTime(bufferReader.Buffer, offset, length);
			}
			return XmlConverter.ToDateTime(GetString());
		}

		public UniqueId ToUniqueId()
		{
			if (type == ValueHandleType.UniqueId)
			{
				return GetUniqueId();
			}
			if (type == ValueHandleType.UTF8)
			{
				return XmlConverter.ToUniqueId(bufferReader.Buffer, offset, length);
			}
			return XmlConverter.ToUniqueId(GetString());
		}

		public TimeSpan ToTimeSpan()
		{
			if (type == ValueHandleType.TimeSpan)
			{
				return new TimeSpan(GetInt64());
			}
			if (type == ValueHandleType.UTF8)
			{
				return XmlConverter.ToTimeSpan(bufferReader.Buffer, offset, length);
			}
			return XmlConverter.ToTimeSpan(GetString());
		}

		public Guid ToGuid()
		{
			if (type == ValueHandleType.Guid)
			{
				return GetGuid();
			}
			if (type == ValueHandleType.UTF8)
			{
				return XmlConverter.ToGuid(bufferReader.Buffer, offset, length);
			}
			return XmlConverter.ToGuid(GetString());
		}

		public override string ToString()
		{
			return GetString();
		}

		public byte[] ToByteArray()
		{
			if (type == ValueHandleType.Base64)
			{
				byte[] array = new byte[length];
				GetBase64(array, 0, length);
				return array;
			}
			if (type == ValueHandleType.UTF8 && length % 4 == 0)
			{
				try
				{
					int num = length / 4 * 3;
					if (length > 0 && bufferReader.Buffer[offset + length - 1] == 61)
					{
						num--;
						if (bufferReader.Buffer[offset + length - 2] == 61)
						{
							num--;
						}
					}
					byte[] array2 = new byte[num];
					int bytes = Base64Encoding.GetBytes(bufferReader.Buffer, offset, length, array2, 0);
					if (bytes != array2.Length)
					{
						byte[] array3 = new byte[bytes];
						Buffer.BlockCopy(array2, 0, array3, 0, bytes);
						array2 = array3;
					}
					return array2;
				}
				catch (FormatException)
				{
				}
			}
			try
			{
				return Base64Encoding.GetBytes(XmlConverter.StripWhitespace(GetString()));
			}
			catch (FormatException ex2)
			{
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(ex2.Message, ex2.InnerException));
			}
		}

		public string GetString()
		{
			ValueHandleType valueHandleType = type;
			if (valueHandleType == ValueHandleType.UTF8)
			{
				return GetCharsText();
			}
			switch (valueHandleType)
			{
			case ValueHandleType.False:
				return "false";
			case ValueHandleType.True:
				return "true";
			case ValueHandleType.Zero:
				return "0";
			case ValueHandleType.One:
				return "1";
			case ValueHandleType.Int8:
			case ValueHandleType.Int16:
			case ValueHandleType.Int32:
				return XmlConverter.ToString(ToInt());
			case ValueHandleType.Int64:
				return XmlConverter.ToString(GetInt64());
			case ValueHandleType.UInt64:
				return XmlConverter.ToString(GetUInt64());
			case ValueHandleType.Single:
				return XmlConverter.ToString(GetSingle());
			case ValueHandleType.Double:
				return XmlConverter.ToString(GetDouble());
			case ValueHandleType.Decimal:
				return XmlConverter.ToString(GetDecimal());
			case ValueHandleType.DateTime:
				return XmlConverter.ToString(ToDateTime());
			case ValueHandleType.Empty:
				return string.Empty;
			case ValueHandleType.UTF8:
				return GetCharsText();
			case ValueHandleType.Unicode:
				return GetUnicodeCharsText();
			case ValueHandleType.EscapedUTF8:
				return GetEscapedCharsText();
			case ValueHandleType.Char:
				return GetCharText();
			case ValueHandleType.Dictionary:
				return GetDictionaryString().Value;
			case ValueHandleType.Base64:
				return Base64Encoding.GetString(ToByteArray());
			case ValueHandleType.List:
				return XmlConverter.ToString(ToList());
			case ValueHandleType.UniqueId:
				return XmlConverter.ToString(ToUniqueId());
			case ValueHandleType.Guid:
				return XmlConverter.ToString(ToGuid());
			case ValueHandleType.TimeSpan:
				return XmlConverter.ToString(ToTimeSpan());
			case ValueHandleType.QName:
				return GetQNameDictionaryText();
			case ValueHandleType.ConstString:
				return constStrings[offset];
			default:
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException());
			}
		}

		public bool Equals2(string str, bool checkLower)
		{
			if (type != ValueHandleType.UTF8)
			{
				return GetString() == str;
			}
			if (length != str.Length)
			{
				return false;
			}
			byte[] buffer = bufferReader.Buffer;
			for (int i = 0; i < length; i++)
			{
				byte b = buffer[i + offset];
				if (b != str[i] && (!checkLower || char.ToLowerInvariant((char)b) != str[i]))
				{
					return false;
				}
			}
			return true;
		}

		public void Sign(XmlSigningNodeWriter writer)
		{
			switch (type)
			{
			case ValueHandleType.Int8:
			case ValueHandleType.Int16:
			case ValueHandleType.Int32:
				writer.WriteInt32Text(ToInt());
				break;
			case ValueHandleType.Int64:
				writer.WriteInt64Text(GetInt64());
				break;
			case ValueHandleType.UInt64:
				writer.WriteUInt64Text(GetUInt64());
				break;
			case ValueHandleType.Single:
				writer.WriteFloatText(GetSingle());
				break;
			case ValueHandleType.Double:
				writer.WriteDoubleText(GetDouble());
				break;
			case ValueHandleType.Decimal:
				writer.WriteDecimalText(GetDecimal());
				break;
			case ValueHandleType.DateTime:
				writer.WriteDateTimeText(ToDateTime());
				break;
			case ValueHandleType.UTF8:
				writer.WriteEscapedText(bufferReader.Buffer, offset, length);
				break;
			case ValueHandleType.Base64:
				writer.WriteBase64Text(bufferReader.Buffer, 0, bufferReader.Buffer, offset, length);
				break;
			case ValueHandleType.UniqueId:
				writer.WriteUniqueIdText(ToUniqueId());
				break;
			case ValueHandleType.Guid:
				writer.WriteGuidText(ToGuid());
				break;
			case ValueHandleType.TimeSpan:
				writer.WriteTimeSpanText(ToTimeSpan());
				break;
			default:
				writer.WriteEscapedText(GetString());
				break;
			case ValueHandleType.Empty:
				break;
			}
		}

		public object[] ToList()
		{
			return bufferReader.GetList(offset, length);
		}

		public object ToObject()
		{
			switch (type)
			{
			case ValueHandleType.True:
			case ValueHandleType.False:
				return ToBoolean();
			case ValueHandleType.Zero:
			case ValueHandleType.One:
			case ValueHandleType.Int8:
			case ValueHandleType.Int16:
			case ValueHandleType.Int32:
				return ToInt();
			case ValueHandleType.Int64:
				return ToLong();
			case ValueHandleType.UInt64:
				return GetUInt64();
			case ValueHandleType.Single:
				return ToSingle();
			case ValueHandleType.Double:
				return ToDouble();
			case ValueHandleType.Decimal:
				return ToDecimal();
			case ValueHandleType.DateTime:
				return ToDateTime();
			case ValueHandleType.Empty:
			case ValueHandleType.UTF8:
			case ValueHandleType.EscapedUTF8:
			case ValueHandleType.Dictionary:
			case ValueHandleType.Char:
			case ValueHandleType.Unicode:
			case ValueHandleType.ConstString:
				return ToString();
			case ValueHandleType.Base64:
				return ToByteArray();
			case ValueHandleType.List:
				return ToList();
			case ValueHandleType.UniqueId:
				return ToUniqueId();
			case ValueHandleType.Guid:
				return ToGuid();
			case ValueHandleType.TimeSpan:
				return ToTimeSpan();
			default:
				throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException());
			}
		}

		public bool TryReadBase64(byte[] buffer, int offset, int count, out int actual)
		{
			if (type == ValueHandleType.Base64)
			{
				actual = Math.Min(length, count);
				GetBase64(buffer, offset, actual);
				this.offset += actual;
				length -= actual;
				return true;
			}
			if (type == ValueHandleType.UTF8 && count >= 3 && length % 4 == 0)
			{
				try
				{
					int num = Math.Min(count / 3 * 4, length);
					actual = Base64Encoding.GetBytes(bufferReader.Buffer, this.offset, num, buffer, offset);
					this.offset += num;
					length -= num;
					return true;
				}
				catch (FormatException)
				{
				}
			}
			actual = 0;
			return false;
		}

		public bool TryReadChars(char[] chars, int offset, int count, out int actual)
		{
			if (type == ValueHandleType.Unicode)
			{
				return TryReadUnicodeChars(chars, offset, count, out actual);
			}
			if (type != ValueHandleType.UTF8)
			{
				actual = 0;
				return false;
			}
			int num = offset;
			int num2 = count;
			byte[] buffer = bufferReader.Buffer;
			int num3 = this.offset;
			int num4 = length;
			bool flag = false;
			while (true)
			{
				if (num2 > 0 && num4 > 0)
				{
					byte b = buffer[num3];
					if (b < 128)
					{
						chars[num] = (char)b;
						num3++;
						num4--;
						num++;
						num2--;
						continue;
					}
				}
				if (num2 == 0 || num4 == 0 || flag)
				{
					break;
				}
				UTF8Encoding uTF8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
				int chars2;
				int num5;
				try
				{
					if (num2 >= uTF8Encoding.GetMaxCharCount(num4) || num2 >= uTF8Encoding.GetCharCount(buffer, num3, num4))
					{
						chars2 = uTF8Encoding.GetChars(buffer, num3, num4, chars, num);
						num5 = num4;
					}
					else
					{
						Decoder decoder = uTF8Encoding.GetDecoder();
						num5 = Math.Min(num2, num4);
						chars2 = decoder.GetChars(buffer, num3, num5, chars, num);
						while (chars2 == 0)
						{
							if (num5 >= 3 && num2 < 2)
							{
								flag = true;
								break;
							}
							chars2 = decoder.GetChars(buffer, num3 + num5, 1, chars, num);
							num5++;
						}
						num5 = uTF8Encoding.GetByteCount(chars, num, chars2);
					}
				}
				catch (FormatException exception)
				{
					throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateEncodingException(buffer, num3, num4, exception));
				}
				num3 += num5;
				num4 -= num5;
				num += chars2;
				num2 -= chars2;
			}
			this.offset = num3;
			length = num4;
			actual = count - num2;
			return true;
		}

		private bool TryReadUnicodeChars(char[] chars, int offset, int count, out int actual)
		{
			int num = Math.Min(count, length / 2);
			for (int i = 0; i < num; i++)
			{
				chars[offset + i] = (char)bufferReader.GetInt16(this.offset + i * 2);
			}
			this.offset += num * 2;
			length -= num * 2;
			actual = num;
			return true;
		}

		public bool TryGetDictionaryString(out XmlDictionaryString value)
		{
			if (type == ValueHandleType.Dictionary)
			{
				value = GetDictionaryString();
				return true;
			}
			value = null;
			return false;
		}

		public bool TryGetByteArrayLength(out int length)
		{
			if (type == ValueHandleType.Base64)
			{
				length = this.length;
				return true;
			}
			length = 0;
			return false;
		}

		private string GetCharsText()
		{
			if (length == 1 && bufferReader.GetByte(offset) == 49)
			{
				return "1";
			}
			return bufferReader.GetString(offset, length);
		}

		private string GetUnicodeCharsText()
		{
			return bufferReader.GetUnicodeString(offset, length);
		}

		private string GetEscapedCharsText()
		{
			return bufferReader.GetEscapedString(offset, length);
		}

		private string GetCharText()
		{
			int @char = GetChar();
			if (@char > 65535)
			{
				SurrogateChar surrogateChar = new SurrogateChar(@char);
				return new string(new char[2] { surrogateChar.HighChar, surrogateChar.LowChar }, 0, 2);
			}
			return ((char)@char).ToString();
		}

		private int GetChar()
		{
			return offset;
		}

		private int GetInt8()
		{
			return bufferReader.GetInt8(offset);
		}

		private int GetInt16()
		{
			return bufferReader.GetInt16(offset);
		}

		private int GetInt32()
		{
			return bufferReader.GetInt32(offset);
		}

		private long GetInt64()
		{
			return bufferReader.GetInt64(offset);
		}

		private ulong GetUInt64()
		{
			return bufferReader.GetUInt64(offset);
		}

		private float GetSingle()
		{
			return bufferReader.GetSingle(offset);
		}

		private double GetDouble()
		{
			return bufferReader.GetDouble(offset);
		}

		private decimal GetDecimal()
		{
			return bufferReader.GetDecimal(offset);
		}

		private UniqueId GetUniqueId()
		{
			return bufferReader.GetUniqueId(offset);
		}

		private Guid GetGuid()
		{
			return bufferReader.GetGuid(offset);
		}

		private void GetBase64(byte[] buffer, int offset, int count)
		{
			bufferReader.GetBase64(this.offset, buffer, offset, count);
		}

		private XmlDictionaryString GetDictionaryString()
		{
			return bufferReader.GetDictionaryString(offset);
		}

		private string GetQNameDictionaryText()
		{
			return PrefixHandle.GetString(PrefixHandle.GetAlphaPrefix(length)) + ":" + bufferReader.GetDictionaryString(offset);
		}
	}
	internal abstract class XmlBaseReader : XmlDictionaryReader
	{
		protected enum QNameType
		{
			Normal,
			Xmlns
		}

		protected class XmlNode
		{
			protected enum XmlNodeFlags
			{
				None = 0,
				CanGetAttribute = 1,
				CanMoveToElement = 2,
				HasValue = 4,
				AtomicValue = 8,
				SkipValue = 0x10,
				HasContent = 0x20
			}

			private XmlNodeType nodeType;

			private PrefixHandle prefix;

			private StringHandle localName;

			private ValueHandle value;

			private Namespace ns;

			private bool hasValue;

			private bool canGetAttribute;

			private bool canMoveToElement;

			private ReadState readState;

			private XmlAttributeTextNode attributeTextNode;

			private bool exitScope;

			private int depthDelta;

			private bool isAtomicValue;

			private bool skipValue;

			private QNameType qnameType;

			private bool hasContent;

			private bool isEmptyElement;

			private char quoteChar;

			public bool HasValue => hasValue;

			public ReadState ReadState => readState;

			public StringHandle LocalName => localName;

			public PrefixHandle Prefix => prefix;

			public bool CanGetAttribute => canGetAttribute;

			public bool CanMoveToElement => canMoveToElement;

			public XmlAttributeTextNode AttributeText => attributeTextNode;

			public bool SkipValue => skipValue;

			public ValueHandle Value => value;

			public int DepthDelta => depthDelta;

			public bool HasContent => hasContent;

			public XmlNodeType NodeType
			{
				get
				{
					return nodeType;
				}
				set
				{
					nodeType = value;
				}
			}

			public QNameType QNameType
			{
				get
				{
					return qnameType;
				}
				set
				{
					qnameType = value;
				}
			}

			public Namespace Namespace
			{
				get
				{
					return ns;
				}
				set
				{
					ns = value;
				}
			}

			public bool IsAtomicValue
			{
				get
				{
					return isAtomicValue;
				}
				set
				{
					isAtomicValue = value;
				}
			}

			public bool ExitScope
			{
				get
				{
					return exitScope;
				}
				set
				{
					exitScope = value;
				}
			}

			public bool IsEmptyElement
			{
				get
				{
					return isEmptyElement;
				}
				set
				{
					isEmptyElement = value;
				}
			}

			public char QuoteChar
			{
				get
				{
					return quoteChar;
				}
				set
				{
					quoteChar = value;
				}
			}

			public string ValueAsString
			{
				get
				{
					if (qnameType == QNameType.Normal)
					{
						return Value.GetString();
					}
					return Namespace.Uri.GetString();
				}
			}

			protected XmlNode(XmlNodeType nodeType, PrefixHandle prefix, StringHandle localName, ValueHandle value, XmlNodeFlags nodeFlags, ReadState readState, XmlAttributeTextNode attributeTextNode, int depthDelta)
			{
				this.nodeType = nodeType;
				this.prefix = prefix;
				this.localName = localName;
				this.value = value;
				ns = NamespaceManager.EmptyNamespace;
				hasValue = (nodeFlags & XmlNodeFlags.HasValue) != 0;
				canGetAttribute = (nodeFlags & XmlNodeFlags.CanGetAttribute) != 0;
				canMoveToElement = (nodeFlags & XmlNodeFlags.CanMoveToElement) != 0;
				isAtomicValue = (nodeFlags & XmlNodeFlags.AtomicValue) != 0;
				skipValue = (nodeFlags & XmlNodeFlags.SkipValue) != 0;
				hasContent = (nodeFlags & XmlNodeFlags.HasContent) != 0;
				this.readState = readState;
				this.attributeTextNode = attributeTextNode;
				exitScope = nodeType == XmlNodeType.EndElement;
				this.depthDelta = depthDelta;
				isEmptyElement = false;
				quoteChar = '"';
				qnameType = QNameType.Normal;
			}

			public bool IsLocalName(string localName)
			{
				if (qnameType == QNameType.Normal)
				{
					return LocalName == localName;
				}
				return Namespace.Prefix == localName;
			}

			public bool IsLocalName(XmlDictionaryString localName)
			{
				if (qnameType == QNameType.Normal)
				{
					return LocalName == localName;
				}
				return Namespace.Prefix == localName;
			}

			public bool IsNamespaceUri(string ns)
			{
				if (qnameType == QNameType.Normal)
				{
					return Namespace.IsUri(ns);
				}
				return ns == "http://www.w3.org/2000/xmlns/";
			}

			public bool IsNamespaceUri(XmlDictionaryString ns)
			{
				if (qnameType == QNameType.Normal)
				{
					return Namespace.IsUri(ns);
				}
				return ns.Value == "http://www.w3.org/2000/xmlns/";
			}

			public bool IsLocalNameAndNamespaceUri(string localName, string ns)
			{
				if (qnameType == QNameType.Normal)
				{
					if (LocalName == localName)
					{
						return Namespace.IsUri(ns);
					}
					return false;
				}
				if (Namespace.Prefix == localName)
				{
					return ns == "http://www.w3.org/2000/xmlns/";
				}
				return false;
			}

			public bool IsLocalNameAndNamespaceUri(XmlDictionaryString localName, XmlDictionaryString ns)
			{
				if (qnameType == QNameType.Normal)
				{
					if (LocalName == localName)
					{
						return Namespace.IsUri(ns);
					}
					return false;
				}
				if (Namespace.Prefix == localName)
				{
					return ns.Value == "http://www.w3.org/2000/xmlns/";
				}
				return false;
			}

			public bool IsPrefixAndLocalName(string prefix, string localName)
			{
				if (qnameType == QNameType.Normal)
				{
					if (Prefix == prefix)
					{
						return LocalName == localName;
					}
					return false;
				}
				if (prefix == "xmlns")
				{
					return Namespace.Prefix == localName;
				}
				return false;
			}

			public bool TryGetLocalNameAsDictionaryString(out XmlDictionaryString localName)
			{
				if (qnameType == QNameType.Normal)
				{
					return LocalName.TryGetDictionaryString(out localName);
				}
				localName = null;
				return false;
			}

			public bool TryGetNamespaceUriAsDictionaryString(out XmlDictionaryString ns)
			{
				if (qnameType == QNameType.Normal)
				{
					return Namespace.Uri.TryGetDictionaryString(out ns);
				}
				ns = null;
				return false;
			}

			public bool TryGetValueAsDictionaryString(out XmlDictionaryString value)
			{
				if (qnameType == QNameType.Normal)
				{
					return Value.TryGetDictionaryString(out value);
				}
				value = null;
				return false;
			}
		}

		protected class XmlElementNode : XmlNode
		{
			private XmlEndElementNode endElementNode;

			private int bufferOffset;

			public int NameOffset;

			public int NameLength;

			public XmlEndElementNode EndElement => endElementNode;

			public int BufferOffset
			{
				get
				{
					return bufferOffset;
				}
				set
				{
					bufferOffset = value;
				}
			}

			public XmlElementNode(XmlBufferReader bufferReader)
				: this(new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader))
			{
			}

			private XmlElementNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
				: base(XmlNodeType.Element, prefix, localName, value, (XmlNodeFlags)33, ReadState.Interactive, null, -1)
			{
				endElementNode = new XmlEndElementNode(prefix, localName, value);
			}
		}

		protected class XmlAttributeNode : XmlNode
		{
			public XmlAttributeNode(XmlBufferReader bufferReader)
				: this(new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader))
			{
			}

			private XmlAttributeNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
				: base(XmlNodeType.Attribute, prefix, localName, value, (XmlNodeFlags)15, ReadState.Interactive, new XmlAttributeTextNode(prefix, localName, value), 0)
			{
			}
		}

		protected class XmlEndElementNode : XmlNode
		{
			public XmlEndElementNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
				: base(XmlNodeType.EndElement, prefix, localName, value, XmlNodeFlags.HasContent, ReadState.Interactive, null, -1)
			{
			}
		}

		protected class XmlTextNode : XmlNode
		{
			protected XmlTextNode(XmlNodeType nodeType, PrefixHandle prefix, StringHandle localName, ValueHandle value, XmlNodeFlags nodeFlags, ReadState readState, XmlAttributeTextNode attributeTextNode, int depthDelta)
				: base(nodeType, prefix, localName, value, nodeFlags, readState, attributeTextNode, depthDelta)
			{
			}
		}

		protected class XmlAtomicTextNode : XmlTextNode
		{
			public XmlAtomicTextNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.Text, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), (XmlNodeFlags)60, ReadState.Interactive, null, 0)
			{
			}
		}

		protected class XmlComplexTextNode : XmlTextNode
		{
			public XmlComplexTextNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.Text, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), (XmlNodeFlags)36, ReadState.Interactive, null, 0)
			{
			}
		}

		protected class XmlWhitespaceTextNode : XmlTextNode
		{
			public XmlWhitespaceTextNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.Whitespace, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.HasValue, ReadState.Interactive, null, 0)
			{
			}
		}

		protected class XmlCDataNode : XmlTextNode
		{
			public XmlCDataNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.CDATA, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), (XmlNodeFlags)36, ReadState.Interactive, null, 0)
			{
			}
		}

		protected class XmlAttributeTextNode : XmlTextNode
		{
			public XmlAttributeTextNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
				: base(XmlNodeType.Text, prefix, localName, value, (XmlNodeFlags)47, ReadState.Interactive, null, 1)
			{
			}
		}

		protected class XmlInitialNode : XmlNode
		{
			public XmlInitialNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.None, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.None, ReadState.Initial, null, 0)
			{
			}
		}

		protected class XmlDeclarationNode : XmlNode
		{
			public XmlDeclarationNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.XmlDeclaration, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.CanGetAttribute, ReadState.Interactive, null, 0)
			{
			}
		}

		protected class XmlCommentNode : XmlNode
		{
			public XmlCommentNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.Comment, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.HasValue, ReadState.Interactive, null, 0)
			{
			}
		}

		protected class XmlEndOfFileNode : XmlNode
		{
			public XmlEndOfFileNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.None, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.None, ReadState.EndOfFile, null, 0)
			{
			}
		}

		protected class XmlClosedNode : XmlNode
		{
			public XmlClosedNode(XmlBufferReader bufferReader)
				: base(XmlNodeType.None, new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader), XmlNodeFlags.None, ReadState.Closed, null, 0)
			{
			}
		}

		private class AttributeSorter : IComparer
		{
			private object[] indeces;

			private XmlAttributeNode[] attributeNodes;

			private int attributeCount;

			private int attributeIndex1;

			private int attributeIndex2;

			public bool Sort(XmlAttributeNode[] attributeNodes, int attributeCount)
			{
				attributeIndex1 = -1;
				attributeIndex2 = -1;
				this.attributeNodes = attributeNodes;
				this.attributeCount = attributeCount;
				bool result = Sort();
				this.attributeNodes = null;
				this.attributeCount = 0;
				return result;
			}

			public void GetIndeces(out int attributeIndex1, out int attributeIndex2)
			{
				attributeIndex1 = this.attributeIndex1;
				attributeIndex2 = this.attributeIndex2;
			}

			public void Close()
			{
				if (indeces != null && indeces.Length > 32)
				{
					indeces = null;
				}
			}

			private bool Sort()
			{
				if (indeces != null && indeces.Length == attributeCount && IsSorted())
				{
					return true;
				}
				object[] array = new object[attributeCount];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = i;
				}
				indeces = array;
				Array.Sort(indeces, 0, attributeCount, this);
				return IsSorted();
			}

			private bool IsSorted()
			{
				for (int i = 0; i < indeces.Length - 1; i++)
				{
					if (Compare(indeces[i], indeces[i + 1]) >= 0)
					{
						attributeIndex1 = (int)indeces[i];
						attributeIndex2 = (int)indeces[i + 1];
						return false;
					}
				}
				return true;
			}

			public int Compare(object obj1, object obj2)
			{
				int num = (int)obj1;
				int num2 = (int)obj2;
				XmlAttributeNode xmlAttributeNode = attributeNodes[num];
				XmlAttributeNode xmlAttributeNode2 = attributeNodes[num2];
				int num3 = CompareQNameType(xmlAttributeNode.QNameType, xmlAttributeNode2.QNameType);
				if (num3 == 0)
				{
					if (xmlAttributeNode.QNameType == QNameType.Normal)
					{
						num3 = xmlAttributeNode.LocalName.CompareTo(xmlAttributeNode2.LocalName);
						if (num3 == 0)
						{
							num3 = xmlAttributeNode.Namespace.Uri.CompareTo(xmlAttributeNode2.Namespace.Uri);
						}
					}
					else
					{
						num3 = xmlAttributeNode.Namespace.Prefix.CompareTo(xmlAttributeNode2.Namespace.Prefix);
					}
				}
				return num3;
			}

			public int CompareQNameType(QNameType type1, QNameType type2)
			{
				return type1 - type2;
			}
		}

		private class NamespaceManager
		{
			private class XmlAttribute
			{
				private XmlSpace space;

				private string lang;

				private int depth;

				public int Depth
				{
					get
					{
						return depth;
					}
					set
					{
						depth = value;
					}
				}

				public string XmlLang
				{
					get
					{
						return lang;

System.Security.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Net;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography.Xml;
using System.Security.Permissions;
using System.Security.Policy;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using Mono.Security;
using Mono.Security.Cryptography;
using Mono.Security.X509;
using Unity;

[assembly: AllowPartiallyTrustedCallers]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: SatelliteContractVersion("4.0.0.0")]
[assembly: CLSCompliant(true)]
[assembly: ComVisible(false)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyDelaySign(true)]
[assembly: AssemblyDefaultAlias("System.Security.dll")]
[assembly: AssemblyDescription("System.Security.dll")]
[assembly: AssemblyTitle("System.Security.dll")]
[assembly: AssemblyFileVersion("4.6.57.0")]
[assembly: AssemblyInformationalVersion("4.6.57.0")]
[assembly: AssemblyCompany("Mono development team")]
[assembly: AssemblyProduct("Mono Common Language Infrastructure")]
[assembly: AssemblyCopyright("(c) Various Mono authors")]
[assembly: AssemblyVersion("4.0.0.0")]
internal static class Consts
{
	public const string MonoVersion = "5.11.0.0";

	public const string MonoCompany = "Mono development team";

	public const string MonoProduct = "Mono Common Language Infrastructure";

	public const string MonoCopyright = "(c) Various Mono authors";

	public const int MonoCorlibVersion = 1051100001;

	public const string FxVersion = "4.0.0.0";

	public const string FxFileVersion = "4.6.57.0";

	public const string EnvironmentVersion = "4.0.30319.42000";

	public const string VsVersion = "0.0.0.0";

	public const string VsFileVersion = "11.0.0.0";

	private const string PublicKeyToken = "b77a5c561934e089";

	public const string AssemblyI18N = "I18N, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMicrosoft_JScript = "Microsoft.JScript, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMicrosoft_VisualStudio = "Microsoft.VisualStudio, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMicrosoft_VisualStudio_Web = "Microsoft.VisualStudio.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMicrosoft_VSDesigner = "Microsoft.VSDesigner, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblyMono_Http = "Mono.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMono_Posix = "Mono.Posix, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMono_Security = "Mono.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyMono_Messaging_RabbitMQ = "Mono.Messaging.RabbitMQ, Version=4.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756";

	public const string AssemblyCorlib = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem = "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_Data = "System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_Design = "System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_DirectoryServices = "System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Drawing = "System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Drawing_Design = "System.Drawing.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Messaging = "System.Messaging, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Security = "System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_ServiceProcess = "System.ServiceProcess, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Web = "System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";

	public const string AssemblySystem_Windows_Forms = "System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_2_0 = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystemCore_3_5 = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string AssemblySystem_Core = "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

	public const string WindowsBase_3_0 = "WindowsBase, Version=3.0.0.0, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyWindowsBase = "WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyPresentationCore_3_5 = "PresentationCore, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyPresentationCore_4_0 = "PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblyPresentationFramework_3_5 = "PresentationFramework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";

	public const string AssemblySystemServiceModel_3_0 = "System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
}
internal sealed class Locale
{
	private Locale()
	{
	}

	public static string GetText(string msg)
	{
		return msg;
	}

	public static string GetText(string fmt, params object[] args)
	{
		return string.Format(fmt, args);
	}
}
internal class SR
{
	public const string ArgumentOutOfRange_Index = "Index was out of range.  Must be non-negative and less than the size of the collection.";

	public const string Arg_EmptyOrNullString = "String cannot be empty or null.";

	public const string Cryptography_Partial_Chain = "A certificate chain could not be built to a trusted root authority.";

	public const string Cryptography_Xml_BadWrappedKeySize = "Bad wrapped key size.";

	public const string Cryptography_Xml_CipherValueElementRequired = "A Cipher Data element should have either a CipherValue or a CipherReference element.";

	public const string Cryptography_Xml_CreateHashAlgorithmFailed = "Could not create hash algorithm object.";

	public const string Cryptography_Xml_CreateTransformFailed = "Could not create the XML transformation identified by the URI {0}.";

	public const string Cryptography_Xml_CreatedKeyFailed = "Failed to create signing key.";

	public const string Cryptography_Xml_DigestMethodRequired = "A DigestMethod must be specified on a Reference prior to generating XML.";

	public const string Cryptography_Xml_DigestValueRequired = "A Reference must contain a DigestValue.";

	public const string Cryptography_Xml_EnvelopedSignatureRequiresContext = "An XmlDocument context is required for enveloped transforms.";

	public const string Cryptography_Xml_InvalidElement = "Malformed element {0}.";

	public const string Cryptography_Xml_InvalidEncryptionProperty = "Malformed encryption property element.";

	public const string Cryptography_Xml_InvalidKeySize = "The key size should be a non negative integer.";

	public const string Cryptography_Xml_InvalidReference = "Malformed reference element.";

	public const string Cryptography_Xml_InvalidSignatureLength = "The length of the signature with a MAC should be less than the hash output length.";

	public const string Cryptography_Xml_InvalidSignatureLength2 = "The length in bits of the signature with a MAC should be a multiple of 8.";

	public const string Cryptography_Xml_InvalidX509IssuerSerialNumber = "X509 issuer serial number is invalid.";

	public const string Cryptography_Xml_KeyInfoRequired = "A KeyInfo element is required to check the signature.";

	public const string Cryptography_Xml_KW_BadKeySize = "The length of the encrypted data in Key Wrap is either 32, 40 or 48 bytes.";

	public const string Cryptography_Xml_LoadKeyFailed = "Signing key is not loaded.";

	public const string Cryptography_Xml_MissingAlgorithm = "Symmetric algorithm is not specified.";

	public const string Cryptography_Xml_MissingCipherData = "Cipher data is not specified.";

	public const string Cryptography_Xml_MissingDecryptionKey = "Unable to retrieve the decryption key.";

	public const string Cryptography_Xml_MissingEncryptionKey = "Unable to retrieve the encryption key.";

	public const string Cryptography_Xml_NotSupportedCryptographicTransform = "The specified cryptographic transform is not supported.";

	public const string Cryptography_Xml_ReferenceElementRequired = "At least one Reference element is required.";

	public const string Cryptography_Xml_ReferenceTypeRequired = "The Reference type must be set in an EncryptedReference object.";

	public const string Cryptography_Xml_SelfReferenceRequiresContext = "An XmlDocument context is required to resolve the Reference Uri {0}.";

	public const string Cryptography_Xml_SignatureDescriptionNotCreated = "SignatureDescription could not be created for the signature algorithm supplied.";

	public const string Cryptography_Xml_SignatureMethodKeyMismatch = "The key does not fit the SignatureMethod.";

	public const string Cryptography_Xml_SignatureMethodRequired = "A signature method is required.";

	public const string Cryptography_Xml_SignatureValueRequired = "Signature requires a SignatureValue.";

	public const string Cryptography_Xml_SignedInfoRequired = "Signature requires a SignedInfo.";

	public const string Cryptography_Xml_TransformIncorrectInputType = "The input type was invalid for this transform.";

	public const string Cryptography_Xml_IncorrectObjectType = "Type of input object is invalid.";

	public const string Cryptography_Xml_UnknownTransform = "Unknown transform has been encountered.";

	public const string Cryptography_Xml_UriNotResolved = "Unable to resolve Uri {0}.";

	public const string Cryptography_Xml_UriNotSupported = " The specified Uri is not supported.";

	public const string Cryptography_Xml_UriRequired = "A Uri attribute is required for a CipherReference element.";

	public const string Cryptography_Xml_XrmlMissingContext = "Null Context property encountered.";

	public const string Cryptography_Xml_XrmlMissingIRelDecryptor = "IRelDecryptor is required.";

	public const string Cryptography_Xml_XrmlMissingIssuer = "Issuer node is required.";

	public const string Cryptography_Xml_XrmlMissingLicence = "License node is required.";

	public const string Cryptography_Xml_XrmlUnableToDecryptGrant = "Unable to decrypt grant content.";

	public const string NotSupported_KeyAlgorithm = "The certificate key algorithm is not supported.";

	public const string Log_ActualHashValue = "Actual hash value: {0}";

	public const string Log_BeginCanonicalization = "Beginning canonicalization using \"{0}\" ({1}).";

	public const string Log_BeginSignatureComputation = "Beginning signature computation.";

	public const string Log_BeginSignatureVerification = "Beginning signature verification.";

	public const string Log_BuildX509Chain = "Building and verifying the X509 chain for certificate {0}.";

	public const string Log_CanonicalizationSettings = "Canonicalization transform is using resolver {0} and base URI \"{1}\".";

	public const string Log_CanonicalizedOutput = "Output of canonicalization transform: {0}";

	public const string Log_CertificateChain = "Certificate chain:";

	public const string Log_CheckSignatureFormat = "Checking signature format using format validator \"[{0}] {1}.{2}\".";

	public const string Log_CheckSignedInfo = "Checking signature on SignedInfo with id \"{0}\".";

	public const string Log_FormatValidationSuccessful = "Signature format validation was successful.";

	public const string Log_FormatValidationNotSuccessful = "Signature format validation failed.";

	public const string Log_KeyUsages = "Found key usages \"{0}\" in extension {1} on certificate {2}.";

	public const string Log_NoNamespacesPropagated = "No namespaces are being propagated.";

	public const string Log_PropagatingNamespace = "Propagating namespace {0}=\"{1}\".";

	public const string Log_RawSignatureValue = "Raw signature: {0}";

	public const string Log_ReferenceHash = "Reference {0} hashed with \"{1}\" ({2}) has hash value {3}, expected hash value {4}.";

	public const string Log_RevocationMode = "Revocation mode for chain building: {0}.";

	public const string Log_RevocationFlag = "Revocation flag for chain building: {0}.";

	public const string Log_SigningAsymmetric = "Calculating signature with key {0} using signature description {1}, hash algorithm {2}, and asymmetric signature formatter {3}.";

	public const string Log_SigningHmac = "Calculating signature using keyed hash algorithm {0}.";

	public const string Log_SigningReference = "Hashing reference {0}, Uri \"{1}\", Id \"{2}\", Type \"{3}\" with hash algorithm \"{4}\" ({5}).";

	public const string Log_TransformedReferenceContents = "Transformed reference contents: {0}";

	public const string Log_UnsafeCanonicalizationMethod = "Canonicalization method \"{0}\" is not on the safe list. Safe canonicalization methods are: {1}.";

	public const string Log_UrlTimeout = "URL retrieval timeout for chain building: {0}.";

	public const string Log_VerificationFailed = "Verification failed checking {0}.";

	public const string Log_VerificationFailed_References = "references";

	public const string Log_VerificationFailed_SignedInfo = "SignedInfo";

	public const string Log_VerificationFailed_X509Chain = "X509 chain verification";

	public const string Log_VerificationFailed_X509KeyUsage = "X509 key usage verification";

	public const string Log_VerificationFlag = "Verification flags for chain building: {0}.";

	public const string Log_VerificationTime = "Verification time for chain building: {0}.";

	public const string Log_VerificationWithKeySuccessful = "Verification with key {0} was successful.";

	public const string Log_VerificationWithKeyNotSuccessful = "Verification with key {0} was not successful.";

	public const string Log_VerifyReference = "Processing reference {0}, Uri \"{1}\", Id \"{2}\", Type \"{3}\".";

	public const string Log_VerifySignedInfoAsymmetric = "Verifying SignedInfo using key {0}, signature description {1}, hash algorithm {2}, and asymmetric signature deformatter {3}.";

	public const string Log_VerifySignedInfoHmac = "Verifying SignedInfo using keyed hash algorithm {0}.";

	public const string Log_X509ChainError = "Error building X509 chain: {0}: {1}.";

	public const string Log_XmlContext = "Using context: {0}";

	public const string Log_SignedXmlRecursionLimit = "Signed xml recursion limit hit while trying to decrypt the key. Reference {0} hashed with \"{1}\" and ({2}).";

	public const string Log_UnsafeTransformMethod = "Transform method \"{0}\" is not on the safe list. Safe transform methods are: {1}.";
}
namespace Mono.Security.Cryptography
{
	internal static class ManagedProtection
	{
		private static RSA user;

		private static RSA machine;

		private static readonly object user_lock = new object();

		private static readonly object machine_lock = new object();

		public static byte[] Protect(byte[] userData, byte[] optionalEntropy, DataProtectionScope scope)
		{
			if (userData == null)
			{
				throw new ArgumentNullException("userData");
			}
			Rijndael rijndael = Rijndael.Create();
			rijndael.KeySize = 128;
			byte[] array = null;
			using (MemoryStream memoryStream = new MemoryStream())
			{
				ICryptoTransform transform = rijndael.CreateEncryptor();
				using CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);
				cryptoStream.Write(userData, 0, userData.Length);
				cryptoStream.Close();
				array = memoryStream.ToArray();
			}
			byte[] array2 = null;
			byte[] array3 = null;
			byte[] array4 = null;
			byte[] array5 = null;
			SHA256 sHA = SHA256.Create();
			try
			{
				array2 = rijndael.Key;
				array3 = rijndael.IV;
				array4 = new byte[68];
				byte[] src = sHA.ComputeHash(userData);
				if (optionalEntropy != null && optionalEntropy.Length != 0)
				{
					byte[] array6 = sHA.ComputeHash(optionalEntropy);
					for (int i = 0; i < 16; i++)
					{
						array2[i] ^= array6[i];
						array3[i] ^= array6[i + 16];
					}
					array4[0] = 2;
				}
				else
				{
					array4[0] = 1;
				}
				array4[1] = 16;
				Buffer.BlockCopy(array2, 0, array4, 2, 16);
				array4[18] = 16;
				Buffer.BlockCopy(array3, 0, array4, 19, 16);
				array4[35] = 32;
				Buffer.BlockCopy(src, 0, array4, 36, 32);
				array5 = new RSAOAEPKeyExchangeFormatter(GetKey(scope)).CreateKeyExchange(array4);
			}
			finally
			{
				if (array2 != null)
				{
					Array.Clear(array2, 0, array2.Length);
					array2 = null;
				}
				if (array4 != null)
				{
					Array.Clear(array4, 0, array4.Length);
					array4 = null;
				}
				if (array3 != null)
				{
					Array.Clear(array3, 0, array3.Length);
					array3 = null;
				}
				rijndael.Clear();
				sHA.Clear();
			}
			byte[] array7 = new byte[array5.Length + array.Length];
			Buffer.BlockCopy(array5, 0, array7, 0, array5.Length);
			Buffer.BlockCopy(array, 0, array7, array5.Length, array.Length);
			return array7;
		}

		public static byte[] Unprotect(byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope)
		{
			if (encryptedData == null)
			{
				throw new ArgumentNullException("encryptedData");
			}
			byte[] array = null;
			Rijndael rijndael = Rijndael.Create();
			RSA key = GetKey(scope);
			int num = key.KeySize >> 3;
			bool flag = encryptedData.Length >= num;
			if (!flag)
			{
				num = encryptedData.Length;
			}
			byte[] array2 = new byte[num];
			Buffer.BlockCopy(encryptedData, 0, array2, 0, num);
			byte[] array3 = null;
			byte[] array4 = null;
			byte[] array5 = null;
			bool flag2 = false;
			bool flag3 = false;
			bool flag4 = false;
			SHA256 sHA = SHA256.Create();
			try
			{
				try
				{
					array3 = new RSAOAEPKeyExchangeDeformatter(key).DecryptKeyExchange(array2);
					flag2 = array3.Length == 68;
				}
				catch
				{
					flag2 = false;
				}
				if (!flag2)
				{
					array3 = new byte[68];
				}
				flag3 = array3[1] == 16 && array3[18] == 16 && array3[35] == 32;
				array4 = new byte[16];
				Buffer.BlockCopy(array3, 2, array4, 0, 16);
				array5 = new byte[16];
				Buffer.BlockCopy(array3, 19, array5, 0, 16);
				if (optionalEntropy != null && optionalEntropy.Length != 0)
				{
					byte[] array6 = sHA.ComputeHash(optionalEntropy);
					for (int i = 0; i < 16; i++)
					{
						array4[i] ^= array6[i];
						array5[i] ^= array6[i + 16];
					}
					flag3 &= array3[0] == 2;
				}
				else
				{
					flag3 &= array3[0] == 1;
				}
				using (MemoryStream memoryStream = new MemoryStream())
				{
					ICryptoTransform transform = rijndael.CreateDecryptor(array4, array5);
					using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
					{
						try
						{
							cryptoStream.Write(encryptedData, num, encryptedData.Length - num);
							cryptoStream.Close();
						}
						catch
						{
						}
					}
					array = memoryStream.ToArray();
				}
				byte[] array7 = sHA.ComputeHash(array);
				flag4 = true;
				for (int j = 0; j < 32; j++)
				{
					if (array7[j] != array3[36 + j])
					{
						flag4 = false;
					}
				}
			}
			finally
			{
				if (array4 != null)
				{
					Array.Clear(array4, 0, array4.Length);
					array4 = null;
				}
				if (array3 != null)
				{
					Array.Clear(array3, 0, array3.Length);
					array3 = null;
				}
				if (array5 != null)
				{
					Array.Clear(array5, 0, array5.Length);
					array5 = null;
				}
				rijndael.Clear();
				sHA.Clear();
			}
			if (!flag || !flag2 || !flag3 || !flag4)
			{
				if (array != null)
				{
					Array.Clear(array, 0, array.Length);
					array = null;
				}
				throw new CryptographicException(Locale.GetText("Invalid data."));
			}
			return array;
		}

		private static RSA GetKey(DataProtectionScope scope)
		{
			switch (scope)
			{
			case DataProtectionScope.CurrentUser:
				if (user == null)
				{
					lock (user_lock)
					{
						CspParameters cspParameters2 = new CspParameters();
						cspParameters2.KeyContainerName = "DAPI";
						user = new RSACryptoServiceProvider(1536, cspParameters2);
					}
				}
				return user;
			case DataProtectionScope.LocalMachine:
				if (machine == null)
				{
					lock (machine_lock)
					{
						CspParameters cspParameters = new CspParameters();
						cspParameters.KeyContainerName = "DAPI";
						cspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
						machine = new RSACryptoServiceProvider(1536, cspParameters);
					}
				}
				return machine;
			default:
				throw new CryptographicException(Locale.GetText("Invalid scope."));
			}
		}
	}
	internal class NativeDapiProtection
	{
		[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
		private struct DATA_BLOB
		{
			private int cbData;

			private IntPtr pbData;

			public void Alloc(int size)
			{
				if (size > 0)
				{
					pbData = Marshal.AllocHGlobal(size);
					cbData = size;
				}
			}

			public void Alloc(byte[] managedMemory)
			{
				if (managedMemory != null)
				{
					int cb = managedMemory.Length;
					pbData = Marshal.AllocHGlobal(cb);
					cbData = cb;
					Marshal.Copy(managedMemory, 0, pbData, cbData);
				}
			}

			public void Free()
			{
				if (pbData != IntPtr.Zero)
				{
					ZeroMemory(pbData, cbData);
					Marshal.FreeHGlobal(pbData);
					pbData = IntPtr.Zero;
					cbData = 0;
				}
			}

			public byte[] ToBytes()
			{
				if (cbData <= 0)
				{
					return new byte[0];
				}
				byte[] array = new byte[cbData];
				Marshal.Copy(pbData, array, 0, cbData);
				return array;
			}
		}

		[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
		private struct CRYPTPROTECT_PROMPTSTRUCT
		{
			private int cbSize;

			private uint dwPromptFlags;

			private IntPtr hwndApp;

			private string szPrompt;

			public CRYPTPROTECT_PROMPTSTRUCT(uint flags)
			{
				cbSize = Marshal.SizeOf(typeof(CRYPTPROTECT_PROMPTSTRUCT));
				dwPromptFlags = flags;
				hwndApp = IntPtr.Zero;
				szPrompt = null;
			}
		}

		private const uint CRYPTPROTECT_UI_FORBIDDEN = 1u;

		private const uint CRYPTPROTECT_LOCAL_MACHINE = 4u;

		[DllImport("crypt32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
		[SuppressUnmanagedCodeSecurity]
		private static extern bool CryptProtectData(ref DATA_BLOB pDataIn, string szDataDescr, ref DATA_BLOB pOptionalEntropy, IntPtr pvReserved, ref CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, uint dwFlags, ref DATA_BLOB pDataOut);

		[DllImport("crypt32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
		[SuppressUnmanagedCodeSecurity]
		private static extern bool CryptUnprotectData(ref DATA_BLOB pDataIn, string szDataDescr, ref DATA_BLOB pOptionalEntropy, IntPtr pvReserved, ref CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, uint dwFlags, ref DATA_BLOB pDataOut);

		[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, EntryPoint = "RtlZeroMemory")]
		[SuppressUnmanagedCodeSecurity]
		private static extern void ZeroMemory(IntPtr dest, int size);

		public static byte[] Protect(byte[] userData, byte[] optionalEntropy, DataProtectionScope scope)
		{
			byte[] array = null;
			int num = 0;
			DATA_BLOB pDataIn = default(DATA_BLOB);
			DATA_BLOB pOptionalEntropy = default(DATA_BLOB);
			DATA_BLOB pDataOut = default(DATA_BLOB);
			try
			{
				CRYPTPROTECT_PROMPTSTRUCT pPromptStruct = new CRYPTPROTECT_PROMPTSTRUCT(0u);
				pDataIn.Alloc(userData);
				pOptionalEntropy.Alloc(optionalEntropy);
				uint num2 = 1u;
				if (scope == DataProtectionScope.LocalMachine)
				{
					num2 |= 4u;
				}
				if (CryptProtectData(ref pDataIn, string.Empty, ref pOptionalEntropy, IntPtr.Zero, ref pPromptStruct, num2, ref pDataOut))
				{
					array = pDataOut.ToBytes();
				}
				else
				{
					num = Marshal.GetLastWin32Error();
				}
			}
			catch (Exception inner)
			{
				throw new CryptographicException(Locale.GetText("Error protecting data."), inner);
			}
			finally
			{
				pDataOut.Free();
				pDataIn.Free();
				pOptionalEntropy.Free();
			}
			if (array == null || num != 0)
			{
				throw new CryptographicException(num);
			}
			return array;
		}

		public static byte[] Unprotect(byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope)
		{
			byte[] array = null;
			int num = 0;
			DATA_BLOB pDataIn = default(DATA_BLOB);
			DATA_BLOB pOptionalEntropy = default(DATA_BLOB);
			DATA_BLOB pDataOut = default(DATA_BLOB);
			try
			{
				CRYPTPROTECT_PROMPTSTRUCT pPromptStruct = new CRYPTPROTECT_PROMPTSTRUCT(0u);
				pDataIn.Alloc(encryptedData);
				pOptionalEntropy.Alloc(optionalEntropy);
				uint num2 = 1u;
				if (scope == DataProtectionScope.LocalMachine)
				{
					num2 |= 4u;
				}
				if (CryptUnprotectData(ref pDataIn, null, ref pOptionalEntropy, IntPtr.Zero, ref pPromptStruct, num2, ref pDataOut))
				{
					array = pDataOut.ToBytes();
				}
				else
				{
					num = Marshal.GetLastWin32Error();
				}
			}
			catch (Exception inner)
			{
				throw new CryptographicException(Locale.GetText("Error protecting data."), inner);
			}
			finally
			{
				pDataIn.Free();
				pDataOut.Free();
				pOptionalEntropy.Free();
			}
			if (array == null || num != 0)
			{
				throw new CryptographicException(num);
			}
			return array;
		}
	}
}
namespace System
{
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	internal class MonoTODOAttribute : Attribute
	{
		private string comment;

		public string Comment => comment;

		public MonoTODOAttribute()
		{
		}

		public MonoTODOAttribute(string comment)
		{
			this.comment = comment;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	internal class MonoDocumentationNoteAttribute : MonoTODOAttribute
	{
		public MonoDocumentationNoteAttribute(string comment)
			: base(comment)
		{
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	internal class MonoExtensionAttribute : MonoTODOAttribute
	{
		public MonoExtensionAttribute(string comment)
			: base(comment)
		{
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	internal class MonoInternalNoteAttribute : MonoTODOAttribute
	{
		public MonoInternalNoteAttribute(string comment)
			: base(comment)
		{
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	internal class MonoLimitationAttribute : MonoTODOAttribute
	{
		public MonoLimitationAttribute(string comment)
			: base(comment)
		{
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
	internal class MonoNotSupportedAttribute : MonoTODOAttribute
	{
		public MonoNotSupportedAttribute(string comment)
			: base(comment)
		{
		}
	}
}
namespace System.Security.Permissions
{
	[Serializable]
	public sealed class DataProtectionPermission : CodeAccessPermission, IUnrestrictedPermission
	{
		private const int version = 1;

		private DataProtectionPermissionFlags _flags;

		public DataProtectionPermissionFlags Flags
		{
			get
			{
				return _flags;
			}
			set
			{
				if (((uint)value & 0xFFFFFFF0u) != 0)
				{
					throw new ArgumentException(string.Format(Locale.GetText("Invalid enum {0}"), value), "DataProtectionPermissionFlags");
				}
				_flags = value;
			}
		}

		public DataProtectionPermission(PermissionState state)
		{
			if (PermissionHelper.CheckPermissionState(state, allowUnrestricted: true) == PermissionState.Unrestricted)
			{
				_flags = DataProtectionPermissionFlags.AllFlags;
			}
		}

		public DataProtectionPermission(DataProtectionPermissionFlags flag)
		{
			Flags = flag;
		}

		public bool IsUnrestricted()
		{
			return _flags == DataProtectionPermissionFlags.AllFlags;
		}

		public override IPermission Copy()
		{
			return (IPermission)(object)new DataProtectionPermission(_flags);
		}

		public override IPermission Intersect(IPermission target)
		{
			DataProtectionPermission dataProtectionPermission = Cast(target);
			if (dataProtectionPermission == null)
			{
				return null;
			}
			if (IsUnrestricted() && dataProtectionPermission.IsUnrestricted())
			{
				return (IPermission)(object)new DataProtectionPermission(PermissionState.Unrestricted);
			}
			if (IsUnrestricted())
			{
				return ((CodeAccessPermission)dataProtectionPermission).Copy();
			}
			if (dataProtectionPermission.IsUnrestricted())
			{
				return ((CodeAccessPermission)this).Copy();
			}
			return (IPermission)(object)new DataProtectionPermission(_flags & dataProtectionPermission._flags);
		}

		public override IPermission Union(IPermission target)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			DataProtectionPermission dataProtectionPermission = Cast(target);
			if (dataProtectionPermission == null)
			{
				return ((CodeAccessPermission)this).Copy();
			}
			if (IsUnrestricted() || dataProtectionPermission.IsUnrestricted())
			{
				return (IPermission)new SecurityPermission(PermissionState.Unrestricted);
			}
			return (IPermission)(object)new DataProtectionPermission(_flags | dataProtectionPermission._flags);
		}

		public override bool IsSubsetOf(IPermission target)
		{
			DataProtectionPermission dataProtectionPermission = Cast(target);
			if (dataProtectionPermission == null)
			{
				return _flags == DataProtectionPermissionFlags.NoFlags;
			}
			if (dataProtectionPermission.IsUnrestricted())
			{
				return true;
			}
			if (IsUnrestricted())
			{
				return false;
			}
			return (_flags & ~dataProtectionPermission._flags) == 0;
		}

		public override void FromXml(SecurityElement securityElement)
		{
			PermissionHelper.CheckSecurityElement(securityElement, "securityElement", 1, 1);
			_flags = (DataProtectionPermissionFlags)Enum.Parse(typeof(DataProtectionPermissionFlags), securityElement.Attribute("Flags"));
		}

		public override SecurityElement ToXml()
		{
			SecurityElement securityElement = PermissionHelper.Element(typeof(DataProtectionPermission), 1);
			securityElement.AddAttribute("Flags", _flags.ToString());
			return securityElement;
		}

		private DataProtectionPermission Cast(IPermission target)
		{
			if (target == null)
			{
				return null;
			}
			DataProtectionPermission obj = target as DataProtectionPermission;
			if (obj == null)
			{
				PermissionHelper.ThrowInvalidPermission(target, typeof(DataProtectionPermission));
			}
			return obj;
		}
	}
	[Serializable]
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
	public sealed class DataProtectionPermissionAttribute : CodeAccessSecurityAttribute
	{
		private DataProtectionPermissionFlags _flags;

		public DataProtectionPermissionFlags Flags
		{
			get
			{
				return _flags;
			}
			set
			{
				if ((value & DataProtectionPermissionFlags.AllFlags) != value)
				{
					throw new ArgumentException(string.Format(Locale.GetText("Invalid flags {0}"), value), "DataProtectionPermissionFlags");
				}
				_flags = value;
			}
		}

		public bool ProtectData
		{
			get
			{
				return (_flags & DataProtectionPermissionFlags.ProtectData) != 0;
			}
			set
			{
				if (value)
				{
					_flags |= DataProtectionPermissionFlags.ProtectData;
				}
				else
				{
					_flags &= ~DataProtectionPermissionFlags.ProtectData;
				}
			}
		}

		public bool UnprotectData
		{
			get
			{
				return (_flags & DataProtectionPermissionFlags.UnprotectData) != 0;
			}
			set
			{
				if (value)
				{
					_flags |= DataProtectionPermissionFlags.UnprotectData;
				}
				else
				{
					_flags &= ~DataProtectionPermissionFlags.UnprotectData;
				}
			}
		}

		public bool ProtectMemory
		{
			get
			{
				return (_flags & DataProtectionPermissionFlags.ProtectMemory) != 0;
			}
			set
			{
				if (value)
				{
					_flags |= DataProtectionPermissionFlags.ProtectMemory;
				}
				else
				{
					_flags &= ~DataProtectionPermissionFlags.ProtectMemory;
				}
			}
		}

		public bool UnprotectMemory
		{
			get
			{
				return (_flags & DataProtectionPermissionFlags.UnprotectMemory) != 0;
			}
			set
			{
				if (value)
				{
					_flags |= DataProtectionPermissionFlags.UnprotectMemory;
				}
				else
				{
					_flags &= ~DataProtectionPermissionFlags.UnprotectMemory;
				}
			}
		}

		public DataProtectionPermissionAttribute(SecurityAction action)
			: base(action)
		{
		}

		public override IPermission CreatePermission()
		{
			DataProtectionPermission dataProtectionPermission = null;
			if (base.Unrestricted)
			{
				return (IPermission)(object)new DataProtectionPermission(PermissionState.Unrestricted);
			}
			return (IPermission)(object)new DataProtectionPermission(_flags);
		}
	}
	[Serializable]
	[Flags]
	public enum DataProtectionPermissionFlags
	{
		NoFlags = 0,
		ProtectData = 1,
		UnprotectData = 2,
		ProtectMemory = 4,
		UnprotectMemory = 8,
		AllFlags = 0xF
	}
	internal sealed class PermissionHelper
	{
		internal static SecurityElement Element(Type type, int version)
		{
			SecurityElement securityElement = new SecurityElement("IPermission");
			securityElement.AddAttribute("class", type.FullName + ", " + type.Assembly.ToString().Replace('"', '\''));
			securityElement.AddAttribute("version", version.ToString());
			return securityElement;
		}

		internal static PermissionState CheckPermissionState(PermissionState state, bool allowUnrestricted)
		{
			switch (state)
			{
			case PermissionState.Unrestricted:
				if (!allowUnrestricted)
				{
					throw new ArgumentException(Locale.GetText("Unrestricted isn't not allowed for identity permissions."), "state");
				}
				break;
			default:
				throw new ArgumentException(string.Format(Locale.GetText("Invalid enum {0}"), state), "state");
			case PermissionState.None:
				break;
			}
			return state;
		}

		internal static int CheckSecurityElement(SecurityElement se, string parameterName, int minimumVersion, int maximumVersion)
		{
			if (se == null)
			{
				throw new ArgumentNullException(parameterName);
			}
			if (se.Attribute("class") == null)
			{
				throw new ArgumentException(Locale.GetText("Missing 'class' attribute."), parameterName);
			}
			int num = minimumVersion;
			string text = se.Attribute("version");
			if (text != null)
			{
				try
				{
					num = int.Parse(text);
				}
				catch (Exception innerException)
				{
					throw new ArgumentException(string.Format(Locale.GetText("Couldn't parse version from '{0}'."), text), parameterName, innerException);
				}
			}
			if (num < minimumVersion || num > maximumVersion)
			{
				throw new ArgumentException(string.Format(Locale.GetText("Unknown version '{0}', expected versions between ['{1}','{2}']."), num, minimumVersion, maximumVersion), parameterName);
			}
			return num;
		}

		internal static bool IsUnrestricted(SecurityElement se)
		{
			string text = se.Attribute("Unrestricted");
			if (text == null)
			{
				return false;
			}
			return string.Compare(text, bool.TrueString, ignoreCase: true, CultureInfo.InvariantCulture) == 0;
		}

		internal static void ThrowInvalidPermission(IPermission target, Type expected)
		{
			throw new ArgumentException(string.Format(Locale.GetText("Invalid permission type '{0}', expected type '{1}'."), target.GetType(), expected), "target");
		}
	}
}
namespace System.Security.Cryptography
{
	public sealed class CryptographicAttributeObject
	{
		private Oid _oid;

		private AsnEncodedDataCollection _list;

		public Oid Oid => _oid;

		public AsnEncodedDataCollection Values => _list;

		public CryptographicAttributeObject(Oid oid)
		{
			if (oid == null)
			{
				throw new ArgumentNullException("oid");
			}
			_oid = new Oid(oid);
			_list = new AsnEncodedDataCollection();
		}

		public CryptographicAttributeObject(Oid oid, AsnEncodedDataCollection values)
		{
			if (oid == null)
			{
				throw new ArgumentNullException("oid");
			}
			_oid = new Oid(oid);
			if (values == null)
			{
				_list = new AsnEncodedDataCollection();
			}
			else
			{
				_list = values;
			}
		}
	}
	public sealed class CryptographicAttributeObjectCollection : ICollection, IEnumerable
	{
		private ArrayList _list;

		public int Count => _list.Count;

		public bool IsSynchronized => _list.IsSynchronized;

		public CryptographicAttributeObject this[int index] => (CryptographicAttributeObject)_list[index];

		public object SyncRoot => this;

		public CryptographicAttributeObjectCollection()
		{
			_list = new ArrayList();
		}

		public CryptographicAttributeObjectCollection(CryptographicAttributeObject attribute)
			: this()
		{
			_list.Add(attribute);
		}

		public int Add(AsnEncodedData asnEncodedData)
		{
			if (asnEncodedData == null)
			{
				throw new ArgumentNullException("asnEncodedData");
			}
			AsnEncodedDataCollection values = new AsnEncodedDataCollection(asnEncodedData);
			return Add(new CryptographicAttributeObject(asnEncodedData.Oid, values));
		}

		public int Add(CryptographicAttributeObject attribute)
		{
			if (attribute == null)
			{
				throw new ArgumentNullException("attribute");
			}
			int num = -1;
			string value = attribute.Oid.Value;
			for (int i = 0; i < _list.Count; i++)
			{
				if ((_list[i] as CryptographicAttributeObject).Oid.Value == value)
				{
					num = i;
					break;
				}
			}
			if (num >= 0)
			{
				CryptographicAttributeObject cryptographicAttributeObject = this[num];
				AsnEncodedDataEnumerator enumerator = attribute.Values.GetEnumerator();
				while (enumerator.MoveNext())
				{
					AsnEncodedData current = enumerator.Current;
					cryptographicAttributeObject.Values.Add(current);
				}
				return num;
			}
			return _list.Add(attribute);
		}

		public void CopyTo(CryptographicAttributeObject[] array, int index)
		{
			_list.CopyTo(array, index);
		}

		void ICollection.CopyTo(Array array, int index)
		{
			_list.CopyTo(array, index);
		}

		public CryptographicAttributeObjectEnumerator GetEnumerator()
		{
			return new CryptographicAttributeObjectEnumerator(_list);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return new CryptographicAttributeObjectEnumerator(_list);
		}

		public void Remove(CryptographicAttributeObject attribute)
		{
			if (attribute == null)
			{
				throw new ArgumentNullException("attribute");
			}
			_list.Remove(attribute);
		}
	}
	public sealed class CryptographicAttributeObjectEnumerator : IEnumerator
	{
		private IEnumerator enumerator;

		public CryptographicAttributeObject Current => (CryptographicAttributeObject)enumerator.Current;

		object IEnumerator.Current => enumerator.Current;

		internal CryptographicAttributeObjectEnumerator(IEnumerable enumerable)
		{
			enumerator = enumerable.GetEnumerator();
		}

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

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

		internal CryptographicAttributeObjectEnumerator()
		{
			ThrowStub.ThrowNotSupportedException();
		}
	}
	public enum DataProtectionScope
	{
		CurrentUser,
		LocalMachine
	}
	public enum MemoryProtectionScope
	{
		SameProcess,
		CrossProcess,
		SameLogon
	}
	public sealed class ProtectedData
	{
		private enum DataProtectionImplementation
		{
			Unknown = 0,
			Win32CryptoProtect = 1,
			ManagedProtection = 2,
			Unsupported = int.MinValue
		}

		private static DataProtectionImplementation impl;

		private ProtectedData()
		{
		}

		public static byte[] Protect(byte[] userData, byte[] optionalEntropy, DataProtectionScope scope)
		{
			if (userData == null)
			{
				throw new ArgumentNullException("userData");
			}
			Check(scope);
			switch (impl)
			{
			case DataProtectionImplementation.ManagedProtection:
				try
				{
					return ManagedProtection.Protect(userData, optionalEntropy, scope);
				}
				catch (Exception inner2)
				{
					throw new CryptographicException(Locale.GetText("Data protection failed."), inner2);
				}
			case DataProtectionImplementation.Win32CryptoProtect:
				try
				{
					return NativeDapiProtection.Protect(userData, optionalEntropy, scope);
				}
				catch (Exception inner)
				{
					throw new CryptographicException(Locale.GetText("Data protection failed."), inner);
				}
			default:
				throw new PlatformNotSupportedException();
			}
		}

		public static byte[] Unprotect(byte[] encryptedData, byte[] optionalEntropy, DataProtectionScope scope)
		{
			if (encryptedData == null)
			{
				throw new ArgumentNullException("encryptedData");
			}
			Check(scope);
			switch (impl)
			{
			case DataProtectionImplementation.ManagedProtection:
				try
				{
					return ManagedProtection.Unprotect(encryptedData, optionalEntropy, scope);
				}
				catch (Exception inner2)
				{
					throw new CryptographicException(Locale.GetText("Data unprotection failed."), inner2);
				}
			case DataProtectionImplementation.Win32CryptoProtect:
				try
				{
					return NativeDapiProtection.Unprotect(encryptedData, optionalEntropy, scope);
				}
				catch (Exception inner)
				{
					throw new CryptographicException(Locale.GetText("Data unprotection failed."), inner);
				}
			default:
				throw new PlatformNotSupportedException();
			}
		}

		private static void Detect()
		{
			OperatingSystem oSVersion = Environment.OSVersion;
			switch (oSVersion.Platform)
			{
			case PlatformID.Win32NT:
				if (oSVersion.Version.Major < 5)
				{
					impl = DataProtectionImplementation.Unsupported;
				}
				else
				{
					impl = DataProtectionImplementation.Win32CryptoProtect;
				}
				break;
			case PlatformID.Unix:
				impl = DataProtectionImplementation.ManagedProtection;
				break;
			default:
				impl = DataProtectionImplementation.Unsupported;
				break;
			}
		}

		private static void Check(DataProtectionScope scope)
		{
			if (scope < DataProtectionScope.CurrentUser || scope > DataProtectionScope.LocalMachine)
			{
				throw new ArgumentException(Locale.GetText("Invalid enum value '{0}' for '{1}'.", scope, "DataProtectionScope"), "scope");
			}
			switch (impl)
			{
			case DataProtectionImplementation.Unknown:
				Detect();
				break;
			case DataProtectionImplementation.Unsupported:
				throw new PlatformNotSupportedException();
			}
		}
	}
	public sealed class ProtectedMemory
	{
		private enum MemoryProtectionImplementation
		{
			Unknown = 0,
			Win32RtlEncryptMemory = 1,
			Win32CryptoProtect = 2,
			Unsupported = int.MinValue
		}

		private const int BlockSize = 16;

		private static MemoryProtectionImplementation impl;

		private ProtectedMemory()
		{
		}

		[MonoTODO("only supported on Windows 2000 SP3 and later")]
		public static void Protect(byte[] userData, MemoryProtectionScope scope)
		{
			if (userData == null)
			{
				throw new ArgumentNullException("userData");
			}
			Check(userData.Length, scope);
			try
			{
				uint cbData = (uint)userData.Length;
				switch (impl)
				{
				case MemoryProtectionImplementation.Win32RtlEncryptMemory:
				{
					int num = RtlEncryptMemory(userData, cbData, (uint)scope);
					if (num < 0)
					{
						throw new CryptographicException(Locale.GetText("Error. NTSTATUS = {0}.", num));
					}
					break;
				}
				case MemoryProtectionImplementation.Win32CryptoProtect:
					if (!CryptProtectMemory(userData, cbData, (uint)scope))
					{
						throw new CryptographicException(Marshal.GetLastWin32Error());
					}
					break;
				default:
					throw new PlatformNotSupportedException();
				}
			}
			catch
			{
				impl = MemoryProtectionImplementation.Unsupported;
				throw new PlatformNotSupportedException();
			}
		}

		[MonoTODO("only supported on Windows 2000 SP3 and later")]
		public static void Unprotect(byte[] encryptedData, MemoryProtectionScope scope)
		{
			if (encryptedData == null)
			{
				throw new ArgumentNullException("encryptedData");
			}
			Check(encryptedData.Length, scope);
			try
			{
				uint cbData = (uint)encryptedData.Length;
				switch (impl)
				{
				case MemoryProtectionImplementation.Win32RtlEncryptMemory:
				{
					int num = RtlDecryptMemory(encryptedData, cbData, (uint)scope);
					if (num < 0)
					{
						throw new CryptographicException(Locale.GetText("Error. NTSTATUS = {0}.", num));
					}
					break;
				}
				case MemoryProtectionImplementation.Win32CryptoProtect:
					if (!CryptUnprotectMemory(encryptedData, cbData, (uint)scope))
					{
						throw new CryptographicException(Marshal.GetLastWin32Error());
					}
					break;
				default:
					throw new PlatformNotSupportedException();
				}
			}
			catch
			{
				impl = MemoryProtectionImplementation.Unsupported;
				throw new PlatformNotSupportedException();
			}
		}

		private static void Detect()
		{
			OperatingSystem oSVersion = Environment.OSVersion;
			PlatformID platform = oSVersion.Platform;
			if (platform == PlatformID.Win32NT)
			{
				Version version = oSVersion.Version;
				if (version.Major < 5)
				{
					impl = MemoryProtectionImplementation.Unsupported;
				}
				else if (version.Major == 5)
				{
					if (version.Minor < 2)
					{
						impl = MemoryProtectionImplementation.Win32RtlEncryptMemory;
					}
					else
					{
						impl = MemoryProtectionImplementation.Win32CryptoProtect;
					}
				}
				else
				{
					impl = MemoryProtectionImplementation.Win32CryptoProtect;
				}
			}
			else
			{
				impl = MemoryProtectionImplementation.Unsupported;
			}
		}

		private static void Check(int size, MemoryProtectionScope scope)
		{
			if (size % 16 != 0)
			{
				throw new CryptographicException(Locale.GetText("Not a multiple of {0} bytes.", 16));
			}
			if (scope < MemoryProtectionScope.SameProcess || scope > MemoryProtectionScope.SameLogon)
			{
				throw new ArgumentException(Locale.GetText("Invalid enum value for '{0}'.", "MemoryProtectionScope"), "scope");
			}
			switch (impl)
			{
			case MemoryProtectionImplementation.Unknown:
				Detect();
				break;
			case MemoryProtectionImplementation.Unsupported:
				throw new PlatformNotSupportedException();
			}
		}

		[DllImport("advapi32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, EntryPoint = "SystemFunction040", SetLastError = true)]
		[SuppressUnmanagedCodeSecurity]
		private static extern int RtlEncryptMemory(byte[] pData, uint cbData, uint dwFlags);

		[DllImport("advapi32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, EntryPoint = "SystemFunction041", SetLastError = true)]
		[SuppressUnmanagedCodeSecurity]
		private static extern int RtlDecryptMemory(byte[] pData, uint cbData, uint dwFlags);

		[DllImport("crypt32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
		[SuppressUnmanagedCodeSecurity]
		private static extern bool CryptProtectMemory(byte[] pData, uint cbData, uint dwFlags);

		[DllImport("crypt32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
		[SuppressUnmanagedCodeSecurity]
		private static extern bool CryptUnprotectMemory(byte[] pData, uint cbData, uint dwFlags);
	}
}
namespace System.Security.Cryptography.Pkcs
{
	public sealed class AlgorithmIdentifier
	{
		private Oid _oid;

		private int _length;

		private byte[] _params;

		public int KeyLength
		{
			get
			{
				return _length;
			}
			set
			{
				_length = value;
			}
		}

		public Oid Oid
		{
			get
			{
				return _oid;
			}
			set
			{
				_oid = value;
			}
		}

		public byte[] Parameters
		{
			get
			{
				return _params;
			}
			set
			{
				_params = value;
			}
		}

		public AlgorithmIdentifier()
		{
			_oid = new Oid("1.2.840.113549.3.7", "3des");
			_params = new byte[0];
		}

		public AlgorithmIdentifier(Oid oid)
		{
			_oid = oid;
			_params = new byte[0];
		}

		public AlgorithmIdentifier(Oid oid, int keyLength)
		{
			_oid = oid;
			_length = keyLength;
			_params = new byte[0];
		}
	}
	public sealed class CmsRecipient
	{
		private SubjectIdentifierType _recipient;

		private X509Certificate2 _certificate;

		public X509Certificate2 Certificate => _certificate;

		public SubjectIdentifierType RecipientIdentifierType => _recipient;

		public CmsRecipient(X509Certificate2 certificate)
		{
			if (certificate == null)
			{
				throw new ArgumentNullException("certificate");
			}
			_recipient = SubjectIdentifierType.IssuerAndSerialNumber;
			_certificate = certificate;
		}

		public CmsRecipient(SubjectIdentifierType recipientIdentifierType, X509Certificate2 certificate)
		{
			if (certificate == null)
			{
				throw new ArgumentNullException("certificate");
			}
			if (recipientIdentifierType == SubjectIdentifierType.Unknown)
			{
				_recipient = SubjectIdentifierType.IssuerAndSerialNumber;
			}
			else
			{
				_recipient = recipientIdentifierType;
			}
			_certificate = certificate;
		}
	}
	public sealed class CmsRecipientCollection : ICollection, IEnumerable
	{
		private ArrayList _list;

		public int Count => _list.Count;

		public bool IsSynchronized => _list.IsSynchronized;

		public CmsRecipient this[int index] => (CmsRecipient)_list[index];

		public object SyncRoot => _list.SyncRoot;

		public CmsRecipientCollection()
		{
			_list = new ArrayList();
		}

		public CmsRecipientCollection(CmsRecipient recipient)
		{
			_list.Add(recipient);
		}

		public CmsRecipientCollection(SubjectIdentifierType recipientIdentifierType, X509Certificate2Collection certificates)
		{
			X509Certificate2Enumerator enumerator = certificates.GetEnumerator();
			while (enumerator.MoveNext())
			{
				X509Certificate2 current = enumerator.Current;
				CmsRecipient value = new CmsRecipient(recipientIdentifierType, current);
				_list.Add(value);
			}
		}

		public int Add(CmsRecipient recipient)
		{
			return _list.Add(recipient);
		}

		public void CopyTo(Array array, int index)
		{
			_list.CopyTo(array, index);
		}

		public void CopyTo(CmsRecipient[] array, int index)
		{
			_list.CopyTo(array, index);
		}

		public CmsRecipientEnumerator GetEnumerator()
		{
			return new CmsRecipientEnumerator(_list);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return new CmsRecipientEnumerator(_list);
		}

		public void Remove(CmsRecipient recipient)
		{
			_list.Remove(recipient);
		}
	}
	public sealed class CmsRecipientEnumerator : IEnumerator
	{
		private IEnumerator enumerator;

		public CmsRecipient Current => (CmsRecipient)enumerator.Current;

		object IEnumerator.Current => enumerator.Current;

		internal CmsRecipientEnumerator(IEnumerable enumerable)
		{
			enumerator = enumerable.GetEnumerator();
		}

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

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

		internal CmsRecipientEnumerator()
		{
			ThrowStub.ThrowNotSupportedException();
		}
	}
	public sealed class CmsSigner
	{
		private SubjectIdentifierType _signer;

		private X509Certificate2 _certificate;

		private X509Certificate2Collection _coll;

		private Oid _digest;

		private X509IncludeOption _options;

		private CryptographicAttributeObjectCollection _signed;

		private CryptographicAttributeObjectCollection _unsigned;

		public CryptographicAttributeObjectCollection SignedAttributes => _signed;

		public X509Certificate2 Certificate
		{
			get
			{
				return _certificate;
			}
			set
			{
				_certificate = value;
			}
		}

		public X509Certificate2Collection Certificates => _coll;

		public Oid DigestAlgorithm
		{
			get
			{
				return _digest;
			}
			set
			{
				_digest = value;
			}
		}

		public X509IncludeOption IncludeOption
		{
			get
			{
				return _options;
			}
			set
			{
				_options = value;
			}
		}

		public SubjectIdentifierType SignerIdentifierType
		{
			get
			{
				return _signer;
			}
			set
			{
				if (value == SubjectIdentifierType.Unknown)
				{
					throw new ArgumentException("value");
				}
				_signer = value;
			}
		}

		public CryptographicAttributeObjectCollection UnsignedAttributes => _unsigned;

		public CmsSigner()
		{
			_signer = SubjectIdentifierType.IssuerAndSerialNumber;
			_digest = new Oid("1.3.14.3.2.26");
			_options = X509IncludeOption.ExcludeRoot;
			_signed = new CryptographicAttributeObjectCollection();
			_unsigned = new CryptographicAttributeObjectCollection();
			_coll = new X509Certificate2Collection();
		}

		public CmsSigner(SubjectIdentifierType signerIdentifierType)
			: this()
		{
			if (signerIdentifierType == SubjectIdentifierType.Unknown)
			{
				_signer = SubjectIdentifierType.IssuerAndSerialNumber;
			}
			else
			{
				_signer = signerIdentifierType;
			}
		}

		public CmsSigner(SubjectIdentifierType signerIdentifierType, X509Certificate2 certificate)
			: this(signerIdentifierType)
		{
			_certificate = certificate;
		}

		public CmsSigner(X509Certificate2 certificate)
			: this()
		{
			_certificate = certificate;
		}

		[MonoTODO]
		public CmsSigner(CspParameters parameters)
			: this()
		{
		}
	}
	public sealed class ContentInfo
	{
		private Oid _oid;

		private byte[] _content;

		public byte[] Content => (byte[])_content.Clone();

		public Oid ContentType => _oid;

		public ContentInfo(byte[] content)
			: this(new Oid("1.2.840.113549.1.7.1"), content)
		{
		}

		public ContentInfo(Oid contentType, byte[] content)
		{
			if (contentType == null)
			{
				throw new ArgumentNullException("contentType");
			}
			if (content == null)
			{
				throw new ArgumentNullException("content");
			}
			_oid = contentType;
			_content = content;
		}

		~ContentInfo()
		{
		}

		[MonoTODO("MS is stricter than us about the content structure")]
		public static Oid GetContentType(byte[] encodedMessage)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			if (encodedMessage == null)
			{
				throw new ArgumentNullException("algorithm");
			}
			try
			{
				ContentInfo val = new ContentInfo(encodedMessage);
				switch (val.ContentType)
				{
				case "1.2.840.113549.1.7.1":
				case "1.2.840.113549.1.7.2":
				case "1.2.840.113549.1.7.3":
				case "1.2.840.113549.1.7.5":
				case "1.2.840.113549.1.7.6":
					return new Oid(val.ContentType);
				default:
					throw new CryptographicException(string.Format(Locale.GetText("Bad ASN1 - invalid OID '{0}'"), val.ContentType));
				}
			}
			catch (Exception inner)
			{
				throw new CryptographicException(Locale.GetText("Bad ASN1 - invalid structure"), inner);
			}
		}
	}
	public sealed class EnvelopedCms
	{
		private ContentInfo _content;

		private AlgorithmIdentifier _identifier;

		private X509Certificate2Collection _certs;

		private RecipientInfoCollection _recipients;

		private CryptographicAttributeObjectCollection _uattribs;

		private SubjectIdentifierType _idType;

		private int _version;

		public X509Certificate2Collection Certificates => _certs;

		public AlgorithmIdentifier ContentEncryptionAlgorithm
		{
			get
			{
				if (_identifier == null)
				{
					_identifier = new AlgorithmIdentifier();
				}
				return _identifier;
			}
		}

		public ContentInfo ContentInfo
		{
			get
			{
				if (_content == null)
				{
					Oid contentType = new Oid("1.2.840.113549.1.7.1");
					_content = new ContentInfo(contentType, new byte[0]);
				}
				return _content;
			}
		}

		public RecipientInfoCollection RecipientInfos => _recipients;

		public CryptographicAttributeObjectCollection UnprotectedAttributes => _uattribs;

		public int Version => _version;

		public EnvelopedCms()
		{
			_certs = new X509Certificate2Collection();
			_recipients = new RecipientInfoCollection();
			_uattribs = new CryptographicAttributeObjectCollection();
		}

		public EnvelopedCms(ContentInfo contentInfo)
			: this()
		{
			if (contentInfo == null)
			{
				throw new ArgumentNullException("contentInfo");
			}
			_content = contentInfo;
		}

		public EnvelopedCms(ContentInfo contentInfo, AlgorithmIdentifier encryptionAlgorithm)
			: this(contentInfo)
		{
			if (encryptionAlgorithm == null)
			{
				throw new ArgumentNullException("encryptionAlgorithm");
			}
			_identifier = encryptionAlgorithm;
		}

		public EnvelopedCms(SubjectIdentifierType recipientIdentifierType, ContentInfo contentInfo)
			: this(contentInfo)
		{
			_idType = recipientIdentifierType;
			if (_idType == SubjectIdentifierType.SubjectKeyIdentifier)
			{
				_version = 2;
			}
		}

		public EnvelopedCms(SubjectIdentifierType recipientIdentifierType, ContentInfo contentInfo, AlgorithmIdentifier encryptionAlgorithm)
			: this(contentInfo, encryptionAlgorithm)
		{
			_idType = recipientIdentifierType;
			if (_idType == SubjectIdentifierType.SubjectKeyIdentifier)
			{
				_version = 2;
			}
		}

		private X509IssuerSerial GetIssuerSerial(string issuer, byte[] serial)
		{
			X509IssuerSerial result = default(X509IssuerSerial);
			result.IssuerName = issuer;
			StringBuilder stringBuilder = new StringBuilder();
			foreach (byte b in serial)
			{
				stringBuilder.Append(b.ToString("X2"));
			}
			result.SerialNumber = stringBuilder.ToString();
			return result;
		}

		[MonoTODO]
		public void Decode(byte[] encodedMessage)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			if (encodedMessage == null)
			{
				throw new ArgumentNullException("encodedMessage");
			}
			ContentInfo val = new ContentInfo(encodedMessage);
			if (val.ContentType != "1.2.840.113549.1.7.3")
			{
				throw new Exception("");
			}
			EnvelopedData val2 = new EnvelopedData(val.Content);
			Oid contentType = new Oid(val2.ContentInfo.ContentType);
			_content = new ContentInfo(contentType, new byte[0]);
			foreach (RecipientInfo recipientInfo in val2.RecipientInfos)
			{
				RecipientInfo val3 = recipientInfo;
				AlgorithmIdentifier keyEncryptionAlgorithm = new AlgorithmIdentifier(new Oid(val3.Oid));
				SubjectIdentifier recipientIdentifier = null;
				if (val3.SubjectKeyIdentifier != null)
				{
					recipientIdentifier = new SubjectIdentifier(SubjectIdentifierType.SubjectKeyIdentifier, val3.SubjectKeyIdentifier);
				}
				else if (val3.Issuer != null && val3.Serial != null)
				{
					X509IssuerSerial issuerSerial = GetIssuerSerial(val3.Issuer, val3.Serial);
					recipientIdentifier = new SubjectIdentifier(SubjectIdentifierType.IssuerAndSerialNumber, issuerSerial);
				}
				KeyTransRecipientInfo ri = new KeyTransRecipientInfo(val3.Key, keyEncryptionAlgorithm, recipientIdentifier, val3.Version);
				_recipients.Add(ri);
			}
			_version = val2.Version;
		}

		[MonoTODO]
		public void Decrypt()
		{
			throw new InvalidOperationException("not encrypted");
		}

		[MonoTODO]
		public void Decrypt(RecipientInfo recipientInfo)
		{
			if (recipientInfo == null)
			{
				throw new ArgumentNullException("recipientInfo");
			}
			Decrypt();
		}

		[MonoTODO]
		public void Decrypt(RecipientInfo recipientInfo, X509Certificate2Collection extraStore)
		{
			if (recipientInfo == null)
			{
				throw new ArgumentNullException("recipientInfo");
			}
			if (extraStore == null)
			{
				throw new ArgumentNullException("extraStore");
			}
			Decrypt();
		}

		[MonoTODO]
		public void Decrypt(X509Certificate2Collection extraStore)
		{
			if (extraStore == null)
			{
				throw new ArgumentNullException("extraStore");
			}
			Decrypt();
		}

		[MonoTODO]
		public byte[] Encode()
		{
			throw new InvalidOperationException("not encrypted");
		}

		[MonoTODO]
		public void Encrypt()
		{
			if (_content == null || _content.Content == null || _content.Content.Length == 0)
			{
				throw new CryptographicException("no content to encrypt");
			}
		}

		[MonoTODO]
		public void Encrypt(CmsRecipient recipient)
		{
			if (recipient == null)
			{
				throw new ArgumentNullException("recipient");
			}
			Encrypt();
		}

		[MonoTODO]
		public void Encrypt(CmsRecipientCollection recipients)
		{
			if (recipients == null)
			{
				throw new ArgumentNullException("recipients");
			}
		}
	}
	public enum KeyAgreeKeyChoice
	{
		Unknown,
		EphemeralKey,
		StaticKey
	}
	[MonoTODO]
	public sealed class KeyAgreeRecipientInfo : RecipientInfo
	{
		public DateTime Date => DateTime.MinValue;

		public override byte[] EncryptedKey => null;

		public override AlgorithmIdentifier KeyEncryptionAlgorithm => null;

		public SubjectIdentifierOrKey OriginatorIdentifierOrKey => null;

		public CryptographicAttributeObject OtherKeyAttribute => null;

		public override SubjectIdentifier RecipientIdentifier => null;

		public override int Version => 0;

		internal KeyAgreeRecipientInfo()
			: base(RecipientInfoType.KeyAgreement)
		{
		}
	}
	public sealed class KeyTransRecipientInfo : RecipientInfo
	{
		private byte[] _encryptedKey;

		private AlgorithmIdentifier _keyEncryptionAlgorithm;

		private SubjectIdentifier _recipientIdentifier;

		private int _version;

		public override byte[] EncryptedKey => _encryptedKey;

		public override AlgorithmIdentifier KeyEncryptionAlgorithm => _keyEncryptionAlgorithm;

		public override SubjectIdentifier RecipientIdentifier => _recipientIdentifier;

		public override int Version => _version;

		internal KeyTransRecipientInfo(byte[] encryptedKey, AlgorithmIdentifier keyEncryptionAlgorithm, SubjectIdentifier recipientIdentifier, int version)
			: base(RecipientInfoType.KeyTransport)
		{
			_encryptedKey = encryptedKey;
			_keyEncryptionAlgorithm = keyEncryptionAlgorithm;
			_recipientIdentifier = recipientIdentifier;
			_version = version;
		}

		internal KeyTransRecipientInfo()
		{
			ThrowStub.ThrowNotSupportedException();
		}
	}
	public class Pkcs9AttributeObject : AsnEncodedData
	{
		public new Oid Oid
		{
			get
			{
				return base.Oid;
			}
			internal set
			{
				base.Oid = value;
			}
		}

		public Pkcs9AttributeObject()
		{
		}

		public Pkcs9AttributeObject(AsnEncodedData asnEncodedData)
			: base(asnEncodedData)
		{
		}

		public Pkcs9AttributeObject(Oid oid, byte[] encodedData)
		{
			if (oid == null)
			{
				throw new ArgumentNullException("oid");
			}
			base.Oid = oid;
			base.RawData = encodedData;
		}

		public Pkcs9AttributeObject(string oid, byte[] encodedData)
			: base(oid, encodedData)
		{
		}

		public override void CopyFrom(AsnEncodedData asnEncodedData)
		{
			if (asnEncodedData == null)
			{
				throw new ArgumentNullException("asnEncodedData");
			}
			throw new ArgumentException("Cannot convert the PKCS#9 attribute.");
		}
	}
	public sealed class Pkcs9ContentType : Pkcs9AttributeObject
	{
		internal const string oid = "1.2.840.113549.1.9.3";

		internal const string friendlyName = "Content Type";

		private Oid _contentType;

		private byte[] _encoded;

		public Oid ContentType
		{
			get
			{
				if (_encoded != null)
				{
					Decode(_encoded);
				}
				return _contentType;
			}
		}

		public Pkcs9ContentType()
		{
			((AsnEncodedData)this).Oid = new Oid("1.2.840.113549.1.9.3", "Content Type");
			_encoded = null;
		}

		internal Pkcs9ContentType(string contentType)
		{
			((AsnEncodedData)this).Oid = new Oid("1.2.840.113549.1.9.3", "Content Type");
			_contentType = new Oid(contentType);
			base.RawData = Encode();
			_encoded = null;
		}

		internal Pkcs9ContentType(byte[] encodedContentType)
		{
			if (encodedContentType == null)
			{
				throw new ArgumentNullException("encodedContentType");
			}
			((AsnEncodedData)this).Oid = new Oid("1.2.840.113549.1.9.3", "Content Type");
			base.RawData = encodedContentType;
			Decode(encodedContentType);
		}

		public override void CopyFrom(AsnEncodedData asnEncodedData)
		{
			base.CopyFrom(asnEncodedData);
			_encoded = asnEncodedData.RawData;
		}

		internal void Decode(byte[] attribute)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (attribute == null || attribute[0] != 6)
			{
				throw new CryptographicException(Locale.GetText("Expected an OID."));
			}
			ASN1 val = new ASN1(attribute);
			_contentType = new Oid(ASN1Convert.ToOid(val));
			_encoded = null;
		}

		internal byte[] Encode()
		{
			if (_contentType == null)
			{
				return null;
			}
			return ASN1Convert.FromOid(_contentType.Value).GetBytes();
		}
	}
	public sealed class Pkcs9DocumentDescription : Pkcs9AttributeObject
	{
		internal const string oid = "1.3.6.1.4.1.311.88.2.2";

		internal const string friendlyName = null;

		private string _desc;

		public string DocumentDescription => _desc;

		public Pkcs9DocumentDescription()
		{
			((AsnEncodedData)this).Oid = new Oid("1.3.6.1.4.1.311.88.2.2", null);
		}

		public Pkcs9DocumentDescription(string documentDescription)
		{
			if (documentDescription == null)
			{
				throw new ArgumentNullException("documentName");
			}
			((AsnEncodedData)this).Oid = new Oid("1.3.6.1.4.1.311.88.2.2", null);
			_desc = documentDescription;
			base.RawData = Encode();
		}

		public Pkcs9DocumentDescription(byte[] encodedDocumentDescription)
		{
			if (encodedDocumentDescription == null)
			{
				throw new ArgumentNullException("encodedDocumentDescription");
			}
			((AsnEncodedData)this).Oid = new Oid("1.3.6.1.4.1.311.88.2.2", null);
			base.RawData = encodedDocumentDescription;
			Decode(encodedDocumentDescription);
		}

		public override void CopyFrom(AsnEncodedData asnEncodedData)
		{
			base.CopyFrom(asnEncodedData);
			Decode(base.RawData);
		}

		internal void Decode(byte[] attribute)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (attribute[0] == 4)
			{
				byte[] value = new ASN1(attribute).Value;
				int num = value.Length;
				if (value[num - 2] == 0)
				{
					num -= 2;
				}
				_desc = Encoding.Unicode.GetString(value, 0, num);
			}
		}

		internal byte[] Encode()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			return new ASN1((byte)4, Encoding.Unicode.GetBytes(_desc + "\0")).GetBytes();
		}
	}
	public sealed class Pkcs9DocumentName : Pkcs9AttributeObject
	{
		internal const string oid = "1.3.6.1.4.1.311.88.2.1";

		internal const string friendlyName = null;

		private string _name;

		public string DocumentName => _name;

		public Pkcs9DocumentName()
		{
			((AsnEncodedData)this).Oid = new Oid("1.3.6.1.4.1.311.88.2.1", null);
		}

		public Pkcs9DocumentName(string documentName)
		{
			if (documentName == null)
			{
				throw new ArgumentNullException("documentName");
			}
			((AsnEncodedData)this).Oid = new Oid("1.3.6.1.4.1.311.88.2.1", null);
			_name = documentName;
			base.RawData = Encode();
		}

		public Pkcs9DocumentName(byte[] encodedDocumentName)
		{
			if (encodedDocumentName == null)
			{
				throw new ArgumentNullException("encodedDocumentName");
			}
			((AsnEncodedData)this).Oid = new Oid("1.3.6.1.4.1.311.88.2.1", null);
			base.RawData = encodedDocumentName;
			Decode(encodedDocumentName);
		}

		public override void CopyFrom(AsnEncodedData asnEncodedData)
		{
			base.CopyFrom(asnEncodedData);
			Decode(base.RawData);
		}

		internal void Decode(byte[] attribute)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (attribute[0] == 4)
			{
				byte[] value = new ASN1(attribute).Value;
				int num = value.Length;
				if (value[num - 2] == 0)
				{
					num -= 2;
				}
				_name = Encoding.Unicode.GetString(value, 0, num);
			}
		}

		internal byte[] Encode()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			return new ASN1((byte)4, Encoding.Unicode.GetBytes(_name + "\0")).GetBytes();
		}
	}
	public sealed class Pkcs9MessageDigest : Pkcs9AttributeObject
	{
		internal const string oid = "1.2.840.113549.1.9.4";

		internal const string friendlyName = "Message Digest";

		private byte[] _messageDigest;

		private byte[] _encoded;

		public byte[] MessageDigest
		{
			get
			{
				if (_encoded != null)
				{
					Decode(_encoded);
				}
				return _messageDigest;
			}
		}

		public Pkcs9MessageDigest()
		{
			((AsnEncodedData)this).Oid = new Oid("1.2.840.113549.1.9.4", "Message Digest");
			_encoded = null;
		}

		internal Pkcs9MessageDigest(byte[] messageDigest, bool encoded)
		{
			if (messageDigest == null)
			{
				throw new ArgumentNullException("messageDigest");
			}
			if (encoded)
			{
				((AsnEncodedData)this).Oid = new Oid("1.2.840.113549.1.9.4", "Message Digest");
				base.RawData = messageDigest;
				Decode(messageDigest);
			}
			else
			{
				((AsnEncodedData)this).Oid = new Oid("1.2.840.113549.1.9.4", "Message Digest");
				_messageDigest = (byte[])_messageDigest.Clone();
				base.RawData = Encode();
			}
		}

		public override void CopyFrom(AsnEncodedData asnEncodedData)
		{
			base.CopyFrom(asnEncodedData);
			_encoded = asnEncodedData.RawData;
		}

		internal void Decode(byte[] attribute)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (attribute == null || attribute[0] != 4)
			{
				throw new CryptographicException(Locale.GetText("Expected an OCTETSTRING."));
			}
			ASN1 val = new ASN1(attribute);
			_messageDigest = val.Value;
			_encoded = null;
		}

		internal byte[] Encode()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return new ASN1((byte)4, _messageDigest).GetBytes();
		}
	}
	public sealed class Pkcs9SigningTime : Pkcs9AttributeObject
	{
		internal const string oid = "1.2.840.113549.1.9.5";

		internal const string friendlyName = "Signing Time";

		private DateTime _signingTime;

		public DateTime SigningTime => _signingTime;

		public Pkcs9SigningTime()
		{
			((AsnEncodedData)this).Oid = new Oid("1.2.840.113549.1.9.5", "Signing Time");
			_signingTime = DateTime.Now;
			base.RawData = Encode();
		}

		public Pkcs9SigningTime(DateTime signingTime)
		{
			((AsnEncodedData)this).Oid = new Oid("1.2.840.113549.1.9.5", "Signing Time");
			_signingTime = signingTime;
			base.RawData = Encode();
		}

		public Pkcs9SigningTime(byte[] encodedSigningTime)
		{
			if (encodedSigningTime == null)
			{
				throw new ArgumentNullException("encodedSigningTime");
			}
			((AsnEncodedData)this).Oid = new Oid("1.2.840.113549.1.9.5", "Signing Time");
			base.RawData = encodedSigningTime;
			Decode(encodedSigningTime);
		}

		public override void CopyFrom(AsnEncodedData asnEncodedData)
		{
			if (asnEncodedData == null)
			{
				throw new ArgumentNullException("asnEncodedData");
			}
			Decode(asnEncodedData.RawData);
			base.Oid = asnEncodedData.Oid;
			base.RawData = asnEncodedData.RawData;
		}

		internal void Decode(byte[] attribute)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (attribute[0] != 23)
			{
				throw new CryptographicException(Locale.GetText("Only UTCTIME is supported."));
			}
			byte[] value = new ASN1(attribute).Value;
			string @string = Encoding.ASCII.GetString(value, 0, value.Length - 1);
			_signingTime = DateTime.ParseExact(@string, "yyMMddHHmmss", null);
		}

		internal byte[] Encode()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if (_signingTime.Year <= 1600)
			{
				throw new ArgumentOutOfRangeException("<= 1600");
			}
			if (_signingTime.Year < 1950 || _signingTime.Year >= 2050)
			{
				throw new CryptographicException("[1950,2049]");
			}
			string s = _signingTime.ToString("yyMMddHHmmss", CultureInfo.InvariantCulture) + "Z";
			return new ASN1((byte)23, Encoding.ASCII.GetBytes(s)).GetBytes();
		}
	}
	public sealed class PublicKeyInfo
	{
		private AlgorithmIdentifier _algorithm;

		private byte[] _key;

		public AlgorithmIdentifier Algorithm => _algorithm;

		public byte[] KeyValue => _key;

		internal PublicKeyInfo(AlgorithmIdentifier algorithm, byte[] key)
		{
			_algorithm = algorithm;
			_key = key;
		}

		internal PublicKeyInfo()
		{
			ThrowStub.ThrowNotSupportedException();
		}
	}
	public abstract class RecipientInfo
	{
		private RecipientInfoType _type;

		public abstract byte[] EncryptedKey { get; }

		public abstract AlgorithmIdentifier KeyEncryptionAlgorithm { get; }

		public abstract SubjectIdentifier RecipientIdentifier { get; }

		public RecipientInfoType Type => _type;

		public abstract int Version { get; }

		internal RecipientInfo(RecipientInfoType recipInfoType)
		{
			_type = recipInfoType;
		}

		internal RecipientInfo()
		{
			ThrowStub.ThrowNotSupportedException();
		}
	}
	public sealed class RecipientInfoCollection : ICollection, IEnumerable
	{
		private ArrayList _list;

		public int Count => _list.Count;

		public bool IsSynchronized => _list.IsSynchronized;

		public RecipientInfo this[int index] => (RecipientInfo)_list[index];

		public object SyncRoot => _list.SyncRoot;

		internal RecipientInfoCollection()
		{
			_list = new ArrayList();
		}

		internal int Add(RecipientInfo ri)
		{
			return _list.Add(ri);
		}

		public void CopyTo(Array array, int index)
		{
			_list.CopyTo(array, index);
		}

		public void CopyTo(RecipientInfo[] array, int index)
		{
			_list.CopyTo(array, index);
		}

		public RecipientInfoEnumerator GetEnumerator()
		{
			return new RecipientInfoEnumerator(_list);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return new RecipientInfoEnumerator(_list);
		}
	}
	public sealed class RecipientInfoEnumerator : IEnumerator
	{
		private IEnumerator enumerator;

		public RecipientInfo Current => (RecipientInfo)enumerator.Current;

		object IEnumerator.Current => enumerator.Current;

		internal RecipientInfoEnumerator(IEnumerable enumerable)
		{
			enumerator = enumerable.GetEnumerator();
		}

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

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

		internal RecipientInfoEnumerator()
		{
			ThrowStub.ThrowNotSupportedException();
		}
	}
	public enum RecipientInfoType
	{
		Unknown,
		KeyTransport,
		KeyAgreement
	}
	public sealed class SignedCms
	{
		private ContentInfo _content;

		private bool _detached;

		private SignerInfoCollection _info;

		private X509Certificate2Collection _certs;

		private SubjectIdentifierType _type;

		private int _version;

		public X509Certificate2Collection Certificates => _certs;

		public ContentInfo ContentInfo
		{
			get
			{
				if (_content == null)
				{
					Oid contentType = new Oid("1.2.840.113549.1.7.1");
					_content = new ContentInfo(contentType, new byte[0]);
				}
				return _content;
			}
		}

		public bool Detached => _detached;

		public SignerInfoCollection SignerInfos => _info;

		public int Version => _version;

		public SignedCms()
		{
			_certs = new X509Certificate2Collection();
			_info = new SignerInfoCollection();
		}

		public SignedCms(ContentInfo contentInfo)
			: this(contentInfo, detached: false)
		{
		}

		public SignedCms(ContentInfo contentInfo, bool detached)
			: this()
		{
			if (contentInfo == null)
			{
				throw new ArgumentNullException("contentInfo");
			}
			_content = contentInfo;
			_detached = detached;
		}

		public SignedCms(SubjectIdentifierType signerIdentifierType)
			: this()
		{
			_type = signerIdentifierType;
		}

		public SignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo contentInfo)
			: this(contentInfo, detached: false)
		{
			_type = signerIdentifierType;
		}

		public SignedCms(SubjectIdentifierType signerIdentifierType, ContentInfo contentInfo, bool detached)
			: this(contentInfo, detached)
		{
			_type = signerIdentifierType;
		}

		[MonoTODO]
		public void CheckSignature(bool verifySignatureOnly)
		{
			SignerInfoEnumerator enumerator = _info.GetEnumerator();
			while (enumerator.MoveNext())
			{
				enumerator.Current.CheckSignature(verifySignatureOnly);
			}
		}

		[MonoTODO]
		public void CheckSignature(X509Certificate2Collection extraStore, bool verifySignatureOnly)
		{
			SignerInfoEnumerator enumerator = _info.GetEnumerator();
			while (enumerator.MoveNext())
			{
				enumerator.Current.CheckSignature(extraStore, verifySignatureOnly);
			}
		}

		[MonoTODO]
		public void CheckHash()
		{
			throw new InvalidOperationException("");
		}

		[MonoTODO]
		public void ComputeSignature()
		{
			throw new CryptographicException("");
		}

		[MonoTODO]
		public void ComputeSignature(CmsSigner signer)
		{
			ComputeSignature();
		}

		[MonoTODO]
		public void ComputeSignature(CmsSigner signer, bool silent)
		{
			ComputeSignature();
		}

		private string ToString(byte[] array, bool reverse)
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (reverse)
			{
				for (int num = array.Length - 1; num >= 0; num--)
				{
					stringBuilder.Append(array[num].ToString("X2"));
				}
			}
			else
			{
				for (int i = 0; i < array.Length; i++)
				{
					stringBuilder.Append(array[i].ToString("X2"));
				}
			}
			return stringBuilder.ToString();
		}

		private byte[] GetKeyIdentifier(X509Certificate x509)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			X509Extension val = x509.Extensions["2.5.29.14"];
			if (val != null)
			{
				return new ASN1(val.Value.Value).Value;
			}
			ASN1 val2 = new ASN1((byte)48);
			ASN1 obj = val2.Add(new ASN1((byte)48));
			obj.Add(new ASN1(CryptoConfig.EncodeOID(x509.KeyAlgorithm)));
			obj.Add(new ASN1(x509.KeyAlgorithmParameters));
			byte[] publicKey = x509.PublicKey;
			byte[] array = new byte[publicKey.Length + 1];
			Array.Copy(publicKey, 0, array, 1, publicKey.Length);
			val2.Add(new ASN1((byte)3, array));
			return SHA1.Create().ComputeHash(val2.GetBytes());
		}

		[MonoTODO("incomplete - missing attributes")]
		public void Decode(byte[] encodedMessage)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			ContentInfo val = new ContentInfo(encodedMessage);
			if (val.ContentType != "1.2.840.113549.1.7.2")
			{
				throw new Exception("");
			}
			SignedData val2 = new SignedData(val.Content);
			SubjectIdentifierType type = SubjectIdentifierType.Unknown;
			object o = null;
			X509Certificate2 certificate = null;
			X509CertificateEnumerator enumerator;
			if (val2.SignerInfo.Certificate != null)
			{
				certificate = new X509Certificate2(val2.SignerInfo.Certificate.RawData);
			}
			else if (val2.SignerInfo.IssuerName != null && val2.SignerInfo.SerialNumber != null)
			{
				byte[] serialNumber = val2.SignerInfo.SerialNumber;
				Array.Reverse(serialNumber);
				type = SubjectIdentifierType.IssuerAndSerialNumber;
				X509IssuerSerial x509IssuerSerial = default(X509IssuerSerial);
				x509IssuerSerial.IssuerName = val2.SignerInfo.IssuerName;
				x509IssuerSerial.SerialNumber = ToString(serialNumber, reverse: true);
				o = x509IssuerSerial;
				enumerator = val2.Certificates.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						X509Certificate current = enumerator.Current;
						if (current.IssuerName == val2.SignerInfo.IssuerName && ToString(current.SerialNumber, reverse: true) == x509IssuerSerial.SerialNumber)
						{
							certificate = new X509Certificate2(current.RawData);
							break;
						}
					}
				}
				finally
				{
					if (enumerator is IDisposable disposable)
					{
						disposable.Dispose();
					}
				}
			}
			else if (val2.SignerInfo.SubjectKeyIdentifier != null)
			{
				string text = ToString(val2.SignerInfo.SubjectKeyIdentifier, reverse: false);
				type = SubjectIdentifierType.SubjectKeyIdentifier;
				o = text;
				enumerator = val2.Certificates.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						X509Certificate current2 = enumerator.Current;
						if (ToString(GetKeyIdentifier(current2), reverse: false) == text)
						{
							certificate = new X509Certificate2(current2.RawData);
							break;
						}
					}
				}
				finally
				{
					if (enumerator is IDisposable disposable2)
					{
						disposable2.Dispose();
					}
				}
			}
			SignerInfo signer = new SignerInfo(val2.SignerInfo.HashName, certificate, type, o, val2.SignerInfo.Version);
			_info.Add(signer);
			ASN1 content = val2.ContentInfo.Content;
			Oid contentType = new Oid(val2.ContentInfo.ContentType);
			if (!_detached || _content == null)
			{
				if (content[0] == null)
				{
					throw new ArgumentException("ContentInfo has no content. Detached signature ?");
				}
				_content = new ContentInfo(contentType, content[0].Value);
			}
			enumerator = val2.Certificates.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					X509Certificate current3 = enumerator.Current;
					_certs.Add(new X509Certificate2(current3.RawData));
				}
			}
			finally
			{
				if (enumerator is IDisposable disposable3)
				{
					disposable3.Dispose();
				}
			}
			_version = val2.Version;
		}

		[MonoTODO]
		public byte[] Encode()
		{
			return null;
		}

		[MonoTODO]
		public void RemoveSignature(SignerInfo signerInfo)
		{
		}

		[MonoTODO]
		public void RemoveSignature(int index)
		{
		}
	}
	public sealed class SignerInfo
	{
		private SubjectIdentifier _signer;

		private X509Certificate2 _certificate;

		private Oid _digest;

		private SignerInfoCollection _counter;

		private CryptographicAttributeObjectCollection _signed;

		private CryptographicAttributeObjectCollection _unsigned;

		private int _version;

		public CryptographicAttributeObjectCollection SignedAttributes => _signed;

		public X509Certificate2 Certificate => _certificate;

		public SignerInfoCollection CounterSignerInfos => _counter;

		public Oid DigestAlgorithm => _digest;

		public SubjectIdentifier SignerIdentifier => _signer;

		public CryptographicAttributeObjectCollection UnsignedAttributes => _unsigned;

		public int Version => _version;

		internal SignerInfo(string hashName, X509Certificate2 certificate, SubjectIdentifierType type, object o, int version)
		{
			_digest = new Oid(CryptoConfig.MapNameToOID(hashName));
			_certificate = certificate;
			_counter = new SignerInfoCollection();
			_signed = new CryptographicAttributeObjectCollection();
			_unsigned = new CryptographicAttributeObjectCollection();
			_signer = new SubjectIdentifier(type, o);
			_version = version;
		}

		[MonoTODO]
		public void CheckHash()
		{
		}

		[MonoTODO]
		public void CheckSignature(bool verifySignatureOnly)
		{
		}

		[MonoTODO]
		public void CheckSignature(X509Certificate2Collection extraStore, bool verifySignatureOnly)
		{
		}

		[MonoTODO]
		public void ComputeCounterSignature()
		{
		}

		[MonoTODO]
		public void ComputeCounterSignature(CmsSigner signer)
		{
		}

		[MonoTODO]
		public void RemoveCounterSignature(SignerInfo counterSignerInfo)
		{
		}

		[MonoTODO]
		public void RemoveCounterSignature(int index)
		{
		}

		internal SignerInfo()
		{
			ThrowStub.ThrowNotSupportedException();
		}
	}
	public sealed class SignerInfoCollection : ICollection, IEnumerable
	{
		private ArrayList _list;

		public int Count => _list.Count;

		public bool IsSynchronized => false;

		public SignerInfo this[int index] => (SignerInfo)_list[index];

		public object SyncRoot => _list.SyncRoot;

		internal SignerInfoCollection()
		{
			_list = new ArrayList();
		}

		internal void Add(SignerInfo signer)
		{
			_list.Add(signer);
		}

		public void CopyTo(Array array, int index)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (index < 0 || index >= array.Length)
			{
				throw new ArgumentOutOfRangeException("index");
			}
			_list.CopyTo(array, index);
		}

		public void CopyTo(SignerInfo[] array, int index)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (index < 0 || index >= array.Length)
			{
				throw new ArgumentOutOfRangeException("index");
			}
			_list.CopyTo(array, index);
		}

		public SignerInfoEnumerator GetEnumerator()
		{
			return new SignerInfoEnumerator(_list);
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return new SignerInfoEnumerator(_list);
		}
	}
	public sealed class SignerInfoEnumerator : IEnumerator
	{
		private IEnumerator enumerator;

		public SignerInfo Current => (SignerInfo)enumerator.Current;

		object IEnumerator.Current => enumerator.Current;

		internal SignerInfoEnumerator(IEnumerable enumerable)
		{
			enumerator = enumerable.GetEnumerator();
		}

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

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

		internal SignerInfoEnumerator()
		{
			ThrowStub.ThrowNotSupportedException();
		}
	}
	public sealed class SubjectIdentifier
	{
		private SubjectIdentifierType _type;

		private object _value;

		public SubjectIdentifierType Type => _type;

		public object Value => _value;

		internal SubjectIdentifier(SubjectIdentifierType type, object value)
		{
			_type = type;
			_value = value;
		}

		internal SubjectIdentifier()
		{
			ThrowStub.ThrowNotSupportedException();
		}
	}
	public sealed class SubjectIdentifierOrKey
	{
		private SubjectIdentifierOrKeyType _type;

		private object _value;

		public SubjectIdentifierOrKeyType Type => _type;

		public object Value => _value;

		internal SubjectIdentifierOrKey(SubjectIdentifierOrKeyType type, object value)
		{
			_type = type;
			_value = value;
		}

		internal SubjectIdentifierOrKey()
		{
			ThrowStub.ThrowNotSupportedException();
		}
	}
	public enum SubjectIdentifierOrKeyType
	{
		Unknown,
		IssuerAndSerialNumber,
		SubjectKeyIdentifier,
		PublicKeyInfo
	}
	public enum SubjectIdentifierType
	{
		Unknown,
		IssuerAndSerialNumber,
		SubjectKeyIdentifier,
		NoSignature
	}
}
namespace System.Security.Cryptography.X509Certificates
{
	internal static class RSACertificateExtensions
	{
		public static RSA GetRSAPrivateKey(this X509Certificate2 certificate)
		{
			if (certificate == null)
			{
				throw new ArgumentNullException("certificate");
			}
			return certificate.PrivateKey as RSA;
		}

		public static RSA GetRSAPublicKey(this X509Certificate2 certificate)
		{
			if (certificate == null)
			{
				throw new ArgumentNullException("certificate");
			}
			return certificate.PublicKey.Key as RSA;
		}
	}
	public static class X509Certificate2UI
	{
		[MonoTODO]
		public static void DisplayCertificate(X509Certificate2 certificate)
		{
			DisplayCertificate(certificate, IntPtr.Zero);
		}

		[MonoTODO]
		[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
		public static void DisplayCertificate(X509Certificate2 certificate, IntPtr hwndParent)
		{
			if (certificate == null)
			{
				throw new ArgumentNullException("certificate");
			}
			certificate.GetRawCertData();
			throw new NotImplementedException();
		}

		[MonoTODO]
		public static X509Certificate2Collection SelectFromCollection(X509Certificate2Collection certificates, string title, string message, X509SelectionFlag selectionFlag)
		{
			return SelectFromCollection(certificates, title, message, selectionFlag, IntPtr.Zero);
		}

		[MonoTODO]
		[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
		public static X509Certificate2Collection SelectFromCollection(X509Certificate2Collection certificates, string title, string message, X509SelectionFlag selectionFlag, IntPtr hwndParent)
		{
			if (certificates == null)
			{
				throw new ArgumentNullException("certificates");
			}
			if (selectionFlag < X509SelectionFlag.SingleSelection || selectionFlag > X509SelectionFlag.MultiSelection)
			{
				throw new ArgumentException("selectionFlag");
			}
			throw new NotImplementedException();
		}
	}
	public enum X509SelectionFlag
	{
		SingleSelection,
		MultiSelection
	}
}
namespace System.Security.Cryptography.Xml
{
	internal abstract class AncestralNamespaceContextManager
	{
		internal ArrayList _ancestorStack = new ArrayList();

		internal NamespaceFrame GetScopeAt(int i)
		{
			return (NamespaceFrame)_ancestorStack[i];
		}

		internal NamespaceFrame GetCurrentScope()
		{
			return GetScopeAt(_ancestorStack.Count - 1);
		}

		protected XmlAttribute GetNearestRenderedNamespaceWithMatchingPrefix(string nsPrefix, out int depth)
		{
			XmlAttribute xmlAttribute = null;
			depth = -1;
			for (int num = _ancestorStack.Count - 1; num >= 0; num--)
			{
				if ((xmlAttribute = GetScopeAt(num).GetRendered(nsPrefix)) != null)
				{
					depth = num;
					return xmlAttribute;
				}
			}
			return null;
		}

		protected XmlAttribute GetNearestUnrenderedNamespaceWithMatchingPrefix(string nsPrefix, out int depth)
		{
			XmlAttribute xmlAttribute = null;
			depth = -1;
			for (int num = _ancestorStack.Count - 1; num >= 0; num--)
			{
				if ((xmlAttribute = GetScopeAt(num).GetUnrendered(nsPrefix)) != null)
				{
					depth = num;
					return xmlAttribute;
				}
			}
			return null;
		}

		internal void EnterElementContext()
		{
			_ancestorStack.Add(new NamespaceFrame());
		}

		internal void ExitElementContext()
		{
			_ancestorStack.RemoveAt(_ancestorStack.Count - 1);
		}

		internal abstract void TrackNamespaceNode(XmlAttribute attr, SortedList nsListToRender, Hashtable nsLocallyDeclared);

		internal abstract void TrackXmlNamespaceNode(XmlAttribute attr, SortedList nsListToRender, SortedList attrListToRender, Hashtable nsLocallyDeclared);

		internal abstract void GetNamespacesToRender(XmlElement element, SortedList attrListToRender, SortedList nsListToRender, Hashtable nsLocallyDeclared);

		internal void LoadUnrenderedNamespaces(Hashtable nsLocallyDeclared)
		{
			object[] array = new object[nsLocallyDeclared.Count];
			nsLocallyDeclared.Values.CopyTo(array, 0);
			object[] array2 = array;
			foreach (object obj in array2)
			{
				AddUnrendered((XmlAttribute)obj);
			}
		}

		internal void LoadRenderedNamespaces(SortedList nsRenderedList)
		{
			foreach (object key in nsRenderedList.GetKeyList())
			{
				AddRendered((XmlAttribute)key);
			}
		}

		internal void AddRendered(XmlAttribute attr)
		{
			GetCurrentScope().AddRendered(attr);
		}

		internal void AddUnrendered(XmlAttribute attr)
		{
			GetCurrentScope().AddUnrendered(attr);
		}
	}
	internal class AttributeSortOrder : IComparer
	{
		internal AttributeSortOrder()
		{
		}

		public int Compare(object a, object b)
		{
			XmlNode xmlNode = a as XmlNode;
			XmlNode xmlNode2 = b as XmlNode;
			if (xmlNode == null || xmlNode2 == null)
			{
				throw new ArgumentException();
			}
			int num = string.CompareOrdinal(xmlNode.NamespaceURI, xmlNode2.NamespaceURI);
			if (num != 0)
			{
				return num;
			}
			return string.CompareOrdinal(xmlNode.LocalName, xmlNode2.LocalName);
		}
	}
	internal class C14NAncestralNamespaceContextManager : AncestralNamespaceContextManager
	{
		internal C14NAncestralNamespaceContextManager()
		{
		}

		private void GetNamespaceToRender(string nsPrefix, SortedList attrListToRender, SortedList nsListToRender, Hashtable nsLocallyDeclared)
		{
			foreach (XmlAttribute key in nsListToRender.GetKeyList())
			{
				if (Utils.HasNamespacePrefix(key, nsPrefix))
				{
					return;
				}
			}
			foreach (XmlAttribute key2 in attrListToRender.GetKeyList())
			{
				if (key2.LocalName.Equals(nsPrefix))
				{
					return;
				}
			}
			XmlAttribute xmlAttribute = (XmlAttribute)nsLocallyDeclared[nsPrefix];
			int depth;
			XmlAttribute nearestRenderedNamespaceWithMatchingPrefix = GetNearestRenderedNamespaceWithMatchingPrefix(nsPrefix, out depth);
			if (xmlAttribute != null)
			{
				if (Utils.IsNonRedundantNamespaceDecl(xmlAttribute, nearestRenderedNamespaceWithMatchingPrefix))
				{
					nsLocallyDeclared.Remove(nsPrefix);
					if (Utils.IsXmlNamespaceNode(xmlAttribute))
					{
						attrListToRender.Add(xmlAttribute, null);
					}
					else
					{
						nsListToRender.Add(xmlAttribute, null);
					}
				}
				return;
			}
			int depth2;
			XmlAttribute nearestUnrenderedNamespaceWithMatchingPrefix = GetNearestUnrenderedNamespaceWithMatchingPrefix(nsPrefix, out depth2);
			if (nearestUnrenderedNamespaceWithMatchingPrefix != null && depth2 > depth && Utils.IsNonRedundantNamespaceDecl(nearestUnrenderedNamespaceWithMatchingPrefix, nearestRenderedNamespaceWithMatchingPrefix))
			{
				if (Utils.IsXmlNamespaceNode(nearestUnrenderedNamespaceWithMatchingPrefix))
				{
					attrListToRender.Add(nearestUnrenderedNamespaceWithMatchingPrefix, null);
				}
				else
				{
					nsListToRender.Add(nearestUnrenderedNamespaceWithMatchingPrefix, null);
				}
			}
		}

		internal override void GetNamespacesToRender(XmlElement element, SortedList attrListToRender, SortedList nsListToRender, Hashtable nsLocallyDeclared)
		{
			XmlAttribute xmlAttribute = null;
			object[] array = new object[nsLocallyDeclared.Count];
			nsLocallyDeclared.Values.CopyTo(array, 0);
			object[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				xmlAttribute = (XmlAttribute)array2[i];
				int depth;
				XmlAttribute nearestRenderedNamespaceWithMatchingPrefix = GetNearestRenderedNamespaceWithMatchingPrefix(Utils.GetNamespacePrefix(xmlAttribute), out depth);
				if (Utils.IsNonRedundantNamespaceDecl(xmlAttribute, nearestRenderedNamespaceWithMatchingPrefix))
				{
					nsLocallyDeclared.Remove(Utils.GetNamespacePrefix(xmlAttribute));
					if (Utils.IsXmlNamespaceNode(xmlAttribute))
					{
						attrListToRender.Add(xmlAttribute, null);
					}
					else
					{
						nsListToRender.Add(xmlAttribute, null);
					}
				}
			}
			for (int num = _ancestorStack.Count - 1; num >= 0; num--)
			{
				foreach (XmlAttribute value in GetScopeAt(num).GetUnrendered().Values)
				{
					if (value != null)
					{
						GetNamespaceToRender(Utils.GetNamespacePrefix(value), attrListToRender, nsListToRender, nsLocallyDeclared);
					}
				}
			}
		}

		internal override void TrackNamespaceNode(XmlAttribute attr, SortedList nsListToRender, Hashtable nsLocallyDeclared)
		{
			nsLocallyDeclared.Add(Utils.GetNamespacePrefix(attr), attr);
		}

		internal override void TrackXmlNamespaceNode(XmlAttribute attr, SortedList nsListToRender, SortedList attrListToRender, Hashtable nsLocallyDeclared)
		{
			nsLocallyDeclared.Add(Utils.GetNamespacePrefix(attr), attr);
		}
	}
	internal class CanonicalXml
	{
		private CanonicalXmlDocument _c14nDoc;

		private C14NAncestralNamespaceContextManager _ancMgr;

		internal CanonicalXml(Stream inputStream, bool includeComments, XmlResolver resolver, string strBaseUri)
		{
			if (inputStream == null)
			{
				throw new ArgumentNullException("inputStream");
			}
			_c14nDoc = new CanonicalXmlDocument(defaultNodeSetInclusionState: true, includeComments);
			_c14nDoc.XmlResolver = resolver;
			_c14nDoc.Load(Utils.PreProcessStreamInput(inputStream, resolver, strBaseUri));
			_ancMgr = new C14NAncestralNamespaceContextManager();
		}

		internal CanonicalXml(XmlDocument document, XmlResolver resolver)
			: this(document, resolver, includeComments: false)
		{
		}

		internal CanonicalXml(XmlDocument document, XmlResolver resolver, bool includeComments)
		{
			if (document == null)
			{
				throw new ArgumentNullException("document");
			}
			_c14nDoc = new CanonicalXmlDocument(defaultNodeSetInclusionState: true, includeComments);
			_c14nDoc.XmlResolver = resolver;
			_c14nDoc.Load(new XmlNodeReader(document));
			_ancMgr = new C14NAncestralNamespaceContextManager();
		}

		internal CanonicalXml(XmlNodeList nodeList, XmlResolver resolver, bool includeComments)
		{
			if (nodeList == null)
			{
				throw new ArgumentNullException("nodeList");
			}
			XmlDocument ownerDocument = Utils.GetOwnerDocument(nodeList);
			if (ownerDocument == null)
			{
				throw new ArgumentException("nodeList");
			}
			_c14nDoc = new CanonicalXmlDocument(defaultNodeSetInclusionState: false, includeComments);
			_c14nDoc.XmlResolver = resolver;
			_c14nDoc.Load(new XmlNodeReader(ownerDocument));
			_ancMgr = new C14NAncestralNamespaceContextManager();
			MarkInclusionStateForNodes(nodeList, ownerDocument, _c14nDoc);
		}

		private static void MarkNodeAsIncluded(XmlNode node)
		{
			if (node is ICanonicalizableNode)
			{
				((ICanonicalizableNode)node).IsInNodeSet = true;
			}
		}

		private static void MarkInclusionStateForNodes(XmlNodeList nodeList, XmlDocument inputRoot, XmlDocument root)
		{
			CanonicalXmlNodeList canonicalXmlNodeList = new CanonicalXmlNodeList();
			CanonicalXmlNodeList canonicalXmlNodeList2 = new CanonicalXmlNodeList();
			canonicalXmlNodeList.Add(inputRoot);
			canonicalXmlNodeList2.Add(root);
			int num = 0;
			do
			{
				XmlNode xmlNode = canonicalXmlNodeList[num];
				XmlNode? xmlNode2 = canonicalXmlNodeList2[num];
				XmlNodeList childNodes = xmlNode.ChildNodes;
				XmlNodeList childNodes2 = xmlNode2.ChildNodes;
				for (int i = 0; i < childNodes.Count; i++)
				{
					canonicalXmlNodeList.Add(childNodes[i]);
					canonicalXmlNodeList2.Add(childNodes2[i]);
					if (Utils.NodeInList(childNodes[i], nodeList))
					{
						MarkNodeAsIncluded(childNodes2[i]);
					}
					XmlAttributeCollection attributes = childNodes[i].Attributes;
					if (attributes == null)
					{
						continue;
					}
					for (int j = 0; j < attributes.Count; j++)
					{
						if (Utils.NodeInList(attributes[j], nodeList))
						{
							MarkNodeAsIncluded(childNodes2[i].Attributes.Item(j));
						}
					}
				}
				num++;
			}
			while (num < canonicalXmlNodeList.Count);
		}

		internal byte[] GetBytes()
		{
			StringBuilder stringBuilder = new StringBuilder();
			_c14nDoc.Write(stringBuilder, DocPosition.BeforeRootElement, _ancMgr);
			return new UTF8Encoding(encoderShouldEmitUTF8Identifier: false).GetBytes(stringBuilder.ToString());
		}

		internal byte[] GetDigestedBytes(HashAlgorithm hash)
		{
			_c14nDoc.WriteHash(hash, DocPosition.BeforeRootElement, _ancMgr);
			hash.TransformFinalBlock(new byte[0], 0, 0);
			byte[] result = (byte[])hash.Hash.Clone();
			hash.Initialize();
			return result;
		}
	}
	internal class CanonicalXmlAttribute : XmlAttribute, ICanonicalizableNode
	{
		private bool _isInNodeSet;

		public bool IsInNodeSet
		{
			get
			{
				return _isInNodeSet;
			}
			set
			{
				_isInNodeSet = value;
			}
		}

		public CanonicalXmlAttribute(string prefix, string localName, string namespaceURI, XmlDocument doc, bool defaultNodeSetInclusionState)
			: base(prefix, localName, namespaceURI, doc)
		{
			IsInNodeSet = defaultNodeSetInclusionState;
		}

		public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc)
		{
			strBuilder.Append(" " + Name + "=\"");
			strBuilder.Append(Utils.EscapeAttributeValue(Value));
			strBuilder.Append("\"");
		}

		public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc)
		{
			UTF8Encoding uTF8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
			byte[] bytes = uTF8Encoding.GetBytes(" " + Name + "=\"");
			hash.TransformBlock(bytes, 0, bytes.Length, bytes, 0);
			bytes = uTF8Encoding.GetBytes(Utils.EscapeAttributeValue(Value));
			hash.TransformBlock(bytes, 0, bytes.Length, bytes, 0);
			bytes = uTF8Encoding.GetBytes("\"");
			hash.TransformBlock(bytes, 0, bytes.Length, bytes, 0);
		}
	}
	internal class CanonicalXmlCDataSection : XmlCDataSection, ICanonicalizableNode
	{
		private bool _isInNodeSet;

		public bool IsInNodeSet
		{
			get
			{
				return _isInNodeSet;
			}
			set
			{
				_isInNodeSet = value;
			}
		}

		public CanonicalXmlCDataSection(string data, XmlDocument doc, bool defaultNodeSetInclusionState)
			: base(data, doc)
		{
			_isInNodeSet = defaultNodeSetInclusionState;
		}

		public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc)
		{
			if (IsInNodeSet)
			{
				strBuilder.Append(Utils.EscapeCData(Data));
			}
		}

		public void WriteHash(HashAlgorithm hash, DocPosition docPos, AncestralNamespaceContextManager anc)
		{
			if (IsInNodeSet)
			{
				byte[] bytes = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false).GetBytes(Utils.EscapeCData(Data));
				hash.TransformBlock(bytes, 0, bytes.Length, bytes, 0);
			}
		}
	}
	internal class CanonicalXmlComment : XmlComment, ICanonicalizableNode
	{
		private bool _isInNodeSet;

		private bool _includeComments;

		public bool IsInNodeSet
		{
			get
			{
				return _isInNodeSet;
			}
			set
			{
				_isInNodeSet = value;
			}
		}

		public bool IncludeComments => _includeComments;

		public CanonicalXmlComment(string comment, XmlDocument doc, bool defaultNodeSetInclusionState, bool includeComments)
			: base(comment, doc)
		{
			_isInNodeSet = defaultNodeSetInclusionState;
			_includeComments = includeComments;
		}

		public void Write(StringBuilder strBuilder, DocPosition docPos, AncestralNamespaceContextManager anc)
		{
			if (IsInNodeSet && IncludeC