Decompiled source of DuctTape v1.1.1

patchers/rounds-port.AutoFix.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using Mono.Collections.Generic;

[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: AssemblyCompany("0rounds-port.AutoFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.5.1.0")]
[assembly: AssemblyInformationalVersion("1.5.1")]
[assembly: AssemblyProduct("0rounds-port.AutoFix")]
[assembly: AssemblyTitle("0rounds-port.AutoFix")]
[assembly: AssemblyVersion("1.5.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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;
		}
	}
}
internal sealed class AutoFix(Settings settings, ManualLogSource log)
{
	public sealed record Settings(string GameDir, string Managed, string Core, string Plugins, string Cache, string[] Exclude);

	private sealed class Entry
	{
		public long Size;

		public long Time;

		public string Sha = "";

		public string Orig = "";

		public string Result = "";

		public string Note = "";

		public bool Retry;
	}

	private const string Fixed = "fixed";

	private const string Unchanged = "unchanged";

	private const string NotMod = "not-a-mod";

	private const string Excluded = "excluded";

	private const string Error = "error";

	private const string Old = "old";

	private readonly string indexPath = Path.Combine(settings.Cache, "index.tsv");

	private readonly string originals = Path.Combine(settings.Cache, "originals");

	private readonly Curated curated = new Curated(settings.Cache, log);

	private Game? game;

	private Scanner? scanner;

	private string Key()
	{
		ModuleDefinition val = ModuleDefinition.ReadModule(Path.Combine(settings.Managed, "Assembly-CSharp.dll"));
		string text;
		try
		{
			text = val.Mvid.ToString();
		}
		finally
		{
			((IDisposable)val)?.Dispose();
		}
		return string.Join(" ", typeof(AutoFix).Assembly.ManifestModule.ModuleVersionId, text, string.Join(",", settings.Exclude));
	}

	public void Run()
	{
		Stopwatch stopwatch = Stopwatch.StartNew();
		Directory.CreateDirectory(settings.Cache);
		List<(string, FileInfo)> list = PluginFiles();
		string text = Key();
		var (text2, dictionary) = ReadIndex();
		if (text2 == text + " old-game")
		{
			log.LogInfo((object)"this is the old game build (old-rounds-for-mods): mods work on it as they are");
			return;
		}
		bool flag = text2 != text;
		List<string> list2 = curated.Plan(list.Select<(string, FileInfo), string>(((string rel, FileInfo fi) f) => f.fi.FullName)).ToList();
		SortedDictionary<string, Entry> next = new SortedDictionary<string, Entry>(StringComparer.Ordinal);
		List<(string, FileInfo)> list3 = new List<(string, FileInfo)>();
		foreach (var (text3, fileInfo) in list)
		{
			if (!flag && dictionary.TryGetValue(text3, out var value) && value.Size == fileInfo.Length && value.Time == fileInfo.LastWriteTimeUtc.Ticks && (!(value.Result == "old") || list2.Count <= 0))
			{
				next[text3] = value;
			}
			else
			{
				list3.Add((text3, fileInfo));
			}
		}
		if (list3.Count > 0)
		{
			log.LogInfo((object)((flag && dictionary.Count > 0) ? $"checking {list3.Count} DLLs again (rounds-port, the game or the settings changed)" : $"checking {list3.Count} new or updated DLLs"));
			try
			{
				game = new Game(settings.GameDir, settings.Managed, settings.Core, settings.Plugins);
			}
			catch (UserError)
			{
				if (dictionary.Count > 0)
				{
					RestoreOriginals(off: false);
				}
				WriteIndex(text + " old-game", new SortedDictionary<string, Entry>());
				log.LogInfo((object)"this is the old game build (old-rounds-for-mods): mods work on it as they are");
				return;
			}
			foreach (string item in list2)
			{
				game.Resolver.Set(item);
			}
			if (game.Resolver.Path("UnboundLib") == null)
			{
				log.LogWarning((object)"UnboundLib 4 isn't installed: most mods need it (Bknibb's port, github.com/Bknibb/UnboundLib)");
			}
			scanner = new Scanner(game);
			foreach (var (text4, fileInfo2) in list3)
			{
				dictionary.TryGetValue(text4, out var value2);
				Entry entry;
				try
				{
					entry = Check(text4, fileInfo2.FullName, value2, flag);
				}
				catch (Exception ex)
				{
					entry = new Entry
					{
						Result = "error",
						Note = OneLine(ex.GetType().Name + ": " + ex.Message),
						Sha = (value2?.Sha ?? ""),
						Orig = (value2?.Orig ?? "")
					};
					log.LogWarning((object)$"couldn't check {text4}, left as it is: {ex}");
				}
				FileInfo fileInfo3 = new FileInfo(fileInfo2.FullName);
				if (fileInfo3.Exists)
				{
					entry.Size = (entry.Retry ? (-1) : fileInfo3.Length);
					entry.Time = fileInfo3.LastWriteTimeUtc.Ticks;
					next[text4] = entry;
				}
			}
			game.Resolver.Dispose();
			game = null;
			scanner = null;
			GC.Collect();
		}
		HashSet<string> hashSet = new HashSet<string>(from e in next.Values.Where(IsCopy)
			select e.Orig, StringComparer.OrdinalIgnoreCase);
		if (Directory.Exists(originals))
		{
			string[] files = Directory.GetFiles(originals, "*.dll");
			foreach (string path in files)
			{
				if (!hashSet.Contains(Path.GetFileNameWithoutExtension(path)))
				{
					TryDelete(path);
				}
			}
		}
		if (list3.Count > 0 || next.Count != dictionary.Count)
		{
			WriteIndex(text, next);
		}
		foreach (KeyValuePair<string, Entry> item2 in next.Where<KeyValuePair<string, Entry>>((KeyValuePair<string, Entry> kv) => kv.Value.Result == "old"))
		{
			log.LogWarning((object)("BepInEx/plugins/" + item2.Key + " is " + item2.Value.Note + ", which doesn't work on the current game: use Bknibb's port (github.com/Bknibb/UnboundLib, github.com/Bknibb/RoundsWithFriends). Mods aren't fixed against it"));
		}
		int num2 = next.Count - Count("not-a-mod") - Count("old");
		int num3 = next.Values.Count((Entry e) => e.Result == "fixed" && e.Note.Length > 0);
		string text5 = string.Format("{0} mods: {1} fixed", num2, Count("fixed")) + ((num3 > 0) ? $" ({num3} with problems only their authors can fix)" : "") + string.Format(", {0} need nothing", Count("unchanged"));
		if (Count("excluded") > 0)
		{
			text5 += string.Format(", {0} excluded", Count("excluded"));
		}
		if (Count("error") > 0)
		{
			text5 += string.Format(", {0} with errors", Count("error"));
		}
		if (Count("old") > 0)
		{
			text5 += string.Format("; {0} old librar{1} skipped", Count("old"), (Count("old") == 1) ? "y" : "ies");
		}
		log.LogInfo((object)$"{text5} ({stopwatch.ElapsedMilliseconds} ms)");
		if (list3.Count != 0)
		{
			return;
		}
		foreach (KeyValuePair<string, Entry> item3 in next.Where<KeyValuePair<string, Entry>>((KeyValuePair<string, Entry> kv) => kv.Value.Result == "error"))
		{
			log.LogInfo((object)("  error: " + item3.Key + ": " + item3.Value.Note));
		}
		int Count(string r)
		{
			return next.Values.Count((Entry e) => e.Result == r);
		}
	}

	private Entry Check(string rel, string path, Entry? e, bool keyChanged)
	{
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Expected O, but got Unknown
		byte[] array = ReadShared(path);
		string sha = Sha(array);
		if (e != null && !keyChanged && sha == e.Sha && e.Size >= 0)
		{
			return e;
		}
		bool ours = e != null && IsCopy(e) && sha == e.Sha;
		byte[] orig = array;
		string origSha = sha;
		if (ours)
		{
			string path2 = Path.Combine(originals, e.Orig + ".dll");
			if (File.Exists(path2))
			{
				orig = File.ReadAllBytes(path2);
				origSha = e.Orig;
			}
			else
			{
				ours = false;
				log.LogWarning((object)(rel + ": its original isn't in " + originals + " any more; checking the file as it is"));
			}
		}
		if (Matches(rel, settings.Exclude))
		{
			return Done("excluded");
		}
		byte[] array2;
		try
		{
			array2 = curated.Apply(path, orig, origSha);
		}
		catch (Exception ex)
		{
			log.LogWarning((object)(rel + ": " + ex.Message + "; fixing it without its curated patch"));
			array2 = orig;
		}
		bool flag = array2 != orig;
		ReaderParameters val = new ReaderParameters
		{
			AssemblyResolver = (IAssemblyResolver)(object)game.Resolver,
			ReadingMode = (ReadingMode)1
		};
		ModuleDefinition val3;
		try
		{
			ModuleDefinition val2 = ModuleDefinition.ReadModule((Stream)new MemoryStream(array2));
			try
			{
				if (!flag && val2.Assembly != null)
				{
					string text = Game.OldLibrary(path, val2.Assembly.Name);
					if (text != null)
					{
						return Done("old", text);
					}
				}
				if (!((IEnumerable<AssemblyNameReference>)val2.AssemblyReferences).Any(delegate(AssemblyNameReference a)
				{
					string name = a.Name;
					return (name == "Assembly-CSharp" || name == "UnboundLib") ? true : false;
				}) || ((ModuleReference)val2).Name.StartsWith("MMHOOK"))
				{
					return flag ? Save(array2, null, "fixed") : Done("not-a-mod");
				}
			}
			finally
			{
				((IDisposable)val2)?.Dispose();
			}
			val3 = ModuleDefinition.ReadModule((Stream)new MemoryStream(array2), val);
		}
		catch (Exception ex2)
		{
			log.LogWarning((object)("couldn't read " + rel + ", left as it is: " + ex2.GetType().Name + ": " + OneLine(ex2.Message)));
			return Done("error", OneLine(ex2.GetType().Name + ": " + ex2.Message));
		}
		scanner.Scan(val3);
		Fixer fixer = new Fixer(val3, game, scanner);
		fixer.Run();
		if (!fixer.Changed)
		{
			if (!flag)
			{
				return Done("unchanged");
			}
			return Save(array2, null, "fixed");
		}
		MemoryStream memoryStream = new MemoryStream();
		val3.Write((Stream)memoryStream);
		byte[] array3 = memoryStream.ToArray();
		List<Issue> source = scanner.Scan(ModuleDefinition.ReadModule((Stream)new MemoryStream(array3), val));
		List<Issue> list = source.Where((Issue i) => i.Fix == Fix.Manual).ToList();
		Entry entry = Save(array3, (list.Count > 0) ? $"{list.Count} MANUAL left" : null, "fixed");
		if (entry.Result == "error")
		{
			return entry;
		}
		List<string> list2 = (from i in source
			where i.Fix == Fix.Review
			select i.Kind).Distinct().ToList();
		string text2 = string.Format("fixed {0}: {1} kind{2} of change", rel, fixer.Changes.Count(), (fixer.Changes.Count() == 1) ? "" : "s") + ((list2.Count > 0) ? ("; to check in game: " + string.Join(", ", list2)) : "");
		if (list.Count == 0)
		{
			log.LogInfo((object)text2);
		}
		else
		{
			log.LogWarning((object)(text2 + string.Format("; {0} MANUAL item{1} left, which only its author can fix: ", list.Count, (list.Count == 1) ? "" : "s") + string.Join("; ", from i in list.Take(3)
				select i.What) + ((list.Count > 3) ? "; ..." : "")));
		}
		return entry;
		Entry Done(string result, string note = "")
		{
			if (ours)
			{
				Replace(path, orig);
				log.LogInfo((object)("put back the original of " + rel));
			}
			return new Entry
			{
				Sha = origSha,
				Orig = origSha,
				Result = result,
				Note = note
			};
		}
		Entry Save(byte[] bytes, string? note, string result)
		{
			string text3 = Sha(bytes);
			try
			{
				SaveOriginal(origSha, orig);
				if (text3 != sha)
				{
					Replace(path, bytes);
				}
			}
			catch (Exception ex3) when (((ex3 is IOException || ex3 is UnauthorizedAccessException) ? 1 : 0) != 0)
			{
				log.LogWarning((object)("couldn't save the fixed copy of " + rel + ", left as it is: " + ex3.Message));
				return new Entry
				{
					Sha = sha,
					Orig = origSha,
					Result = "error",
					Note = OneLine("can't write: " + ex3.Message),
					Retry = true
				};
			}
			return new Entry
			{
				Sha = text3,
				Orig = origSha,
				Result = result,
				Note = (note ?? "")
			};
		}
	}

	private static byte[] ReadShared(string path)
	{
		int num = 0;
		while (true)
		{
			try
			{
				using FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
				MemoryStream memoryStream = new MemoryStream();
				fileStream.CopyTo(memoryStream);
				return memoryStream.ToArray();
			}
			catch (IOException) when (num < 10 && File.Exists(path))
			{
				Thread.Sleep(300);
			}
			num++;
		}
	}

	public void RestoreOriginals(bool off = true)
	{
		Dictionary<string, Entry> item = ReadIndex().index;
		int num = 0;
		foreach (KeyValuePair<string, Entry> item2 in item.Where<KeyValuePair<string, Entry>>((KeyValuePair<string, Entry> kv) => IsCopy(kv.Value)))
		{
			string path = Path.Combine(settings.Plugins, item2.Key);
			string path2 = Path.Combine(originals, item2.Value.Orig + ".dll");
			try
			{
				if (File.Exists(path) && File.Exists(path2) && !(Sha(File.ReadAllBytes(path)) != item2.Value.Sha))
				{
					Replace(path, File.ReadAllBytes(path2));
					num++;
				}
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("couldn't put back the original of " + item2.Key + ": " + ex.Message));
			}
		}
		TryDelete(indexPath);
		log.LogInfo((object)(string.Format("put back {0} original mod{1}", num, (num == 1) ? "" : "s") + (off ? "; AutoFix is off now (Enabled in rounds-port.autofix.cfg)" : ": this is the old game build")));
	}

	private static bool IsCopy(Entry e)
	{
		if (e.Orig.Length > 0)
		{
			return e.Sha != e.Orig;
		}
		return false;
	}

	private List<(string rel, FileInfo fi)> PluginFiles()
	{
		List<(string, FileInfo)> list = new List<(string, FileInfo)>();
		if (!Directory.Exists(settings.Plugins))
		{
			return list;
		}
		string[] files = Directory.GetFiles(settings.Plugins, "*.rpbak", SearchOption.AllDirectories);
		foreach (string text in files)
		{
			string text2 = text.Substring(0, text.Length - ".rpbak".Length);
			if (File.Exists(text2))
			{
				TryDelete(text);
			}
			else
			{
				File.Move(text, text2);
			}
		}
		files = Directory.GetFiles(settings.Plugins, "*.rptmp", SearchOption.AllDirectories);
		for (int i = 0; i < files.Length; i++)
		{
			TryDelete(files[i]);
		}
		files = Directory.GetFiles(settings.Plugins, "*.dll", SearchOption.AllDirectories);
		foreach (string text3 in files)
		{
			if (text3.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
			{
				list.Add((text3.Substring(settings.Plugins.Length).TrimStart('/', '\\'), new FileInfo(text3)));
			}
		}
		list.Sort(((string, FileInfo) a, (string, FileInfo) b) => string.CompareOrdinal(a.Item1, b.Item1));
		return list;
	}

	private static bool Matches(string rel, string[] names)
	{
		string[] parts = rel.Split('/', '\\');
		string file = parts[parts.Length - 1];
		return names.Any((string n) => parts.Any((string p) => p.Equals(n, StringComparison.OrdinalIgnoreCase)) || Path.GetFileNameWithoutExtension(file).Equals(n, StringComparison.OrdinalIgnoreCase));
	}

	private static void Replace(string path, byte[] bytes)
	{
		string text = path + ".rptmp";
		string text2 = path + ".rpbak";
		File.WriteAllBytes(text, bytes);
		if (File.Exists(text2))
		{
			File.Delete(text2);
		}
		File.Move(path, text2);
		File.Move(text, path);
		File.Delete(text2);
	}

	private void SaveOriginal(string sha, byte[] bytes)
	{
		string text = Path.Combine(originals, sha + ".dll");
		if (!File.Exists(text))
		{
			Directory.CreateDirectory(originals);
			File.WriteAllBytes(text + ".rptmp", bytes);
			File.Move(text + ".rptmp", text);
		}
	}

	private (string key, Dictionary<string, Entry> index) ReadIndex()
	{
		Dictionary<string, Entry> dictionary = new Dictionary<string, Entry>(StringComparer.Ordinal);
		if (!File.Exists(indexPath))
		{
			return (key: "", index: dictionary);
		}
		try
		{
			string[] source = File.ReadAllLines(indexPath);
			string item = source.FirstOrDefault((string l) => l.StartsWith("key\t"))?.Substring(4) ?? "";
			foreach (string[] item2 in from l in source
				where l.Length > 0 && !l.StartsWith("#") && !l.StartsWith("key\t")
				select l.Split(new char[1] { '\t' }))
			{
				if (item2.Length >= 6)
				{
					dictionary[item2[0]] = new Entry
					{
						Size = long.Parse(item2[1]),
						Time = long.Parse(item2[2]),
						Sha = item2[3],
						Orig = item2[4],
						Result = item2[5],
						Note = ((item2.Length > 6) ? item2[6] : "")
					};
				}
			}
			return (key: item, index: dictionary);
		}
		catch (Exception ex)
		{
			log.LogWarning((object)(indexPath + " is unreadable (" + ex.Message + "); checking every mod"));
			return (key: "", index: new Dictionary<string, Entry>(StringComparer.Ordinal));
		}
	}

	private void WriteIndex(string key, SortedDictionary<string, Entry> index)
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.Append("# rounds-port AutoFix: mods checked at the last start. Delete this file to check them all again.\n");
		stringBuilder.Append("key\t").Append(key).Append('\n');
		foreach (KeyValuePair<string, Entry> item in index)
		{
			stringBuilder.Append(string.Join("\t", item.Key, item.Value.Size, item.Value.Time, item.Value.Sha, item.Value.Orig, item.Value.Result, item.Value.Note)).Append('\n');
		}
		File.WriteAllText(indexPath + ".rptmp", stringBuilder.ToString());
		if (File.Exists(indexPath))
		{
			File.Delete(indexPath);
		}
		File.Move(indexPath + ".rptmp", indexPath);
	}

	internal static string Sha(byte[] bytes)
	{
		using SHA256 sHA = SHA256.Create();
		return BitConverter.ToString(sHA.ComputeHash(bytes)).Replace("-", "").ToLowerInvariant();
	}

	private static string OneLine(string s)
	{
		return s.Replace('\t', ' ').Replace('\r', ' ').Replace('\n', ' ');
	}

	private static void TryDelete(string path)
	{
		try
		{
			File.Delete(path);
		}
		catch
		{
		}
	}
}
internal sealed class Curated(string cache, ManualLogSource log)
{
	private sealed record Port(string File, string Sha, string Package);

	private sealed record Patch(string Name, string Before, string After, string Resource);

	private static readonly Port[] Ports = new Port[3]
	{
		new Port("UnboundLib.dll", "2eecd826d889cc1dda5efc0433bc77ab9bafa85cacc00323f3a8c7de79558154", "UnboundLib 4 (https://github.com/Bknibb/UnboundLib/releases)"),
		new Port("MMHOOK_Assembly-CSharp.dll", "926b53b329d94f6a8842e6d51ca17ff96f081df59695d7862845d5ccce9e5a62", "UnboundLib 4 (https://github.com/Bknibb/UnboundLib/releases)"),
		new Port("RoundsWithFriends.dll", "1bd4d5aa47de0e04661710a77bb0b5f1214dac4b3baabc9364b3418ecbc8ab61", "RoundsWithFriends 3 (https://github.com/Bknibb/RoundsWithFriends/releases)")
	};

	private static readonly Dictionary<string, Patch> Patches = ReadPatches();

	private readonly Dictionary<string, (string Path, string From)> needed = new Dictionary<string, (string, string)>(StringComparer.OrdinalIgnoreCase);

	private static bool OnMac
	{
		get
		{
			PlatformID platform = Environment.OSVersion.Platform;
			if (platform == PlatformID.Unix || platform == PlatformID.MacOSX)
			{
				return true;
			}
			return false;
		}
	}

	public IEnumerable<string> Plan(IEnumerable<string> pluginFiles)
	{
		foreach (IGrouping<string, string> g in pluginFiles.GroupBy<string, string>(Path.GetFileName, StringComparer.OrdinalIgnoreCase))
		{
			Port port = Ports.FirstOrDefault((Port p) => p.File.Equals(g.Key, StringComparison.OrdinalIgnoreCase));
			if (port == null)
			{
				continue;
			}
			List<(string, byte[])> source = g.Select((string f) => (path: f, bytes: File.ReadAllBytes(f))).ToList();
			if (!source.Any<(string, byte[])>(((string path, byte[] bytes) c) => IsOld(c.path, c.bytes)))
			{
				continue;
			}
			(string, byte[]) tuple = (from c in source
				where !IsOld(c.path, c.bytes)
				orderby AutoFix.Sha(c.bytes) == port.Sha descending
				select c).FirstOrDefault();
			if (tuple.Item1 != null)
			{
				needed[port.File] = (tuple.Item1, Short(tuple.Item1));
				continue;
			}
			Patch value;
			List<(string, byte[], Patch)> source2 = (from c in source
				where IsOld(c.path, c.bytes)
				select (path: c.path, bytes: c.bytes, patch: Patches.TryGetValue(g.Key + "\t" + AutoFix.Sha(c.bytes), out value) ? value : null)).ToList();
			(string, byte[], Patch) tuple2 = source2.FirstOrDefault<(string, byte[], Patch)>(((string path, byte[] bytes, Patch patch) o) => o.patch != null);
			Patch item = tuple2.Item3;
			if ((object)item != null)
			{
				string text = Path.Combine(cache, "ports", item.After + ".dll");
				if (!File.Exists(text) || AutoFix.Sha(File.ReadAllBytes(text)) != item.After)
				{
					byte[] bytes = Bspatch(tuple2.Item2, Resource(item));
					if (AutoFix.Sha(bytes) != item.After)
					{
						log.LogWarning((object)("the curated patch for " + g.Key + " gave the wrong file; left as it is"));
						continue;
					}
					Directory.CreateDirectory(Path.GetDirectoryName(text));
					File.WriteAllBytes(text, bytes);
				}
				needed[port.File] = (text, "curated patch " + item.Resource.Substring("curated/".Length));
			}
			foreach (var (path, bytes2, _) in source2.Where<(string, byte[], Patch)>(((string path, byte[] bytes, Patch patch) o) => o.patch == null && !needed.ContainsKey(port.File)))
			{
				log.LogWarning((object)(Short(path) + " is " + OldName(bytes2) + ", which DuctTape can't update: update it in your mod manager (or install Bknibb's " + port.Package + "). Until then, mods that need it won't load"));
			}
		}
		return needed.Values.Select<(string, string), string>(((string Path, string From) n) => n.Path);
	}

	public byte[] Apply(string path, byte[] bytes, string sha)
	{
		string fileName = Path.GetFileName(path);
		if (needed.TryGetValue(fileName, out (string, string) value) && IsOld(path, bytes))
		{
			log.LogInfo((object)(Short(path) + ": Bknibb's port in place of the old release (" + value.Item2 + ")"));
			bytes = File.ReadAllBytes(value.Item1);
			sha = AutoFix.Sha(bytes);
		}
		for (int i = 0; i < 4; i++)
		{
			if (!Patches.TryGetValue(fileName + "\t" + sha, out Patch value2))
			{
				break;
			}
			byte[] array = Bspatch(bytes, Resource(value2));
			if (AutoFix.Sha(array) != value2.After)
			{
				throw new InvalidDataException("the curated patch for " + fileName + " gave the wrong file");
			}
			log.LogInfo((object)(Short(path) + ": curated patch (" + value2.Resource.Substring("curated/".Length) + ")"));
			bytes = array;
			sha = value2.After;
		}
		return bytes;
	}

	private static string Short(string path)
	{
		return Path.GetFileName(Path.GetDirectoryName(path)) + "/" + Path.GetFileName(path);
	}

	private static byte[] Resource(Patch patch)
	{
		using Stream stream = typeof(Curated).Assembly.GetManifestResourceStream(patch.Resource);
		MemoryStream memoryStream = new MemoryStream();
		stream.CopyTo(memoryStream);
		return memoryStream.ToArray();
	}

	private static string OldName(byte[] bytes)
	{
		try
		{
			ModuleDefinition val = ModuleDefinition.ReadModule((Stream)new MemoryStream(bytes));
			try
			{
				return ((AssemblyNameReference)val.Assembly.Name).Name + " " + ((AssemblyNameReference)val.Assembly.Name).Version.ToString(3);
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}
		catch
		{
			return "an old release";
		}
	}

	private static bool IsOld(string path, byte[] bytes)
	{
		try
		{
			ModuleDefinition val = ModuleDefinition.ReadModule((Stream)new MemoryStream(bytes));
			try
			{
				return val.Assembly != null && Game.OldLibrary(path, val.Assembly.Name) != null;
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}
		catch
		{
			return false;
		}
	}

	private static Dictionary<string, Patch> ReadPatches()
	{
		Dictionary<string, Patch> dictionary = new Dictionary<string, Patch>(StringComparer.OrdinalIgnoreCase);
		using Stream stream = typeof(Curated).Assembly.GetManifestResourceStream("curated/patches.tsv");
		if (stream == null)
		{
			return dictionary;
		}
		string[] array = new StreamReader(stream).ReadToEnd().Split(new char[1] { '\n' });
		for (int i = 0; i < array.Length; i++)
		{
			string[] array2 = array[i].Split(new char[1] { '\t' });
			if ((array2.Length < 5 || !(array2[4].Trim() == "macos") || OnMac) && array2.Length >= 4)
			{
				dictionary[array2[0] + "\t" + array2[1]] = new Patch(array2[0], array2[1], array2[2], "curated/" + array2[3].Trim());
			}
		}
		return dictionary;
	}

	private static byte[] Bspatch(byte[] old, byte[] patch)
	{
		if (Encoding.ASCII.GetString(patch, 0, 8) != "BSDIFFDF")
		{
			throw new InvalidDataException("not a BSDIFFDF patch");
		}
		long num = Off(patch, 8L);
		long num2 = Off(patch, 16L);
		long num3 = Off(patch, 24L);
		using DeflateStream s = Block(patch, 32L, num);
		using DeflateStream s2 = Block(patch, 32 + num, num2);
		using DeflateStream s3 = Block(patch, 32 + num + num2, patch.Length - 32 - num - num2);
		byte[] array = new byte[num3];
		byte[] array2 = new byte[24];
		long num4 = 0L;
		long num5 = 0L;
		while (num5 < num3)
		{
			Fill(s, array2, 0L, 24L);
			long num6 = Off(array2, 0L);
			long num7 = Off(array2, 8L);
			long num8 = Off(array2, 16L);
			Fill(s2, array, num5, num6);
			for (long num9 = 0L; num9 < num6; num9++)
			{
				if (num4 + num9 >= 0 && num4 + num9 < old.Length)
				{
					array[num5 + num9] += old[num4 + num9];
				}
			}
			num5 += num6;
			num4 += num6;
			Fill(s3, array, num5, num7);
			num5 += num7;
			num4 += num8;
		}
		return array;
	}

	private static DeflateStream Block(byte[] b, long at, long len)
	{
		return new DeflateStream(new MemoryStream(b, (int)at, (int)len), CompressionMode.Decompress);
	}

	private static void Fill(Stream s, byte[] into, long at, long len)
	{
		while (len > 0)
		{
			int num = s.Read(into, (int)at, (int)Math.Min(len, 2147483647L));
			if (num <= 0)
			{
				throw new InvalidDataException("the patch is cut short");
			}
			at += num;
			len -= num;
		}
	}

	private static long Off(byte[] b, long at)
	{
		long num = BitConverter.ToInt64(b, (int)at);
		if (num >= 0)
		{
			return num;
		}
		return -(num & 0x7FFFFFFFFFFFFFFFL);
	}
}
public static class AutoFixPatcher
{
	public static IEnumerable<string> TargetDLLs { get; } = new string[0];

	public static void Patch(AssemblyDefinition assembly)
	{
	}

	public static void Initialize()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		ManualLogSource val = Logger.CreateLogSource("rounds-port");
		try
		{
			ConfigEntry<bool> val2 = ((ConfigFile)typeof(ConfigFile).GetProperty("CoreConfig", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null, null)).Bind<bool>("Chainloader", "HideManagerGameObject", false, (ConfigDescription)null);
			if (!val2.Value)
			{
				val2.Value = true;
				val.LogInfo((object)"turned on HideManagerGameObject in BepInEx.cfg");
			}
		}
		catch (Exception ex)
		{
			val.LogWarning((object)("couldn't turn on HideManagerGameObject: " + ex.Message));
		}
		try
		{
			Run(val);
		}
		catch (Exception arg)
		{
			val.LogError((object)$"AutoFix failed, mods are left as they are: {arg}");
		}
	}

	private static void Run(ManualLogSource log)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, "rounds-port.autofix.cfg"), true);
		ConfigEntry<bool> val2 = val.Bind<bool>("General", "Enabled", true, "Fix mods made for the game before its 2025 update while the game starts (rounds-port's fix, applied in place).");
		ConfigEntry<string> val3 = val.Bind<string>("General", "Exclude", "", "Mods never to touch, comma-separated: DLL names (MapsExtended.dll) or folder names (olavim-MapsExtended). A mod fixed earlier gets its original back.");
		ConfigEntry<bool> val4 = val.Bind<bool>("General", "RestoreOriginals", false, "Put back the original of every mod AutoFix changed, then turn AutoFix off (Enabled = false).");
		AutoFix autoFix = new AutoFix(new AutoFix.Settings(Paths.GameRootPath, Paths.ManagedPath, Paths.BepInExAssemblyDirectory, Paths.PluginPath, Path.Combine(Paths.CachePath, "rounds-port"), List(val3.Value)), log);
		if (val4.Value)
		{
			autoFix.RestoreOriginals();
			val4.Value = false;
			val2.Value = false;
		}
		else if (!val2.Value)
		{
			log.LogInfo((object)"AutoFix is off (Enabled in rounds-port.autofix.cfg)");
		}
		else
		{
			autoFix.Run();
		}
	}

	private static string[] List(string s)
	{
		return (from x in s.Split(new char[1] { ',' })
			select x.Trim() into x
			where x.Length > 0
			select x).ToArray();
	}
}
internal static class NetFrameworkPolyfills
{
	public static IEnumerable<(A First, B Second)> Zip<A, B>(this IEnumerable<A> a, IEnumerable<B> b)
	{
		return a.Zip(b, (A x, B y) => (x: x, y: y));
	}

	public static bool TryAdd<K, V>(this Dictionary<K, V> d, K key, V value)
	{
		if (d.ContainsKey(key))
		{
			return false;
		}
		d.Add(key, value);
		return true;
	}

	public static bool Remove<K, V>(this Dictionary<K, V> d, K key, out V value)
	{
		if (d.TryGetValue(key, out value))
		{
			d.Remove(key);
			return true;
		}
		return false;
	}
}
internal enum Fix
{
	Auto,
	Review,
	Manual
}
internal sealed record Issue(Fix Fix, string Kind, string What, string Detail);
internal sealed class Scanner(Game game)
{
	public sealed record RpcSite(Instruction Newarr, Instruction Call, string Name, int Args, List<MethodDefinition> Targets);

	public sealed record ReflectSite(Instruction Ldstr, string Call, string Name, string? Problem, string? FixTo)
	{
		public bool Unsure { get; init; }
	}

	private readonly MapResolver resolver = game.Resolver;

	private readonly MetadataResolver md = new MetadataResolver((IAssemblyResolver)(object)game.Resolver);

	public readonly SortedSet<string> Unchecked = new SortedSet<string>(StringComparer.OrdinalIgnoreCase);

	private static readonly HashSet<string> ObjectLookups = new HashSet<string> { "FindObjectOfType", "FindObjectsOfType", "FindFirstObjectByType", "FindAnyObjectByType", "FindObjectsByType" };

	private static readonly HashSet<string> GameObjectLookups = new HashSet<string> { "Find", "FindWithTag", "FindGameObjectWithTag", "FindGameObjectsWithTag" };

	public const string DisabledPatch = "__RoundsCompat_Disabled_";

	private bool MissingModDependency(TypeReference t)
	{
		string text = TypeProblem(t);
		if (text == null || !text.StartsWith("assembly "))
		{
			return false;
		}
		string text2 = Scope(t);
		bool flag = text2.StartsWith("Sirenix.");
		if (!flag)
		{
			bool flag2;
			switch (text2)
			{
			case "UnboundLib":
			case "MMHOOK_Assembly-CSharp":
			case "Assembly-CSharp-firstpass":
			case "UnityEngine.TextCoreModule":
				flag2 = true;
				break;
			default:
				flag2 = false;
				break;
			}
			flag = flag2;
		}
		if (flag || File.Exists(Path.Combine(game.Managed, text2 + ".dll")))
		{
			return false;
		}
		Unchecked.Add(text2);
		return true;
	}

	public List<Issue> Scan(ModuleDefinition module)
	{
		//IL_066d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0672: Unknown result type (might be due to invalid IL or missing references)
		//IL_07b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_07b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_07bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_07c2: Invalid comparison between Unknown and I4
		//IL_06d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_06d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_06e0: Invalid comparison between Unknown and I4
		List<Issue> issues = new List<Issue>();
		Unchecked.Clear();
		foreach (TypeReference typeReference in module.GetTypeReferences())
		{
			if (!MissingModDependency(typeReference))
			{
				string text = TypeProblem(typeReference);
				if (text != null)
				{
					Add(Known.Type(typeReference, Scope(typeReference), text, MovedTextCore(typeReference)));
				}
			}
		}
		foreach (MemberReference memberReference in module.GetMemberReferences())
		{
			if (memberReference.DeclaringType is ArrayType)
			{
				continue;
			}
			string text2 = null;
			TypeDefinition val = null;
			try
			{
				val = Resolve(memberReference.DeclaringType.GetElementType());
				if (val == null)
				{
					continue;
				}
				MethodReference val2 = (MethodReference)(object)((memberReference is MethodReference) ? memberReference : null);
				IMemberDefinition val4;
				if (val2 == null)
				{
					FieldReference val3 = (FieldReference)(object)((memberReference is FieldReference) ? memberReference : null);
					val4 = (IMemberDefinition)(object)((val3 == null) ? null : ResolveF(val3));
				}
				else
				{
					val4 = (IMemberDefinition)(object)ResolveM(val2);
				}
				if (val4 == null)
				{
					text2 = "not found" + Hints(val, memberReference.Name);
				}
				goto IL_013d;
			}
			catch (Exception ex)
			{
				text2 = ex.GetType().Name + ": " + ex.Message;
				goto IL_013d;
			}
			IL_013d:
			if (text2 != null)
			{
				TypeDefinition dt = val;
				string why = text2;
				MethodReference val5 = (MethodReference)(object)((memberReference is MethodReference) ? memberReference : null);
				Add(Known.Member(memberReference, dt, why, val5 != null && ResultDropped(module, val5)));
			}
		}
		foreach (TypeDefinition item in AllTypes(module))
		{
			Inheritance(module, item, Add);
			MethodDefinition val6 = PluginAwake(item);
			if (val6 != null)
			{
				string text3 = SceneLookupAtLoad(val6);
				if (text3 != null)
				{
					Add(new Issue(Fix.Auto, "behaviour", ((MemberReference)item).FullName + "::Awake finds scene objects at plugin load", text3 + ": BepInEx now starts plugins before the game has loaded any scene (on the old game the first scene was there), so this finds nothing. fix runs this Awake once the first scene has loaded"));
				}
			}
			foreach (var (harmonyInfo, list) in HarmonyPatches(item))
			{
				if (harmonyInfo.Type != null && MissingModDependency(harmonyInfo.Type))
				{
					continue;
				}
				string text4 = TargetProblem(harmonyInfo);
				if (text4 != null)
				{
					Add(Known.HarmonyTarget(harmonyInfo, text4, DamageSourceOverload(harmonyInfo) != null, TargetInPortedCode(harmonyInfo)));
					continue;
				}
				foreach (MethodDefinition item2 in list)
				{
					foreach (var (text5, text6, text7) in PatchParamProblems(harmonyInfo, item2))
					{
						Add(new Issue((text7 != null) ? Fix.Review : Fix.Manual, "harmony param", $"{((MemberReference)item).FullName}::{((MemberReference)item2).Name} ({text5}) -> {harmonyInfo}", text6 + ((text7 != null) ? ("; fix renames it to " + text7) : "")));
					}
				}
			}
			foreach (MethodDefinition item3 in ((IEnumerable<MethodDefinition>)item.Methods).Where((MethodDefinition m) => m.HasBody))
			{
				foreach (ReflectSite item4 in ReflectSites(item3))
				{
					if (item4.Problem != null)
					{
						Add(new Issue((item4.FixTo != null || item4.Unsure) ? Fix.Review : Fix.Manual, "reflection", ((MemberReference)item).FullName + "::" + ((MemberReference)item3).Name + " " + item4.Call + "(\"" + item4.Name + "\")", item4.Problem + ((item4.FixTo != null) ? ("; fix changes it to \"" + item4.FixTo + "\"") : "")));
					}
				}
				foreach (RpcSite r in RpcSites(item3))
				{
					if (r.Targets.Any((MethodDefinition x) => ((MethodReference)x).Parameters.Count == r.Args))
					{
						continue;
					}
					Add(new Issue((!OnlyMissingDamageSource(r)) ? Fix.Manual : Fix.Auto, "rpc", string.Format("{0}::{1} RPC(\"{2}\") with {3} argument{4}", ((MemberReference)item).FullName, ((MemberReference)item3).Name, r.Name, r.Args, (r.Args == 1) ? "" : "s"), "the game's version takes " + string.Join(" | ", r.Targets.Select((MethodDefinition x) => "(" + string.Join(", ", ((IEnumerable<ParameterDefinition>)((MethodReference)x).Parameters).Select((ParameterDefinition p) => ((MemberReference)((ParameterReference)p).ParameterType).Name)) + ")")) + ", and PUN drops RPCs with the wrong argument count" + (OnlyMissingDamageSource(r) ? "; fix appends DamageSource.Player" : Known.RpcNote(r))));
				}
				if (((MemberReference)item3).Name.StartsWith("__RoundsCompat_Disabled_"))
				{
					Add(new Issue(Fix.Review, "harmony", ((MemberReference)item).FullName + "::" + ((MemberReference)item3).Name, "rounds-port disabled this Harmony patch: its target is gone in the current game, and HarmonyX would have thrown on it and stopped PatchAll. " + (((MemberReference)item3).Name.StartsWith("__RoundsCompat_Disabled_CardBar_Update_") ? "rounds-port Runtime calls it every frame for each active CardBar, as CardBar.Update did" : "What it did is lost")));
				}
				Enumerator<Instruction> enumerator10 = item3.Body.Instructions.GetEnumerator();
				try
				{
					while (enumerator10.MoveNext())
					{
						Instruction current7 = enumerator10.Current;
						object operand = current7.Operand;
						FieldReference val7 = (FieldReference)((operand is FieldReference) ? operand : null);
						OpCode opCode;
						if (val7 != null && ((MemberReference)val7).Name == "cardName" && ((MemberReference)((MemberReference)val7).DeclaringType).FullName == "CardInfo" && IsGame(((MemberReference)val7).DeclaringType))
						{
							opCode = current7.OpCode;
							Add(((int)((OpCode)(ref opCode)).Code == 122) ? new Issue(Fix.Review, "behaviour", "CardInfo.cardName (write)", "private now. fix writes the private field, so name lookups still find it, but the title the game shows comes from localization: set that through UnboundLib's CustomCard") : new Issue(Fix.Auto, "behaviour", "CardInfo.cardName (read)", "private now, and empty for UnboundLib 4 cards (names moved to localization). fix reads it through a helper that falls back to the localized key, CardName, then the GameObject name"));
						}
						object operand2 = current7.Operand;
						FieldReference val8 = (FieldReference)((operand2 is FieldReference) ? operand2 : null);
						if (val8 != null)
						{
							FieldDefinition val9 = NowPrivate(val8);
							if (val9 != null)
							{
								Add(new Issue(Fix.Auto, "access", ((MemberReference)val9.DeclaringType).Name + "." + ((MemberReference)val9).Name + " (private now)", "the runtime throws FieldAccessException on it. fix reads and writes it through reflection"));
							}
						}
						if (IsDontDestroyOnLoad(current7) && RunsAtPluginLoad(item3))
						{
							Add(new Issue(Fix.Auto, "behaviour", ((MemberReference)item).FullName + "::" + ((MemberReference)item3).Name + " DontDestroyOnLoad at plugin load", "BepInEx starts plugins before the game loads its first scene, and that load destroys every object made earlier, DontDestroyOnLoad or not (MapsExtended's map object manager dies this way). fix also sets hideFlags DontSave on it, which keeps it"));
						}
						opCode = current7.OpCode;
						if ((int)((OpCode)(ref opCode)).Code == 113 && (string)current7.Operand == "GetRanomCard")
						{
							Add(new Issue(Fix.Auto, "reflection", ((MemberReference)item).FullName + "::" + ((MemberReference)item3).Name + " \"GetRanomCard\"", "the typo was fixed: CardChoice.GetRandomCard"));
						}
					}
				}
				finally
				{
					((IDisposable)enumerator10/*cast due to .constrained prefix*/).Dispose();
				}
			}
		}
		return issues;
		void Add(Issue i)
		{
			if (!issues.Contains(i))
			{
				issues.Add(i);
			}
		}
	}

	private void Inheritance(ModuleDefinition module, TypeDefinition t, Action<Issue> add)
	{
		if (t.BaseType == null || t.IsInterface)
		{
			return;
		}
		List<TypeDefinition> list = new List<TypeDefinition>();
		for (TypeDefinition val = Resolve(t.BaseType); val != null; val = ((val.BaseType == null) ? null : Resolve(val.BaseType)))
		{
			list.Add(val);
		}
		if (!list.Any((TypeDefinition val2) => ((AssemblyNameReference)((MemberReference)val2).Module.Assembly.Name).Name != ((AssemblyNameReference)module.Assembly.Name).Name && !((AssemblyNameReference)((MemberReference)val2).Module.Assembly.Name).Name.StartsWith("UnityEngine") && ((AssemblyNameReference)((MemberReference)val2).Module.Assembly.Name).Name != "mscorlib"))
		{
			return;
		}
		List<TypeDefinition> list2 = new List<TypeDefinition> { t };
		list2.AddRange(list);
		if (!t.IsAbstract)
		{
			foreach (TypeDefinition b in list)
			{
				foreach (MethodDefinition am in ((IEnumerable<MethodDefinition>)b.Methods).Where((MethodDefinition x) => x.IsAbstract))
				{
					if (!list2.TakeWhile((TypeDefinition x) => x != b).Any((TypeDefinition x) => ((IEnumerable<MethodDefinition>)x.Methods).Any((MethodDefinition val2) => ((MemberReference)val2).Name == ((MemberReference)am).Name && !val2.IsAbstract && SigEq(val2, am))))
					{
						add(new Issue(Fix.Manual, "override", ((MemberReference)t).FullName + " doesn't implement " + ((MemberReference)am).FullName, "TypeLoadException when the type loads: the base method changed (e.g. the damage methods gained a HealthHandler.DamageSource parameter). Update your override"));
					}
				}
			}
		}
		foreach (MethodDefinition m in ((IEnumerable<MethodDefinition>)t.Methods).Where((MethodDefinition val2) => val2.IsVirtual && !val2.IsNewSlot && !val2.IsAbstract))
		{
			if (list.Any((TypeDefinition val2) => ((IEnumerable<MethodDefinition>)val2.Methods).Any((MethodDefinition x) => x.IsVirtual && ((MemberReference)x).Name == ((MemberReference)m).Name && SigEq(m, x))) || !list.Any((TypeDefinition val2) => IsGame(val2) && ((IEnumerable<MethodDefinition>)val2.Methods).Any((MethodDefinition x) => ((MemberReference)x).Name == ((MemberReference)m).Name)))
			{
				continue;
			}
			add(new Issue(Fix.Manual, "override", ((MemberReference)t).FullName + "::" + ((MemberReference)m).Name, "no longer overrides anything; the game now has: " + string.Join(" | ", from x in list.SelectMany((TypeDefinition val2) => ((IEnumerable<MethodDefinition>)val2.Methods).Where((MethodDefinition x) => ((MemberReference)x).Name == ((MemberReference)m).Name))
				select ((MemberReference)x).FullName)));
		}
	}

	public IEnumerable<(HarmonyInfo info, List<MethodDefinition> methods)> HarmonyPatches(TypeDefinition t)
	{
		if (((IEnumerable<MethodDefinition>)t.Methods).Any(delegate(MethodDefinition m)
		{
			string name = ((MemberReference)m).Name;
			return (name == "TargetMethod" || name == "TargetMethods") ? true : false;
		}))
		{
			yield break;
		}
		HarmonyInfo classAttr = HarmonyInfo.From((IEnumerable<CustomAttribute>)t.CustomAttributes);
		List<MethodDefinition> own = ((IEnumerable<MethodDefinition>)t.Methods).Where((MethodDefinition m) => ((IEnumerable<CustomAttribute>)m.CustomAttributes).Any((CustomAttribute a) => ((MemberReference)a.AttributeType).Name == "HarmonyPatch")).ToList();
		if (classAttr != null && own.Count == 0)
		{
			yield return (info: classAttr, methods: ((IEnumerable<MethodDefinition>)t.Methods).Where(IsPatchMethod).ToList());
		}
		bool classType = classAttr?.Type != null || classAttr?.TypeName != null;
		foreach (MethodDefinition pm in own)
		{
			List<HarmonyInfo> each = (from a in (IEnumerable<CustomAttribute>)pm.CustomAttributes
				where ((MemberReference)a.AttributeType).Name == "HarmonyPatch"
				select HarmonyInfo.From((IEnumerable<CustomAttribute>)(object)new CustomAttribute[1] { a })).ToList();
			List<HarmonyInfo> list = each.Where(Complete).ToList();
			IEnumerable<HarmonyInfo> enumerable2;
			if (list.Count <= 1)
			{
				IEnumerable<HarmonyInfo> enumerable = new HarmonyInfo[1] { HarmonyInfo.From((IEnumerable<CustomAttribute>)pm.CustomAttributes) };
				enumerable2 = enumerable;
			}
			else
			{
				enumerable2 = list.Select((HarmonyInfo c) => each.Where((HarmonyInfo x) => !Complete(x)).Append(c).Aggregate(HarmonyInfo.Merge));
			}
			IEnumerable<HarmonyInfo> enumerable3 = enumerable2;
			foreach (HarmonyInfo item in enumerable3)
			{
				yield return (info: (classAttr != null) ? HarmonyInfo.Merge(classAttr, item) : item, methods: new List<MethodDefinition> { pm });
			}
		}
		bool Complete(HarmonyInfo x)
		{
			if (x.Method != null)
			{
				if (!classType && x.Type == null)
				{
					return x.TypeName != null;
				}
				return true;
			}
			return false;
		}
		static bool IsPatchMethod(MethodDefinition m)
		{
			bool flag;
			switch (((MemberReference)m).Name)
			{
			case "Prefix":
			case "Postfix":
			case "Finalizer":
				flag = true;
				break;
			default:
				flag = false;
				break;
			}
			if (!flag)
			{
				return ((IEnumerable<CustomAttribute>)m.CustomAttributes).Any(delegate(CustomAttribute a)
				{
					switch (((MemberReference)a.AttributeType).Name)
					{
					case "HarmonyPrefix":
					case "HarmonyPostfix":
					case "HarmonyFinalizer":
						return true;
					default:
						return false;
					}
				});
			}
			return true;
		}
	}

	public TypeDefinition? TargetType(HarmonyInfo h)
	{
		if (h.Type == null)
		{
			if (h.TypeName == null)
			{
				return null;
			}
			return FindType(h.TypeName);
		}
		return Resolve(h.Type);
	}

	public string? TargetProblem(HarmonyInfo h)
	{
		if (h.Type == null && h.TypeName == null)
		{
			return null;
		}
		TypeDefinition val = TargetType(h);
		if (val == null)
		{
			return "target type not found";
		}
		int valueOrDefault = h.MethodType.GetValueOrDefault();
		switch (valueOrDefault)
		{
		case 3:
			if (!((IEnumerable<MethodDefinition>)val.Methods).Any((MethodDefinition m) => m.IsConstructor && !m.IsStatic && ArgsMatch(m, h.ArgTypes)))
			{
				return "constructor with those arguments not found";
			}
			return null;
		case 4:
			if (!((IEnumerable<MethodDefinition>)val.Methods).Any((MethodDefinition m) => m.IsConstructor && m.IsStatic))
			{
				return "static constructor not found";
			}
			return null;
		default:
			if (h.Method == null)
			{
				return null;
			}
			switch (valueOrDefault)
			{
			case 1:
				if (!HasMember(val, h.Method, "Getter"))
				{
					return "property getter not found" + Hints(val, h.Method);
				}
				return null;
			case 2:
				if (!HasMember(val, h.Method, "Setter"))
				{
					return "property setter not found" + Hints(val, h.Method);
				}
				return null;
			default:
			{
				for (TypeDefinition val2 = val; val2 != null; val2 = ((val2.BaseType == null) ? null : Resolve(val2.BaseType)))
				{
					List<MethodDefinition> list = ((IEnumerable<MethodDefinition>)val2.Methods).Where((MethodDefinition m) => ((MemberReference)m).Name == h.Method).ToList();
					if (list.Count != 0)
					{
						if (h.ArgTypes == null)
						{
							if (list.Count <= 1 || list.Any((MethodDefinition c) => ((MethodReference)c).Parameters.Count == 0))
							{
								return null;
							}
							return "ambiguous: Harmony throws AmbiguousMatchException. Add argumentTypes, one of: " + string.Join(" | ", list.Select((MethodDefinition c) => ((MemberReference)c).FullName));
						}
						if (list.Any((MethodDefinition m) => ArgsMatch(m, h.ArgTypes)))
						{
							return null;
						}
						return "no overload with those argumentTypes; the game has: " + string.Join(" | ", list.Select((MethodDefinition c) => ((MemberReference)c).FullName));
					}
				}
				return "method not found" + Hints(val, h.Method);
			}
			}
		}
	}

	public bool TargetInPortedCode(HarmonyInfo h)
	{
		TypeDefinition? obj = TargetType(h);
		object obj2 = ((obj != null) ? ((AssemblyNameReference)((MemberReference)obj).Module.Assembly.Name).Name : null);
		if (obj2 == null)
		{
			TypeReference? type = h.Type;
			if (type == null)
			{
				obj2 = null;
			}
			else
			{
				IMetadataScope scope = type.Scope;
				obj2 = ((scope != null) ? scope.Name : null);
			}
		}
		string text = (string)obj2;
		if (text != null)
		{
			TypeReference? type2 = h.Type;
			if (!(((type2 != null) ? type2.Scope : null) is ModuleDefinition))
			{
				bool flag = text.StartsWith("Assembly-CSharp") || text.StartsWith("UnityEngine") || text.StartsWith("Unity.") || text.StartsWith("Photon");
				if (!flag)
				{
					bool flag2;
					switch (text)
					{
					case "UnboundLib":
					case "RoundsWithFriends":
					case "MMHOOK_Assembly-CSharp":
						flag2 = true;
						break;
					default:
						flag2 = false;
						break;
					}
					flag = flag2;
				}
				return flag;
			}
		}
		return false;
	}

	public MethodDefinition? DamageSourceOverload(HarmonyInfo h)
	{
		if (h.ArgTypes != null && h.Method != null && h.MethodType.GetValueOrDefault() == 0)
		{
			TypeDefinition val = TargetType(h);
			if (val != null && IsGame(val))
			{
				List<MethodDefinition> list = ((IEnumerable<MethodDefinition>)val.Methods).Where((MethodDefinition m) => ((MemberReference)m).Name == h.Method).ToList();
				if (list.Count == 0 || list.Any((MethodDefinition m) => ArgsMatch(m, h.ArgTypes)))
				{
					return null;
				}
				return ((IEnumerable<MethodDefinition>)list).FirstOrDefault((Func<MethodDefinition, bool>)delegate(MethodDefinition m)
				{
					if (((MethodReference)m).Parameters.Count == h.ArgTypes.Count + 1)
					{
						Collection<ParameterDefinition> parameters = ((MethodReference)m).Parameters;
						if (((MemberReference)((ParameterReference)parameters[parameters.Count - 1]).ParameterType).FullName == "HealthHandler/DamageSource")
						{
							List<TypeReference>? argTypes = h.ArgTypes;
							Collection<ParameterDefinition> parameters2 = ((MethodReference)m).Parameters;
							return ArgsMatch(m, argTypes.Append(((ParameterReference)parameters2[parameters2.Count - 1]).ParameterType).ToList());
						}
					}
					return false;
				});
			}
		}
		return null;
	}

	public bool OnHoverAmbiguous(HarmonyInfo h)
	{
		if (h.ArgTypes == null && h.Method == "OnHover" && h.MethodType.GetValueOrDefault() == 0)
		{
			TypeDefinition val = TargetType(h);
			if (val != null && ((MemberReference)val).FullName == "CardBar")
			{
				return ((IEnumerable<MethodDefinition>)val.Methods).Count((MethodDefinition m) => ((MemberReference)m).Name == "OnHover") > 1;
			}
		}
		return false;
	}

	public IEnumerable<(string param, string problem, string? fixTo)> PatchParamProblems(HarmonyInfo h, MethodDefinition patch)
	{
		TypeDefinition td = TargetType(h);
		if (td == null || ((MemberReference)patch).Name == "Transpiler" || ((IEnumerable<CustomAttribute>)patch.CustomAttributes).Any((CustomAttribute a) => ((MemberReference)a.AttributeType).Name == "HarmonyTranspiler"))
		{
			yield break;
		}
		int valueOrDefault = h.MethodType.GetValueOrDefault();
		List<MethodDefinition> list = new List<MethodDefinition>();
		TypeDefinition val = td;
		while (val != null && list.Count == 0)
		{
			switch (valueOrDefault)
			{
			case 3:
				list.AddRange(((IEnumerable<MethodDefinition>)val.Methods).Where((MethodDefinition m) => m.IsConstructor && !m.IsStatic && ArgsMatch(m, h.ArgTypes)));
				break;
			case 1:
				list.AddRange(from p in (IEnumerable<PropertyDefinition>)val.Properties
					where ((MemberReference)p).Name == h.Method && p.GetMethod != null
					select p.GetMethod);
				break;
			case 2:
				list.AddRange(from p in (IEnumerable<PropertyDefinition>)val.Properties
					where ((MemberReference)p).Name == h.Method && p.SetMethod != null
					select p.SetMethod);
				break;
			default:
				if (h.Method != null)
				{
					list.AddRange(((IEnumerable<MethodDefinition>)val.Methods).Where((MethodDefinition m) => ((MemberReference)m).Name == h.Method && ArgsMatch(m, h.ArgTypes)));
				}
				break;
			}
			val = ((val.BaseType == null) ? null : Resolve(val.BaseType));
		}
		if (list.Count != 1)
		{
			yield break;
		}
		MethodDefinition target = list[0];
		string fullName = ((MemberReference)((MethodReference)patch).ReturnType).FullName;
		bool flag = ((fullName == "System.Void" || fullName == "System.Boolean") ? true : false);
		bool flag2 = !flag && ((MethodReference)patch).Parameters.Count > 0 && ((MemberReference)((ParameterReference)((MethodReference)patch).Parameters[0]).ParameterType).FullName == ((MemberReference)((MethodReference)patch).ReturnType).FullName;
		foreach (ParameterDefinition item in ((IEnumerable<ParameterDefinition>)((MethodReference)patch).Parameters).Skip(flag2 ? 1 : 0))
		{
			string n = ((ParameterReference)item).Name;
			if (((IEnumerable<CustomAttribute>)item.CustomAttributes).Any((CustomAttribute a) => ((MemberReference)a.AttributeType).Name == "HarmonyArgument"))
			{
				continue;
			}
			if (n.StartsWith("___"))
			{
				fullName = n;
				string text = fullName.Substring(3, fullName.Length - 3);
				if (FieldOn(td, text) == null)
				{
					yield return (param: n, problem: "field '" + text + "' isn't on " + ((MemberReference)td).Name + Hints(td, text), fixTo: (FieldOn(td, "m_" + text) != null) ? ("___m_" + text) : null);
				}
				continue;
			}
			switch (n)
			{
			case "__instance":
			case "__result":
			case "__state":
			case "__originalMethod":
			case "__args":
			case "__runOriginal":
			case "__exception":
				flag = true;
				break;
			default:
				flag = false;
				break;
			}
			if (flag)
			{
				continue;
			}
			if (n.StartsWith("__"))
			{
				fullName = n;
				if (int.TryParse(fullName.Substring(2, fullName.Length - 2), out var _))
				{
					continue;
				}
			}
			ParameterDefinition val2 = ((IEnumerable<ParameterDefinition>)((MethodReference)target).Parameters).FirstOrDefault((Func<ParameterDefinition, bool>)((ParameterDefinition x) => ((ParameterReference)x).Name == n));
			if (val2 == null && n == "card" && ((MemberReference)((ParameterReference)item).ParameterType).FullName == "CardInfo" && IsHoverByButton(target))
			{
				yield return (param: n, problem: "OnHover takes the hovered CardBarButton (cardButton) now, and its m_cardInfo is the card; fix reads that wherever the patch used card. The game's OnHover now also sets DoesHover and moves the selection marker, which a prefix returning false skips", fixTo: "cardButton");
				continue;
			}
			if (val2 == null)
			{
				yield return (param: n, problem: "the target has no parameter with that name; it has (" + string.Join(", ", ((IEnumerable<ParameterDefinition>)((MethodReference)target).Parameters).Select((ParameterDefinition x) => ((MemberReference)((ParameterReference)x).ParameterType).Name + " " + ((ParameterReference)x).Name)) + ")", fixTo: null);
				continue;
			}
			TypeReference parameterType = ((ParameterReference)item).ParameterType;
			ByReferenceType val3 = (ByReferenceType)(object)((parameterType is ByReferenceType) ? parameterType : null);
			TypeReference val4 = ((val3 != null) ? ((TypeSpecification)val3).ElementType : ((ParameterReference)item).ParameterType);
			TypeReference parameterType2 = ((ParameterReference)val2).ParameterType;
			ByReferenceType val5 = (ByReferenceType)(object)((parameterType2 is ByReferenceType) ? parameterType2 : null);
			TypeReference val6 = ((val5 != null) ? ((TypeSpecification)val5).ElementType : ((ParameterReference)val2).ParameterType);
			if (((MemberReference)val4).FullName != ((MemberReference)val6).FullName && ((MemberReference)val4).FullName != "System.Object")
			{
				yield return (param: n, problem: "type " + ((MemberReference)val4).Name + " doesn't match the target's " + ((MemberReference)val6).Name, fixTo: null);
			}
		}
	}

	public static bool IsHoverByButton(MethodDefinition m)
	{
		if (((MemberReference)m).Name == "OnHover" && ((MemberReference)m.DeclaringType).FullName == "CardBar" && ((MethodReference)m).Parameters.Count == 1)
		{
			return ((MemberReference)((ParameterReference)((MethodReference)m).Parameters[0]).ParameterType).FullName == "CardBarButton";
		}
		return false;
	}

	private static bool ResultDropped(ModuleDefinition module, MethodReference m)
	{
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Invalid comparison between Unknown and I4
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Invalid comparison between Unknown and I4
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Invalid comparison between Unknown and I4
		if (((MemberReference)m.ReturnType).FullName == "System.Void")
		{
			return false;
		}
		int num = 0;
		foreach (TypeDefinition item in AllTypes(module))
		{
			foreach (MethodDefinition item2 in ((IEnumerable<MethodDefinition>)item.Methods).Where((MethodDefinition x) => x.HasBody))
			{
				Enumerator<Instruction> enumerator3 = item2.Body.Instructions.GetEnumerator();
				try
				{
					while (enumerator3.MoveNext())
					{
						Instruction current = enumerator3.Current;
						OpCode opCode = current.OpCode;
						Code code = ((OpCode)(ref opCode)).Code;
						if (((int)code != 39 && (int)code != 110) || 1 == 0)
						{
							continue;
						}
						object operand = current.Operand;
						MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
						if (val == null || !(((MemberReference)val).FullName == ((MemberReference)m).FullName))
						{
							continue;
						}
						Instruction next = current.Next;
						if (next != null)
						{
							opCode = next.OpCode;
							if ((int)((OpCode)(ref opCode)).Code == 37)
							{
								num++;
								continue;
							}
						}
						return false;
					}
				}
				finally
				{
					((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose();
				}
			}
		}
		return num > 0;
	}

	public string? MovedTextCore(TypeReference t)
	{
		if (((MemberReference)t).DeclaringType == null)
		{
			IMetadataScope scope = t.Scope;
			if (!(((scope != null) ? scope.Name : null) != "UnityEngine.TextCoreModule"))
			{
				string[] array = new string[2] { "UnityEngine.TextCoreFontEngineModule", "UnityEngine.TextCoreTextEngineModule" };
				foreach (string text in array)
				{
					AssemblyDefinition val = resolver.Get(text);
					if (val != null && val.MainModule.GetType(((MemberReference)t).FullName) != null)
					{
						return text;
					}
				}
				return null;
			}
		}
		return null;
	}

	public IEnumerable<RpcSite> RpcSites(MethodDefinition m)
	{
		foreach (Instruction item in ((IEnumerable<Instruction>)m.Body.Instructions).Where(delegate(Instruction i)
		{
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			OpCode opCode2 = i.OpCode;
			Code code = ((OpCode)(ref opCode2)).Code;
			if (((int)code == 39 || (int)code == 110) ? true : false)
			{
				object operand = i.Operand;
				MethodReference val3 = (MethodReference)((operand is MethodReference) ? operand : null);
				if (val3 != null && ((MemberReference)val3).Name == "RPC")
				{
					return ((MemberReference)((MemberReference)val3).DeclaringType).Name == "PhotonView";
				}
			}
			return false;
		}))
		{
			Instruction val = null;
			Instruction val2 = null;
			for (Instruction previous = item.Previous; previous != null; previous = previous.Previous)
			{
				OpCode opCode = previous.OpCode;
				if ((int)((OpCode)(ref opCode)).Code == 138)
				{
					val2 = previous;
				}
				opCode = previous.OpCode;
				if ((int)((OpCode)(ref opCode)).Code == 113)
				{
					val = previous;
					break;
				}
			}
			if (val == null || val2 == null)
			{
				continue;
			}
			int? num = IntValue(val2.Previous);
			if (num.HasValue)
			{
				int valueOrDefault = num.GetValueOrDefault();
				string name = (string)val.Operand;
				List<MethodDefinition> list = (from x in AllTypes(game.AssemblyCSharp).SelectMany((TypeDefinition t) => (IEnumerable<MethodDefinition>)t.Methods)
					where ((MemberReference)x).Name == name
					select x).ToList();
				if (list.Count > 0)
				{
					yield return new RpcSite(val2, item, name, valueOrDefault, list);
				}
			}
		}
	}

	public static int? IntValue(Instruction? i)
	{
		//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_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: 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_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Expected I4, but got Unknown
		Code? obj;
		if (i == null)
		{
			obj = null;
		}
		else
		{
			OpCode opCode = i.OpCode;
			obj = ((OpCode)(ref opCode)).Code;
		}
		return obj switch
		{
			(Code)0L => 0, 
			(Code)1L => 1, 
			(Code)2L => 2, 
			(Code)3L => 3, 
			(Code)4L => 4, 
			(Code)5L => 5, 
			(Code)6L => 6, 
			(Code)7L => 7, 
			(Code)8L => 8, 
			(Code)9L => (sbyte)i.Operand, 
			(Code)10L => (int)i.Operand, 
			_ => null, 
		};
	}

	public static bool OnlyMissingDamageSource(RpcSite s)
	{
		if (s.Targets.Count == 1 && ((MethodReference)s.Targets[0]).Parameters.Count == s.Args + 1)
		{
			Collection<ParameterDefinition> parameters = ((MethodReference)s.Targets[0]).Parameters;
			return ((MemberReference)((ParameterReference)parameters[parameters.Count - 1]).ParameterType).FullName == "HealthHandler/DamageSource";
		}
		return false;
	}

	public IEnumerable<ReflectSite> ReflectSites(MethodDefinition m)
	{
		Collection<Instruction> ins = m.Body.Instructions;
		for (int i = 0; i < ins.Count; i++)
		{
			OpCode opCode = ins[i].OpCode;
			Code code = ((OpCode)(ref opCode)).Code;
			if (((int)code != 39 && (int)code != 110) || 1 == 0)
			{
				continue;
			}
			object operand = ins[i].Operand;
			MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
			if (val == null)
			{
				continue;
			}
			string name = ((MemberReference)((MemberReference)val).DeclaringType).Name;
			string name2 = ((MemberReference)val).Name;
			bool flag = name == "AccessTools";
			if (flag)
			{
				bool flag2;
				switch (name2)
				{
				case "DeclaredMethod":
				case "PropertySetter":
				case "FieldRefAccess":
				case "PropertyGetter":
				case "DeclaredPropertyGetter":
				case "DeclaredPropertySetter":
				case "Method":
				case "Field":
				case "Property":
				case "DeclaredField":
				case "DeclaredProperty":
				case "StaticFieldRefAccess":
					flag2 = true;
					break;
				default:
					flag2 = false;
					break;
				}
				flag = flag2;
			}
			bool flag3 = flag;
			flag = ((MemberReference)((MemberReference)val).DeclaringType).FullName == "System.Type";
			if (flag)
			{
				bool flag2;
				switch (name2)
				{
				case "GetMethod":
				case "GetField":
				case "GetProperty":
					flag2 = true;
					break;
				default:
					flag2 = false;
					break;
				}
				flag = flag2;
			}
			bool flag4 = flag;
			flag = name == "Traverse";
			if (flag)
			{
				bool flag2;
				switch (name2)
				{
				case "Field":
				case "Method":
				case "Property":
					flag2 = true;
					break;
				default:
					flag2 = false;
					break;
				}
				flag = flag2;
			}
			bool flag5 = flag;
			flag = ((MemberReference)((MemberReference)val).DeclaringType).FullName == "UnboundLib.ExtensionMethods";
			if (flag)
			{
				bool flag2;
				switch (name2)
				{
				case "GetFieldValue":
				case "SetFieldValue":
				case "GetPropertyValue":
				case "SetPropertyValue":
				case "InvokeMethod":
					flag2 = true;
					break;
				default:
					flag2 = false;
					break;
				}
				flag = flag2;
			}
			bool flag6 = flag;
			if (!(flag3 || flag4 || flag5 || flag6))
			{
				continue;
			}
			Instruction val2 = FindLdstr(ins, i, 8);
			if (val2 == null)
			{
				continue;
			}
			string name3 = (string)val2.Operand;
			string kind = (name2.Contains("Field") ? "Field" : (name2.Contains("Propert") ? "Property" : "Method"));
			if (flag6)
			{
				int num = ins.IndexOf(val2);
				if (num < 1)
				{
					continue;
				}
				TypeReference val3 = PushedType(m, ins[num - 1]);
				if (val3 == null || ((MemberReference)val3).FullName == "System.Object" || val3.IsGenericParameter)
				{
					continue;
				}
				TypeDefinition val4 = Resolve(val3);
				if (val4 != null && !HasMember(val4, name3, kind))
				{
					string text = ((kind == "Field") ? (Renamed(((MemberReference)val4).Name, name3) ?? (HasMember(val4, "m_" + name3, "Field") ? ("m_" + name3) : null)) : null);
					if (text != null)
					{
						yield return new ReflectSite(val2, name + "." + name2, name3, kind.ToLower() + " " + ((MemberReference)val4).Name + "." + name3 + " not found", text);
					}
				}
				continue;
			}
			string call = name + "." + name2;
			if (name == "AccessTools" && name2 == "Method" && Enumerable.Contains(name3, ':'))
			{
				string[] array = name3.Split(new char[1] { ':' });
				TypeDefinition val5 = FindType(array[0]);
				yield return new ReflectSite(val2, call, name3, (val5 == null) ? "type not found" : (HasMember(val5, array[1], "Method") ? null : ("method not found" + Hints(val5, array[1]))), null);
				continue;
			}
			GenericInstanceMethod val6 = (GenericInstanceMethod)(object)((val is GenericInstanceMethod) ? val : null);
			TypeReference val7 = (TypeReference)((val6 != null && name2.Contains("FieldRefAccess")) ? ((object)val6.GenericArguments[0]) : ((object)FindLdtoken(ins, ins.IndexOf(val2), 6)));
			if (val7 == null)
			{
				if (!AnyGameTypeHas(name3, kind) && !AllTypes(((MemberReference)m).Module).Any((TypeDefinition t) => Has(t, name3, kind)))
				{
					string text2 = GameTypeWith("m_" + name3, "Field");
					yield return (text2 != null) ? new ReflectSite(val2, call, name3, "no " + kind.ToLower() + " named '" + name3 + "' anywhere; " + text2 + " has m_" + name3 + " (renamed?)", null) : new ReflectSite(val2, call, name3, "no game or mod type has a " + kind.ToLower() + " named '" + name3 + "'. The target type isn't known statically: if it's another mod's type this is fine, if it's the game's it was removed", null)
					{
						Unsure = true
					};
				}
			}
			else if (!val7.IsGenericParameter)
			{
				TypeDefinition val8 = Resolve(val7);
				if (val8 == null)
				{
					yield return new ReflectSite(val2, call, name3, "type " + ((MemberReference)val7).FullName + " not found", null);
				}
				else if (!HasMember(val8, name3, kind))
				{
					string fixTo = ((kind == "Field" && HasMember(val8, "m_" + name3, "Field")) ? ("m_" + name3) : null);
					yield return new ReflectSite(val2, call, name3, kind.ToLower() + " " + ((MemberReference)val8).Name + "." + name3 + " not found" + Hints(val8, name3), fixTo);
				}
			}
		}
	}

	public MethodDefinition? PluginAwake(TypeDefinition t)
	{
		return ((IEnumerable<MethodDefinition>)t.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == "Awake" && !m.IsStatic && !m.IsVirtual && ((MethodReference)m).Parameters.Count == 0 && m.HasBody && RunsAtPluginLoad(m)));
	}

	public string? SceneLookupAtLoad(MethodDefinition awake)
	{
		HashSet<MethodDefinition> seen = new HashSet<MethodDefinition>();
		return Walk(awake, ((MemberReference)awake.DeclaringType).Name + ".Awake", 0);
		string? Walk(MethodDefinition m, string path, int depth)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Invalid comparison between Unknown and I4
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Invalid comparison between Unknown and I4
			if (!seen.Add(m) || !m.HasBody)
			{
				return null;
			}
			Enumerator<Instruction> enumerator = m.Body.Instructions.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Instruction current = enumerator.Current;
					OpCode opCode = current.OpCode;
					Code code = ((OpCode)(ref opCode)).Code;
					if (((int)code == 39 || (int)code == 110 || (int)code == 114) ? true : false)
					{
						object operand = current.Operand;
						MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
						if (val != null)
						{
							string fullName = ((MemberReference)((MemberReference)val).DeclaringType).FullName;
							if ((fullName == "UnityEngine.Object" && ObjectLookups.Contains(((MemberReference)val).Name)) || (fullName == "UnityEngine.GameObject" && GameObjectLookups.Contains(((MemberReference)val).Name)) || (fullName == "UnityEngine.Camera" && ((MemberReference)val).Name == "get_main"))
							{
								return path + " -> " + ((MemberReference)((MemberReference)val).DeclaringType).Name + "." + ((MemberReference)val).Name;
							}
							if (depth < 4)
							{
								MethodDefinition val2 = ResolveM(val);
								if (val2 != null && ((MemberReference)val2).Module == ((MemberReference)m).Module)
								{
									string text = Walk(val2, path + " > " + ((MemberReference)val2).Name, depth + 1);
									if (text != null)
									{
										return text;
									}
								}
							}
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			return null;
		}
	}

	public static bool IsDontDestroyOnLoad(Instruction ins)
	{
		//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_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Invalid comparison between Unknown and I4
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Invalid comparison between Unknown and I4
		OpCode opCode = ins.OpCode;
		Code code = ((OpCode)(ref opCode)).Code;
		if (((int)code == 39 || (int)code == 110) ? true : false)
		{
			object operand = ins.Operand;
			MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
			if (val != null && ((MemberReference)val).Name == "DontDestroyOnLoad")
			{
				return ((MemberReference)((MemberReference)val).DeclaringType).FullName == "UnityEngine.Object";
			}
		}
		return false;
	}

	public bool RunsAtPluginLoad(MethodDefinition m)
	{
		string name = ((MemberReference)m).Name;
		if ((!(name == "Awake") && !(name == ".ctor")) || 1 == 0)
		{
			return false;
		}
		for (TypeDefinition val = Resolve((TypeReference)(((object)m.DeclaringType.BaseType) ?? ((object)m.DeclaringType))); val != null; val = ((val.BaseType == null) ? null : Resolve(val.BaseType)))
		{
			if (((MemberReference)val).FullName == "BepInEx.BaseUnityPlugin")
			{
				return true;
			}
		}
		return false;
	}

	public TypeDefinition? Resolve(TypeReference t)
	{
		try
		{
			return t.Resolve();
		}
		catch
		{
			return null;
		}
	}

	private MethodDefinition? ResolveM(MethodReference m)
	{
		try
		{
			return md.Resolve(m);
		}
		catch
		{
			return null;
		}
	}

	private FieldDefinition? ResolveF(FieldReference f)
	{
		try
		{
			return md.Resolve(f);
		}
		catch
		{
			return null;
		}
	}

	public static FieldDefinition? NowPrivate(FieldReference f)
	{
		bool flag = !IsGame(((MemberReference)f).DeclaringType) || ((MemberReference)f).DeclaringType is GenericInstanceType;
		if (!flag)
		{
			string name = ((MemberReference)f).Name;
			bool flag2 = ((name == "cardName" || name == "cardDestription") ? true : false);
			flag = flag2;
		}
		if (flag)
		{
			return null;
		}
		FieldDefinition val;
		try
		{
			val = f.Resolve();
		}
		catch (AssemblyResolutionException)
		{
			return null;
		}
		if (val == null || ((TypeReference)val.DeclaringType).IsValueType || (!val.IsPrivate && !val.IsAssembly && !val.IsFamilyAndAssembly))
		{
			return null;
		}
		return val;
	}

	private static bool IsGame(TypeReference t)
	{
		while (((MemberReference)t).DeclaringType != null)
		{
			t = ((MemberReference)t).DeclaringType;
		}
		IMetadataScope scope = t.Scope;
		if (scope == null)
		{
			return false;
		}
		return scope.Name?.StartsWith("Assembly-CSharp") == true;
	}

	private static bool IsGame(TypeDefinition t)
	{
		return ((AssemblyNameReference)((MemberReference)t).Module.Assembly.Name).Name == "Assembly-CSharp";
	}

	private static string Scope(TypeReference t)
	{
		while (((MemberReference)t).DeclaringType != null)
		{
			t = ((MemberReference)t).DeclaringType;
		}
		IMetadataScope scope = t.Scope;
		return ((scope != null) ? scope.Name : null) ?? "?";
	}

	private string? TypeProblem(TypeReference t)
	{
		//IL_001f: Expected O, but got Unknown
		try
		{
			return (t.Resolve() == null) ? ("not in " + Scope(t)) : null;
		}
		catch (AssemblyResolutionException ex)
		{
			AssemblyResolutionException ex2 = ex;
			return "assembly " + ex2.AssemblyReference.Name + " not found";
		}
		catch (Exception ex3)
		{
			return ex3.Message;
		}
	}

	private FieldDefinition? FieldOn(TypeDefinition td, string name)
	{
		for (TypeDefinition val = td; val != null; val = ((val.BaseType == null) ? null : Resolve(val.BaseType)))
		{
			FieldDefinition val2 = ((IEnumerable<FieldDefinition>)val.Fields).FirstOrDefault((Func<FieldDefinition, bool>)((FieldDefinition f) => ((MemberReference)f).Name == name));
			if (val2 != null)
			{
				return val2;
			}
		}
		return null;
	}

	public string Hints(TypeDefinition td, string name)
	{
		List<string> list = new List<string>();
		for (TypeDefinition val = td; val != null; val = ((val.BaseType == null) ? null : Resolve(val.BaseType)))
		{
			list.AddRange(from x in (IEnumerable<MethodDefinition>)val.Methods
				where ((MemberReference)x).Name.Equals(name, StringComparison.OrdinalIgnoreCase) || ((MemberReference)x).Name == "get_" + name
				select ((MemberReference)x).FullName);
			list.AddRange(from x in (IEnumerable<FieldDefinition>)val.Fields
				where ((MemberReference)x).Name.Equals(name, StringComparison.OrdinalIgnoreCase) || ((MemberReference)x).Name.Equals("m_" + name, StringComparison.OrdinalIgnoreCase)
				select "field " + ((MemberReference)x).FullName);
			list.AddRange(from x in (IEnumerable<PropertyDefinition>)val.Properties
				where ((MemberReference)x).Name.Equals(name, StringComparison.OrdinalIgnoreCase)
				select "property " + ((MemberReference)x).FullName);
			if (((AssemblyNameReference)((MemberReference)val).Module.Assembly.Name).Name != ((AssemblyNameReference)((MemberReference)td).Module.Assembly.Name).Name)
			{
				break;
			}
		}
		if (list.Count != 0)
		{
			return " (the game has: " + string.Join("; ", list.Distinct()) + ")";
		}
		return "";
	}

	private bool HasMember(TypeDefinition td, string name, string kind)
	{
		for (TypeDefinition val = td; val != null; val = ((val.BaseType == null) ? null : Resolve(val.BaseType)))
		{
			if (Has(val, name, kind))
			{
				return true;
			}
			if (kind == "Getter" && ((IEnumerable<PropertyDefinition>)val.Properties).Any((PropertyDefinition p) => ((MemberReference)p).Name == name && p.GetMethod != null))
			{
				return true;
			}
			if (kind == "Setter" && ((IEnumerable<PropertyDefinition>)val.Properties).Any((PropertyDefinition p) => ((MemberReference)p).Name == name && p.SetMethod != null))
			{
				return true;
			}
		}
		return false;
	}

	private static bool Has(TypeDefinition t, string name, string kind)
	{
		if ((!(kind == "Field") || !((IEnumerable<FieldDefinition>)t.Fields).Any((FieldDefinition f) => ((MemberReference)f).Name == name)) && (!(kind == "Property") || !((IEnumerable<PropertyDefinition>)t.Properties).Any((PropertyDefinition p) => ((MemberReference)p).Name == name)))
		{
			if (kind == "Method")
			{
				return ((IEnumerable<MethodDefinition>)t.Methods).Any((MethodDefinition p) => ((MemberReference)p).Name == name);
			}
			return false;
		}
		return true;
	}

	public static IEnumerable<TypeDefinition> AllTypes(ModuleDefinition m)
	{
		Enumerator<TypeDefinition> enumerator = m.Types.GetEnumerator();
		try
		{
			while (enumerator.MoveNext())
			{
				TypeDefinition t = enumerator.Current;
				yield return t;
				foreach (TypeDefinition item in Nested(t))
				{
					yield return item;
				}
			}
		}
		finally
		{
			((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
		}
		static IEnumerable<TypeDefinition> Nested(TypeDefinition val)
		{
			Enumerator<TypeDefinition> enumerator3 = val.NestedTypes.GetEnumerator();
			try
			{
				while (enumerator3.MoveNext())
				{
					TypeDefinition n = enumerator3.Current;
					yield return n;
					foreach (TypeDefinition item2 in Nested(n))
					{
						yield return item2;
					}
				}
			}
			finally
			{
				((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose();
			}
		}
	}

	private static Instruction? FindLdstr(Collection<Instruction> ins, int i, int back)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Invalid comparison between Unknown and I4
		int num = i - 1;
		while (num >= 0 && num >= i - back)
		{
			OpCode opCode = ins[num].OpCode;
			if ((int)((OpCode)(ref opCode)).Code == 113)
			{
				return ins[num];
			}
			num--;
		}
		return null;
	}

	private static string? Renamed(string type, string field)
	{
		if (type == "CardBarButton" && field == "card")
		{
			return "m_cardInfo";
		}
		return null;
	}

	private static TypeReference? PushedType(MethodDefinition m, Instruction p)
	{
		//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_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Invalid comparison between Unknown and I4
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Invalid comparison between Unknown and I4
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Invalid comparison between Unknown and I4
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Invalid comparison between Unknown and I4
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Invalid comparison between Unknown and I4
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Invalid comparison between Unknown and I4
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Expected I4, but got Unknown
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Invalid comparison between Unknown and I4
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Invalid comparison between Unknown and I4
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Expected O, but got Unknown
		//IL_0077: 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_007c: Invalid comparison between Unknown and I4
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Expected I4, but got Unknown
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Expected I4, but got Unknown
		//IL_00e2: 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_0065: Invalid comparison between Unknown and I4
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Expected O, but got Unknown
		OpCode opCode = p.OpCode;
		Code code = ((OpCode)(ref opCode)).Code;
		if ((int)code <= 116)
		{
			if ((int)code <= 39)
			{
				switch (code - 2)
				{
				case 4:
				case 5:
				case 6:
				case 7:
				{
					Collection<VariableDefinition> variables = m.Body.Variables;
					opCode = p.OpCode;
					return ((VariableReference)variables[((OpCode)(ref opCode)).Code - 6]).VariableType;
				}
				case 15:
					goto IL_00dc;
				case 0:
				case 1:
				case 2:
				case 3:
					goto IL_00ed;
				case 12:
					goto IL_0126;
				case 8:
				case 9:
				case 10:
				case 11:
				case 13:
				case 14:
					goto IL_0199;
				}
				if ((int)code == 39)
				{
					goto IL_0154;
				}
			}
			else
			{
				if ((int)code == 110)
				{
					goto IL_0154;
				}
				if (code - 115 <= 1)
				{
					return (TypeReference)p.Operand;
				}
			}
		}
		else if ((int)code <= 123)
		{
			if ((int)code == 120 || (int)code == 123)
			{
				return ((FieldReference)p.Operand).FieldType;
			}
		}
		else
		{
			if ((int)code == 199)
			{
				goto IL_0126;
			}
			if ((int)code == 202)
			{
				goto IL_00dc;
			}
		}
		goto IL_0199;
		IL_00dc:
		return ((VariableReference)(VariableDefinition)p.Operand).VariableType;
		IL_0126:
		return ((ParameterReference)(ParameterDefinition)p.Operand).ParameterType;
		IL_00ed:
		opCode = p.OpCode;
		int num = ((OpCode)(ref opCode)).Code - 2 - ((MethodReference)m).HasThis;
		if (num >= 0)
		{
			return ((ParameterReference)((MethodReference)m).Parameters[num]).ParameterType;
		}
		return (TypeReference?)(object)m.DeclaringType;
		IL_0154:
		MethodReference val = (MethodReference)p.Operand;
		GenericInstanceMethod val2 = (GenericInstanceMethod)(object)((val is GenericInstanceMethod) ? val : null);
		if (val2 != null && val.ReturnType.IsGenericParameter && val2.GenericArguments.Count == 1)
		{
			return val2.GenericArguments[0];
		}
		return val.ReturnType;
		IL_0199:
		return null;
	}

	private static TypeReference? FindLdtoken(Collection<Instruction> ins, int i, int back)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Invalid comparison between Unknown and I4
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Invalid comparison between Unknown and I4
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Invalid comparison between Unknown and I4
		int num = i - 1;
		MethodReference val2 = default(MethodReference);
		while (num >= 0 && num >= i - back)
		{
			OpCode opCode = ins[num].OpCode;
			if ((int)((OpCode)(ref opCode)).Code == 174)
			{
				object operand = ins[num].Operand;
				TypeReference val = (TypeReference)((operand is TypeReference) ? operand : null);
				if (val != null)
				{
					return val;
				}
			}
			opCode = ins[num].OpCode;
			Code code = ((OpCode)(ref opCode)).Code;
			int num2;
			if (((int)code == 39 || (int)code == 110) ? true : false)
			{
				object operand2 = ins[num].Operand;
				val2 = (MethodReference)((operand2 is MethodReference) ? operand2 : null);
				num2 = ((val2 != null) ? 1 : 0);
			}
			else
			{
				num2 = 0;
			}
			bool flag = (byte)num2 != 0;
			if (flag)
			{
				bool flag2;
				switch (((MemberReference)val2).Name)
				{
				case "GetMethod":
				case "GetField":
				case "GetProperty":
				case "Method":
				case "Field":
				case "Property":
					flag2 = true;
					break;
				default:
					flag2 = false;
					break;
				}
				flag = flag2;
			}
			if (flag)
			{
				return null;
			}
			num--;
		}
		return null;
	}

	private TypeDefinition? FindType(string n)
	{
		foreach (AssemblyDefinition item in resolver.Loaded())
		{
			TypeDefinition type = item.MainModule.GetType(n);
			if (type != null)
			{
				return type;
			}
		}
		return ((IEnumerable<TypeDefinition>)game.AssemblyCSharp.Types).FirstOrDefault((Func<TypeDefinition, bool>)((TypeDefinition t) => ((MemberReference)t).Name == n));
	}

	private string? GameTypeWith(string name, string kind)
	{
		TypeDefinition? obj = AllTypes(game.AssemblyCSharp).FirstOrDefault((Func<TypeDefinition, bool>)((TypeDefinition t) => Has(t, name, kind)));
		if (obj == null)
		{
			return null;
		}
		return ((MemberReference)obj).FullName;
	}

	private bool AnyGameTypeHas(string name, string kind)
	{
		string[] array = new string[8] { "Assembly-CSharp", "UnityEngine.CoreModule", "UnityEngine.PhysicsModule", "UnityEngine.Physics2DModule", "UnityEngine.UI", "Unity.TextMeshPro", "PhotonUnityNetworking", "PhotonRealtime" };
		foreach (string name2 in array)
		{
			AssemblyDefinition val = resolver.Get(name2);
			if (val != null && AllTypes(val.MainModule).Any((TypeDefinition t) => Has(t, name, kind)))
			{
				return true;
			}
		}
		return false;
	}

	private static bool SigEq(MethodDefinition a, MethodDefinition b)
	{
		if (((MethodReference)a).Parameters.Count != ((MethodReference)b).Parameters.Count)
		{
			return false;
		}
		for (int i = 0; i < ((MethodReference)a).Parameters.Count; i++)
		{
			if (!Same(((ParameterReference)((MethodReference)a).Parameters[i]).ParameterType, ((ParameterReference)((MethodReference)b).Parameters[i]).ParameterType))
			{
				return false;
			}
		}
		return Same(((MethodReference)a).ReturnType, ((MethodReference)b).ReturnType);
		static bool Same(TypeReference x, TypeReference y)
		{
			if (!(((MemberReference)x).FullName == ((MemberReference)y).FullName) && !((MemberReference)x).ContainsGenericParameter)
			{
				return ((MemberReference)y).ContainsGenericParameter;
			}
			return true;
		}
	}

	private static bool ArgsMatch(MethodDefinition m, List<TypeReference>? args)
	{
		if (args == null)
		{
			return true;
		}
		if (((MethodReference)m).Parameters.Count != args.Count)
		{
			return false;
		}
		for (int i = 0; i < args.Count; i++)
		{
			TypeReference parameterType = ((ParameterReference)((MethodReference)m).Parameters[i]).ParameterType;
			ByReferenceType val = (ByReferenceType)(object)((parameterType is ByReferenceType) ? parameterType : null);
			if (((val != null) ? ((MemberReference)((TypeSpecification)val).ElementType).FullName : ((MemberReference)parameterType).FullName) != ((MemberReference)args[i]).FullName && ((MemberReference)parameterType).Name.TrimEnd(new char[1] { '&' }) != ((MemberReference)args[i]).Name)
			{
				return false;
			}
		}
		return true;
	}
}
internal sealed class HarmonyInfo
{
	public TypeReference? Type;

	public string? TypeName;

	public string? Method;

	public int? MethodType;

	public List<TypeReference>? ArgTypes;

	public override string ToString()
	{
		string[] array = new string[5];
		TypeReference? type = Type;
		array[0] = ((type != null) ? ((MemberReference)type).FullName : null) ?? TypeName ?? "?";
		array[1] = "::";
		array[2] = Method ?? "?";
		int? methodType = MethodType;
		object obj;
		if (methodType.HasValue)
		{
			int valueOrDefault = methodType.GetValueOrDefault();
			if (valueOrDefault != 0)
			{
				obj = $" [MethodType {valueOrDefault}]";
				goto IL_007c;
			}
		}
		obj = "";
		goto IL_007c;
		IL_007c:
		array[3] = (string)obj;
		array[4] = ((ArgTypes != null) ? ("(" + string.Join(",", ArgTypes.Select((TypeReference a) => ((MemberReference)a).Name)) + ")") : "");
		return string.Concat(array);
	}

	public static HarmonyInfo Merge(HarmonyInfo a, HarmonyInfo b)
	{
		return new HarmonyInfo
		{
			Type = (b.Type ?? a.Type),
			TypeName = (b.TypeName ?? a.TypeName),
			Method = (b.Method ?? a.Method),
			MethodType = (b.MethodType ?? a.MethodType),
			ArgTypes = (b.ArgTypes ?? a.ArgTypes)
		};
	}

	public static HarmonyInfo? From(IEnumerable<CustomAttribute> attrs)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		HarmonyInfo harmonyInfo = null;
		foreach (CustomAttribute item in attrs.Where((CustomAttribute a) => ((MemberReference)a.AttributeType).Name == "HarmonyPatch"))
		{
			if (harmonyInfo == null)
			{
				harmonyInfo = new HarmonyInfo();
			}
			bool flag = true;
			Enumerator<CustomAttributeArgument> enumerator2 = item.ConstructorArguments.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					CustomAttributeArgument current2 = enumerator2.Current;
					object value = ((CustomAttributeArgument)(ref current2)).Value;
					TypeReference val = (TypeReference)((value is TypeReference) ? value : null);
					if (val != null)
					{
						harmonyInfo.Type = val;
						continue;
					}
					if (value is string text)
					{
						CustomAttributeArgument val2;
						int num;
						if (item.ConstructorArguments.Count >= 2)
						{
							val2 = item.ConstructorArguments[0];
							num = ((((CustomAttributeArgument)(ref val2)).Value is string) ? 1 : 0);
						}
						else
						{
							num = 0;
						}
						if (((uint)num & (flag ? 1u : 0u)) != 0)
						{
							val2 = item.ConstructorArguments[1];
							if (((CustomAttributeArgument)(ref val2)).Value is string)
							{
								harmonyInfo.TypeName = text;
								goto IL_00ef;
							}
						}
						harmonyInfo.Method = text;
						goto IL_00ef;
					}
					if (((MemberReference)((CustomAttributeArgument)(ref current2)).Type).Name == "MethodType")
					{
						harmonyInfo.MethodType = Convert.ToInt32(value);
					}
					else if (value is CustomAttributeArgument[] array && array.Length != 0 && ((CustomAttributeArgument)(ref array[0])).Value is TypeReference)
					{
						harmonyInfo.ArgTypes = ((IEnumerable<CustomAttributeArgument>)array).Select((Func<CustomAttributeArgument, TypeReference>)((CustomAttributeArgument x) => (TypeReference)((CustomAttributeArgument)(ref x)).Value)).ToList();
					}
					else if (value is CustomAttributeArgument[] array2 && array2.Length == 0 && ((MemberReference)((CustomAttributeArgument)(ref current2)).Type.GetElementType()).FullName == "System.Type")
					{
						harmonyInfo.ArgTypes = new List<TypeReference>();
					}
					continue;
					IL_00ef:
					flag = false;
				}
			}
			finally
			{
				((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
		}
		return harmonyInfo;
	}
}
internal sealed class Fixer
{
	private readonly ModuleDefinition M;

	private readonly ModuleDefinition Game;

	private readonly Scanner scanner;

	private readonly TypeDefinition HelperSrc;

	public readonly List<string> Notes = new List<string>();

	private readonly SortedDictionary<string, int> counts = new SortedDictionary<string, int>();

	private TypeDefinition? helper;

	private readonly Dictionary<string, MethodDefinition> helperMethods = new Dictionary<string, MethodDefinition>();

	public IEnumerable<string> Changes => counts.Select<KeyValuePair<string, int>, string>((KeyValuePair<string, int> kv) => (kv.Value <= 1) ? kv.Key : $"{kv.Key}  (x{kv.Value})");

	public bool Changed => counts.Count > 0;

	public Fixer(ModuleDefinition module, Game game, Scanner scanner)
	{
		//IL_0072: 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_0088: Expected O, but got Unknown
		M = module;
		Game = game.AssemblyCSharp;
		this.scanner = scanner;
		using Stream stream = typeof(Fixer).Assembly.GetManifestResourceStream("compathelpers.dll");
		MemoryStream memoryStream = new MemoryStream();
		stream.CopyTo(memoryStream);
		memoryStream.Position = 0L;
		HelperSrc = ModuleDefinition.ReadModule((Stream)memoryStream, new ReaderParameters
		{
			AssemblyResolver = (IAssemblyResolver)(object)game.Resolver
		}).GetType("__RoundsCompat");
	}

	public void Run()
	{
		Generic();
		RpcArgs();
		Renames();
		PluginLoad();
		SpawnObjectResults();
	}

	private void SpawnObjectResults()
	{
		//IL_00a8: 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_00e2: Expected O, but got Unknown
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		foreach (MethodDefinition item in Bodies(M).ToList())
		{
			ParameterDefinition p = ((IEnumerable<ParameterDefinition>)((MethodReference)item).Parameters).FirstOrDefault((Func<ParameterDefinition, bool>)((ParameterDefinition x) => ((ParameterReference)x).Name == "__result"));
			if (p == null || !TargetsSpawnObject(item))
			{
				continue;
			}
			bool byRef = ((ParameterReference)p).ParameterType is ByReferenceType;
			if (((MemberReference)(byRef ? ((TypeSpecification)(ByReferenceType)((ParameterReference)p).ParameterType).ElementType : ((ParameterReference)p).ParameterType)).FullName != "UnityEngine.GameObject[]")
			{
				continue;
			}
			ArrayType val = new ArrayType(M.ImportReference((TypeReference)(object)GT("FriendlyFoe.PoolableWrapper")));
			MethodBody body = item.Body;
			ILProcessor iLProcessor = body.GetILProcessor();
			MethodBodyRocks.SimplifyMacros(body);
			List<Instruction> list = ((IEnumerable<Instruction>)body.Instructions).Where((Instruction i) => i.Operand == p).ToList();
			if (!list.All(delegate(Instruction i)
			{
				//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_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				if (i.OpCode == OpCodes.Ldarg)
				{
					if (byRef)
					{
						Instruction next = i.Next;
						OpCode? val2 = ((next != null) ? new OpCode?(next.OpCode) : ((OpCode?)null));
						OpCode ldind_Ref = OpCodes.Ldind_Ref;
						if (!val2.HasValue)
						{
							return false;
						}
						return val2.GetValueOrDefault() == ldind_Ref;
					}
					return true;
				}
				return false;
			}))
			{
				MethodBodyRocks.OptimizeMacros(body);
				Notes.Add("MANUAL " + ((MemberReference)item).FullName + ": writes SpawnObject's result (PoolableWrapper[] now); left as is");
				continue;
			}
			((ParameterReference)p).ParameterType = (TypeReference)((!byRef) ? ((object)val) : ((object)new ByReferenceType((TypeReference)(object)val)));
			foreach (Instruction item2 in list)
			{
				iLProcessor.InsertAfter(byRef ? item2.Next : item2, Instruction.Create(OpCodes.Call, Helper("PooledObjects")));
			}
			MethodBodyRocks.OptimizeMacros(body);
			Count(((MemberReference)item.DeclaringType).Name + "." + ((MemberReference)item).Name + ": SpawnObject result GameObject[] -> PoolableWrapper[] (reads get the objects)");
		}
	}

	private static bool TargetsSpawnObject(MethodDefinition md)
	{
		return ((IEnumerable<CustomAttribute>)md.CustomAttributes).Concat((IEnumerable<CustomAttribute>)md.DeclaringType.CustomAttributes).Any((CustomAttribute a) => ((MemberReference)a.AttributeType).Name == "HarmonyPatch" && ((IEnumerable<CustomAttributeArgument>)a.ConstructorArguments).Any(delegate(CustomAttributeArgument x)
		{
			object value = ((CustomAttributeArgument)(ref x)).Value;
			TypeReference val = (TypeReference)((value is TypeReference) ? value : null);
			return val != null && ((MemberReference)val).FullName == "ObjectsToSpawn";
		}) && ((IEnumerable<CustomAttributeArgument>)a.ConstructorArguments).Any((CustomAttributeArgument x) => ((CustomAttributeArgument)(ref x)).Value is string text && text == "SpawnObject"));
	}

	private void Count(string what)
	{
		counts.TryGetValue(what, out var value);
		counts[what] = value + 1;
	}

	private TypeDefinition GT(string full)
	{
		return Game.GetType(full) ?? throw new Exception("game type missing " + full);
	}

	private MethodReference GM(string type, string name, int pc = -1)
	{
		return M.ImportReference((MethodReference)(object)((IEnumerable<MethodDefinition>)GT(type).Methods).Single((MethodDefinition x) => ((MemberReference)x).Name == name && (pc < 0 || ((MethodReference)x).Parameters.Count == pc)));
	}

	private static bool IsGameField(FieldReference f, string type, string name)
	{
		if (((MemberReference)f).Name == name && ((MemberReference)((MemberReference)f).DeclaringType).FullName == type)
		{
			return ((MemberReference)f).DeclaringType.Scope.Name.StartsWith("Assembly-CSharp");
		}
		return false;
	}

	private static IEnumerable<MethodDefinition> Bodies(ModuleDefinition m)
	{
		return from md in m.GetTypes().SelectMany((TypeDefinition t) => (IEnumerable<MethodDefinition>)t.Methods)
			where md.HasBody
			select md;
	}

	private MethodReference Helper(string name)
	{
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Expected O, but got Unknown
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Expected O, but got 

plugins/rounds-port.Runtime.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;
using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.SceneManagement;
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: AssemblyCompany("rounds-port.Runtime")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("rounds-port.Runtime")]
[assembly: AssemblyTitle("rounds-port.Runtime")]
[assembly: AssemblyVersion("1.2.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 RoundsPort.Runtime
{
	internal class CardBarUpdateRunner : MonoBehaviour
	{
		private sealed class Patch
		{
			public MethodInfo Method;

			public object[] Args;

			public FieldInfo[] Fields;

			public bool Told;
		}

		internal static ManualLogSource Log;

		private const string Disabled = "__RoundsCompat_Disabled_CardBar_Update_";

		private readonly List<Patch> patches = new List<Patch>();

		private readonly HashSet<Assembly> scanned = new HashSet<Assembly>();

		private bool newAssemblies = true;

		private CardBar[] bars = (CardBar[])(object)new CardBar[0];

		private float nextFind;

		private void OnEnable()
		{
			AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoad;
		}

		private void OnDisable()
		{
			AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoad;
		}

		private void OnAssemblyLoad(object sender, AssemblyLoadEventArgs e)
		{
			newAssemblies = true;
		}

		private void Update()
		{
			if (newAssemblies)
			{
				newAssemblies = false;
				Scan();
			}
			if (patches.Count == 0)
			{
				return;
			}
			if (Time.unscaledTime >= nextFind)
			{
				nextFind = Time.unscaledTime + 1f;
				bars = Object.FindObjectsOfType<CardBar>();
			}
			CardBar[] array = bars;
			foreach (CardBar val in array)
			{
				if ((Object)(object)val == (Object)null || !((Behaviour)val).isActiveAndEnabled)
				{
					continue;
				}
				foreach (Patch patch in patches)
				{
					Run(patch, val);
				}
			}
		}

		private void Scan()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (!scanned.Add(assembly) || assembly.IsDynamic)
				{
					continue;
				}
				Type[] array;
				try
				{
					array = assembly.GetTypes();
				}
				catch (ReflectionTypeLoadException ex)
				{
					array = ex.Types.Where((Type t) => t != null).ToArray();
				}
				catch (Exception)
				{
					continue;
				}
				Type[] array2 = array;
				foreach (Type type in array2)
				{
					MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (MethodInfo methodInfo in methods)
					{
						if (!methodInfo.Name.StartsWith("__RoundsCompat_Disabled_CardBar_Update_"))
						{
							continue;
						}
						ParameterInfo[] parameters = methodInfo.GetParameters();
						Patch patch = new Patch
						{
							Method = methodInfo,
							Args = new object[parameters.Length],
							Fields = new FieldInfo[parameters.Length]
						};
						for (int num3 = 0; num3 < parameters.Length; num3++)
						{
							if (parameters[num3].Name.StartsWith("___"))
							{
								string text = parameters[num3].Name.Substring(3);
								patch.Fields[num3] = AccessTools.DeclaredField(typeof(CardBar), text) ?? AccessTools.DeclaredField(typeof(CardBar), "m_" + text);
							}
						}
						patches.Add(patch);
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogInfo((object)("CardBar.Update has no counterpart now: running " + type.FullName + "." + methodInfo.Name + " every frame for each card bar"));
						}
					}
				}
			}
		}

		private static void Run(Patch p, CardBar bar)
		{
			ParameterInfo[] parameters = p.Method.GetParameters();
			for (int i = 0; i < parameters.Length; i++)
			{
				if (parameters[i].Name == "__instance")
				{
					p.Args[i] = bar;
					continue;
				}
				if (p.Fields[i] != null)
				{
					p.Args[i] = p.Fields[i].GetValue(bar);
					continue;
				}
				Type type = (parameters[i].ParameterType.IsByRef ? parameters[i].ParameterType.GetElementType() : parameters[i].ParameterType);
				p.Args[i] = (type.IsValueType ? Activator.CreateInstance(type) : null);
			}
			try
			{
				p.Method.Invoke(null, p.Args);
			}
			catch (Exception ex)
			{
				if (!p.Told)
				{
					p.Told = true;
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)$"{p.Method.DeclaringType.FullName}.{p.Method.Name}: {ex.GetBaseException()}");
					}
				}
				return;
			}
			for (int j = 0; j < parameters.Length; j++)
			{
				if (p.Fields[j] != null && parameters[j].ParameterType.IsByRef)
				{
					p.Fields[j].SetValue(bar, p.Args[j]);
				}
			}
		}
	}
	[HarmonyPatch(typeof(CardInfo), "Awake")]
	internal static class CardSelfSource_Fix
	{
		private static void Prefix(CardInfo __instance, out bool __state)
		{
			__state = (Object)(object)__instance.sourceCard == (Object)(object)__instance;
			if (__state)
			{
				__instance.sourceCard = null;
			}
		}

		private static void Finalizer(CardInfo __instance, bool __state)
		{
			if (__state && (Object)(object)__instance.sourceCard == (Object)null)
			{
				__instance.sourceCard = __instance;
			}
		}
	}
	[HarmonyPatch]
	internal static class CyberCardPrefab_Fix
	{
		private static Type Effect => Types.Find("CardsPlusPlugin.Cards.Cyberpunk.CyberCardEffect");

		private static bool Prepare()
		{
			return Effect != null;
		}

		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(Effect, "Start", (Type[])null, (Type[])null);
		}

		private static bool Prefix(MonoBehaviour __instance)
		{
			CardInfo componentInParent = ((Component)__instance).GetComponentInParent<CardInfo>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				return ((Component)componentInParent).transform.childCount > 0;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CardInfo), "Awake")]
	internal static class PrefabCardText_Fix
	{
		private static readonly FieldRef<CardInfo, string> Name = AccessTools.FieldRefAccess<CardInfo, string>("cardName");

		private static readonly FieldRef<CardInfo, string> Description = AccessTools.FieldRefAccess<CardInfo, string>("cardDestription");

		private static readonly FieldRef<CardInfo, LocalizedString> LocalizedName = AccessTools.FieldRefAccess<CardInfo, LocalizedString>("m_localizedCardName");

		private static readonly FieldRef<CardInfo, LocalizedString> LocalizedDescription = AccessTools.FieldRefAccess<CardInfo, LocalizedString>("m_localizedCardDescription");

		private static void Prefix(CardInfo __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				Fill(ref LocalizedName.Invoke(__instance), Name.Invoke(__instance));
				Fill(ref LocalizedDescription.Invoke(__instance), Description.Invoke(__instance));
			}
		}

		private static void Fill(ref LocalizedString localized, string text)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if (!string.IsNullOrEmpty(text) && (localized == null || ((LocalizedReference)localized).IsEmpty))
			{
				localized = new LocalizedString(TableReference.op_Implicit("StringTableCards"), TableEntryReference.op_Implicit(text));
			}
		}
	}
	[HarmonyPatch(typeof(CardInfoDisplayer), "DrawCard")]
	internal static class OldCardFrame_Fix
	{
		private static bool IsOld(CardInfoDisplayer d)
		{
			if (Object.op_Implicit((Object)(object)d.nameText))
			{
				if (Object.op_Implicit((Object)(object)d.m_localizedNameText))
				{
					if (Object.op_Implicit((Object)(object)d.statObject) && d.statObject.transform.childCount > 0)
					{
						return !Object.op_Implicit((Object)(object)((Component)d.statObject.transform.GetChild(0)).GetComponent<UILocalizedString>());
					}
					return false;
				}
				return true;
			}
			return false;
		}

		[HarmonyPriority(800)]
		private static bool Prefix(CardInfoDisplayer __instance, CardInfoStat[] stats, LocalizedString cardName, LocalizedString description, Sprite image, bool charge)
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOld(__instance))
			{
				return true;
			}
			if (charge && Object.op_Implicit((Object)(object)__instance.chargeObj))
			{
				__instance.chargeObj.SetActive(true);
				__instance.chargeObj.transform.SetParent(__instance.grid.transform, true);
			}
			string text = Text(description);
			if (text != "" && Object.op_Implicit((Object)(object)__instance.effectText))
			{
				((TMP_Text)__instance.effectText).text = text;
				((Component)__instance.effectText).gameObject.SetActive(true);
				((TMP_Text)__instance.effectText).transform.SetParent(__instance.grid.transform, true);
			}
			((TMP_Text)__instance.nameText).text = Text(cardName).ToUpper();
			bool currentValueToggle = Optionshandler.instance.OptionsData.GetSettingsData("OPTION_SHOWSTATNUMBERS").CurrentValueToggle;
			CardInfoStat[] array = stats ?? Array.Empty<CardInfoStat>();
			foreach (CardInfoStat val in array)
			{
				GameObject obj = Object.Instantiate<GameObject>(__instance.statObject, __instance.grid.transform.position, __instance.grid.transform.rotation, __instance.grid.transform);
				obj.SetActive(true);
				obj.transform.localScale = Vector3.one;
				TextMeshProUGUI component = ((Component)obj.transform.GetChild(1)).GetComponent<TextMeshProUGUI>();
				((TMP_Text)((Component)obj.transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = (string.IsNullOrEmpty(val.stat) ? Text(val.LocalizedStat) : val.stat);
				((TMP_Text)component).text = (((int)val.simepleAmount != 0 && !currentValueToggle) ? val.GetSimpleAmount() : val.amount);
				((Graphic)component).color = (val.positive ? __instance.positiveColor : __instance.negativeColor);
			}
			if (Object.op_Implicit((Object)(object)image) && Object.op_Implicit((Object)(object)__instance.icon))
			{
				__instance.icon.sprite = image;
			}
			if (Object.op_Implicit((Object)(object)__instance.effectText))
			{
				Transform transform = ((TMP_Text)__instance.effectText).transform;
				transform.position += Vector3.up * 0.3f;
			}
			return false;
		}

		private static string Text(LocalizedString s)
		{
			object obj;
			if (s != null && !((LocalizedReference)s).IsEmpty)
			{
				obj = s.GetLocalizedString();
				if (obj == null)
				{
					return "";
				}
			}
			else
			{
				obj = "";
			}
			return (string)obj;
		}
	}
	internal static class UnboundUi
	{
		private static Type menuCard;

		private static Type animHandler;

		private static Type toggleCards;

		private static Type toggleLevels;

		private static MethodInfo toggleAnim;

		private static FieldInfo cardMenuField;

		private static FieldInfo mapInstanceField;

		private static FieldInfo mapCanvasField;

		public static Type MenuCard => menuCard ?? (menuCard = Types.Find("UnboundLib.Cards.MenuCard"));

		public static Type AnimHandler => animHandler ?? (animHandler = Types.Find("UnboundLib.Utils.UI.CardAnimationHandler"));

		private static Type ToggleCards => toggleCards ?? (toggleCards = Types.Find("UnboundLib.Utils.UI.ToggleCardsMenuHandler"));

		private static Type ToggleLevels => toggleLevels ?? (toggleLevels = Types.Find("UnboundLib.Utils.UI.ToggleLevelMenuHandler"));

		public static GameObject CardMenuCanvas
		{
			get
			{
				if (cardMenuField == null && ToggleCards != null)
				{
					cardMenuField = AccessTools.Field(ToggleCards, "cardMenuCanvas");
				}
				object? obj = cardMenuField?.GetValue(null);
				return (GameObject)((obj is GameObject) ? obj : null);
			}
		}

		public static GameObject MapMenuCanvas
		{
			get
			{
				if (mapInstanceField == null && ToggleLevels != null)
				{
					mapInstanceField = AccessTools.Field(ToggleLevels, "instance");
					mapCanvasField = AccessTools.Field(ToggleLevels, "mapMenuCanvas");
				}
				object obj = mapInstanceField?.GetValue(null);
				if (obj != null)
				{
					object? obj2 = mapCanvasField?.GetValue(obj);
					return (GameObject)((obj2 is GameObject) ? obj2 : null);
				}
				return null;
			}
		}

		public static void ToggleAnimation(Component handler, bool on)
		{
			if (!((Object)(object)handler == (Object)null))
			{
				if (toggleAnim == null)
				{
					toggleAnim = AccessTools.Method(((object)handler).GetType(), "ToggleAnimation", new Type[1] { typeof(bool) }, (Type[])null);
				}
				toggleAnim?.Invoke(handler, new object[1] { on });
			}
		}
	}
	[HarmonyPatch(typeof(CardVisuals), "ChangeSelected")]
	internal static class CardVisuals_DeadToggleTargets_Fix
	{
		private static bool IsDead(Delegate d)
		{
			object? target = d.Target;
			Object val = (Object)((target is Object) ? target : null);
			if (val != null)
			{
				return val == (Object)null;
			}
			return false;
		}

		private static void Prefix(CardVisuals __instance)
		{
			Prune(__instance);
		}

		internal static void Prune(CardVisuals __instance)
		{
			Action<bool> toggleSelectionAction = __instance.toggleSelectionAction;
			if (toggleSelectionAction == null)
			{
				return;
			}
			Delegate[] invocationList = toggleSelectionAction.GetInvocationList();
			bool flag = false;
			Delegate[] array = invocationList;
			for (int i = 0; i < array.Length; i++)
			{
				if (IsDead(array[i]))
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return;
			}
			Action<bool> action = null;
			array = invocationList;
			foreach (Delegate obj in array)
			{
				if (!IsDead(obj))
				{
					action = (Action<bool>)Delegate.Combine(action, (Action<bool>)obj);
				}
			}
			__instance.toggleSelectionAction = action;
		}
	}
	[HarmonyPatch(typeof(CardRarityColor), "Toggle")]
	internal static class CardRarityColor_Destroyed_Fix
	{
		private static Exception Finalizer(Exception __exception, CardRarityColor __instance)
		{
			if (!(__exception is NullReferenceException) || !((Object)(object)__instance == (Object)null))
			{
				return __exception;
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(CardVisuals), "Start")]
	internal static class CardVisualsStart_MenuFix
	{
		private static void Prefix(CardVisuals __instance)
		{
			MenuCards.Fix(__instance);
		}
	}
	internal static class MenuCards
	{
		internal static readonly List<Component> added = new List<Component>();

		public static int Fix(CardVisuals v)
		{
			if ((Object)(object)v == (Object)null)
			{
				return 0;
			}
			int num = (HideCoveringParticles(v) ? 1 : 0);
			Component val = ((UnboundUi.MenuCard == null) ? null : ((Component)v).GetComponentInParent(UnboundUi.MenuCard, true));
			Transform val2 = (((Object)(object)val == (Object)null) ? null : val.transform.parent);
			if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).GetComponent<MenuCardHover>() == (Object)null)
			{
				added.Add((Component)(object)((Component)val2).gameObject.AddComponent<MenuCardHover>());
				num |= 2;
			}
			return num;
		}

		private static bool HideCoveringParticles(CardVisuals v)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)v).transform.Find("Canvas/Front/Background/Particles");
			Transform obj = ((Component)v).transform.Find("Canvas");
			Canvas val2 = ((obj != null) ? ((Component)obj).GetComponent<Canvas>() : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return false;
			}
			Canvas val3 = val2;
			if (!val2.overrideSorting)
			{
				Transform parent = ((Component)val2).transform.parent;
				while ((Object)(object)parent != (Object)null)
				{
					Canvas component = ((Component)parent).GetComponent<Canvas>();
					if (!((Object)(object)component == (Object)null))
					{
						val3 = component;
						if (component.overrideSorting)
						{
							break;
						}
					}
					parent = parent.parent;
				}
			}
			if ((Object)(object)val3 == (Object)(object)val2)
			{
				return false;
			}
			if ((int)val3.renderMode != 0)
			{
				SortingGroup component2 = ((Component)val).GetComponent<SortingGroup>();
				int num = (((Object)(object)component2 != (Object)null) ? component2.sortingLayerID : val2.sortingLayerID);
				int num2 = (((Object)(object)component2 != (Object)null) ? component2.sortingOrder : val2.sortingOrder);
				int layerValueFromID = SortingLayer.GetLayerValueFromID(num);
				int layerValueFromID2 = SortingLayer.GetLayerValueFromID(val3.sortingLayerID);
				if (layerValueFromID < layerValueFromID2 || (layerValueFromID == layerValueFromID2 && num2 < val3.sortingOrder))
				{
					return false;
				}
			}
			bool result = false;
			Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val4 in componentsInChildren)
			{
				if (val4.enabled)
				{
					val4.enabled = false;
					result = true;
				}
			}
			return result;
		}

		public static string FixExisting()
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			CardVisuals[] array = Object.FindObjectsOfType<CardVisuals>(true);
			foreach (CardVisuals obj in array)
			{
				num++;
				int num4 = Fix(obj);
				if ((num4 & 1) != 0)
				{
					num2++;
				}
				if ((num4 & 2) != 0)
				{
					num3++;
				}
				CardVisuals_DeadToggleTargets_Fix.Prune(obj);
			}
			return $"{num} cards, {num2} with covering particles hidden, {num3} hover forwarders";
		}

		public static void RemoveAdded()
		{
			foreach (Component item in added)
			{
				if ((Object)(object)item != (Object)null)
				{
					Object.Destroy((Object)(object)item);
				}
			}
			added.Clear();
		}
	}
	internal class MenuCardHover : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public bool Hovered { get; private set; }

		public void OnPointerEnter(PointerEventData eventData)
		{
			Set(on: true);
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			Set(on: false);
		}

		private void Set(bool on)
		{
			Hovered = on;
			if (!(UnboundUi.AnimHandler == null))
			{
				Component[] componentsInChildren = ((Component)this).GetComponentsInChildren(UnboundUi.AnimHandler, true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					UnboundUi.ToggleAnimation(componentsInChildren[i], on);
				}
			}
		}
	}
	internal static class MenuSelectedColors
	{
		public const string CategoriesPath = "CardMenu/Top/Categories/ButtonsScroll/Viewport/Content";

		private static readonly Color unityDefault = ((ColorBlock)(ref ColorBlock.defaultColorBlock)).selectedColor;

		private static bool IsDefault(Color c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (Mathf.Abs(c.r - unityDefault.r) < 0.01f && Mathf.Abs(c.g - unityDefault.g) < 0.01f && Mathf.Abs(c.b - unityDefault.b) < 0.01f)
			{
				return c.a > 0.99f;
			}
			return false;
		}

		public static int Apply(GameObject canvas)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)canvas == (Object)null)
			{
				return 0;
			}
			Transform val = canvas.transform.Find("CardMenu/Top/Categories/ButtonsScroll/Viewport/Content");
			int num = 0;
			Selectable[] componentsInChildren = canvas.GetComponentsInChildren<Selectable>(true);
			foreach (Selectable val2 in componentsInChildren)
			{
				if ((int)val2.transition != 1)
				{
					continue;
				}
				ColorBlock colors = val2.colors;
				if (IsDefault(((ColorBlock)(ref colors)).selectedColor))
				{
					Color val3 = ((ColorBlock)(ref colors)).highlightedColor;
					if ((Object)(object)val != (Object)null && (Object)(object)((Component)val2).transform.parent == (Object)(object)val)
					{
						val3 = Color.Lerp(((ColorBlock)(ref colors)).highlightedColor, ((ColorBlock)(ref colors)).pressedColor, 0.5f);
						val3.a = 1f;
					}
					if (!(val3 == ((ColorBlock)(ref colors)).selectedColor))
					{
						((ColorBlock)(ref colors)).selectedColor = val3;
						val2.colors = colors;
						num++;
					}
				}
			}
			return num;
		}
	}
	internal class CardVisualFixesRunner : MonoBehaviour
	{
		public static ManualLogSource Log;

		private float next;

		private int cardMenuDone;

		private bool mapMenuWasActive;

		private void Start()
		{
			try
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)("menu card fix (existing): " + MenuCards.FixExisting()));
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("menu card fix (existing cards) failed: " + ex.Message));
				}
			}
		}

		private void Update()
		{
			if (Time.unscaledTime < next)
			{
				return;
			}
			next = Time.unscaledTime + 0.5f;
			try
			{
				GameObject cardMenuCanvas = UnboundUi.CardMenuCanvas;
				if ((Object)(object)cardMenuCanvas != (Object)null && ((Object)cardMenuCanvas).GetInstanceID() != cardMenuDone)
				{
					Transform val = cardMenuCanvas.transform.Find("CardMenu/Top/Categories/ButtonsScroll/Viewport/Content");
					if ((Object)(object)val != (Object)null && val.childCount > 0)
					{
						cardMenuDone = ((Object)cardMenuCanvas).GetInstanceID();
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogInfo((object)$"menu selected-colour fix: {MenuSelectedColors.Apply(cardMenuCanvas)} controls");
						}
					}
				}
				GameObject mapMenuCanvas = UnboundUi.MapMenuCanvas;
				bool flag = (Object)(object)mapMenuCanvas != (Object)null && mapMenuCanvas.activeInHierarchy;
				if (flag && !mapMenuWasActive)
				{
					MenuSelectedColors.Apply(mapMenuCanvas);
				}
				mapMenuWasActive = flag;
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("menu selected-colour fix failed: " + ex.Message));
				}
				next = float.MaxValue;
			}
		}

		private void OnDestroy()
		{
			MenuCards.RemoveAdded();
		}
	}
	internal static class LobbyCode
	{
		internal static readonly Type Packer = Types.Find("LobbyImprovements.Utils.ObfuscateJoinCode");

		internal static readonly Type Handler = Types.Find("LobbyImprovements.Networking.LobbyCodeHandler");

		private const string Digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

		internal static char[] Delimiters => (char[])AccessTools.Field(Packer, "Delimeters").GetValue(null);

		internal static long FromBase36(string s)
		{
			long num = 0L;
			string text = s.ToUpperInvariant();
			foreach (char value in text)
			{
				int num2 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".IndexOf(value);
				if (num2 < 0)
				{
					throw new FormatException();
				}
				num = checked(num * 36 + num2);
			}
			return num;
		}

		internal static string ToBase36(long v)
		{
			string text = "";
			do
			{
				text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[(int)(v % 36)] + text;
				v /= 36;
			}
			while (v > 0);
			return text;
		}

		internal static object Call(string method, object arg)
		{
			return AccessTools.Method(Packer, method, (Type[])null, (Type[])null).Invoke(null, new object[1] { arg });
		}
	}
	[HarmonyPatch]
	internal static class LI_PackCode_Fix
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(LobbyCode.Packer, "Obfuscate", (Type[])null, (Type[])null);
		}

		private static bool Prepare()
		{
			if (LobbyCode.Packer != null)
			{
				return TargetMethod() != null;
			}
			return false;
		}

		private static bool Prefix(string code, ref string __result)
		{
			string[] array = code.Split(new char[1] { ':' });
			if (array.Length < 2)
			{
				return true;
			}
			int num = (int)LobbyCode.Call("GetRegionNumber", array[0]);
			char[] delimiters = LobbyCode.Delimiters;
			__result = (string)LobbyCode.Call("LongToBase", (long)num) + delimiters[Random.Range(0, delimiters.Length)] + (string)LobbyCode.Call("LongToBase", LobbyCode.FromBase36(array[1]));
			return false;
		}
	}
	[HarmonyPatch]
	internal static class LI_UnpackCode_Fix
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(LobbyCode.Packer, "DeObfuscate", (Type[])null, (Type[])null);
		}

		private static bool Prepare()
		{
			if (LobbyCode.Packer != null)
			{
				return TargetMethod() != null;
			}
			return false;
		}

		private static bool Prefix(string code, ref string __result)
		{
			string[] array = code.Split(LobbyCode.Delimiters);
			if (array.Length != 2)
			{
				throw new FormatException();
			}
			int num = (int)(long)LobbyCode.Call("BaseToLong", array[0]);
			long v = (long)LobbyCode.Call("BaseToLong", array[1]);
			__result = (string)LobbyCode.Call("GetRegionCode", num) + ":" + LobbyCode.ToBase36(v);
			return false;
		}
	}
	[HarmonyPatch]
	internal static class LI_JoinLetterRooms_Fix
	{
		private static readonly MethodInfo IsDigit = AccessTools.Method(typeof(char), "IsDigit", new Type[1] { typeof(char) }, (Type[])null);

		private static readonly MethodInfo IsLetterOrDigit = AccessTools.Method(typeof(char), "IsLetterOrDigit", new Type[1] { typeof(char) }, (Type[])null);

		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(LobbyCode.Handler, "PureConnectToRoom", (Type[])null, (Type[])null);
		}

		private static bool Prepare()
		{
			if (LobbyCode.Handler != null)
			{
				return TargetMethod() != null;
			}
			return false;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> code)
		{
			foreach (CodeInstruction item in code)
			{
				if (item.opcode == OpCodes.Ldftn && item.operand is MethodInfo methodInfo && methodInfo == IsDigit)
				{
					item.operand = IsLetterOrDigit;
				}
				yield return item;
			}
		}
	}
	[HarmonyPatch]
	internal static class LI_CodeRoomsStayVisible_Fix
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(Types.Find("LobbyImprovements.Networking.LobbyMonitor"), "OnJoinedRoom", (Type[])null, (Type[])null);
		}

		private static bool Prepare()
		{
			if (Types.Find("LobbyImprovements.Networking.LobbyMonitor") != null)
			{
				return TargetMethod() != null;
			}
			return false;
		}

		internal static bool QuickMatchRoom(Room room)
		{
			if (room.IsVisible)
			{
				return !((Dictionary<object, object>)(object)((RoomInfo)room).CustomProperties).ContainsKey((object)NetworkConnectionHandler.ROOM_CODE);
			}
			return false;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> code)
		{
			MethodInfo quickMatch = AccessTools.Method(typeof(LI_CodeRoomsStayVisible_Fix), "QuickMatchRoom", (Type[])null, (Type[])null);
			foreach (CodeInstruction item in code)
			{
				if ((item.opcode == OpCodes.Callvirt || item.opcode == OpCodes.Call) && item.operand is MethodInfo { Name: "get_IsVisible" })
				{
					item.opcode = OpCodes.Call;
					item.operand = quickMatch;
				}
				yield return item;
			}
		}
	}
	[HarmonyPatch]
	internal static class MapsExtClientSync_Fix
	{
		internal static ManualLogSource Log;

		internal static MonoBehaviour Host;

		private static bool told;

		private static Type Manager => Types.Find("MapsExt.NetworkedMapObjectManager");

		private static bool Prepare()
		{
			if (Manager != null)
			{
				return TargetMethod() != null;
			}
			return false;
		}

		internal static MethodBase TargetMethod()
		{
			return AccessTools.DeclaredMethod(Manager, "Instantiate", new Type[3]
			{
				Types.Find("MapsExt.MapObjects.MapObjectData"),
				typeof(Transform),
				typeof(Action<GameObject>)
			}, (Type[])null);
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo start = AccessTools.Method(typeof(MonoBehaviour), "StartCoroutine", new Type[1] { typeof(IEnumerator) }, (Type[])null);
			MethodInfo ours = AccessTools.Method(typeof(MapsExtClientSync_Fix), "StartCoroutine", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, start))
				{
					yield return new CodeInstruction(OpCodes.Call, (object)ours)
					{
						labels = instruction.labels,
						blocks = instruction.blocks
					};
				}
				else
				{
					yield return instruction;
				}
			}
		}

		internal static bool Active(string harmonyId)
		{
			MethodBase methodBase = ((Manager == null) ? null : TargetMethod());
			if (methodBase != null)
			{
				Patches patchInfo = Harmony.GetPatchInfo(methodBase);
				if (patchInfo == null)
				{
					return false;
				}
				return patchInfo.Owners.Contains(harmonyId);
			}
			return false;
		}

		public static Coroutine StartCoroutine(MonoBehaviour self, IEnumerator routine)
		{
			if ((Object)(object)self != (Object)null)
			{
				return self.StartCoroutine(routine);
			}
			if (!told)
			{
				told = true;
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)"MapsExtended's map object manager was destroyed; its client sync runs on rounds-port's helper object");
				}
			}
			return Host.StartCoroutine(routine);
		}
	}
	internal class CoroutineHost : MonoBehaviour
	{
	}
	[BepInPlugin("rounds-port.runtime", "rounds-port Runtime", "1.6.0")]
	[BepInIncompatibility("kieran.rounds.maccompatfixes")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony harmony;

		private GameObject helper;

		private ManualLogSource log;

		private static readonly HashSet<Type> ShaderHooks = new HashSet<Type>
		{
			typeof(AssetBundleLoad_Hook),
			typeof(MaterialCtorShader_Hook),
			typeof(MaterialCtorMaterial_Hook)
		};

		internal static bool IsMetal => (int)SystemInfo.graphicsDeviceType == 16;

		private void Awake()
		{
			log = Logger.CreateLogSource("rounds-port");
			if (AccessTools.Method(typeof(Player), "SetPlayerID", (Type[])null, (Type[])null) == null)
			{
				log.LogInfo((object)"old game build: runtime fixes off");
			}
			else
			{
				Start2025();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private void Start2025()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			harmony = new Harmony("rounds-port.runtime." + Guid.NewGuid().ToString("N"));
			Type[] types = typeof(Plugin).Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0 && (IsMetal || !ShaderHooks.Contains(type)))
				{
					try
					{
						harmony.CreateClassProcessor(type).Patch();
					}
					catch (Exception ex)
					{
						log.LogError((object)("patch " + type.Name + " failed: " + ex.GetBaseException().Message));
					}
				}
			}
			ShaderFix.Log = log;
			CardBarHover_Fix.Log = log;
			StatsPanelGuard_Fix.Log = log;
			UL_UpdateNotice_Fix.Log = log;
			helper = LetterboxClear.Create();
			MapsExtClientSync_Fix.Log = log;
			MapsExtClientSync_Fix.Host = (MonoBehaviour)(object)helper.AddComponent<CoroutineHost>();
			if (MapsExtClientSync_Fix.Active(harmony.Id))
			{
				log.LogInfo((object)"MapsExtended client map sync fix: on");
			}
			MissingText.Apply(log);
			CameraStack_Fix.Postfix(MainCam.instance);
			CardVisualFixesRunner.Log = log;
			helper.AddComponent<CardVisualFixesRunner>();
			CardBarUpdateRunner.Log = log;
			helper.AddComponent<CardBarUpdateRunner>();
			if (IsMetal)
			{
				ShaderFix.Sweep();
				SceneManager.sceneLoaded += OnSceneLoaded;
				helper.AddComponent<ShaderFixRunner>();
			}
			log.LogInfo((object)$"runtime fixes {((BaseUnityPlugin)this).Info.Metadata.Version} loaded ({SystemInfo.graphicsDeviceType})");
		}

		private void Start()
		{
			if (harmony == null)
			{
				return;
			}
			try
			{
				if (((BaseUnityPlugin)this).Info.Location.IndexOf("DuctTape", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					AccessTools.Method("UnboundLib.Unbound:RegisterCredits", new Type[4]
					{
						typeof(string),
						typeof(string[]),
						typeof(string[]),
						typeof(string[])
					}, (Type[])null)?.Invoke(null, new object[4]
					{
						"DuctTape",
						new string[1] { "Kieran" },
						new string[1] { "GitHub" },
						new string[1] { "https://github.com/KieranK07/DuctTape" }
					});
				}
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("credits not added: " + ex.GetBaseException().Message));
			}
		}

		private void OnSceneLoaded(Scene s, LoadSceneMode m)
		{
			ShaderFix.Sweep();
		}

		private void OnDestroy()
		{
			if (harmony != null)
			{
				SceneManager.sceneLoaded -= OnSceneLoaded;
				Harmony obj = harmony;
				if (obj != null)
				{
					obj.UnpatchSelf();
				}
				MissingText.Restore();
				if ((Object)(object)helper != (Object)null)
				{
					Object.Destroy((Object)(object)helper);
				}
				ManualLogSource obj2 = log;
				if (obj2 != null)
				{
					obj2.LogInfo((object)"runtime fixes unloaded");
				}
				if (log != null)
				{
					Logger.Sources.Remove((ILogSource)(object)log);
				}
			}
		}
	}
	internal static class CardNames
	{
		public static string Strip(string s)
		{
			return s?.Replace("(Clone)", "").Trim();
		}

		public static CardInfo Find(string name, bool everything)
		{
			IEnumerable<CardInfo> enumerable = HiddenCards();
			if ((Object)(object)CardChoice.instance != (Object)null)
			{
				enumerable = CardChoice.instance.cards.Concat(enumerable);
			}
			if (everything)
			{
				enumerable = enumerable.Concat(Resources.FindObjectsOfTypeAll<CardInfo>());
			}
			return enumerable.FirstOrDefault((Func<CardInfo, bool>)((CardInfo c) => (Object)(object)c != (Object)null && Strip(((Object)((Component)c).gameObject).name) == name));
		}

		private static IEnumerable<CardInfo> HiddenCards()
		{
			Type type = Types.Find("ModdingUtils.Utils.Cards");
			object obj = ((type == null) ? null : AccessTools.Field(type, "instance")?.GetValue(null));
			IEnumerable<CardInfo> enumerable = ((obj == null) ? null : (AccessTools.Property(type, "HiddenCards")?.GetValue(obj, null) as IEnumerable<CardInfo>));
			return enumerable ?? Array.Empty<CardInfo>();
		}
	}
	internal static class Types
	{
		private static readonly Dictionary<string, Type> found = new Dictionary<string, Type>();

		public static Type Find(string fullName)
		{
			if (found.TryGetValue(fullName, out var value))
			{
				return value;
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					value = assembly.GetType(fullName, throwOnError: false);
				}
				catch
				{
					value = null;
				}
				if (value != null)
				{
					return found[fullName] = value;
				}
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(CardChoice), "GetSourceCard")]
	internal static class GetSourceCard_Fallback
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(CardInfo info, ref CardInfo __result)
		{
			if ((Object)(object)__result == (Object)null && (Object)(object)info != (Object)null)
			{
				__result = CardNames.Find(CardNames.Strip(((Object)((Component)info).gameObject).name), everything: false);
			}
		}
	}
	[HarmonyPatch(typeof(CardBar))]
	internal static class CardBarHover_Fix
	{
		private static readonly Dictionary<int, string> buttonCard = new Dictionary<int, string>();

		private static readonly FieldRef<CardBar, List<CardBarButton>> cardsRef = AccessTools.FieldRefAccess<CardBar, List<CardBarButton>>("m_cards");

		public static ManualLogSource Log;

		[HarmonyPostfix]
		[HarmonyPatch("AddCard")]
		private static void AddCard_Postfix(CardBar __instance, CardInfo card)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			List<CardBarButton> list = cardsRef.Invoke(__instance);
			if (!((Object)(object)card == (Object)null) && list != null && list.Count != 0 && !((Object)(object)list[0] == (Object)null))
			{
				buttonCard[((Object)list[0]).GetInstanceID()] = CardNames.Strip(((Object)((Component)card).gameObject).name);
				ManualLogSource log = Log;
				if (log != null)
				{
					string[] obj = new string[5]
					{
						"card bar + ",
						((Object)((Component)card).gameObject).name,
						" (scene '",
						null,
						null
					};
					Scene scene = ((Component)card).gameObject.scene;
					obj[3] = ((Scene)(ref scene)).name;
					obj[4] = "')";
					log.LogDebug((object)string.Concat(obj));
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("OnHover", new Type[] { typeof(CardBarButton) })]
		private static bool OnHover_Prefix(CardBarButton cardButton)
		{
			if ((Object)(object)cardButton == (Object)null)
			{
				return false;
			}
			if ((Object)(object)cardButton.m_cardInfo != (Object)null)
			{
				return true;
			}
			if (buttonCard.TryGetValue(((Object)cardButton).GetInstanceID(), out var value))
			{
				CardInfo val = CardNames.Find(value, everything: true);
				if ((Object)(object)val != (Object)null)
				{
					cardButton.m_cardInfo = val;
					return true;
				}
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("card bar hover: no live card named " + value));
				}
			}
			return false;
		}
	}
	internal static class MissingText
	{
		private static string previous;

		public static void Apply(ManualLogSource log)
		{
			try
			{
				LocalizedStringDatabase stringDatabase = LocalizationSettings.StringDatabase;
				if (stringDatabase != null)
				{
					if (previous == null)
					{
						previous = stringDatabase.NoTranslationFoundMessage;
					}
					stringDatabase.NoTranslationFoundMessage = "{key}";
					log.LogInfo((object)("missing-translation text: '" + previous + "' -> '{key}'"));
				}
			}
			catch (Exception ex)
			{
				log.LogWarning((object)("missing-translation text not changed: " + ex.Message));
			}
		}

		public static void Restore()
		{
			try
			{
				if (previous != null)
				{
					LocalizationSettings.StringDatabase.NoTranslationFoundMessage = previous;
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(CardInfoDisplayer), "DrawCard")]
	internal static class StatNames_Fix
	{
		private static void Postfix(CardInfoDisplayer __instance, CardInfoStat[] stats)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			if (stats == null || stats.Length == 0 || (Object)(object)__instance.grid == (Object)null || (Object)(object)__instance.statObject == (Object)null)
			{
				return;
			}
			List<Transform> list = new List<Transform>();
			string text = ((Object)__instance.statObject).name + "(Clone)";
			foreach (Transform item in __instance.grid.transform)
			{
				Transform val = item;
				if (((Object)val).name == text)
				{
					list.Add(val);
				}
			}
			int i = 0;
			int num = list.Count - stats.Length;
			for (; i < stats.Length; i++)
			{
				if (num < 0)
				{
					break;
				}
				CardInfoStat val2 = stats[i];
				if (val2 != null && !string.IsNullOrEmpty(val2.stat) && (val2.LocalizedStat == null || ((LocalizedReference)val2.LocalizedStat).IsEmpty) && list[num + i].childCount > 0)
				{
					UILocalizedString component = ((Component)list[num + i].GetChild(0)).GetComponent<UILocalizedString>();
					if (component != null)
					{
						component.ResetReference(val2.stat);
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(MainCam), "Awake")]
	internal static class CameraStack_Fix
	{
		internal static void Postfix(MainCam __instance)
		{
			PostProcessLayer val = (Object.op_Implicit((Object)(object)__instance) ? ((Component)__instance).GetComponent<PostProcessLayer>() : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				val.finalBlitToCameraTarget = false;
			}
		}
	}
	internal static class LetterboxClear
	{
		public static GameObject Create()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			GameObject val = new GameObject("rounds-port Runtime");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			Camera obj = val.AddComponent<Camera>();
			obj.depth = -100f;
			obj.clearFlags = (CameraClearFlags)2;
			obj.backgroundColor = Color.black;
			obj.cullingMask = 0;
			obj.rect = new Rect(0f, 0f, 1f, 1f);
			obj.useOcclusionCulling = false;
			return val;
		}
	}
	internal static class ShaderFix
	{
		public static ManualLogSource Log;

		private static readonly HashSet<AssetBundle> recordedBundles = new HashSet<AssetBundle>();

		private static readonly HashSet<string> reported = new HashSet<string>();

		private static readonly HashSet<Shader> foreign = new HashSet<Shader>();

		private static Dictionary<string, Shader> native;

		private static int nativeFrame = -1;

		private static readonly HashSet<string> ModOnlyShaders = new HashSet<string> { "Legacy Shaders/Particles/Additive", "Custom/Add", "Custom/Opacity2", "Standard" };

		private static bool changed = true;

		private static bool IsForeign(Shader sh)
		{
			if ((Object)(object)sh != (Object)null)
			{
				if (!foreign.Contains(sh))
				{
					return !sh.isSupported;
				}
				return true;
			}
			return false;
		}

		private static Shader Native(string name)
		{
			if ((native == null || !native.ContainsKey(name)) && nativeFrame != Time.frameCount)
			{
				nativeFrame = Time.frameCount;
				native = new Dictionary<string, Shader>();
				Shader[] array = Resources.FindObjectsOfTypeAll<Shader>();
				foreach (Shader val in array)
				{
					if (!((Object)(object)val == (Object)null) && !foreign.Contains(val) && val.isSupported && ((Object)val).GetInstanceID() > 0 && (!native.TryGetValue(((Object)val).name, out var value) || ((Object)val).GetInstanceID() < ((Object)value).GetInstanceID()))
					{
						native[((Object)val).name] = val;
					}
				}
			}
			if (native == null || !native.TryGetValue(name, out var value2))
			{
				return null;
			}
			return value2;
		}

		public static void RecordBundle(AssetBundle bundle)
		{
			if ((Object)(object)bundle == (Object)null || bundle.isStreamedSceneAssetBundle || !recordedBundles.Add(bundle) || ((Object)bundle).name.EndsWith(".bundle"))
			{
				return;
			}
			Object[] array = bundle.LoadAllAssets();
			Object[] array2 = array;
			foreach (Object obj in array2)
			{
				Shader val = (Shader)(object)((obj is Shader) ? obj : null);
				if (val != null)
				{
					foreign.Add(val);
				}
			}
			array2 = array;
			foreach (Object val2 in array2)
			{
				Material val3 = (Material)(object)((val2 is Material) ? val2 : null);
				if (val3 != null)
				{
					Fix(val3, ((Object)bundle).name);
					continue;
				}
				GameObject val4 = (GameObject)(object)((val2 is GameObject) ? val2 : null);
				if (val4 == null)
				{
					continue;
				}
				Renderer[] componentsInChildren = val4.GetComponentsInChildren<Renderer>(true);
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					Material[] sharedMaterials = componentsInChildren[j].sharedMaterials;
					for (int k = 0; k < sharedMaterials.Length; k++)
					{
						Fix(sharedMaterials[k], ((Object)bundle).name);
					}
				}
			}
		}

		public static void Sweep()
		{
			foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles())
			{
				RecordBundle(allLoadedAssetBundle);
			}
			Material[] array = Resources.FindObjectsOfTypeAll<Material>();
			for (int i = 0; i < array.Length; i++)
			{
				Fix(array[i], null);
			}
			if (!changed)
			{
				return;
			}
			changed = false;
			Graphic[] array2 = Resources.FindObjectsOfTypeAll<Graphic>();
			foreach (Graphic val in array2)
			{
				if ((Object)(object)val != (Object)null && ((Behaviour)val).isActiveAndEnabled)
				{
					val.SetMaterialDirty();
					val.SetVerticesDirty();
				}
			}
			Canvas.ForceUpdateCanvases();
		}

		public static void Fix(Material m, string where)
		{
			if ((Object)(object)m == (Object)null || (Object)(object)m.shader == (Object)null)
			{
				return;
			}
			Shader shader = m.shader;
			string name = ((Object)shader).name;
			if (ModOnlyShaders.Contains(name))
			{
				if (!Rebuild(m, name))
				{
					Report("waiting for a Metal shader for " + name + " (" + ((Object)m).name + ")");
				}
				else
				{
					changed = true;
					Report(string.Format("{0}/{1}: {2}#{3} -> {4}#{5} (rebuilt)", where ?? "runtime", ((Object)m).name, name, ((Object)shader).GetInstanceID(), ((Object)m.shader).name, ((Object)m.shader).GetInstanceID()));
				}
				return;
			}
			Shader val = Native(name);
			if ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)val == (Object)(object)shader)
				{
					return;
				}
				m.shader = val;
			}
			else
			{
				if (!IsForeign(shader))
				{
					return;
				}
				if (!Rebuild(m, name))
				{
					Report("waiting for a Metal shader for " + name + " (" + ((Object)m).name + ")");
					return;
				}
			}
			changed = true;
			Report(string.Format("{0}/{1}: {2}#{3} -> {4}#{5}", where ?? "runtime", ((Object)m).name, name, ((Object)shader).GetInstanceID(), ((Object)m.shader).name, ((Object)m.shader).GetInstanceID()));
		}

		private static void Report(string msg)
		{
			if (reported.Add(msg))
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)msg);
				}
			}
		}

		private static bool Rebuild(Material m, string name)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Native("Particles/Standard Unlit");
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Texture val3;
			Color val4;
			int num;
			int num2;
			bool flag;
			switch (name)
			{
			case "Legacy Shaders/Particles/Additive":
				val3 = Tex(m, "_MainTex");
				val4 = (Color)(m.HasProperty("_TintColor") ? m.GetColor("_TintColor") : new Color(0.5f, 0.5f, 0.5f, 0.5f)) * 2f;
				num = 5;
				num2 = 1;
				flag = false;
				break;
			case "Custom/Add":
				val3 = Tex(m, "_MainTexture");
				val4 = Color.white;
				num = 1;
				num2 = 1;
				flag = false;
				break;
			case "Custom/Opacity2":
				val3 = Tex(m, "_MainTexture");
				val4 = Color.white;
				num = 1;
				num2 = 0;
				flag = true;
				break;
			case "Standard":
				val3 = Tex(m, "_MainTex");
				val4 = (m.HasProperty("_Color") ? m.GetColor("_Color") : Color.white);
				num = ((!m.HasProperty("_SrcBlend")) ? 1 : ((int)m.GetFloat("_SrcBlend")));
				num2 = (m.HasProperty("_DstBlend") ? ((int)m.GetFloat("_DstBlend")) : 0);
				flag = !m.HasProperty("_ZWrite") || m.GetFloat("_ZWrite") > 0.5f;
				break;
			default:
			{
				Shader val2 = Native("Sprites/Default");
				if ((Object)(object)val2 == (Object)null)
				{
					return false;
				}
				m.shader = val2;
				return true;
			}
			}
			int renderQueue = m.renderQueue;
			m.shader = val;
			m.shaderKeywords = new string[0];
			if ((Object)(object)val3 != (Object)null)
			{
				m.SetTexture("_MainTex", val3);
			}
			m.SetColor("_Color", val4);
			m.SetFloat("_BlendOp", 0f);
			m.SetFloat("_SrcBlend", (float)num);
			m.SetFloat("_DstBlend", (float)num2);
			m.SetFloat("_ZWrite", (float)(flag ? 1 : 0));
			m.SetFloat("_Cull", 0f);
			if (num != 1 || num2 != 0)
			{
				m.SetOverrideTag("RenderType", "Transparent");
				m.EnableKeyword("_ALPHABLEND_ON");
				m.renderQueue = ((renderQueue >= 2500) ? renderQueue : 3000);
			}
			else
			{
				m.SetOverrideTag("RenderType", "Opaque");
				m.renderQueue = ((renderQueue > 0 && renderQueue < 2500) ? renderQueue : 2000);
			}
			return true;
		}

		private static Texture Tex(Material m, string prop)
		{
			if (!m.HasProperty(prop))
			{
				return null;
			}
			return m.GetTexture(prop);
		}
	}
	[HarmonyPatch]
	internal static class AssetBundleLoad_Hook
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo[] methods = typeof(AssetBundle).GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.ReturnType == typeof(AssetBundle) && methodInfo.Name.StartsWith("LoadFrom") && !methodInfo.Name.EndsWith("Async") && methodInfo.GetMethodBody() != null)
				{
					yield return methodInfo;
				}
			}
		}

		private static void Postfix(AssetBundle __result)
		{
			ShaderFix.RecordBundle(__result);
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class MaterialCtorShader_Hook
	{
		private static void Postfix(Material __instance)
		{
			ShaderFix.Fix(__instance, "new");
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class MaterialCtorMaterial_Hook
	{
		private static void Postfix(Material __instance)
		{
			ShaderFix.Fix(__instance, "copy");
		}
	}
	internal class ShaderFixRunner : MonoBehaviour
	{
		private float next;

		private void Update()
		{
			if (!(Time.unscaledTime < next))
			{
				next = Time.unscaledTime + 0.5f;
				ShaderFix.Sweep();
			}
		}
	}
	[HarmonyPatch]
	internal static class StatsBaseline_Fix
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(CharacterStatModifiers), "ResetStats", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(Block), "ResetStats", (Type[])null, (Type[])null);
		}

		private static Exception Finalizer(Exception __exception, Component __instance)
		{
			if (__exception != null && __instance != null && (Object)(object)__instance == (Object)null)
			{
				return null;
			}
			return __exception;
		}
	}
	[HarmonyPatch]
	internal static class StatsPanelGuard_Fix
	{
		internal static ManualLogSource Log;

		private static bool logged;

		private static Type Attached => Types.Find("UnboundLib.StatsViewer.AttachedCardChoiceUI");

		private static bool Prepare()
		{
			return Attached != null;
		}

		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(Attached, "ChangePlayer", (Type[])null, (Type[])null);
		}

		private static Exception Finalizer(Exception __exception)
		{
			if (__exception == null)
			{
				return null;
			}
			if (!logged)
			{
				logged = true;
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("UnboundLib's stats panel failed; the card pick carries on without it: " + __exception.GetBaseException()));
				}
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(TextMeshProUGUI), "GetMaterials")]
	internal static class UndrawnTextMaterials_Fix
	{
		private static readonly FieldRef<TMP_Text, TMP_TextInfo> TextInfo = AccessTools.FieldRefAccess<TMP_Text, TMP_TextInfo>("m_textInfo");

		private static Exception Finalizer(Exception __exception, TextMeshProUGUI __instance, ref Material[] __result)
		{
			if (!(__exception is NullReferenceException) || (Object)(object)__instance == (Object)null || TextInfo.Invoke((TMP_Text)(object)__instance) != null)
			{
				return __exception;
			}
			__result = (Material[])(object)new Material[1] { ((TMP_Text)__instance).fontSharedMaterial };
			return null;
		}
	}
	[HarmonyPatch]
	internal static class UL_HealthBarRespawns_Fix
	{
		private static MethodBase Target()
		{
			return AccessTools.Method(Types.Find("UnboundLib.Patches.HealthBar_Patch_Update"), "Postfix", (Type[])null, (Type[])null);
		}

		private static bool Prepare()
		{
			return Target() != null;
		}

		private static MethodBase TargetMethod()
		{
			return Target();
		}

		private static bool Prefix(object[] __args)
		{
			if (__args.Length > 1)
			{
				object obj = __args[1];
				CharacterData val = (CharacterData)((obj is CharacterData) ? obj : null);
				if (val != null && (Object)(object)val != (Object)null)
				{
					return (Object)(object)val.stats != (Object)null;
				}
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class UL_UpdateNotice_Fix
	{
		private static readonly string[] Ours = new string[1] { "Bknibb/RoundsWithFriends 3.0.10" };

		private static readonly HashSet<string> logged = new HashSet<string>();

		internal static ManualLogSource Log;

		private static IEnumerable<MethodBase> Targets()
		{
			Type t = Types.Find("UnboundLib.Utils.UI.UpdateChecker");
			if (!(t == null))
			{
				return from m in ((IEnumerable<string>)new string[2] { "RegisterModUpdateChecker", "CreateUpdateMenu" }).Select((Func<string, MethodBase>)((string n) => AccessTools.Method(t, n, (Type[])null, (Type[])null)))
					where m != null
					select m;
			}
			return Enumerable.Empty<MethodBase>();
		}

		private static bool Prepare()
		{
			return Targets().Any();
		}

		private static IEnumerable<MethodBase> TargetMethods()
		{
			return Targets();
		}

		private static bool Prefix(object[] __args, MethodBase __originalMethod)
		{
			if (__args.Length == 0 || __args[0] == null)
			{
				return true;
			}
			Traverse val = Traverse.Create(__args[0]);
			string text = val.Field("repoOwner").GetValue<string>() + "/" + val.Field("repoName").GetValue<string>() + " " + val.Field("currentVersion").GetValue<string>();
			if (Array.IndexOf(Ours, text) < 0)
			{
				return true;
			}
			if (__originalMethod.Name == "RegisterModUpdateChecker" && logged.Add(text))
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)("update notice for " + text + " skipped: DuctTape makes this version"));
				}
			}
			return false;
		}
	}
}

plugins/OdinSerializer/Sirenix.Serialization.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Assemblies;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using Sirenix.Serialization;
using Sirenix.Utilities;
using Sirenix.Utilities.Unsafe;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RegisterFormatterLocator(typeof(ArrayFormatterLocator), -80)]
[assembly: RegisterFormatterLocator(typeof(DelegateFormatterLocator), -50)]
[assembly: RegisterFormatterLocator(typeof(GenericCollectionFormatterLocator), -100)]
[assembly: RegisterFormatterLocator(typeof(ISerializableFormatterLocator), -110)]
[assembly: RegisterFormatterLocator(typeof(SelfFormatterLocator), -60)]
[assembly: RegisterFormatterLocator(typeof(TypeFormatterLocator), -70)]
[assembly: RegisterFormatter(typeof(ArrayListFormatter), 0)]
[assembly: RegisterFormatter(typeof(DateTimeFormatter), 0)]
[assembly: RegisterFormatter(typeof(DateTimeOffsetFormatter), 0)]
[assembly: RegisterFormatter(typeof(DerivedDictionaryFormatter<, , >), typeof(WeakDictionaryFormatter), -1)]
[assembly: RegisterFormatter(typeof(DictionaryFormatter<, >), typeof(WeakDictionaryFormatter), 0)]
[assembly: RegisterFormatter(typeof(DoubleLookupDictionaryFormatter<, , >), typeof(WeakDoubleLookupDictionaryFormatter), 0)]
[assembly: RegisterFormatter(typeof(HashSetFormatter<>), typeof(WeakHashSetFormatter), 0)]
[assembly: RegisterFormatter(typeof(KeyValuePairFormatter<, >), typeof(WeakKeyValuePairFormatter), 0)]
[assembly: RegisterFormatter(typeof(ListFormatter<>), typeof(WeakListFormatter), 0)]
[assembly: RegisterFormatter(typeof(MethodInfoFormatter<>), typeof(WeakMethodInfoFormatter), 0)]
[assembly: RegisterFormatter(typeof(NullableFormatter<>), typeof(WeakNullableFormatter), 0)]
[assembly: RegisterFormatter(typeof(QueueFormatter<, >), typeof(WeakQueueFormatter), 0)]
[assembly: RegisterFormatter(typeof(StackFormatter<, >), typeof(WeakStackFormatter), 0)]
[assembly: RegisterFormatter(typeof(TimeSpanFormatter), 0)]
[assembly: RegisterFormatter(typeof(VersionFormatter), 0)]
[assembly: RegisterDictionaryKeyPathProvider(typeof(Vector2DictionaryKeyPathProvider))]
[assembly: RegisterDictionaryKeyPathProvider(typeof(Vector3DictionaryKeyPathProvider))]
[assembly: RegisterDictionaryKeyPathProvider(typeof(Vector4DictionaryKeyPathProvider))]
[assembly: RegisterFormatter(typeof(AnimationCurveFormatter), 0)]
[assembly: RegisterFormatter(typeof(BoundsFormatter), 0)]
[assembly: RegisterFormatter(typeof(Color32Formatter), 0)]
[assembly: RegisterFormatterLocator(typeof(ColorBlockFormatterLocator), 0)]
[assembly: RegisterFormatter(typeof(ColorFormatter), 0)]
[assembly: RegisterFormatter(typeof(CoroutineFormatter), 0)]
[assembly: RegisterFormatter(typeof(GradientAlphaKeyFormatter), 0)]
[assembly: RegisterFormatter(typeof(GradientColorKeyFormatter), 0)]
[assembly: RegisterFormatter(typeof(GradientFormatter), 0)]
[assembly: RegisterFormatter(typeof(KeyframeFormatter), 0)]
[assembly: RegisterFormatter(typeof(LayerMaskFormatter), 0)]
[assembly: RegisterFormatter(typeof(QuaternionFormatter), 0)]
[assembly: RegisterFormatter(typeof(RectFormatter), 0)]
[assembly: RegisterFormatter(typeof(UnityEventFormatter<>), typeof(WeakUnityEventFormatter), 0)]
[assembly: RegisterFormatter(typeof(Vector2Formatter), 0)]
[assembly: RegisterFormatter(typeof(Vector3Formatter), 0)]
[assembly: RegisterFormatter(typeof(Vector4Formatter), 0)]
[assembly: RegisterFormatter(typeof(Vector2IntFormatter), 0)]
[assembly: RegisterFormatter(typeof(Vector3IntFormatter), 0)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Sirenix IVS (OdinSerializer, Apache-2.0); repackaged for ROUNDS MapsExtended compat")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2018 Sirenix IVS. Licensed under the Apache License, Version 2.0.")]
[assembly: AssemblyFileVersion("2.1.6.0")]
[assembly: AssemblyInformationalVersion("2.1.6+c7742d03f29cd17a12b701152f0f68db2afefa48")]
[assembly: AssemblyProduct("OdinSerializer (open source) built as Sirenix.Serialization 2.1.6 drop-in")]
[assembly: AssemblyTitle("Sirenix.Serialization")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 Sirenix.OdinInspector
{
	public abstract class SerializedMonoBehaviour : Sirenix.Serialization.SerializedMonoBehaviour
	{
	}
	public abstract class SerializedScriptableObject : Sirenix.Serialization.SerializedScriptableObject
	{
	}
	public abstract class SerializedBehaviour : Sirenix.Serialization.SerializedBehaviour
	{
	}
	public abstract class SerializedComponent : Sirenix.Serialization.SerializedComponent
	{
	}
	public abstract class SerializedStateMachineBehaviour : Sirenix.Serialization.SerializedStateMachineBehaviour
	{
	}
}
namespace Sirenix.Serialization
{
	public abstract class BaseDataReader : BaseDataReaderWriter, IDataReader, IDisposable
	{
		private DeserializationContext context;

		private Stream stream;

		public int CurrentNodeId => base.CurrentNode.Id;

		public int CurrentNodeDepth => base.NodeDepth;

		public string CurrentNodeName => base.CurrentNode.Name;

		public virtual Stream Stream
		{
			get
			{
				return stream;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				if (!value.CanRead)
				{
					throw new ArgumentException("Cannot read from stream");
				}
				stream = value;
			}
		}

		public DeserializationContext Context
		{
			get
			{
				if (context == null)
				{
					context = new DeserializationContext();
				}
				return context;
			}
			set
			{
				context = value;
			}
		}

		protected BaseDataReader(Stream stream, DeserializationContext context)
		{
			this.context = context;
			if (stream != null)
			{
				Stream = stream;
			}
		}

		public abstract bool EnterNode(out Type type);

		public abstract bool ExitNode();

		public abstract bool EnterArray(out long length);

		public abstract bool ExitArray();

		public abstract bool ReadPrimitiveArray<T>(out T[] array) where T : struct;

		public abstract EntryType PeekEntry(out string name);

		public abstract bool ReadInternalReference(out int id);

		public abstract bool ReadExternalReference(out int index);

		public abstract bool ReadExternalReference(out Guid guid);

		public abstract bool ReadExternalReference(out string id);

		public abstract bool ReadChar(out char value);

		public abstract bool ReadString(out string value);

		public abstract bool ReadGuid(out Guid value);

		public abstract bool ReadSByte(out sbyte value);

		public abstract bool ReadInt16(out short value);

		public abstract bool ReadInt32(out int value);

		public abstract bool ReadInt64(out long value);

		public abstract bool ReadByte(out byte value);

		public abstract bool ReadUInt16(out ushort value);

		public abstract bool ReadUInt32(out uint value);

		public abstract bool ReadUInt64(out ulong value);

		public abstract bool ReadDecimal(out decimal value);

		public abstract bool ReadSingle(out float value);

		public abstract bool ReadDouble(out double value);

		public abstract bool ReadBoolean(out bool value);

		public abstract bool ReadNull();

		public virtual void SkipEntry()
		{
			switch (PeekEntry())
			{
			case EntryType.StartOfNode:
			{
				bool flag = true;
				EnterNode(out var type);
				try
				{
					if (type != null)
					{
						if (FormatterUtilities.IsPrimitiveType(type))
						{
							object reference = Serializer.Get(type).ReadValueWeak(this);
							if (CurrentNodeId >= 0)
							{
								Context.RegisterInternalReference(CurrentNodeId, reference);
							}
						}
						else
						{
							object reference2 = FormatterLocator.GetFormatter(type, Context.Config.SerializationPolicy).Deserialize(this);
							if (CurrentNodeId >= 0)
							{
								Context.RegisterInternalReference(CurrentNodeId, reference2);
							}
						}
						break;
					}
					while (true)
					{
						switch (PeekEntry())
						{
						case EntryType.EndOfArray:
							ReadToNextEntry();
							break;
						default:
							SkipEntry();
							break;
						case EntryType.EndOfNode:
						case EntryType.EndOfStream:
							return;
						}
					}
				}
				catch (SerializationAbortException ex)
				{
					flag = false;
					throw ex;
				}
				finally
				{
					if (flag)
					{
						ExitNode();
					}
				}
			}
			case EntryType.StartOfArray:
				ReadToNextEntry();
				while (true)
				{
					switch (PeekEntry())
					{
					case EntryType.EndOfArray:
						ReadToNextEntry();
						return;
					case EntryType.EndOfNode:
						ReadToNextEntry();
						break;
					default:
						SkipEntry();
						break;
					case EntryType.EndOfStream:
						return;
					}
				}
			default:
				ReadToNextEntry();
				break;
			case EntryType.EndOfNode:
			case EntryType.EndOfArray:
				break;
			}
		}

		public abstract void Dispose();

		public virtual void PrepareNewSerializationSession()
		{
			ClearNodes();
		}

		public abstract string GetDataDump();

		protected abstract EntryType PeekEntry();

		protected abstract EntryType ReadToNextEntry();
	}
	public abstract class BaseDataReaderWriter
	{
		private NodeInfo[] nodes = new NodeInfo[32];

		private int nodesLength;

		[Obsolete("Use the Binder member on the writer's SerializationContext/DeserializationContext instead.", false)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public TwoWaySerializationBinder Binder
		{
			get
			{
				if (this is IDataWriter)
				{
					return (this as IDataWriter).Context.Binder;
				}
				if (this is IDataReader)
				{
					return (this as IDataReader).Context.Binder;
				}
				return TwoWaySerializationBinder.Default;
			}
			set
			{
				if (this is IDataWriter)
				{
					(this as IDataWriter).Context.Binder = value;
				}
				else if (this is IDataReader)
				{
					(this as IDataReader).Context.Binder = value;
				}
			}
		}

		public bool IsInArrayNode
		{
			get
			{
				if (nodesLength != 0)
				{
					return nodes[nodesLength - 1].IsArray;
				}
				return false;
			}
		}

		protected int NodeDepth => nodesLength;

		protected NodeInfo[] NodesArray => nodes;

		protected NodeInfo CurrentNode
		{
			get
			{
				if (nodesLength != 0)
				{
					return nodes[nodesLength - 1];
				}
				return NodeInfo.Empty;
			}
		}

		protected void PushNode(NodeInfo node)
		{
			if (nodesLength == nodes.Length)
			{
				ExpandNodes();
			}
			nodes[nodesLength] = node;
			nodesLength++;
		}

		protected void PushNode(string name, int id, Type type)
		{
			if (nodesLength == nodes.Length)
			{
				ExpandNodes();
			}
			nodes[nodesLength] = new NodeInfo(name, id, type, isArray: false);
			nodesLength++;
		}

		protected void PushArray()
		{
			if (nodesLength == nodes.Length)
			{
				ExpandNodes();
			}
			if (nodesLength == 0 || nodes[nodesLength - 1].IsArray)
			{
				nodes[nodesLength] = new NodeInfo(null, -1, null, isArray: true);
			}
			else
			{
				NodeInfo nodeInfo = nodes[nodesLength - 1];
				nodes[nodesLength] = new NodeInfo(nodeInfo.Name, nodeInfo.Id, nodeInfo.Type, isArray: true);
			}
			nodesLength++;
		}

		private void ExpandNodes()
		{
			NodeInfo[] array = new NodeInfo[nodes.Length * 2];
			NodeInfo[] array2 = nodes;
			for (int i = 0; i < array2.Length; i++)
			{
				array[i] = array2[i];
			}
			nodes = array;
		}

		protected void PopNode(string name)
		{
			if (nodesLength == 0)
			{
				throw new InvalidOperationException("There are no nodes to pop.");
			}
			nodesLength--;
		}

		protected void PopArray()
		{
			if (nodesLength == 0)
			{
				throw new InvalidOperationException("There are no nodes to pop.");
			}
			if (!nodes[nodesLength - 1].IsArray)
			{
				throw new InvalidOperationException("Was not in array when exiting array.");
			}
			nodesLength--;
		}

		protected void ClearNodes()
		{
			nodesLength = 0;
		}
	}
	public abstract class BaseDataWriter : BaseDataReaderWriter, IDataWriter, IDisposable
	{
		private SerializationContext context;

		private Stream stream;

		public virtual Stream Stream
		{
			get
			{
				return stream;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				if (!value.CanWrite)
				{
					throw new ArgumentException("Cannot write to stream");
				}
				stream = value;
			}
		}

		public SerializationContext Context
		{
			get
			{
				if (context == null)
				{
					context = new SerializationContext();
				}
				return context;
			}
			set
			{
				context = value;
			}
		}

		protected BaseDataWriter(Stream stream, SerializationContext context)
		{
			this.context = context;
			if (stream != null)
			{
				Stream = stream;
			}
		}

		public virtual void FlushToStream()
		{
			Stream.Flush();
		}

		public abstract void BeginReferenceNode(string name, Type type, int id);

		public abstract void BeginStructNode(string name, Type type);

		public abstract void EndNode(string name);

		public abstract void BeginArrayNode(long length);

		public abstract void EndArrayNode();

		public abstract void WritePrimitiveArray<T>(T[] array) where T : struct;

		public abstract void WriteNull(string name);

		public abstract void WriteInternalReference(string name, int id);

		public abstract void WriteExternalReference(string name, int index);

		public abstract void WriteExternalReference(string name, Guid guid);

		public abstract void WriteExternalReference(string name, string id);

		public abstract void WriteChar(string name, char value);

		public abstract void WriteString(string name, string value);

		public abstract void WriteGuid(string name, Guid value);

		public abstract void WriteSByte(string name, sbyte value);

		public abstract void WriteInt16(string name, short value);

		public abstract void WriteInt32(string name, int value);

		public abstract void WriteInt64(string name, long value);

		public abstract void WriteByte(string name, byte value);

		public abstract void WriteUInt16(string name, ushort value);

		public abstract void WriteUInt32(string name, uint value);

		public abstract void WriteUInt64(string name, ulong value);

		public abstract void WriteDecimal(string name, decimal value);

		public abstract void WriteSingle(string name, float value);

		public abstract void WriteDouble(string name, double value);

		public abstract void WriteBoolean(string name, bool value);

		public abstract void Dispose();

		public virtual void PrepareNewSerializationSession()
		{
			ClearNodes();
		}

		public abstract string GetDataDump();
	}
	public class BinaryDataReader : BaseDataReader
	{
		private struct Struct256Bit
		{
			public decimal d1;

			public decimal d2;
		}

		private static readonly Dictionary<Type, Delegate> PrimitiveFromByteMethods = new Dictionary<Type, Delegate>
		{
			{
				typeof(char),
				(Func<byte[], int, char>)((byte[] b, int i) => (char)ProperBitConverter.ToUInt16(b, i))
			},
			{
				typeof(byte),
				(Func<byte[], int, byte>)((byte[] b, int i) => b[i])
			},
			{
				typeof(sbyte),
				(Func<byte[], int, sbyte>)((byte[] b, int i) => (sbyte)b[i])
			},
			{
				typeof(bool),
				(Func<byte[], int, bool>)((byte[] b, int i) => b[i] != 0)
			},
			{
				typeof(short),
				new Func<byte[], int, short>(ProperBitConverter.ToInt16)
			},
			{
				typeof(int),
				new Func<byte[], int, int>(ProperBitConverter.ToInt32)
			},
			{
				typeof(long),
				new Func<byte[], int, long>(ProperBitConverter.ToInt64)
			},
			{
				typeof(ushort),
				new Func<byte[], int, ushort>(ProperBitConverter.ToUInt16)
			},
			{
				typeof(uint),
				new Func<byte[], int, uint>(ProperBitConverter.ToUInt32)
			},
			{
				typeof(ulong),
				new Func<byte[], int, ulong>(ProperBitConverter.ToUInt64)
			},
			{
				typeof(decimal),
				new Func<byte[], int, decimal>(ProperBitConverter.ToDecimal)
			},
			{
				typeof(float),
				new Func<byte[], int, float>(ProperBitConverter.ToSingle)
			},
			{
				typeof(double),
				new Func<byte[], int, double>(ProperBitConverter.ToDouble)
			},
			{
				typeof(Guid),
				new Func<byte[], int, Guid>(ProperBitConverter.ToGuid)
			}
		};

		private byte[] internalBufferBackup;

		private byte[] buffer = new byte[102400];

		private int bufferIndex;

		private int bufferEnd;

		private EntryType? peekedEntryType;

		private BinaryEntryType peekedBinaryEntryType;

		private string peekedEntryName;

		private Dictionary<int, Type> types = new Dictionary<int, Type>(16);

		public BinaryDataReader()
			: base(null, null)
		{
			internalBufferBackup = buffer;
		}

		public BinaryDataReader(Stream stream, DeserializationContext context)
			: base(stream, context)
		{
			internalBufferBackup = buffer;
		}

		public override void Dispose()
		{
		}

		public override EntryType PeekEntry(out string name)
		{
			if (peekedEntryType.HasValue)
			{
				name = peekedEntryName;
				return peekedEntryType.Value;
			}
			peekedBinaryEntryType = (BinaryEntryType)(HasBufferData(1) ? buffer[bufferIndex++] : 49);
			switch (peekedBinaryEntryType)
			{
			case BinaryEntryType.EndOfStream:
				name = null;
				peekedEntryName = null;
				peekedEntryType = EntryType.EndOfStream;
				break;
			case BinaryEntryType.NamedStartOfReferenceNode:
			case BinaryEntryType.NamedStartOfStructNode:
				name = ReadStringValue();
				peekedEntryType = EntryType.StartOfNode;
				break;
			case BinaryEntryType.UnnamedStartOfReferenceNode:
			case BinaryEntryType.UnnamedStartOfStructNode:
				name = null;
				peekedEntryType = EntryType.StartOfNode;
				break;
			case BinaryEntryType.EndOfNode:
				name = null;
				peekedEntryType = EntryType.EndOfNode;
				break;
			case BinaryEntryType.StartOfArray:
				name = null;
				peekedEntryType = EntryType.StartOfArray;
				break;
			case BinaryEntryType.EndOfArray:
				name = null;
				peekedEntryType = EntryType.EndOfArray;
				break;
			case BinaryEntryType.PrimitiveArray:
				name = null;
				peekedEntryType = EntryType.PrimitiveArray;
				break;
			case BinaryEntryType.NamedInternalReference:
				name = ReadStringValue();
				peekedEntryType = EntryType.InternalReference;
				break;
			case BinaryEntryType.UnnamedInternalReference:
				name = null;
				peekedEntryType = EntryType.InternalReference;
				break;
			case BinaryEntryType.NamedExternalReferenceByIndex:
				name = ReadStringValue();
				peekedEntryType = EntryType.ExternalReferenceByIndex;
				break;
			case BinaryEntryType.UnnamedExternalReferenceByIndex:
				name = null;
				peekedEntryType = EntryType.ExternalReferenceByIndex;
				break;
			case BinaryEntryType.NamedExternalReferenceByGuid:
				name = ReadStringValue();
				peekedEntryType = EntryType.ExternalReferenceByGuid;
				break;
			case BinaryEntryType.UnnamedExternalReferenceByGuid:
				name = null;
				peekedEntryType = EntryType.ExternalReferenceByGuid;
				break;
			case BinaryEntryType.NamedExternalReferenceByString:
				name = ReadStringValue();
				peekedEntryType = EntryType.ExternalReferenceByString;
				break;
			case BinaryEntryType.UnnamedExternalReferenceByString:
				name = null;
				peekedEntryType = EntryType.ExternalReferenceByString;
				break;
			case BinaryEntryType.NamedSByte:
				name = ReadStringValue();
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.UnnamedSByte:
				name = null;
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.NamedByte:
				name = ReadStringValue();
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.UnnamedByte:
				name = null;
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.NamedShort:
				name = ReadStringValue();
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.UnnamedShort:
				name = null;
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.NamedUShort:
				name = ReadStringValue();
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.UnnamedUShort:
				name = null;
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.NamedInt:
				name = ReadStringValue();
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.UnnamedInt:
				name = null;
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.NamedUInt:
				name = ReadStringValue();
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.UnnamedUInt:
				name = null;
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.NamedLong:
				name = ReadStringValue();
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.UnnamedLong:
				name = null;
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.NamedULong:
				name = ReadStringValue();
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.UnnamedULong:
				name = null;
				peekedEntryType = EntryType.Integer;
				break;
			case BinaryEntryType.NamedFloat:
				name = ReadStringValue();
				peekedEntryType = EntryType.FloatingPoint;
				break;
			case BinaryEntryType.UnnamedFloat:
				name = null;
				peekedEntryType = EntryType.FloatingPoint;
				break;
			case BinaryEntryType.NamedDouble:
				name = ReadStringValue();
				peekedEntryType = EntryType.FloatingPoint;
				break;
			case BinaryEntryType.UnnamedDouble:
				name = null;
				peekedEntryType = EntryType.FloatingPoint;
				break;
			case BinaryEntryType.NamedDecimal:
				name = ReadStringValue();
				peekedEntryType = EntryType.FloatingPoint;
				break;
			case BinaryEntryType.UnnamedDecimal:
				name = null;
				peekedEntryType = EntryType.FloatingPoint;
				break;
			case BinaryEntryType.NamedChar:
				name = ReadStringValue();
				peekedEntryType = EntryType.String;
				break;
			case BinaryEntryType.UnnamedChar:
				name = null;
				peekedEntryType = EntryType.String;
				break;
			case BinaryEntryType.NamedString:
				name = ReadStringValue();
				peekedEntryType = EntryType.String;
				break;
			case BinaryEntryType.UnnamedString:
				name = null;
				peekedEntryType = EntryType.String;
				break;
			case BinaryEntryType.NamedGuid:
				name = ReadStringValue();
				peekedEntryType = EntryType.Guid;
				break;
			case BinaryEntryType.UnnamedGuid:
				name = null;
				peekedEntryType = EntryType.Guid;
				break;
			case BinaryEntryType.NamedBoolean:
				name = ReadStringValue();
				peekedEntryType = EntryType.Boolean;
				break;
			case BinaryEntryType.UnnamedBoolean:
				name = null;
				peekedEntryType = EntryType.Boolean;
				break;
			case BinaryEntryType.NamedNull:
				name = ReadStringValue();
				peekedEntryType = EntryType.Null;
				break;
			case BinaryEntryType.UnnamedNull:
				name = null;
				peekedEntryType = EntryType.Null;
				break;
			case BinaryEntryType.TypeName:
			case BinaryEntryType.TypeID:
				peekedBinaryEntryType = BinaryEntryType.Invalid;
				peekedEntryType = EntryType.Invalid;
				throw new InvalidOperationException("Invalid binary data stream: BinaryEntryType.TypeName and BinaryEntryType.TypeID must never be peeked by the binary reader.");
			default:
			{
				name = null;
				peekedBinaryEntryType = BinaryEntryType.Invalid;
				peekedEntryType = EntryType.Invalid;
				byte b = (byte)peekedBinaryEntryType;
				throw new InvalidOperationException("Invalid binary data stream: could not parse peeked BinaryEntryType byte '" + b + "' into a known entry type.");
			}
			}
			peekedEntryName = name;
			return peekedEntryType.Value;
		}

		public override bool EnterArray(out long length)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedEntryType == EntryType.StartOfArray)
			{
				PushArray();
				MarkEntryContentConsumed();
				if (UNSAFE_Read_8_Int64(out length))
				{
					if (length < 0)
					{
						length = 0L;
						base.Context.Config.DebugContext.LogError("Invalid array length: " + length + ".");
						return false;
					}
					return true;
				}
				return false;
			}
			SkipEntry();
			length = 0L;
			return false;
		}

		public override bool EnterNode(out Type type)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedStartOfReferenceNode || peekedBinaryEntryType == BinaryEntryType.UnnamedStartOfReferenceNode)
			{
				MarkEntryContentConsumed();
				type = ReadTypeEntry();
				if (!UNSAFE_Read_4_Int32(out var value))
				{
					type = null;
					return false;
				}
				PushNode(peekedEntryName, value, type);
				return true;
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedStartOfStructNode || peekedBinaryEntryType == BinaryEntryType.UnnamedStartOfStructNode)
			{
				type = ReadTypeEntry();
				PushNode(peekedEntryName, -1, type);
				MarkEntryContentConsumed();
				return true;
			}
			SkipEntry();
			type = null;
			return false;
		}

		public override bool ExitArray()
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			while (peekedBinaryEntryType != BinaryEntryType.EndOfArray && peekedBinaryEntryType != BinaryEntryType.EndOfStream)
			{
				if (peekedEntryType == EntryType.EndOfNode)
				{
					base.Context.Config.DebugContext.LogError("Data layout mismatch; skipping past node boundary when exiting array.");
					MarkEntryContentConsumed();
				}
				SkipEntry();
			}
			if (peekedBinaryEntryType == BinaryEntryType.EndOfArray)
			{
				MarkEntryContentConsumed();
				PopArray();
				return true;
			}
			return false;
		}

		public override bool ExitNode()
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			while (peekedBinaryEntryType != BinaryEntryType.EndOfNode && peekedBinaryEntryType != BinaryEntryType.EndOfStream)
			{
				if (peekedEntryType == EntryType.EndOfArray)
				{
					base.Context.Config.DebugContext.LogError("Data layout mismatch; skipping past array boundary when exiting node.");
					MarkEntryContentConsumed();
				}
				SkipEntry();
			}
			if (peekedBinaryEntryType == BinaryEntryType.EndOfNode)
			{
				MarkEntryContentConsumed();
				PopNode(base.CurrentNodeName);
				return true;
			}
			return false;
		}

		public unsafe override bool ReadPrimitiveArray<T>(out T[] array)
		{
			if (!FormatterUtilities.IsPrimitiveArrayType(typeof(T)))
			{
				throw new ArgumentException("Type " + typeof(T).Name + " is not a valid primitive array type.");
			}
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedEntryType == EntryType.PrimitiveArray)
			{
				MarkEntryContentConsumed();
				if (!UNSAFE_Read_4_Int32(out var value) || !UNSAFE_Read_4_Int32(out var value2))
				{
					array = null;
					return false;
				}
				int num = value * value2;
				if (!HasBufferData(num))
				{
					bufferIndex = bufferEnd;
					array = null;
					return false;
				}
				if (typeof(T) == typeof(byte))
				{
					byte[] array2 = new byte[num];
					Buffer.BlockCopy(buffer, bufferIndex, array2, 0, num);
					array = (T[])(object)array2;
					bufferIndex += num;
					return true;
				}
				array = new T[value];
				if (BitConverter.IsLittleEndian)
				{
					GCHandle gCHandle = GCHandle.Alloc(array, GCHandleType.Pinned);
					try
					{
						fixed (byte* ptr = buffer)
						{
							void* ptr2 = ptr + bufferIndex;
							void* ptr3 = gCHandle.AddrOfPinnedObject().ToPointer();
							UnsafeUtilities.MemoryCopy(ptr2, ptr3, num);
						}
					}
					finally
					{
						gCHandle.Free();
					}
				}
				else
				{
					Func<byte[], int, T> func = (Func<byte[], int, T>)PrimitiveFromByteMethods[typeof(T)];
					for (int i = 0; i < value; i++)
					{
						array[i] = func(buffer, bufferIndex + i * value2);
					}
				}
				bufferIndex += num;
				return true;
			}
			SkipEntry();
			array = null;
			return false;
		}

		public override bool ReadBoolean(out bool value)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedEntryType == EntryType.Boolean)
			{
				MarkEntryContentConsumed();
				if (HasBufferData(1))
				{
					value = buffer[bufferIndex++] == 1;
					return true;
				}
				value = false;
				return false;
			}
			SkipEntry();
			value = false;
			return false;
		}

		public override bool ReadSByte(out sbyte value)
		{
			if (ReadInt64(out var value2))
			{
				try
				{
					value = checked((sbyte)value2);
				}
				catch (OverflowException)
				{
					value = 0;
				}
				return true;
			}
			value = 0;
			return false;
		}

		public override bool ReadByte(out byte value)
		{
			if (ReadUInt64(out var value2))
			{
				try
				{
					value = checked((byte)value2);
				}
				catch (OverflowException)
				{
					value = 0;
				}
				return true;
			}
			value = 0;
			return false;
		}

		public override bool ReadInt16(out short value)
		{
			if (ReadInt64(out var value2))
			{
				try
				{
					value = checked((short)value2);
				}
				catch (OverflowException)
				{
					value = 0;
				}
				return true;
			}
			value = 0;
			return false;
		}

		public override bool ReadUInt16(out ushort value)
		{
			if (ReadUInt64(out var value2))
			{
				try
				{
					value = checked((ushort)value2);
				}
				catch (OverflowException)
				{
					value = 0;
				}
				return true;
			}
			value = 0;
			return false;
		}

		public override bool ReadInt32(out int value)
		{
			if (ReadInt64(out var value2))
			{
				try
				{
					value = checked((int)value2);
				}
				catch (OverflowException)
				{
					value = 0;
				}
				return true;
			}
			value = 0;
			return false;
		}

		public override bool ReadUInt32(out uint value)
		{
			if (ReadUInt64(out var value2))
			{
				try
				{
					value = checked((uint)value2);
				}
				catch (OverflowException)
				{
					value = 0u;
				}
				return true;
			}
			value = 0u;
			return false;
		}

		public override bool ReadInt64(out long value)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedEntryType == EntryType.Integer)
			{
				try
				{
					switch (peekedBinaryEntryType)
					{
					case BinaryEntryType.NamedSByte:
					case BinaryEntryType.UnnamedSByte:
					{
						if (!UNSAFE_Read_1_SByte(out var value5))
						{
							value = 0L;
							return false;
						}
						value = value5;
						break;
					}
					case BinaryEntryType.NamedByte:
					case BinaryEntryType.UnnamedByte:
					{
						if (!UNSAFE_Read_1_Byte(out var value6))
						{
							value = 0L;
							return false;
						}
						value = value6;
						break;
					}
					case BinaryEntryType.NamedShort:
					case BinaryEntryType.UnnamedShort:
					{
						if (!UNSAFE_Read_2_Int16(out var value7))
						{
							value = 0L;
							return false;
						}
						value = value7;
						break;
					}
					case BinaryEntryType.NamedUShort:
					case BinaryEntryType.UnnamedUShort:
					{
						if (!UNSAFE_Read_2_UInt16(out var value3))
						{
							value = 0L;
							return false;
						}
						value = value3;
						break;
					}
					case BinaryEntryType.NamedInt:
					case BinaryEntryType.UnnamedInt:
					{
						if (!UNSAFE_Read_4_Int32(out var value4))
						{
							value = 0L;
							return false;
						}
						value = value4;
						break;
					}
					case BinaryEntryType.NamedUInt:
					case BinaryEntryType.UnnamedUInt:
					{
						if (!UNSAFE_Read_4_UInt32(out var value8))
						{
							value = 0L;
							return false;
						}
						value = value8;
						break;
					}
					case BinaryEntryType.NamedLong:
					case BinaryEntryType.UnnamedLong:
						if (!UNSAFE_Read_8_Int64(out value))
						{
							return false;
						}
						break;
					case BinaryEntryType.NamedULong:
					case BinaryEntryType.UnnamedULong:
					{
						if (!UNSAFE_Read_8_UInt64(out var value2))
						{
							value = 0L;
							return false;
						}
						if (value2 > long.MaxValue)
						{
							value = 0L;
							return false;
						}
						value = (long)value2;
						break;
					}
					default:
						throw new InvalidOperationException();
					}
					return true;
				}
				finally
				{
					MarkEntryContentConsumed();
				}
			}
			SkipEntry();
			value = 0L;
			return false;
		}

		public override bool ReadUInt64(out ulong value)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedEntryType == EntryType.Integer)
			{
				try
				{
					switch (peekedBinaryEntryType)
					{
					case BinaryEntryType.NamedSByte:
					case BinaryEntryType.UnnamedSByte:
					case BinaryEntryType.NamedByte:
					case BinaryEntryType.UnnamedByte:
					{
						if (!UNSAFE_Read_1_Byte(out var value7))
						{
							value = 0uL;
							return false;
						}
						value = value7;
						break;
					}
					case BinaryEntryType.NamedShort:
					case BinaryEntryType.UnnamedShort:
					{
						if (!UNSAFE_Read_2_Int16(out var value4))
						{
							value = 0uL;
							return false;
						}
						if (value4 < 0)
						{
							value = 0uL;
							return false;
						}
						value = (ulong)value4;
						break;
					}
					case BinaryEntryType.NamedUShort:
					case BinaryEntryType.UnnamedUShort:
					{
						if (!UNSAFE_Read_2_UInt16(out var value6))
						{
							value = 0uL;
							return false;
						}
						value = value6;
						break;
					}
					case BinaryEntryType.NamedInt:
					case BinaryEntryType.UnnamedInt:
					{
						if (!UNSAFE_Read_4_Int32(out var value5))
						{
							value = 0uL;
							return false;
						}
						if (value5 < 0)
						{
							value = 0uL;
							return false;
						}
						value = (ulong)value5;
						break;
					}
					case BinaryEntryType.NamedUInt:
					case BinaryEntryType.UnnamedUInt:
					{
						if (!UNSAFE_Read_4_UInt32(out var value2))
						{
							value = 0uL;
							return false;
						}
						value = value2;
						break;
					}
					case BinaryEntryType.NamedLong:
					case BinaryEntryType.UnnamedLong:
					{
						if (!UNSAFE_Read_8_Int64(out var value3))
						{
							value = 0uL;
							return false;
						}
						if (value3 < 0)
						{
							value = 0uL;
							return false;
						}
						value = (ulong)value3;
						break;
					}
					case BinaryEntryType.NamedULong:
					case BinaryEntryType.UnnamedULong:
						if (!UNSAFE_Read_8_UInt64(out value))
						{
							return false;
						}
						break;
					default:
						throw new InvalidOperationException();
					}
					return true;
				}
				finally
				{
					MarkEntryContentConsumed();
				}
			}
			SkipEntry();
			value = 0uL;
			return false;
		}

		public override bool ReadChar(out char value)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedChar || peekedBinaryEntryType == BinaryEntryType.UnnamedChar)
			{
				MarkEntryContentConsumed();
				return UNSAFE_Read_2_Char(out value);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedString || peekedBinaryEntryType == BinaryEntryType.UnnamedString)
			{
				MarkEntryContentConsumed();
				string text = ReadStringValue();
				if (text == null || text.Length == 0)
				{
					value = '\0';
					return false;
				}
				value = text[0];
				return true;
			}
			SkipEntry();
			value = '\0';
			return false;
		}

		public override bool ReadSingle(out float value)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedFloat || peekedBinaryEntryType == BinaryEntryType.UnnamedFloat)
			{
				MarkEntryContentConsumed();
				return UNSAFE_Read_4_Float32(out value);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedDouble || peekedBinaryEntryType == BinaryEntryType.UnnamedDouble)
			{
				MarkEntryContentConsumed();
				if (!UNSAFE_Read_8_Float64(out var value2))
				{
					value = 0f;
					return false;
				}
				try
				{
					value = (float)value2;
				}
				catch (OverflowException)
				{
					value = 0f;
				}
				return true;
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedDecimal || peekedBinaryEntryType == BinaryEntryType.UnnamedDecimal)
			{
				MarkEntryContentConsumed();
				if (!UNSAFE_Read_16_Decimal(out var value3))
				{
					value = 0f;
					return false;
				}
				try
				{
					value = (float)value3;
				}
				catch (OverflowException)
				{
					value = 0f;
				}
				return true;
			}
			if (peekedEntryType == EntryType.Integer)
			{
				if (!ReadInt64(out var value4))
				{
					value = 0f;
					return false;
				}
				try
				{
					value = value4;
				}
				catch (OverflowException)
				{
					value = 0f;
				}
				return true;
			}
			SkipEntry();
			value = 0f;
			return false;
		}

		public override bool ReadDouble(out double value)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedDouble || peekedBinaryEntryType == BinaryEntryType.UnnamedDouble)
			{
				MarkEntryContentConsumed();
				return UNSAFE_Read_8_Float64(out value);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedFloat || peekedBinaryEntryType == BinaryEntryType.UnnamedFloat)
			{
				MarkEntryContentConsumed();
				if (!UNSAFE_Read_4_Float32(out var value2))
				{
					value = 0.0;
					return false;
				}
				value = value2;
				return true;
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedDecimal || peekedBinaryEntryType == BinaryEntryType.UnnamedDecimal)
			{
				MarkEntryContentConsumed();
				if (!UNSAFE_Read_16_Decimal(out var value3))
				{
					value = 0.0;
					return false;
				}
				try
				{
					value = (double)value3;
				}
				catch (OverflowException)
				{
					value = 0.0;
				}
				return true;
			}
			if (peekedEntryType == EntryType.Integer)
			{
				if (!ReadInt64(out var value4))
				{
					value = 0.0;
					return false;
				}
				try
				{
					value = value4;
				}
				catch (OverflowException)
				{
					value = 0.0;
				}
				return true;
			}
			SkipEntry();
			value = 0.0;
			return false;
		}

		public override bool ReadDecimal(out decimal value)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedDecimal || peekedBinaryEntryType == BinaryEntryType.UnnamedDecimal)
			{
				MarkEntryContentConsumed();
				return UNSAFE_Read_16_Decimal(out value);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedDouble || peekedBinaryEntryType == BinaryEntryType.UnnamedDouble)
			{
				MarkEntryContentConsumed();
				if (!UNSAFE_Read_8_Float64(out var value2))
				{
					value = default(decimal);
					return false;
				}
				try
				{
					value = (decimal)value2;
				}
				catch (OverflowException)
				{
					value = default(decimal);
				}
				return true;
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedFloat || peekedBinaryEntryType == BinaryEntryType.UnnamedFloat)
			{
				MarkEntryContentConsumed();
				if (!UNSAFE_Read_4_Float32(out var value3))
				{
					value = default(decimal);
					return false;
				}
				try
				{
					value = (decimal)value3;
				}
				catch (OverflowException)
				{
					value = default(decimal);
				}
				return true;
			}
			if (peekedEntryType == EntryType.Integer)
			{
				if (!ReadInt64(out var value4))
				{
					value = default(decimal);
					return false;
				}
				try
				{
					value = value4;
				}
				catch (OverflowException)
				{
					value = default(decimal);
				}
				return true;
			}
			SkipEntry();
			value = default(decimal);
			return false;
		}

		public override bool ReadExternalReference(out Guid guid)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedExternalReferenceByGuid || peekedBinaryEntryType == BinaryEntryType.UnnamedExternalReferenceByGuid)
			{
				MarkEntryContentConsumed();
				return UNSAFE_Read_16_Guid(out guid);
			}
			SkipEntry();
			guid = default(Guid);
			return false;
		}

		public override bool ReadGuid(out Guid value)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedGuid || peekedBinaryEntryType == BinaryEntryType.UnnamedGuid)
			{
				MarkEntryContentConsumed();
				return UNSAFE_Read_16_Guid(out value);
			}
			SkipEntry();
			value = default(Guid);
			return false;
		}

		public override bool ReadExternalReference(out int index)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedExternalReferenceByIndex || peekedBinaryEntryType == BinaryEntryType.UnnamedExternalReferenceByIndex)
			{
				MarkEntryContentConsumed();
				return UNSAFE_Read_4_Int32(out index);
			}
			SkipEntry();
			index = -1;
			return false;
		}

		public override bool ReadExternalReference(out string id)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedExternalReferenceByString || peekedBinaryEntryType == BinaryEntryType.UnnamedExternalReferenceByString)
			{
				id = ReadStringValue();
				MarkEntryContentConsumed();
				return id != null;
			}
			SkipEntry();
			id = null;
			return false;
		}

		public override bool ReadNull()
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedNull || peekedBinaryEntryType == BinaryEntryType.UnnamedNull)
			{
				MarkEntryContentConsumed();
				return true;
			}
			SkipEntry();
			return false;
		}

		public override bool ReadInternalReference(out int id)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedInternalReference || peekedBinaryEntryType == BinaryEntryType.UnnamedInternalReference)
			{
				MarkEntryContentConsumed();
				return UNSAFE_Read_4_Int32(out id);
			}
			SkipEntry();
			id = -1;
			return false;
		}

		public override bool ReadString(out string value)
		{
			if (!peekedEntryType.HasValue)
			{
				PeekEntry(out var _);
			}
			if (peekedBinaryEntryType == BinaryEntryType.NamedString || peekedBinaryEntryType == BinaryEntryType.UnnamedString)
			{
				value = ReadStringValue();
				MarkEntryContentConsumed();
				return value != null;
			}
			SkipEntry();
			value = null;
			return false;
		}

		public override void PrepareNewSerializationSession()
		{
			base.PrepareNewSerializationSession();
			peekedEntryType = null;
			peekedEntryName = null;
			peekedBinaryEntryType = BinaryEntryType.Invalid;
			types.Clear();
			bufferIndex = 0;
			bufferEnd = 0;
			buffer = internalBufferBackup;
		}

		public unsafe override string GetDataDump()
		{
			byte[] array;
			if (bufferEnd == buffer.Length)
			{
				array = buffer;
			}
			else
			{
				array = new byte[bufferEnd];
				fixed (byte* ptr = buffer)
				{
					void* ptr2 = ptr;
					fixed (byte* ptr3 = array)
					{
						void* ptr4 = ptr3;
						UnsafeUtilities.MemoryCopy(ptr2, ptr4, array.Length);
					}
				}
			}
			return "Binary hex dump: " + ProperBitConverter.BytesToHexString(array);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe string ReadStringValue()
		{
			if (!UNSAFE_Read_1_Byte(out var value))
			{
				return null;
			}
			if (!UNSAFE_Read_4_Int32(out var value2))
			{
				return null;
			}
			string text = new string(' ', value2);
			if (value == 0)
			{
				fixed (byte* ptr = buffer)
				{
					fixed (char* ptr2 = text)
					{
						byte* ptr3 = ptr + bufferIndex;
						byte* ptr4 = (byte*)ptr2;
						if (BitConverter.IsLittleEndian)
						{
							for (int i = 0; i < value2; i++)
							{
								*(ptr4++) = *(ptr3++);
								ptr4++;
							}
						}
						else
						{
							for (int j = 0; j < value2; j++)
							{
								ptr4++;
								*(ptr4++) = *(ptr3++);
							}
						}
					}
				}
				bufferIndex += value2;
				return text;
			}
			int num = value2 * 2;
			fixed (byte* ptr5 = buffer)
			{
				fixed (char* ptr6 = text)
				{
					if (BitConverter.IsLittleEndian)
					{
						Struct256Bit* ptr7 = (Struct256Bit*)(ptr5 + bufferIndex);
						Struct256Bit* ptr8 = (Struct256Bit*)ptr6;
						byte* ptr9 = (byte*)ptr6 + num;
						while (ptr8 + 1 < ptr9)
						{
							*(ptr8++) = *(ptr7++);
						}
						byte* ptr10 = (byte*)ptr7;
						byte* ptr11 = (byte*)ptr8;
						while (ptr11 < ptr9)
						{
							*(ptr11++) = *(ptr10++);
						}
					}
					else
					{
						byte* ptr12 = ptr5 + bufferIndex;
						byte* ptr13 = (byte*)ptr6;
						for (int k = 0; k < value2; k++)
						{
							*ptr13 = ptr12[1];
							ptr13[1] = *ptr12;
							ptr12 += 2;
							ptr13 += 2;
						}
					}
				}
			}
			bufferIndex += num;
			return text;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void SkipStringValue()
		{
			if (UNSAFE_Read_1_Byte(out var value) && UNSAFE_Read_4_Int32(out var value2))
			{
				if (value != 0)
				{
					value2 *= 2;
				}
				if (HasBufferData(value2))
				{
					bufferIndex += value2;
				}
				else
				{
					bufferIndex = bufferEnd;
				}
			}
		}

		private void SkipPeekedEntryContent()
		{
			if (!peekedEntryType.HasValue)
			{
				return;
			}
			try
			{
				switch (peekedBinaryEntryType)
				{
				case BinaryEntryType.NamedStartOfReferenceNode:
				case BinaryEntryType.UnnamedStartOfReferenceNode:
					ReadTypeEntry();
					if (SkipBuffer(4))
					{
					}
					break;
				case BinaryEntryType.NamedStartOfStructNode:
				case BinaryEntryType.UnnamedStartOfStructNode:
					ReadTypeEntry();
					break;
				case BinaryEntryType.StartOfArray:
					SkipBuffer(8);
					break;
				case BinaryEntryType.PrimitiveArray:
				{
					if (UNSAFE_Read_4_Int32(out var value) && UNSAFE_Read_4_Int32(out var value2))
					{
						SkipBuffer(value * value2);
					}
					break;
				}
				case BinaryEntryType.NamedSByte:
				case BinaryEntryType.UnnamedSByte:
				case BinaryEntryType.NamedByte:
				case BinaryEntryType.UnnamedByte:
				case BinaryEntryType.NamedBoolean:
				case BinaryEntryType.UnnamedBoolean:
					SkipBuffer(1);
					break;
				case BinaryEntryType.NamedShort:
				case BinaryEntryType.UnnamedShort:
				case BinaryEntryType.NamedUShort:
				case BinaryEntryType.UnnamedUShort:
				case BinaryEntryType.NamedChar:
				case BinaryEntryType.UnnamedChar:
					SkipBuffer(2);
					break;
				case BinaryEntryType.NamedInternalReference:
				case BinaryEntryType.UnnamedInternalReference:
				case BinaryEntryType.NamedExternalReferenceByIndex:
				case BinaryEntryType.UnnamedExternalReferenceByIndex:
				case BinaryEntryType.NamedInt:
				case BinaryEntryType.UnnamedInt:
				case BinaryEntryType.NamedUInt:
				case BinaryEntryType.UnnamedUInt:
				case BinaryEntryType.NamedFloat:
				case BinaryEntryType.UnnamedFloat:
					SkipBuffer(4);
					break;
				case BinaryEntryType.NamedLong:
				case BinaryEntryType.UnnamedLong:
				case BinaryEntryType.NamedULong:
				case BinaryEntryType.UnnamedULong:
				case BinaryEntryType.NamedDouble:
				case BinaryEntryType.UnnamedDouble:
					SkipBuffer(8);
					break;
				case BinaryEntryType.NamedExternalReferenceByGuid:
				case BinaryEntryType.UnnamedExternalReferenceByGuid:
				case BinaryEntryType.NamedDecimal:
				case BinaryEntryType.UnnamedDecimal:
				case BinaryEntryType.NamedGuid:
				case BinaryEntryType.UnnamedGuid:
					SkipBuffer(8);
					break;
				case BinaryEntryType.NamedString:
				case BinaryEntryType.UnnamedString:
				case BinaryEntryType.NamedExternalReferenceByString:
				case BinaryEntryType.UnnamedExternalReferenceByString:
					SkipStringValue();
					break;
				case BinaryEntryType.TypeName:
					base.Context.Config.DebugContext.LogError("Parsing error in binary data reader: should not be able to peek a TypeName entry.");
					SkipBuffer(4);
					ReadStringValue();
					break;
				case BinaryEntryType.TypeID:
					base.Context.Config.DebugContext.LogError("Parsing error in binary data reader: should not be able to peek a TypeID entry.");
					SkipBuffer(4);
					break;
				case BinaryEntryType.Invalid:
				case BinaryEntryType.EndOfNode:
				case BinaryEntryType.EndOfArray:
				case BinaryEntryType.NamedNull:
				case BinaryEntryType.UnnamedNull:
				case BinaryEntryType.EndOfStream:
					break;
				}
			}
			finally
			{
				MarkEntryContentConsumed();
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private bool SkipBuffer(int amount)
		{
			int num = bufferIndex + amount;
			if (num > bufferEnd)
			{
				bufferIndex = bufferEnd;
				return false;
			}
			bufferIndex = num;
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private Type ReadTypeEntry()
		{
			if (!HasBufferData(1))
			{
				return null;
			}
			BinaryEntryType binaryEntryType = (BinaryEntryType)buffer[bufferIndex++];
			int value2;
			Type value;
			switch (binaryEntryType)
			{
			case BinaryEntryType.TypeID:
				if (!UNSAFE_Read_4_Int32(out value2))
				{
					return null;
				}
				if (!types.TryGetValue(value2, out value))
				{
					base.Context.Config.DebugContext.LogError("Missing type ID during deserialization: " + value2 + " at node " + base.CurrentNodeName + " and depth " + base.CurrentNodeDepth + " and id " + base.CurrentNodeId);
				}
				break;
			case BinaryEntryType.TypeName:
			{
				if (!UNSAFE_Read_4_Int32(out value2))
				{
					return null;
				}
				string text = ReadStringValue();
				value = ((text == null) ? null : base.Context.Binder.BindToType(text, base.Context.Config.DebugContext));
				types.Add(value2, value);
				break;
			}
			case BinaryEntryType.UnnamedNull:
				value = null;
				break;
			default:
				value = null;
				base.Context.Config.DebugContext.LogError("Expected TypeName, TypeID or UnnamedNull entry flag for reading type data, but instead got the entry flag: " + binaryEntryType.ToString() + ".");
				break;
			}
			return value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void MarkEntryContentConsumed()
		{
			peekedEntryType = null;
			peekedEntryName = null;
			peekedBinaryEntryType = BinaryEntryType.Invalid;
		}

		protected override EntryType PeekEntry()
		{
			string name;
			return PeekEntry(out name);
		}

		protected override EntryType ReadToNextEntry()
		{
			SkipPeekedEntryContent();
			string name;
			return PeekEntry(out name);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private bool UNSAFE_Read_1_Byte(out byte value)
		{
			if (HasBufferData(1))
			{
				value = buffer[bufferIndex++];
				return true;
			}
			value = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private bool UNSAFE_Read_1_SByte(out sbyte value)
		{
			if (HasBufferData(1))
			{
				value = (sbyte)buffer[bufferIndex++];
				return true;
			}
			value = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe bool UNSAFE_Read_2_Int16(out short value)
		{
			if (HasBufferData(2))
			{
				fixed (byte* ptr = buffer)
				{
					if (BitConverter.IsLittleEndian)
					{
						value = *(short*)(ptr + bufferIndex);
					}
					else
					{
						short num = 0;
						byte* ptr2 = (byte*)(&num) + 1;
						byte* ptr3 = ptr + bufferIndex;
						*(ptr2--) = *(ptr3++);
						*ptr2 = *ptr3;
						value = num;
					}
				}
				bufferIndex += 2;
				return true;
			}
			bufferIndex = bufferEnd;
			value = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe bool UNSAFE_Read_2_UInt16(out ushort value)
		{
			if (HasBufferData(2))
			{
				fixed (byte* ptr = buffer)
				{
					if (BitConverter.IsLittleEndian)
					{
						value = *(ushort*)(ptr + bufferIndex);
					}
					else
					{
						ushort num = 0;
						byte* ptr2 = (byte*)(&num) + 1;
						byte* ptr3 = ptr + bufferIndex;
						*(ptr2--) = *(ptr3++);
						*ptr2 = *ptr3;
						value = num;
					}
				}
				bufferIndex += 2;
				return true;
			}
			bufferIndex = bufferEnd;
			value = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe bool UNSAFE_Read_2_Char(out char value)
		{
			if (HasBufferData(2))
			{
				fixed (byte* ptr = buffer)
				{
					if (BitConverter.IsLittleEndian)
					{
						value = *(char*)(ptr + bufferIndex);
					}
					else
					{
						char c = '\0';
						byte* ptr2 = (byte*)(&c) + 1;
						byte* ptr3 = ptr + bufferIndex;
						*(ptr2--) = *(ptr3++);
						*ptr2 = *ptr3;
						value = c;
					}
				}
				bufferIndex += 2;
				return true;
			}
			bufferIndex = bufferEnd;
			value = '\0';
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe bool UNSAFE_Read_4_Int32(out int value)
		{
			if (HasBufferData(4))
			{
				fixed (byte* ptr = buffer)
				{
					if (BitConverter.IsLittleEndian)
					{
						value = *(int*)(ptr + bufferIndex);
					}
					else
					{
						int num = 0;
						byte* ptr2 = (byte*)(&num) + 3;
						byte* ptr3 = ptr + bufferIndex;
						*(ptr2--) = *(ptr3++);
						*(ptr2--) = *(ptr3++);
						*(ptr2--) = *(ptr3++);
						*ptr2 = *ptr3;
						value = num;
					}
				}
				bufferIndex += 4;
				return true;
			}
			bufferIndex = bufferEnd;
			value = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe bool UNSAFE_Read_4_UInt32(out uint value)
		{
			if (HasBufferData(4))
			{
				fixed (byte* ptr = buffer)
				{
					if (BitConverter.IsLittleEndian)
					{
						value = *(uint*)(ptr + bufferIndex);
					}
					else
					{
						uint num = 0u;
						byte* ptr2 = (byte*)(&num) + 3;
						byte* ptr3 = ptr + bufferIndex;
						*(ptr2--) = *(ptr3++);
						*(ptr2--) = *(ptr3++);
						*(ptr2--) = *(ptr3++);
						*ptr2 = *ptr3;
						value = num;
					}
				}
				bufferIndex += 4;
				return true;
			}
			bufferIndex = bufferEnd;
			value = 0u;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe bool UNSAFE_Read_4_Float32(out float value)
		{
			if (HasBufferData(4))
			{
				fixed (byte* ptr = buffer)
				{
					if (BitConverter.IsLittleEndian)
					{
						if (ArchitectureInfo.Architecture_Supports_Unaligned_Float32_Reads)
						{
							value = *(float*)(ptr + bufferIndex);
						}
						else
						{
							float num = 0f;
							*(int*)(&num) = *(int*)(ptr + bufferIndex);
							value = num;
						}
					}
					else
					{
						float num2 = 0f;
						byte* ptr2 = (byte*)(&num2) + 3;
						byte* ptr3 = ptr + bufferIndex;
						*(ptr2--) = *(ptr3++);
						*(ptr2--) = *(ptr3++);
						*(ptr2--) = *(ptr3++);
						*ptr2 = *ptr3;
						value = num2;
					}
				}
				bufferIndex += 4;
				return true;
			}
			bufferIndex = bufferEnd;
			value = 0f;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe bool UNSAFE_Read_8_Int64(out long value)
		{
			if (HasBufferData(8))
			{
				fixed (byte* ptr = buffer)
				{
					if (BitConverter.IsLittleEndian)
					{
						if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites)
						{
							value = *(long*)(ptr + bufferIndex);
						}
						else
						{
							long num = 0L;
							int* ptr2 = (int*)(&num);
							int* ptr3 = (int*)(ptr + bufferIndex);
							*(ptr2++) = *(ptr3++);
							*ptr2 = *ptr3;
							value = num;
						}
					}
					else
					{
						long num2 = 0L;
						byte* ptr4 = (byte*)(&num2) + 7;
						byte* ptr5 = ptr + bufferIndex;
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*ptr4 = *ptr5;
						value = num2;
					}
				}
				bufferIndex += 8;
				return true;
			}
			bufferIndex = bufferEnd;
			value = 0L;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe bool UNSAFE_Read_8_UInt64(out ulong value)
		{
			if (HasBufferData(8))
			{
				fixed (byte* ptr = buffer)
				{
					if (BitConverter.IsLittleEndian)
					{
						if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites)
						{
							value = *(ulong*)(ptr + bufferIndex);
						}
						else
						{
							ulong num = 0uL;
							int* ptr2 = (int*)(&num);
							int* ptr3 = (int*)(ptr + bufferIndex);
							*(ptr2++) = *(ptr3++);
							*ptr2 = *ptr3;
							value = num;
						}
					}
					else
					{
						ulong num2 = 0uL;
						byte* ptr4 = (byte*)(&num2) + 7;
						byte* ptr5 = ptr + bufferIndex;
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*ptr4 = *ptr5;
						value = num2;
					}
				}
				bufferIndex += 8;
				return true;
			}
			bufferIndex = bufferEnd;
			value = 0uL;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe bool UNSAFE_Read_8_Float64(out double value)
		{
			if (HasBufferData(8))
			{
				fixed (byte* ptr = buffer)
				{
					if (BitConverter.IsLittleEndian)
					{
						if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites)
						{
							value = *(double*)(ptr + bufferIndex);
						}
						else
						{
							double num = 0.0;
							int* ptr2 = (int*)(&num);
							int* ptr3 = (int*)(ptr + bufferIndex);
							*(ptr2++) = *(ptr3++);
							*ptr2 = *ptr3;
							value = num;
						}
					}
					else
					{
						double num2 = 0.0;
						byte* ptr4 = (byte*)(&num2) + 7;
						byte* ptr5 = ptr + bufferIndex;
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*ptr4 = *ptr5;
						value = num2;
					}
				}
				bufferIndex += 8;
				return true;
			}
			bufferIndex = bufferEnd;
			value = 0.0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe bool UNSAFE_Read_16_Decimal(out decimal value)
		{
			if (HasBufferData(16))
			{
				fixed (byte* ptr = buffer)
				{
					if (BitConverter.IsLittleEndian)
					{
						if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites)
						{
							value = *(decimal*)(ptr + bufferIndex);
						}
						else
						{
							decimal num = default(decimal);
							int* ptr2 = (int*)(&num);
							int* ptr3 = (int*)(ptr + bufferIndex);
							*(ptr2++) = *(ptr3++);
							*(ptr2++) = *(ptr3++);
							*(ptr2++) = *(ptr3++);
							*ptr2 = *ptr3;
							value = num;
						}
					}
					else
					{
						decimal num2 = default(decimal);
						byte* ptr4 = (byte*)(&num2) + 15;
						byte* ptr5 = ptr + bufferIndex;
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*ptr4 = *ptr5;
						value = num2;
					}
				}
				bufferIndex += 16;
				return true;
			}
			bufferIndex = bufferEnd;
			value = default(decimal);
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe bool UNSAFE_Read_16_Guid(out Guid value)
		{
			if (HasBufferData(16))
			{
				fixed (byte* ptr = buffer)
				{
					if (BitConverter.IsLittleEndian)
					{
						if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites)
						{
							value = *(Guid*)(ptr + bufferIndex);
						}
						else
						{
							Guid guid = default(Guid);
							int* ptr2 = (int*)(&guid);
							int* ptr3 = (int*)(ptr + bufferIndex);
							*(ptr2++) = *(ptr3++);
							*(ptr2++) = *(ptr3++);
							*(ptr2++) = *(ptr3++);
							*ptr2 = *ptr3;
							value = guid;
						}
					}
					else
					{
						Guid guid2 = default(Guid);
						byte* ptr4 = (byte*)(&guid2);
						byte* ptr5 = ptr + bufferIndex;
						*(ptr4++) = *(ptr5++);
						*(ptr4++) = *(ptr5++);
						*(ptr4++) = *(ptr5++);
						*(ptr4++) = *(ptr5++);
						*(ptr4++) = *(ptr5++);
						*(ptr4++) = *(ptr5++);
						*(ptr4++) = *(ptr5++);
						*(ptr4++) = *(ptr5++);
						*(ptr4++) = *(ptr5++);
						*ptr4 = *(ptr5++);
						ptr4 += 6;
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*(ptr4--) = *(ptr5++);
						*ptr4 = *ptr5;
						value = guid2;
					}
				}
				bufferIndex += 16;
				return true;
			}
			bufferIndex = bufferEnd;
			value = default(Guid);
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private bool HasBufferData(int amount)
		{
			if (bufferEnd == 0)
			{
				ReadEntireStreamToBuffer();
			}
			return bufferIndex + amount <= bufferEnd;
		}

		private void ReadEntireStreamToBuffer()
		{
			bufferIndex = 0;
			if (Stream is MemoryStream)
			{
				try
				{
					buffer = (Stream as MemoryStream).GetBuffer();
					bufferEnd = (int)Stream.Length;
					bufferIndex = (int)Stream.Position;
					return;
				}
				catch (UnauthorizedAccessException)
				{
				}
			}
			buffer = internalBufferBackup;
			int num = (int)(Stream.Length - Stream.Position);
			if (buffer.Length >= num)
			{
				Stream.Read(buffer, 0, num);
			}
			else
			{
				buffer = new byte[num];
				Stream.Read(buffer, 0, num);
				if (num <= 10485760)
				{
					internalBufferBackup = buffer;
				}
			}
			bufferIndex = 0;
			bufferEnd = num;
		}
	}
	public class BinaryDataWriter : BaseDataWriter
	{
		private struct Struct256Bit
		{
			public decimal d1;

			public decimal d2;
		}

		[StructLayout(LayoutKind.Explicit, Size = 8)]
		private struct SixtyFourBitValueToByteUnion
		{
			[FieldOffset(0)]
			public byte b0;

			[FieldOffset(1)]
			public byte b1;

			[FieldOffset(2)]
			public byte b2;

			[FieldOffset(3)]
			public byte b3;

			[FieldOffset(4)]
			public byte b4;

			[FieldOffset(5)]
			public byte b5;

			[FieldOffset(6)]
			public byte b6;

			[FieldOffset(7)]
			public byte b7;

			[FieldOffset(0)]
			public double doubleValue;

			[FieldOffset(0)]
			public ulong ulongValue;

			[FieldOffset(0)]
			public long longValue;
		}

		[StructLayout(LayoutKind.Explicit, Size = 16)]
		private struct OneTwentyEightBitValueToByteUnion
		{
			[FieldOffset(0)]
			public byte b0;

			[FieldOffset(1)]
			public byte b1;

			[FieldOffset(2)]
			public byte b2;

			[FieldOffset(3)]
			public byte b3;

			[FieldOffset(4)]
			public byte b4;

			[FieldOffset(5)]
			public byte b5;

			[FieldOffset(6)]
			public byte b6;

			[FieldOffset(7)]
			public byte b7;

			[FieldOffset(8)]
			public byte b8;

			[FieldOffset(9)]
			public byte b9;

			[FieldOffset(10)]
			public byte b10;

			[FieldOffset(11)]
			public byte b11;

			[FieldOffset(12)]
			public byte b12;

			[FieldOffset(13)]
			public byte b13;

			[FieldOffset(14)]
			public byte b14;

			[FieldOffset(15)]
			public byte b15;

			[FieldOffset(0)]
			public Guid guidValue;

			[FieldOffset(0)]
			public decimal decimalValue;
		}

		private static readonly Dictionary<Type, Delegate> PrimitiveGetBytesMethods = new Dictionary<Type, Delegate>((IEqualityComparer<Type>?)FastTypeComparer.Instance)
		{
			{
				typeof(char),
				(Action<byte[], int, char>)delegate(byte[] b, int i, char v)
				{
					ProperBitConverter.GetBytes(b, i, v);
				}
			},
			{
				typeof(byte),
				(Action<byte[], int, byte>)delegate(byte[] b, int i, byte v)
				{
					b[i] = v;
				}
			},
			{
				typeof(sbyte),
				(Action<byte[], int, sbyte>)delegate(byte[] b, int i, sbyte v)
				{
					b[i] = (byte)v;
				}
			},
			{
				typeof(bool),
				(Action<byte[], int, bool>)delegate(byte[] b, int i, bool v)
				{
					b[i] = (v ? ((byte)1) : ((byte)0));
				}
			},
			{
				typeof(short),
				new Action<byte[], int, short>(ProperBitConverter.GetBytes)
			},
			{
				typeof(int),
				new Action<byte[], int, int>(ProperBitConverter.GetBytes)
			},
			{
				typeof(long),
				new Action<byte[], int, long>(ProperBitConverter.GetBytes)
			},
			{
				typeof(ushort),
				new Action<byte[], int, ushort>(ProperBitConverter.GetBytes)
			},
			{
				typeof(uint),
				new Action<byte[], int, uint>(ProperBitConverter.GetBytes)
			},
			{
				typeof(ulong),
				new Action<byte[], int, ulong>(ProperBitConverter.GetBytes)
			},
			{
				typeof(decimal),
				new Action<byte[], int, decimal>(ProperBitConverter.GetBytes)
			},
			{
				typeof(float),
				new Action<byte[], int, float>(ProperBitConverter.GetBytes)
			},
			{
				typeof(double),
				new Action<byte[], int, double>(ProperBitConverter.GetBytes)
			},
			{
				typeof(Guid),
				new Action<byte[], int, Guid>(ProperBitConverter.GetBytes)
			}
		};

		private static readonly Dictionary<Type, int> PrimitiveSizes = new Dictionary<Type, int>((IEqualityComparer<Type>?)FastTypeComparer.Instance)
		{
			{
				typeof(char),
				2
			},
			{
				typeof(byte),
				1
			},
			{
				typeof(sbyte),
				1
			},
			{
				typeof(bool),
				1
			},
			{
				typeof(short),
				2
			},
			{
				typeof(int),
				4
			},
			{
				typeof(long),
				8
			},
			{
				typeof(ushort),
				2
			},
			{
				typeof(uint),
				4
			},
			{
				typeof(ulong),
				8
			},
			{
				typeof(decimal),
				16
			},
			{
				typeof(float),
				4
			},
			{
				typeof(double),
				8
			},
			{
				typeof(Guid),
				16
			}
		};

		private readonly byte[] small_buffer = new byte[16];

		private readonly byte[] buffer = new byte[102400];

		private int bufferIndex;

		private readonly Dictionary<Type, int> types = new Dictionary<Type, int>(16, (IEqualityComparer<Type>?)FastTypeComparer.Instance);

		public bool CompressStringsTo8BitWhenPossible;

		private static readonly Dictionary<Type, Action<BinaryDataWriter, object>> PrimitiveArrayWriters = new Dictionary<Type, Action<BinaryDataWriter, object>>((IEqualityComparer<Type>?)FastTypeComparer.Instance)
		{
			{
				typeof(char),
				WritePrimitiveArray_char
			},
			{
				typeof(sbyte),
				WritePrimitiveArray_sbyte
			},
			{
				typeof(short),
				WritePrimitiveArray_short
			},
			{
				typeof(int),
				WritePrimitiveArray_int
			},
			{
				typeof(long),
				WritePrimitiveArray_long
			},
			{
				typeof(byte),
				WritePrimitiveArray_byte
			},
			{
				typeof(ushort),
				WritePrimitiveArray_ushort
			},
			{
				typeof(uint),
				WritePrimitiveArray_uint
			},
			{
				typeof(ulong),
				WritePrimitiveArray_ulong
			},
			{
				typeof(decimal),
				WritePrimitiveArray_decimal
			},
			{
				typeof(bool),
				WritePrimitiveArray_bool
			},
			{
				typeof(float),
				WritePrimitiveArray_float
			},
			{
				typeof(double),
				WritePrimitiveArray_double
			},
			{
				typeof(Guid),
				WritePrimitiveArray_Guid
			}
		};

		public BinaryDataWriter()
			: base(null, null)
		{
		}

		public BinaryDataWriter(Stream stream, SerializationContext context)
			: base(stream, context)
		{
		}

		public override void BeginArrayNode(long length)
		{
			EnsureBufferSpace(9);
			buffer[bufferIndex++] = 6;
			UNSAFE_WriteToBuffer_8_Int64(length);
			PushArray();
		}

		public override void BeginReferenceNode(string name, Type type, int id)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 1;
				WriteStringFast(name);
			}
			else
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 2;
			}
			WriteType(type);
			EnsureBufferSpace(4);
			UNSAFE_WriteToBuffer_4_Int32(id);
			PushNode(name, id, type);
		}

		public override void BeginStructNode(string name, Type type)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 3;
				WriteStringFast(name);
			}
			else
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 4;
			}
			WriteType(type);
			PushNode(name, -1, type);
		}

		public override void Dispose()
		{
			FlushToStream();
		}

		public override void EndArrayNode()
		{
			PopArray();
			EnsureBufferSpace(1);
			buffer[bufferIndex++] = 7;
		}

		public override void EndNode(string name)
		{
			PopNode(name);
			EnsureBufferSpace(1);
			buffer[bufferIndex++] = 5;
		}

		private static void WritePrimitiveArray_byte(BinaryDataWriter writer, object o)
		{
			byte[] array = o as byte[];
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(1);
			writer.FlushToStream();
			writer.Stream.Write(array, 0, array.Length);
		}

		private unsafe static void WritePrimitiveArray_sbyte(BinaryDataWriter writer, object o)
		{
			sbyte[] array = o as sbyte[];
			int num = 1;
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				fixed (byte* ptr = writer.buffer)
				{
					fixed (sbyte* ptr2 = array)
					{
						void* ptr3 = ptr2;
						void* ptr4 = ptr + writer.bufferIndex;
						UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
					}
				}
				writer.bufferIndex += num2;
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		private unsafe static void WritePrimitiveArray_bool(BinaryDataWriter writer, object o)
		{
			bool[] array = o as bool[];
			int num = 1;
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				fixed (byte* ptr = writer.buffer)
				{
					fixed (bool* ptr2 = array)
					{
						void* ptr3 = ptr2;
						void* ptr4 = ptr + writer.bufferIndex;
						UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
					}
				}
				writer.bufferIndex += num2;
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		private unsafe static void WritePrimitiveArray_char(BinaryDataWriter writer, object o)
		{
			char[] array = o as char[];
			int num = 2;
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				if (BitConverter.IsLittleEndian)
				{
					fixed (byte* ptr = writer.buffer)
					{
						fixed (char* ptr2 = array)
						{
							void* ptr3 = ptr2;
							void* ptr4 = ptr + writer.bufferIndex;
							UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
						}
					}
					writer.bufferIndex += num2;
				}
				else
				{
					for (int i = 0; i < array.Length; i++)
					{
						writer.UNSAFE_WriteToBuffer_2_Char(array[i]);
					}
				}
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			if (BitConverter.IsLittleEndian)
			{
				UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			}
			else
			{
				byte[] array2 = buffer.Array;
				for (int j = 0; j < array.Length; j++)
				{
					ProperBitConverter.GetBytes(array2, j * num, array[j]);
				}
			}
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		private unsafe static void WritePrimitiveArray_short(BinaryDataWriter writer, object o)
		{
			short[] array = o as short[];
			int num = 2;
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				if (BitConverter.IsLittleEndian)
				{
					fixed (byte* ptr = writer.buffer)
					{
						fixed (short* ptr2 = array)
						{
							void* ptr3 = ptr2;
							void* ptr4 = ptr + writer.bufferIndex;
							UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
						}
					}
					writer.bufferIndex += num2;
				}
				else
				{
					for (int i = 0; i < array.Length; i++)
					{
						writer.UNSAFE_WriteToBuffer_2_Int16(array[i]);
					}
				}
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			if (BitConverter.IsLittleEndian)
			{
				UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			}
			else
			{
				byte[] array2 = buffer.Array;
				for (int j = 0; j < array.Length; j++)
				{
					ProperBitConverter.GetBytes(array2, j * num, array[j]);
				}
			}
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		private unsafe static void WritePrimitiveArray_int(BinaryDataWriter writer, object o)
		{
			int[] array = o as int[];
			int num = 4;
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				if (BitConverter.IsLittleEndian)
				{
					fixed (byte* ptr = writer.buffer)
					{
						fixed (int* ptr2 = array)
						{
							void* ptr3 = ptr2;
							void* ptr4 = ptr + writer.bufferIndex;
							UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
						}
					}
					writer.bufferIndex += num2;
				}
				else
				{
					for (int i = 0; i < array.Length; i++)
					{
						writer.UNSAFE_WriteToBuffer_4_Int32(array[i]);
					}
				}
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			if (BitConverter.IsLittleEndian)
			{
				UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			}
			else
			{
				byte[] array2 = buffer.Array;
				for (int j = 0; j < array.Length; j++)
				{
					ProperBitConverter.GetBytes(array2, j * num, array[j]);
				}
			}
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		private unsafe static void WritePrimitiveArray_long(BinaryDataWriter writer, object o)
		{
			long[] array = o as long[];
			int num = 8;
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				if (BitConverter.IsLittleEndian)
				{
					fixed (byte* ptr = writer.buffer)
					{
						fixed (long* ptr2 = array)
						{
							void* ptr3 = ptr2;
							void* ptr4 = ptr + writer.bufferIndex;
							UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
						}
					}
					writer.bufferIndex += num2;
				}
				else
				{
					for (int i = 0; i < array.Length; i++)
					{
						writer.UNSAFE_WriteToBuffer_8_Int64(array[i]);
					}
				}
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			if (BitConverter.IsLittleEndian)
			{
				UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			}
			else
			{
				byte[] array2 = buffer.Array;
				for (int j = 0; j < array.Length; j++)
				{
					ProperBitConverter.GetBytes(array2, j * num, array[j]);
				}
			}
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		private unsafe static void WritePrimitiveArray_ushort(BinaryDataWriter writer, object o)
		{
			ushort[] array = o as ushort[];
			int num = 2;
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				if (BitConverter.IsLittleEndian)
				{
					fixed (byte* ptr = writer.buffer)
					{
						fixed (ushort* ptr2 = array)
						{
							void* ptr3 = ptr2;
							void* ptr4 = ptr + writer.bufferIndex;
							UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
						}
					}
					writer.bufferIndex += num2;
				}
				else
				{
					for (int i = 0; i < array.Length; i++)
					{
						writer.UNSAFE_WriteToBuffer_2_UInt16(array[i]);
					}
				}
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			if (BitConverter.IsLittleEndian)
			{
				UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			}
			else
			{
				byte[] array2 = buffer.Array;
				for (int j = 0; j < array.Length; j++)
				{
					ProperBitConverter.GetBytes(array2, j * num, array[j]);
				}
			}
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		private unsafe static void WritePrimitiveArray_uint(BinaryDataWriter writer, object o)
		{
			uint[] array = o as uint[];
			int num = 4;
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				if (BitConverter.IsLittleEndian)
				{
					fixed (byte* ptr = writer.buffer)
					{
						fixed (uint* ptr2 = array)
						{
							void* ptr3 = ptr2;
							void* ptr4 = ptr + writer.bufferIndex;
							UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
						}
					}
					writer.bufferIndex += num2;
				}
				else
				{
					for (int i = 0; i < array.Length; i++)
					{
						writer.UNSAFE_WriteToBuffer_4_UInt32(array[i]);
					}
				}
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			if (BitConverter.IsLittleEndian)
			{
				UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			}
			else
			{
				byte[] array2 = buffer.Array;
				for (int j = 0; j < array.Length; j++)
				{
					ProperBitConverter.GetBytes(array2, j * num, array[j]);
				}
			}
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		private unsafe static void WritePrimitiveArray_ulong(BinaryDataWriter writer, object o)
		{
			ulong[] array = o as ulong[];
			int num = 8;
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				if (BitConverter.IsLittleEndian)
				{
					fixed (byte* ptr = writer.buffer)
					{
						fixed (ulong* ptr2 = array)
						{
							void* ptr3 = ptr2;
							void* ptr4 = ptr + writer.bufferIndex;
							UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
						}
					}
					writer.bufferIndex += num2;
				}
				else
				{
					for (int i = 0; i < array.Length; i++)
					{
						writer.UNSAFE_WriteToBuffer_8_UInt64(array[i]);
					}
				}
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			if (BitConverter.IsLittleEndian)
			{
				UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			}
			else
			{
				byte[] array2 = buffer.Array;
				for (int j = 0; j < array.Length; j++)
				{
					ProperBitConverter.GetBytes(array2, j * num, array[j]);
				}
			}
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		private unsafe static void WritePrimitiveArray_decimal(BinaryDataWriter writer, object o)
		{
			decimal[] array = o as decimal[];
			int num = 16;
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				if (BitConverter.IsLittleEndian)
				{
					fixed (byte* ptr = writer.buffer)
					{
						fixed (decimal* ptr2 = array)
						{
							void* ptr3 = ptr2;
							void* ptr4 = ptr + writer.bufferIndex;
							UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
						}
					}
					writer.bufferIndex += num2;
				}
				else
				{
					for (int i = 0; i < array.Length; i++)
					{
						writer.UNSAFE_WriteToBuffer_16_Decimal(array[i]);
					}
				}
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			if (BitConverter.IsLittleEndian)
			{
				UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			}
			else
			{
				byte[] array2 = buffer.Array;
				for (int j = 0; j < array.Length; j++)
				{
					ProperBitConverter.GetBytes(array2, j * num, array[j]);
				}
			}
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		private unsafe static void WritePrimitiveArray_float(BinaryDataWriter writer, object o)
		{
			float[] array = o as float[];
			int num = 4;
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				if (BitConverter.IsLittleEndian)
				{
					fixed (byte* ptr = writer.buffer)
					{
						fixed (float* ptr2 = array)
						{
							void* ptr3 = ptr2;
							void* ptr4 = ptr + writer.bufferIndex;
							UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
						}
					}
					writer.bufferIndex += num2;
				}
				else
				{
					for (int i = 0; i < array.Length; i++)
					{
						writer.UNSAFE_WriteToBuffer_4_Float32(array[i]);
					}
				}
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			if (BitConverter.IsLittleEndian)
			{
				UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			}
			else
			{
				byte[] array2 = buffer.Array;
				for (int j = 0; j < array.Length; j++)
				{
					ProperBitConverter.GetBytes(array2, j * num, array[j]);
				}
			}
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		private unsafe static void WritePrimitiveArray_double(BinaryDataWriter writer, object o)
		{
			double[] array = o as double[];
			int num = 8;
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				if (BitConverter.IsLittleEndian)
				{
					fixed (byte* ptr = writer.buffer)
					{
						fixed (double* ptr2 = array)
						{
							void* ptr3 = ptr2;
							void* ptr4 = ptr + writer.bufferIndex;
							UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
						}
					}
					writer.bufferIndex += num2;
				}
				else
				{
					for (int i = 0; i < array.Length; i++)
					{
						writer.UNSAFE_WriteToBuffer_8_Float64(array[i]);
					}
				}
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			if (BitConverter.IsLittleEndian)
			{
				UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			}
			else
			{
				byte[] array2 = buffer.Array;
				for (int j = 0; j < array.Length; j++)
				{
					ProperBitConverter.GetBytes(array2, j * num, array[j]);
				}
			}
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		private unsafe static void WritePrimitiveArray_Guid(BinaryDataWriter writer, object o)
		{
			Guid[] array = o as Guid[];
			int num = sizeof(Guid);
			int num2 = array.Length * num;
			writer.EnsureBufferSpace(9);
			writer.buffer[writer.bufferIndex++] = 8;
			writer.UNSAFE_WriteToBuffer_4_Int32(array.Length);
			writer.UNSAFE_WriteToBuffer_4_Int32(num);
			if (writer.TryEnsureBufferSpace(num2))
			{
				if (BitConverter.IsLittleEndian)
				{
					fixed (byte* ptr = writer.buffer)
					{
						fixed (Guid* ptr2 = array)
						{
							void* ptr3 = ptr2;
							void* ptr4 = ptr + writer.bufferIndex;
							UnsafeUtilities.MemoryCopy(ptr3, ptr4, num2);
						}
					}
					writer.bufferIndex += num2;
				}
				else
				{
					for (int i = 0; i < array.Length; i++)
					{
						writer.UNSAFE_WriteToBuffer_16_Guid(array[i]);
					}
				}
				return;
			}
			writer.FlushToStream();
			using Buffer<byte> buffer = Buffer<byte>.Claim(num2);
			if (BitConverter.IsLittleEndian)
			{
				UnsafeUtilities.MemoryCopy((object)array, (object)buffer.Array, num2, 0, 0);
			}
			else
			{
				byte[] array2 = buffer.Array;
				for (int j = 0; j < array.Length; j++)
				{
					ProperBitConverter.GetBytes(array2, j * num, array[j]);
				}
			}
			writer.Stream.Write(buffer.Array, 0, num2);
		}

		public override void WritePrimitiveArray<T>(T[] array)
		{
			if (!PrimitiveArrayWriters.TryGetValue(typeof(T), out var value))
			{
				throw new ArgumentException("Type " + typeof(T).Name + " is not a valid primitive array type.");
			}
			value(this, array);
		}

		public override void WriteBoolean(string name, bool value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 43;
				WriteStringFast(name);
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = (value ? ((byte)1) : ((byte)0));
			}
			else
			{
				EnsureBufferSpace(2);
				buffer[bufferIndex++] = 44;
				buffer[bufferIndex++] = (value ? ((byte)1) : ((byte)0));
			}
		}

		public override void WriteByte(string name, byte value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 17;
				WriteStringFast(name);
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = value;
			}
			else
			{
				EnsureBufferSpace(2);
				buffer[bufferIndex++] = 18;
				buffer[bufferIndex++] = value;
			}
		}

		public override void WriteChar(string name, char value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 37;
				WriteStringFast(name);
				EnsureBufferSpace(2);
				UNSAFE_WriteToBuffer_2_Char(value);
			}
			else
			{
				EnsureBufferSpace(3);
				buffer[bufferIndex++] = 38;
				UNSAFE_WriteToBuffer_2_Char(value);
			}
		}

		public override void WriteDecimal(string name, decimal value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 35;
				WriteStringFast(name);
				EnsureBufferSpace(16);
				UNSAFE_WriteToBuffer_16_Decimal(value);
			}
			else
			{
				EnsureBufferSpace(17);
				buffer[bufferIndex++] = 36;
				UNSAFE_WriteToBuffer_16_Decimal(value);
			}
		}

		public override void WriteDouble(string name, double value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 33;
				WriteStringFast(name);
				EnsureBufferSpace(8);
				UNSAFE_WriteToBuffer_8_Float64(value);
			}
			else
			{
				EnsureBufferSpace(9);
				buffer[bufferIndex++] = 34;
				UNSAFE_WriteToBuffer_8_Float64(value);
			}
		}

		public override void WriteGuid(string name, Guid value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 41;
				WriteStringFast(name);
				EnsureBufferSpace(16);
				UNSAFE_WriteToBuffer_16_Guid(value);
			}
			else
			{
				EnsureBufferSpace(17);
				buffer[bufferIndex++] = 42;
				UNSAFE_WriteToBuffer_16_Guid(value);
			}
		}

		public override void WriteExternalReference(string name, Guid guid)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 13;
				WriteStringFast(name);
				EnsureBufferSpace(16);
				UNSAFE_WriteToBuffer_16_Guid(guid);
			}
			else
			{
				EnsureBufferSpace(17);
				buffer[bufferIndex++] = 14;
				UNSAFE_WriteToBuffer_16_Guid(guid);
			}
		}

		public override void WriteExternalReference(string name, int index)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 11;
				WriteStringFast(name);
				EnsureBufferSpace(4);
				UNSAFE_WriteToBuffer_4_Int32(index);
			}
			else
			{
				EnsureBufferSpace(5);
				buffer[bufferIndex++] = 12;
				UNSAFE_WriteToBuffer_4_Int32(index);
			}
		}

		public override void WriteExternalReference(string name, string id)
		{
			if (id == null)
			{
				throw new ArgumentNullException("id");
			}
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 50;
				WriteStringFast(name);
			}
			else
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 51;
			}
			WriteStringFast(id);
		}

		public override void WriteInt32(string name, int value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 23;
				WriteStringFast(name);
				EnsureBufferSpace(4);
				UNSAFE_WriteToBuffer_4_Int32(value);
			}
			else
			{
				EnsureBufferSpace(5);
				buffer[bufferIndex++] = 24;
				UNSAFE_WriteToBuffer_4_Int32(value);
			}
		}

		public override void WriteInt64(string name, long value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 27;
				WriteStringFast(name);
				EnsureBufferSpace(8);
				UNSAFE_WriteToBuffer_8_Int64(value);
			}
			else
			{
				EnsureBufferSpace(9);
				buffer[bufferIndex++] = 28;
				UNSAFE_WriteToBuffer_8_Int64(value);
			}
		}

		public override void WriteNull(string name)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 45;
				WriteStringFast(name);
			}
			else
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 46;
			}
		}

		public override void WriteInternalReference(string name, int id)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 9;
				WriteStringFast(name);
				EnsureBufferSpace(4);
				UNSAFE_WriteToBuffer_4_Int32(id);
			}
			else
			{
				EnsureBufferSpace(5);
				buffer[bufferIndex++] = 10;
				UNSAFE_WriteToBuffer_4_Int32(id);
			}
		}

		public override void WriteSByte(string name, sbyte value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 15;
				WriteStringFast(name);
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = (byte)value;
			}
			else
			{
				EnsureBufferSpace(2);
				buffer[bufferIndex++] = 16;
				buffer[bufferIndex++] = (byte)value;
			}
		}

		public override void WriteInt16(string name, short value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 19;
				WriteStringFast(name);
				EnsureBufferSpace(2);
				UNSAFE_WriteToBuffer_2_Int16(value);
			}
			else
			{
				EnsureBufferSpace(3);
				buffer[bufferIndex++] = 20;
				UNSAFE_WriteToBuffer_2_Int16(value);
			}
		}

		public override void WriteSingle(string name, float value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 31;
				WriteStringFast(name);
				EnsureBufferSpace(4);
				UNSAFE_WriteToBuffer_4_Float32(value);
			}
			else
			{
				EnsureBufferSpace(5);
				buffer[bufferIndex++] = 32;
				UNSAFE_WriteToBuffer_4_Float32(value);
			}
		}

		public override void WriteString(string name, string value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 39;
				WriteStringFast(name);
			}
			else
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 40;
			}
			WriteStringFast(value);
		}

		public override void WriteUInt32(string name, uint value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 25;
				WriteStringFast(name);
				EnsureBufferSpace(4);
				UNSAFE_WriteToBuffer_4_UInt32(value);
			}
			else
			{
				EnsureBufferSpace(5);
				buffer[bufferIndex++] = 26;
				UNSAFE_WriteToBuffer_4_UInt32(value);
			}
		}

		public override void WriteUInt64(string name, ulong value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 29;
				WriteStringFast(name);
				EnsureBufferSpace(8);
				UNSAFE_WriteToBuffer_8_UInt64(value);
			}
			else
			{
				EnsureBufferSpace(9);
				buffer[bufferIndex++] = 30;
				UNSAFE_WriteToBuffer_8_UInt64(value);
			}
		}

		public override void WriteUInt16(string name, ushort value)
		{
			if (name != null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 21;
				WriteStringFast(name);
				EnsureBufferSpace(2);
				UNSAFE_WriteToBuffer_2_UInt16(value);
			}
			else
			{
				EnsureBufferSpace(3);
				buffer[bufferIndex++] = 22;
				UNSAFE_WriteToBuffer_2_UInt16(value);
			}
		}

		public override void PrepareNewSerializationSession()
		{
			base.PrepareNewSerializationSession();
			types.Clear();
			bufferIndex = 0;
		}

		public override string GetDataDump()
		{
			if (!Stream.CanRead)
			{
				return "Binary data stream for writing cannot be read; cannot dump data.";
			}
			if (!Stream.CanSeek)
			{
				return "Binary data stream cannot seek; cannot dump data.";
			}
			FlushToStream();
			long position = Stream.Position;
			byte[] bytes = new byte[position];
			Stream.Position = 0L;
			Stream.Read(bytes, 0, (int)position);
			Stream.Position = position;
			return "Binary hex dump: " + ProperBitConverter.BytesToHexString(bytes);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void WriteType(Type type)
		{
			if (type == null)
			{
				EnsureBufferSpace(1);
				buffer[bufferIndex++] = 46;
				return;
			}
			if (types.TryGetValue(type, out var value))
			{
				EnsureBufferSpace(5);
				buffer[bufferIndex++] = 48;
				UNSAFE_WriteToBuffer_4_Int32(value);
				return;
			}
			value = types.Count;
			types.Add(type, value);
			EnsureBufferSpace(5);
			buffer[bufferIndex++] = 47;
			UNSAFE_WriteToBuffer_4_Int32(value);
			WriteStringFast(base.Context.Binder.BindToName(type, base.Context.Config.DebugContext));
		}

		private unsafe void WriteStringFast(string value)
		{
			bool flag = true;
			if (CompressStringsTo8BitWhenPossible)
			{
				flag = false;
				for (int i = 0; i < value.Length; i++)
				{
					if (value[i] > 'ÿ')
					{
						flag = true;
						break;
					}
				}
			}
			int num;
			if (flag)
			{
				num = value.Length * 2;
				if (TryEnsureBufferSpace(num + 5))
				{
					this.buffer[bufferIndex++] = 1;
					UNSAFE_WriteToBuffer_4_Int32(value.Length);
					if (BitConverter.IsLittleEndian)
					{
						fixed (byte* ptr = this.buffer)
						{
							fixed (char* ptr2 = value)
							{
								Struct256Bit* ptr3 = (Struct256Bit*)(ptr + bufferIndex);
								Struct256Bit* ptr4 = (Struct256Bit*)ptr2;
								byte* ptr5 = (byte*)ptr3 + num;
								while (ptr3 + 1 <= ptr5)
								{
									*(ptr3++) = *(ptr4++);
								}
								char* ptr6 = (char*)ptr3;
								char* ptr7 = (char*)ptr4;
								while (ptr6 < ptr5)
								{
									*(ptr6++) = *(ptr7++);
								}
							}
						}
					}
					else
					{
						fixed (byte* ptr8 = this.buffer)
						{
							fixed (char* ptr9 = value)
							{
								byte* ptr10 = ptr8 + bufferIndex;
								byte* ptr11 = (byte*)ptr9;
								for (int j = 0; j < num; j += 2)
								{
									*ptr10 = ptr11[1];
									ptr10[1] = *ptr11;
									ptr11 += 2;
									ptr10 += 2;
								}
							}
						}
					}
					bufferIndex += num;
					return;
				}
				FlushToStream();
				Stream.WriteByte(1);
				ProperBitConverter.GetBytes(small_buffer, 0, value.Length);
				Stream.Write(small_buffer, 0, 4);
				using Buffer<byte> buffer = Buffer<byte>.Claim(num);
				byte[] array = buffer.Array;
				UnsafeUtilities.StringToBytes(array, value, true);
				Stream.Write(array, 0, num);
				return;
			}
			num = value.Length;
			if (TryEnsureBufferSpace(num + 5))
			{
				this.buffer[bufferIndex++] = 0;
				UNSAFE_WriteToBuffer_4_Int32(value.Length);
				for (int k = 0; k < num; k++)
				{
					this.buffer[bufferIndex++] = (byte)value[k];
				}
				return;
			}
			FlushToStream();
			Stream.WriteByte(0);
			ProperBitConverter.GetBytes(small_buffer, 0, value.Length);
			Stream.Write(small_buffer, 0, 4);
			using Buffer<byte> buffer2 = Buffer<byte>.Claim(value.Length);
			byte[] array2 = buffer2.Array;
			for (int l = 0; l < value.Length; l++)
			{
				array2[l] = (byte)value[l];
			}
			Stream.Write(array2, 0, value.Length);
		}

		public override void FlushToStream()
		{
			if (bufferIndex > 0)
			{
				Stream.Write(buffer, 0, bufferIndex);
				bufferIndex = 0;
			}
			base.FlushToStream();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe void UNSAFE_WriteToBuffer_2_Char(char value)
		{
			fixed (byte* ptr = buffer)
			{
				if (BitConverter.IsLittleEndian)
				{
					*(char*)(ptr + bufferIndex) = value;
				}
				else
				{
					byte* ptr2 = ptr + bufferIndex;
					byte* ptr3 = (byte*)(&value) + 1;
					*(ptr2++) = *(ptr3--);
					*ptr2 = *ptr3;
				}
			}
			bufferIndex += 2;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe void UNSAFE_WriteToBuffer_2_Int16(short value)
		{
			fixed (byte* ptr = buffer)
			{
				if (BitConverter.IsLittleEndian)
				{
					*(short*)(ptr + bufferIndex) = value;
				}
				else
				{
					byte* ptr2 = ptr + bufferIndex;
					byte* ptr3 = (byte*)(&value) + 1;
					*(ptr2++) = *(ptr3--);
					*ptr2 = *ptr3;
				}
			}
			bufferIndex += 2;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe void UNSAFE_WriteToBuffer_2_UInt16(ushort value)
		{
			fixed (byte* ptr = buffer)
			{
				if (BitConverter.IsLittleEndian)
				{
					*(ushort*)(ptr + bufferIndex) = value;
				}
				else
				{
					byte* ptr2 = ptr + bufferIndex;
					byte* ptr3 = (byte*)(&value) + 1;
					*(ptr2++) = *(ptr3--);
					*ptr2 = *ptr3;
				}
			}
			bufferIndex += 2;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe void UNSAFE_WriteToBuffer_4_Int32(int value)
		{
			fixed (byte* ptr = buffer)
			{
				if (BitConverter.IsLittleEndian)
				{
					*(int*)(ptr + bufferIndex) = value;
				}
				else
				{
					byte* ptr2 = ptr + bufferIndex;
					byte* ptr3 = (byte*)(&value) + 3;
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*ptr2 = *ptr3;
				}
			}
			bufferIndex += 4;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe void UNSAFE_WriteToBuffer_4_UInt32(uint value)
		{
			fixed (byte* ptr = buffer)
			{
				if (BitConverter.IsLittleEndian)
				{
					*(uint*)(ptr + bufferIndex) = value;
				}
				else
				{
					byte* ptr2 = ptr + bufferIndex;
					byte* ptr3 = (byte*)(&value) + 3;
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*ptr2 = *ptr3;
				}
			}
			bufferIndex += 4;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private unsafe void UNSAFE_WriteToBuffer_4_Float32(float value)
		{
			fixed (byte* ptr = buffer)
			{
				if (BitConverter.IsLittleEndian)
				{
					if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites)
					{
						*(float*)(ptr + bufferIndex) = value;
					}
					else
					{
						byte* ptr2 = (byte*)(&value);
						byte* ptr3 = ptr + bufferIndex;
						*(ptr3++) = *(ptr2++);
						*(ptr3++) = *(ptr2++);
						*(ptr3++) = *(ptr2++);
						*ptr3 = *ptr2;
					}
				}
				else
				{
					byte* ptr4 = ptr + bufferIndex;
					byte* ptr5 = (byte*)(&value) + 3;
					*(ptr4++) = *(ptr5--);
					*(ptr4++) = *(ptr5--);
					*(ptr4++) = *(ptr5--);
					*ptr4 = *ptr5;
				}
			}
			bufferIndex += 4;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private unsafe void UNSAFE_WriteToBuffer_8_Int64(long value)
		{
			fixed (byte* ptr = buffer)
			{
				if (BitConverter.IsLittleEndian)
				{
					if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites)
					{
						*(long*)(ptr + bufferIndex) = value;
					}
					else
					{
						SixtyFourBitValueToByteUnion sixtyFourBitValueToByteUnion = new SixtyFourBitValueToByteUnion
						{
							longValue = value
						};
						buffer[bufferIndex] = sixtyFourBitValueToByteUnion.b0;
						buffer[bufferIndex + 1] = sixtyFourBitValueToByteUnion.b1;
						buffer[bufferIndex + 2] = sixtyFourBitValueToByteUnion.b2;
						buffer[bufferIndex + 3] = sixtyFourBitValueToByteUnion.b3;
						buffer[bufferIndex + 4] = sixtyFourBitValueToByteUnion.b4;
						buffer[bufferIndex + 5] = sixtyFourBitValueToByteUnion.b5;
						buffer[bufferIndex + 6] = sixtyFourBitValueToByteUnion.b6;
						buffer[bufferIndex + 7] = sixtyFourBitValueToByteUnion.b7;
					}
				}
				else
				{
					byte* ptr2 = ptr + bufferIndex;
					byte* ptr3 = (byte*)(&value) + 7;
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*ptr2 = *ptr3;
				}
			}
			bufferIndex += 8;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private unsafe void UNSAFE_WriteToBuffer_8_UInt64(ulong value)
		{
			fixed (byte* ptr = buffer)
			{
				if (BitConverter.IsLittleEndian)
				{
					if (ArchitectureInfo.Architecture_Supports_All_Unaligned_ReadWrites)
					{
						*(ulong*)(ptr + bufferIndex) = value;
					}
					else
					{
						SixtyFourBitValueToByteUnion sixtyFourBitValueToByteUnion = new SixtyFourBitValueToByteUnion
						{
							ulongValue = value
						};
						buffer[bufferIndex] = sixtyFourBitValueToByteUnion.b0;
						buffer[bufferIndex + 1] = sixtyFourBitValueToByteUnion.b1;
						buffer[bufferIndex + 2] = sixtyFourBitValueToByteUnion.b2;
						buffer[bufferIndex + 3] = sixtyFourBitValueToByteUnion.b3;
						buffer[bufferIndex + 4] = sixtyFourBitValueToByteUnion.b4;
						buffer[bufferIndex + 5] = sixtyFourBitValueToByteUnion.b5;
						buffer[bufferIndex + 6] = sixtyFourBitValueToByteUnion.b6;
						buffer[bufferIndex + 7] = sixtyFourBitValueToByteUnion.b7;
					}
				}
				else
				{
					byte* ptr2 = ptr + bufferIndex;
					byte* ptr3 = (byte*)(&value) + 7;
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
					*(ptr2++) = *(ptr3--);
		

plugins/OdinSerializer/Sirenix.Serialization.Config.dll

Decompiled 3 days ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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: AssemblyCompany("Sirenix IVS (OdinSerializer, Apache-2.0); repackaged for ROUNDS MapsExtended compat")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2018 Sirenix IVS. Licensed under the Apache License, Version 2.0.")]
[assembly: AssemblyFileVersion("2.1.6.0")]
[assembly: AssemblyInformationalVersion("2.1.6")]
[assembly: AssemblyProduct("OdinSerializer (open source) built as Sirenix.Serialization 2.1.6 drop-in")]
[assembly: AssemblyTitle("Sirenix.Serialization.Config")]
[assembly: InternalsVisibleTo("Sirenix.Serialization")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 Sirenix.Serialization
{
	public class CustomLogger : ILogger
	{
		private Action<string> logWarningDelegate;

		private Action<string> logErrorDelegate;

		private Action<Exception> logExceptionDelegate;

		public CustomLogger(Action<string> logWarningDelegate, Action<string> logErrorDelegate, Action<Exception> logExceptionDelegate)
		{
			if (logWarningDelegate == null)
			{
				throw new ArgumentNullException("logWarningDelegate");
			}
			if (logErrorDelegate == null)
			{
				throw new ArgumentNullException("logErrorDelegate");
			}
			if (logExceptionDelegate == null)
			{
				throw new ArgumentNullException("logExceptionDelegate");
			}
			this.logWarningDelegate = logWarningDelegate;
			this.logErrorDelegate = logErrorDelegate;
			this.logExceptionDelegate = logExceptionDelegate;
		}

		public void LogWarning(string warning)
		{
			logWarningDelegate(warning);
		}

		public void LogError(string error)
		{
			logErrorDelegate(error);
		}

		public void LogException(Exception exception)
		{
			logExceptionDelegate(exception);
		}
	}
	public enum DataFormat
	{
		Binary,
		JSON,
		Nodes
	}
	public static class DefaultLoggers
	{
		private static readonly object LOCK = new object();

		private static volatile ILogger unityLogger;

		public static ILogger DefaultLogger => UnityLogger;

		public static ILogger UnityLogger
		{
			get
			{
				if (unityLogger == null)
				{
					lock (LOCK)
					{
						if (unityLogger == null)
						{
							unityLogger = new CustomLogger((Action<string>)Debug.LogWarning, (Action<string>)Debug.LogError, (Action<Exception>)Debug.LogException);
						}
					}
				}
				return unityLogger;
			}
		}
	}
	public enum ErrorHandlingPolicy
	{
		Resilient,
		ThrowOnErrors,
		ThrowOnWarningsAndErrors
	}
	public class GlobalSerializationConfig
	{
		private static readonly GlobalSerializationConfig instance = new GlobalSerializationConfig();

		public static GlobalSerializationConfig Instance => instance;

		public ILogger Logger => DefaultLoggers.UnityLogger;

		public DataFormat EditorSerializationFormat => DataFormat.Nodes;

		public DataFormat BuildSerializationFormat => DataFormat.Binary;

		public LoggingPolicy LoggingPolicy => LoggingPolicy.LogErrors;

		public ErrorHandlingPolicy ErrorHandlingPolicy => ErrorHandlingPolicy.Resilient;

		internal static bool HasInstanceLoaded => true;

		internal static void LoadInstanceIfAssetExists()
		{
		}
	}
	public interface ILogger
	{
		void LogWarning(string warning);

		void LogError(string error);

		void LogException(Exception exception);
	}
	public enum LoggingPolicy
	{
		LogErrors,
		LogWarningsAndErrors,
		Silent
	}
}

plugins/OdinSerializer/Sirenix.Utilities.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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: AssemblyCompany("Sirenix IVS (OdinSerializer, Apache-2.0); repackaged for ROUNDS MapsExtended compat")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2018 Sirenix IVS. Licensed under the Apache License, Version 2.0.")]
[assembly: AssemblyFileVersion("2.1.6.0")]
[assembly: AssemblyInformationalVersion("2.1.6+c7742d03f29cd17a12b701152f0f68db2afefa48")]
[assembly: AssemblyProduct("OdinSerializer (open source) built as Sirenix.Serialization 2.1.6 drop-in")]
[assembly: AssemblyTitle("Sirenix.Utilities")]
[assembly: InternalsVisibleTo("Sirenix.Serialization")]
[assembly: InternalsVisibleTo("Sirenix.Serialization.Config")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 Sirenix.Utilities
{
	public static class FieldInfoExtensions
	{
		public static bool IsAliasField(this FieldInfo fieldInfo)
		{
			return fieldInfo is MemberAliasFieldInfo;
		}

		public static FieldInfo DeAliasField(this FieldInfo fieldInfo, bool throwOnNotAliased = false)
		{
			MemberAliasFieldInfo memberAliasFieldInfo = fieldInfo as MemberAliasFieldInfo;
			if (memberAliasFieldInfo != null)
			{
				while (memberAliasFieldInfo.AliasedField is MemberAliasFieldInfo)
				{
					memberAliasFieldInfo = memberAliasFieldInfo.AliasedField as MemberAliasFieldInfo;
				}
				return memberAliasFieldInfo.AliasedField;
			}
			if (throwOnNotAliased)
			{
				throw new ArgumentException("The field " + fieldInfo.GetNiceName() + " was not aliased.");
			}
			return fieldInfo;
		}
	}
	public static class GarbageFreeIterators
	{
		public struct ListIterator<T> : IDisposable
		{
			private bool isNull;

			private List<T> list;

			private List<T>.Enumerator enumerator;

			public T Current => enumerator.Current;

			public ListIterator(List<T> list)
			{
				isNull = list == null;
				if (isNull)
				{
					this.list = null;
					enumerator = default(List<T>.Enumerator);
				}
				else
				{
					this.list = list;
					enumerator = this.list.GetEnumerator();
				}
			}

			public ListIterator<T> GetEnumerator()
			{
				return this;
			}

			public bool MoveNext()
			{
				if (isNull)
				{
					return false;
				}
				return enumerator.MoveNext();
			}

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

		public struct HashsetIterator<T> : IDisposable
		{
			private bool isNull;

			private HashSet<T> hashset;

			private HashSet<T>.Enumerator enumerator;

			public T Current => enumerator.Current;

			public HashsetIterator(HashSet<T> hashset)
			{
				isNull = hashset == null;
				if (isNull)
				{
					this.hashset = null;
					enumerator = default(HashSet<T>.Enumerator);
				}
				else
				{
					this.hashset = hashset;
					enumerator = this.hashset.GetEnumerator();
				}
			}

			public HashsetIterator<T> GetEnumerator()
			{
				return this;
			}

			public bool MoveNext()
			{
				if (isNull)
				{
					return false;
				}
				return enumerator.MoveNext();
			}

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

		public struct DictionaryIterator<T1, T2> : IDisposable
		{
			private Dictionary<T1, T2> dictionary;

			private Dictionary<T1, T2>.Enumerator enumerator;

			private bool isNull;

			public KeyValuePair<T1, T2> Current => enumerator.Current;

			public DictionaryIterator(Dictionary<T1, T2> dictionary)
			{
				isNull = dictionary == null;
				if (isNull)
				{
					this.dictionary = null;
					enumerator = default(Dictionary<T1, T2>.Enumerator);
				}
				else
				{
					this.dictionary = dictionary;
					enumerator = this.dictionary.GetEnumerator();
				}
			}

			public DictionaryIterator<T1, T2> GetEnumerator()
			{
				return this;
			}

			public bool MoveNext()
			{
				if (isNull)
				{
					return false;
				}
				return enumerator.MoveNext();
			}

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

		public struct DictionaryValueIterator<T1, T2> : IDisposable
		{
			private Dictionary<T1, T2> dictionary;

			private Dictionary<T1, T2>.Enumerator enumerator;

			private bool isNull;

			public T2 Current => enumerator.Current.Value;

			public DictionaryValueIterator(Dictionary<T1, T2> dictionary)
			{
				isNull = dictionary == null;
				if (isNull)
				{
					this.dictionary = null;
					enumerator = default(Dictionary<T1, T2>.Enumerator);
				}
				else
				{
					this.dictionary = dictionary;
					enumerator = this.dictionary.GetEnumerator();
				}
			}

			public DictionaryValueIterator<T1, T2> GetEnumerator()
			{
				return this;
			}

			public bool MoveNext()
			{
				if (isNull)
				{
					return false;
				}
				return enumerator.MoveNext();
			}

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

		public static ListIterator<T> GFIterator<T>(this List<T> list)
		{
			return new ListIterator<T>(list);
		}

		public static DictionaryIterator<T1, T2> GFIterator<T1, T2>(this Dictionary<T1, T2> dictionary)
		{
			return new DictionaryIterator<T1, T2>(dictionary);
		}

		public static DictionaryValueIterator<T1, T2> GFValueIterator<T1, T2>(this Dictionary<T1, T2> dictionary)
		{
			return new DictionaryValueIterator<T1, T2>(dictionary);
		}

		public static HashsetIterator<T> GFIterator<T>(this HashSet<T> hashset)
		{
			return new HashsetIterator<T>(hashset);
		}
	}
	public static class LinqExtensions
	{
		public static bool IsNullOrEmpty<T>(this IList<T> list)
		{
			if (list != null)
			{
				return list.Count == 0;
			}
			return true;
		}

		public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, Action<T> action)
		{
			foreach (T item in source)
			{
				action(item);
			}
			return source;
		}

		public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, Action<T, int> action)
		{
			int num = 0;
			foreach (T item in source)
			{
				action(item, num++);
			}
			return source;
		}

		public static IEnumerable<T> Append<T>(this IEnumerable<T> source, IEnumerable<T> append)
		{
			foreach (T item in source)
			{
				yield return item;
			}
			foreach (T item2 in append)
			{
				yield return item2;
			}
		}
	}
	public static class MemberInfoExtensions
	{
		public static bool IsDefined<T>(this ICustomAttributeProvider member, bool inherit) where T : Attribute
		{
			try
			{
				return member.IsDefined(typeof(T), inherit);
			}
			catch
			{
				return false;
			}
		}

		public static bool IsDefined<T>(this ICustomAttributeProvider member) where T : Attribute
		{
			return member.IsDefined<T>(inherit: false);
		}

		public static T GetAttribute<T>(this ICustomAttributeProvider member, bool inherit) where T : Attribute
		{
			T[] array = member.GetAttributes<T>(inherit).ToArray();
			if (array != null && array.Length != 0)
			{
				return array[0];
			}
			return null;
		}

		public static T GetAttribute<T>(this ICustomAttributeProvider member) where T : Attribute
		{
			return member.GetAttribute<T>(inherit: false);
		}

		public static IEnumerable<T> GetAttributes<T>(this ICustomAttributeProvider member) where T : Attribute
		{
			return member.GetAttributes<T>(inherit: false);
		}

		public static IEnumerable<T> GetAttributes<T>(this ICustomAttributeProvider member, bool inherit) where T : Attribute
		{
			try
			{
				return member.GetCustomAttributes(typeof(T), inherit).Cast<T>();
			}
			catch
			{
				return new T[0];
			}
		}

		public static Attribute[] GetAttributes(this ICustomAttributeProvider member)
		{
			try
			{
				return member.GetAttributes<Attribute>().ToArray();
			}
			catch
			{
				return new Attribute[0];
			}
		}

		public static Attribute[] GetAttributes(this ICustomAttributeProvider member, bool inherit)
		{
			try
			{
				return member.GetAttributes<Attribute>(inherit).ToArray();
			}
			catch
			{
				return new Attribute[0];
			}
		}

		public static string GetNiceName(this MemberInfo member)
		{
			MethodBase methodBase = member as MethodBase;
			string input = ((!(methodBase != null)) ? member.Name : methodBase.GetFullName());
			return input.ToTitleCase();
		}

		public static bool IsStatic(this MemberInfo member)
		{
			FieldInfo fieldInfo = member as FieldInfo;
			if (fieldInfo != null)
			{
				return fieldInfo.IsStatic;
			}
			PropertyInfo propertyInfo = member as PropertyInfo;
			if (propertyInfo != null)
			{
				if (!propertyInfo.CanRead)
				{
					return propertyInfo.GetSetMethod(nonPublic: true).IsStatic;
				}
				return propertyInfo.GetGetMethod(nonPublic: true).IsStatic;
			}
			MethodBase methodBase = member as MethodBase;
			if (methodBase != null)
			{
				return methodBase.IsStatic;
			}
			EventInfo eventInfo = member as EventInfo;
			if (eventInfo != null)
			{
				return eventInfo.GetRaiseMethod(nonPublic: true).IsStatic;
			}
			Type type = member as Type;
			if (type != null)
			{
				if (type.IsSealed)
				{
					return type.IsAbstract;
				}
				return false;
			}
			throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "Unable to determine IsStatic for member {0}.{1}MemberType was {2} but only fields, properties, methods, events and types are supported.", member.DeclaringType.FullName, member.Name, member.GetType().FullName));
		}

		public static bool IsAlias(this MemberInfo memberInfo)
		{
			if (!(memberInfo is MemberAliasFieldInfo) && !(memberInfo is MemberAliasPropertyInfo))
			{
				return memberInfo is MemberAliasMethodInfo;
			}
			return true;
		}

		public static MemberInfo DeAlias(this MemberInfo memberInfo, bool throwOnNotAliased = false)
		{
			MemberAliasFieldInfo memberAliasFieldInfo = memberInfo as MemberAliasFieldInfo;
			if (memberAliasFieldInfo != null)
			{
				return memberAliasFieldInfo.AliasedField;
			}
			MemberAliasPropertyInfo memberAliasPropertyInfo = memberInfo as MemberAliasPropertyInfo;
			if (memberAliasPropertyInfo != null)
			{
				return memberAliasPropertyInfo.AliasedProperty;
			}
			MemberAliasMethodInfo memberAliasMethodInfo = memberInfo as MemberAliasMethodInfo;
			if (memberAliasMethodInfo != null)
			{
				return memberAliasMethodInfo.AliasedMethod;
			}
			if (throwOnNotAliased)
			{
				throw new ArgumentException("The member " + memberInfo.GetNiceName() + " was not aliased.");
			}
			return memberInfo;
		}
	}
	public static class MethodInfoExtensions
	{
		public static string GetFullName(this MethodBase method, string extensionMethodPrefix)
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (method.IsExtensionMethod())
			{
				stringBuilder.Append(extensionMethodPrefix);
			}
			stringBuilder.Append(method.Name);
			stringBuilder.Append("(");
			stringBuilder.Append(method.GetParamsNames());
			stringBuilder.Append(")");
			return stringBuilder.ToString();
		}

		public static string GetParamsNames(this MethodBase method)
		{
			ParameterInfo[] array = (method.IsExtensionMethod() ? method.GetParameters().Skip(1).ToArray() : method.GetParameters());
			StringBuilder stringBuilder = new StringBuilder();
			int i = 0;
			for (int num = array.Length; i < num; i++)
			{
				ParameterInfo parameterInfo = array[i];
				string niceName = parameterInfo.ParameterType.GetNiceName();
				stringBuilder.Append(niceName);
				stringBuilder.Append(" ");
				stringBuilder.Append(parameterInfo.Name);
				if (i < num - 1)
				{
					stringBuilder.Append(", ");
				}
			}
			return stringBuilder.ToString();
		}

		public static string GetFullName(this MethodBase method)
		{
			return method.GetFullName("[ext] ");
		}

		public static bool IsExtensionMethod(this MethodBase method)
		{
			Type declaringType = method.DeclaringType;
			if (declaringType.IsSealed && !declaringType.IsGenericType && !declaringType.IsNested)
			{
				return method.IsDefined(typeof(ExtensionAttribute), inherit: false);
			}
			return false;
		}

		public static bool IsAliasMethod(this MethodInfo methodInfo)
		{
			return methodInfo is MemberAliasMethodInfo;
		}

		public static MethodInfo DeAliasMethod(this MethodInfo methodInfo, bool throwOnNotAliased = false)
		{
			MemberAliasMethodInfo memberAliasMethodInfo = methodInfo as MemberAliasMethodInfo;
			if (memberAliasMethodInfo != null)
			{
				while (memberAliasMethodInfo.AliasedMethod is MemberAliasMethodInfo)
				{
					memberAliasMethodInfo = memberAliasMethodInfo.AliasedMethod as MemberAliasMethodInfo;
				}
				return memberAliasMethodInfo.AliasedMethod;
			}
			if (throwOnNotAliased)
			{
				throw new ArgumentException("The method " + methodInfo.GetNiceName() + " was not aliased.");
			}
			return methodInfo;
		}
	}
	public enum Operator
	{
		Equality,
		Inequality,
		Addition,
		Subtraction,
		Multiply,
		Division,
		LessThan,
		GreaterThan,
		LessThanOrEqual,
		GreaterThanOrEqual,
		Modulus,
		RightShift,
		LeftShift,
		BitwiseAnd,
		BitwiseOr,
		ExclusiveOr,
		BitwiseComplement,
		LogicalAnd,
		LogicalOr,
		LogicalNot
	}
	public static class PathUtilities
	{
		public static bool HasSubDirectory(this DirectoryInfo parentDir, DirectoryInfo subDir)
		{
			string text = parentDir.FullName.TrimEnd('\\', '/');
			while (subDir != null)
			{
				if (subDir.FullName.TrimEnd('\\', '/') == text)
				{
					return true;
				}
				subDir = subDir.Parent;
			}
			return false;
		}
	}
	public static class PropertyInfoExtensions
	{
		public static bool IsAutoProperty(this PropertyInfo propInfo, bool allowVirtual = false)
		{
			if (!propInfo.CanWrite || !propInfo.CanRead)
			{
				return false;
			}
			if (!allowVirtual)
			{
				MethodInfo getMethod = propInfo.GetGetMethod(nonPublic: true);
				MethodInfo setMethod = propInfo.GetSetMethod(nonPublic: true);
				if ((getMethod != null && (getMethod.IsAbstract || getMethod.IsVirtual)) || (setMethod != null && (setMethod.IsAbstract || setMethod.IsVirtual)))
				{
					return false;
				}
			}
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic;
			string value = "<" + propInfo.Name + ">";
			FieldInfo[] fields = propInfo.DeclaringType.GetFields(bindingAttr);
			for (int i = 0; i < fields.Length; i++)
			{
				if (fields[i].Name.Contains(value))
				{
					return true;
				}
			}
			return false;
		}

		public static bool IsAliasProperty(this PropertyInfo propertyInfo)
		{
			return propertyInfo is MemberAliasPropertyInfo;
		}

		public static PropertyInfo DeAliasProperty(this PropertyInfo propertyInfo, bool throwOnNotAliased = false)
		{
			MemberAliasPropertyInfo memberAliasPropertyInfo = propertyInfo as MemberAliasPropertyInfo;
			if (memberAliasPropertyInfo != null)
			{
				while (memberAliasPropertyInfo.AliasedProperty is MemberAliasPropertyInfo)
				{
					memberAliasPropertyInfo = memberAliasPropertyInfo.AliasedProperty as MemberAliasPropertyInfo;
				}
				return memberAliasPropertyInfo.AliasedProperty;
			}
			if (throwOnNotAliased)
			{
				throw new ArgumentException("The property " + propertyInfo.GetNiceName() + " was not aliased.");
			}
			return propertyInfo;
		}
	}
	public static class StringExtensions
	{
		public static string ToTitleCase(this string input)
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < input.Length; i++)
			{
				char c = input[i];
				if (c == '_' && i + 1 < input.Length)
				{
					char c2 = input[i + 1];
					if (char.IsLower(c2))
					{
						c2 = char.ToUpper(c2, CultureInfo.InvariantCulture);
					}
					stringBuilder.Append(c2);
					i++;
				}
				else
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.ToString();
		}

		public static bool IsNullOrWhitespace(this string str)
		{
			if (!string.IsNullOrEmpty(str))
			{
				for (int i = 0; i < str.Length; i++)
				{
					if (!char.IsWhiteSpace(str[i]))
					{
						return false;
					}
				}
			}
			return true;
		}
	}
	public static class TypeExtensions
	{
		private static readonly Func<float, float, bool> FloatEqualityComparerFunc = FloatEqualityComparer;

		private static readonly Func<double, double, bool> DoubleEqualityComparerFunc = DoubleEqualityComparer;

		private static readonly Func<Quaternion, Quaternion, bool> QuaternionEqualityComparerFunc = QuaternionEqualityComparer;

		private static readonly object GenericConstraintsSatisfaction_LOCK = new object();

		private static readonly Dictionary<Type, Type> GenericConstraintsSatisfactionInferredParameters = new Dictionary<Type, Type>();

		private static readonly Dictionary<Type, Type> GenericConstraintsSatisfactionResolvedMap = new Dictionary<Type, Type>();

		private static readonly HashSet<Type> GenericConstraintsSatisfactionProcessedParams = new HashSet<Type>();

		private static readonly HashSet<Type> GenericConstraintsSatisfactionTypesToCheck = new HashSet<Type>();

		private static readonly List<Type> GenericConstraintsSatisfactionTypesToCheck_ToAdd = new List<Type>();

		private static readonly Type GenericListInterface = typeof(IList<>);

		private static readonly Type GenericCollectionInterface = typeof(ICollection<>);

		private static readonly object WeaklyTypedTypeCastDelegates_LOCK = new object();

		private static readonly object StronglyTypedTypeCastDelegates_LOCK = new object();

		private static readonly DoubleLookupDictionary<Type, Type, Func<object, object>> WeaklyTypedTypeCastDelegates = new DoubleLookupDictionary<Type, Type, Func<object, object>>();

		private static readonly DoubleLookupDictionary<Type, Type, Delegate> StronglyTypedTypeCastDelegates = new DoubleLookupDictionary<Type, Type, Delegate>();

		private static readonly Type[] TwoLengthTypeArray_Cached = new Type[2];

		private static readonly Stack<Type> GenericArgumentsContainsTypes_ArgsToCheckCached = new Stack<Type>();

		private static HashSet<string> ReservedCSharpKeywords = new HashSet<string>
		{
			"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked",
			"class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum",
			"event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto",
			"if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "namespace",
			"new", "null", "object", "operator", "out", "override", "params", "private", "protected", "public",
			"readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string",
			"struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked",
			"unsafe", "ushort", "using", "static", "void", "volatile", "while", "in", "get", "set",
			"var"
		};

		public static readonly Dictionary<string, string> TypeNameAlternatives = new Dictionary<string, string>
		{
			{ "Single", "float" },
			{ "Double", "double" },
			{ "SByte", "sbyte" },
			{ "Int16", "short" },
			{ "Int32", "int" },
			{ "Int64", "long" },
			{ "Byte", "byte" },
			{ "UInt16", "ushort" },
			{ "UInt32", "uint" },
			{ "UInt64", "ulong" },
			{ "Decimal", "decimal" },
			{ "String", "string" },
			{ "Char", "char" },
			{ "Boolean", "bool" },
			{ "Single[]", "float[]" },
			{ "Double[]", "double[]" },
			{ "SByte[]", "sbyte[]" },
			{ "Int16[]", "short[]" },
			{ "Int32[]", "int[]" },
			{ "Int64[]", "long[]" },
			{ "Byte[]", "byte[]" },
			{ "UInt16[]", "ushort[]" },
			{ "UInt32[]", "uint[]" },
			{ "UInt64[]", "ulong[]" },
			{ "Decimal[]", "decimal[]" },
			{ "String[]", "string[]" },
			{ "Char[]", "char[]" },
			{ "Boolean[]", "bool[]" }
		};

		private static readonly object CachedNiceNames_LOCK = new object();

		private static readonly Dictionary<Type, string> CachedNiceNames = new Dictionary<Type, string>();

		private static readonly Type VoidPointerType = typeof(void).MakePointerType();

		private static readonly Dictionary<Type, HashSet<Type>> PrimitiveImplicitCasts = new Dictionary<Type, HashSet<Type>>
		{
			{
				typeof(long),
				new HashSet<Type>
				{
					typeof(float),
					typeof(double),
					typeof(decimal)
				}
			},
			{
				typeof(int),
				new HashSet<Type>
				{
					typeof(long),
					typeof(float),
					typeof(double),
					typeof(decimal)
				}
			},
			{
				typeof(short),
				new HashSet<Type>
				{
					typeof(int),
					typeof(long),
					typeof(float),
					typeof(double),
					typeof(decimal)
				}
			},
			{
				typeof(sbyte),
				new HashSet<Type>
				{
					typeof(short),
					typeof(int),
					typeof(long),
					typeof(float),
					typeof(double),
					typeof(decimal)
				}
			},
			{
				typeof(ulong),
				new HashSet<Type>
				{
					typeof(float),
					typeof(double),
					typeof(decimal)
				}
			},
			{
				typeof(uint),
				new HashSet<Type>
				{
					typeof(long),
					typeof(ulong),
					typeof(float),
					typeof(double),
					typeof(decimal)
				}
			},
			{
				typeof(ushort),
				new HashSet<Type>
				{
					typeof(int),
					typeof(uint),
					typeof(long),
					typeof(ulong),
					typeof(float),
					typeof(double),
					typeof(decimal)
				}
			},
			{
				typeof(byte),
				new HashSet<Type>
				{
					typeof(short),
					typeof(ushort),
					typeof(int),
					typeof(uint),
					typeof(long),
					typeof(ulong),
					typeof(float),
					typeof(double),
					typeof(decimal)
				}
			},
			{
				typeof(char),
				new HashSet<Type>
				{
					typeof(ushort),
					typeof(int),
					typeof(uint),
					typeof(long),
					typeof(ulong),
					typeof(float),
					typeof(double),
					typeof(decimal)
				}
			},
			{
				typeof(bool),
				new HashSet<Type>()
			},
			{
				typeof(decimal),
				new HashSet<Type>()
			},
			{
				typeof(float),
				new HashSet<Type> { typeof(double) }
			},
			{
				typeof(double),
				new HashSet<Type>()
			},
			{
				typeof(IntPtr),
				new HashSet<Type>()
			},
			{
				typeof(UIntPtr),
				new HashSet<Type>()
			},
			{
				VoidPointerType,
				new HashSet<Type>()
			}
		};

		private static readonly HashSet<Type> ExplicitCastIntegrals = new HashSet<Type>
		{
			typeof(long),
			typeof(int),
			typeof(short),
			typeof(sbyte),
			typeof(ulong),
			typeof(uint),
			typeof(ushort),
			typeof(byte),
			typeof(char),
			typeof(decimal),
			typeof(float),
			typeof(double),
			typeof(IntPtr),
			typeof(UIntPtr)
		};

		private static string GetCachedNiceName(Type type)
		{
			string value;
			lock (CachedNiceNames_LOCK)
			{
				if (!CachedNiceNames.TryGetValue(type, out value))
				{
					value = CreateNiceName(type);
					CachedNiceNames.Add(type, value);
				}
			}
			return value;
		}

		private static string CreateNiceName(Type type)
		{
			if (type.IsArray)
			{
				int arrayRank = type.GetArrayRank();
				return type.GetElementType().GetNiceName() + ((arrayRank == 1) ? "[]" : "[,]");
			}
			if (type.InheritsFrom(typeof(Nullable<>)))
			{
				return type.GetGenericArguments()[0].GetNiceName() + "?";
			}
			if (type.IsByRef)
			{
				return "ref " + type.GetElementType().GetNiceName();
			}
			if (type.IsGenericParameter || !type.IsGenericType)
			{
				return type.TypeNameGauntlet();
			}
			StringBuilder stringBuilder = new StringBuilder();
			string name = type.Name;
			int num = name.IndexOf("`");
			if (num != -1)
			{
				stringBuilder.Append(name.Substring(0, num));
			}
			else
			{
				stringBuilder.Append(name);
			}
			stringBuilder.Append('<');
			Type[] genericArguments = type.GetGenericArguments();
			for (int i = 0; i < genericArguments.Length; i++)
			{
				Type type2 = genericArguments[i];
				if (i != 0)
				{
					stringBuilder.Append(", ");
				}
				stringBuilder.Append(type2.GetNiceName());
			}
			stringBuilder.Append('>');
			return stringBuilder.ToString();
		}

		internal static bool HasCastDefined(this Type from, Type to, bool requireImplicitCast)
		{
			if (from.IsEnum)
			{
				return Enum.GetUnderlyingType(from).IsCastableTo(to);
			}
			if (to.IsEnum)
			{
				return Enum.GetUnderlyingType(to).IsCastableTo(from);
			}
			if ((from.IsPrimitive || from == VoidPointerType) && (to.IsPrimitive || to == VoidPointerType))
			{
				if (requireImplicitCast)
				{
					return PrimitiveImplicitCasts[from].Contains(to);
				}
				if (from == typeof(IntPtr))
				{
					if (to == typeof(UIntPtr))
					{
						return false;
					}
					if (to == VoidPointerType)
					{
						return true;
					}
				}
				else if (from == typeof(UIntPtr))
				{
					if (to == typeof(IntPtr))
					{
						return false;
					}
					if (to == VoidPointerType)
					{
						return true;
					}
				}
				if (ExplicitCastIntegrals.Contains(from))
				{
					return ExplicitCastIntegrals.Contains(to);
				}
				return false;
			}
			return from.GetCastMethod(to, requireImplicitCast) != null;
		}

		public static bool IsValidIdentifier(string identifier)
		{
			if (identifier == null || identifier.Length == 0)
			{
				return false;
			}
			if (identifier.IndexOf('.') >= 0)
			{
				string[] array = identifier.Split(new char[1] { '.' });
				for (int i = 0; i < array.Length; i++)
				{
					if (!IsValidIdentifier(array[i]))
					{
						return false;
					}
				}
				return true;
			}
			if (ReservedCSharpKeywords.Contains(identifier))
			{
				return false;
			}
			if (!IsValidIdentifierStartCharacter(identifier[0]))
			{
				return false;
			}
			for (int j = 1; j < identifier.Length; j++)
			{
				if (!IsValidIdentifierPartCharacter(identifier[j]))
				{
					return false;
				}
			}
			return true;
		}

		private static bool IsValidIdentifierStartCharacter(char c)
		{
			if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && c != '_' && c != '@')
			{
				return char.IsLetter(c);
			}
			return true;
		}

		private static bool IsValidIdentifierPartCharacter(char c)
		{
			if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z'))
			{
				switch (c)
				{
				default:
					return char.IsLetter(c);
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
				case '_':
					break;
				}
			}
			return true;
		}

		public static bool IsCastableTo(this Type from, Type to, bool requireImplicitCast = false)
		{
			if (from == null)
			{
				throw new ArgumentNullException("from");
			}
			if (to == null)
			{
				throw new ArgumentNullException("to");
			}
			if (from == to)
			{
				return true;
			}
			if (!to.IsAssignableFrom(from))
			{
				return from.HasCastDefined(to, requireImplicitCast);
			}
			return true;
		}

		public static Func<object, object> GetCastMethodDelegate(this Type from, Type to, bool requireImplicitCast = false)
		{
			Func<object, object> value;
			lock (WeaklyTypedTypeCastDelegates_LOCK)
			{
				if (!WeaklyTypedTypeCastDelegates.TryGetInnerValue(from, to, out value))
				{
					MethodInfo method = from.GetCastMethod(to, requireImplicitCast);
					if (method != null)
					{
						value = (object obj) => method.Invoke(null, new object[1] { obj });
					}
					WeaklyTypedTypeCastDelegates.AddInner(from, to, value);
				}
			}
			return value;
		}

		public static Func<TFrom, TTo> GetCastMethodDelegate<TFrom, TTo>(bool requireImplicitCast = false)
		{
			Delegate value;
			lock (StronglyTypedTypeCastDelegates_LOCK)
			{
				if (!StronglyTypedTypeCastDelegates.TryGetInnerValue(typeof(TFrom), typeof(TTo), out value))
				{
					MethodInfo castMethod = typeof(TFrom).GetCastMethod(typeof(TTo), requireImplicitCast);
					if (castMethod != null)
					{
						value = Delegate.CreateDelegate(typeof(Func<TFrom, TTo>), castMethod);
					}
					StronglyTypedTypeCastDelegates.AddInner(typeof(TFrom), typeof(TTo), value);
				}
			}
			return (Func<TFrom, TTo>)value;
		}

		public static MethodInfo GetCastMethod(this Type from, Type to, bool requireImplicitCast = false)
		{
			foreach (MethodInfo allMember in from.GetAllMembers<MethodInfo>(BindingFlags.Static | BindingFlags.Public))
			{
				if ((allMember.Name == "op_Implicit" || (!requireImplicitCast && allMember.Name == "op_Explicit")) && allMember.GetParameters()[0].ParameterType.IsAssignableFrom(from) && to.IsAssignableFrom(allMember.ReturnType))
				{
					return allMember;
				}
			}
			foreach (MethodInfo allMember2 in to.GetAllMembers<MethodInfo>(BindingFlags.Static | BindingFlags.Public))
			{
				if ((allMember2.Name == "op_Implicit" || (!requireImplicitCast && allMember2.Name == "op_Explicit")) && allMember2.GetParameters()[0].ParameterType.IsAssignableFrom(from) && to.IsAssignableFrom(allMember2.ReturnType))
				{
					return allMember2;
				}
			}
			return null;
		}

		private static bool FloatEqualityComparer(float a, float b)
		{
			if (float.IsNaN(a) && float.IsNaN(b))
			{
				return true;
			}
			return a == b;
		}

		private static bool DoubleEqualityComparer(double a, double b)
		{
			if (double.IsNaN(a) && double.IsNaN(b))
			{
				return true;
			}
			return a == b;
		}

		private static bool QuaternionEqualityComparer(Quaternion a, Quaternion b)
		{
			//IL_0000: 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_000e: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (a.x == b.x && a.y == b.y && a.z == b.z)
			{
				return a.w == b.w;
			}
			return false;
		}

		public static Func<T, T, bool> GetEqualityComparerDelegate<T>()
		{
			if (typeof(T) == typeof(float))
			{
				return (Func<T, T, bool>)(object)FloatEqualityComparerFunc;
			}
			if (typeof(T) == typeof(double))
			{
				return (Func<T, T, bool>)(object)DoubleEqualityComparerFunc;
			}
			if (typeof(T) == typeof(Quaternion))
			{
				return (Func<T, T, bool>)(object)QuaternionEqualityComparerFunc;
			}
			Func<T, T, bool> func = null;
			if (typeof(IEquatable<T>).IsAssignableFrom(typeof(T)))
			{
				func = ((!typeof(T).IsValueType) ? ((Func<T, T, bool>)delegate(T a, T b)
				{
					if ((object)a == (object)b)
					{
						return true;
					}
					return a != null && ((IEquatable<T>)(object)a).Equals(b);
				}) : ((Func<T, T, bool>)((T a, T b) => ((IEquatable<T>)(object)a).Equals(b))));
			}
			else
			{
				Type type = typeof(T);
				while (type != null && type != typeof(object))
				{
					MethodInfo operatorMethod = type.GetOperatorMethod(Operator.Equality, type, type);
					if (operatorMethod != null)
					{
						func = (Func<T, T, bool>)Delegate.CreateDelegate(typeof(Func<T, T, bool>), operatorMethod, throwOnBindFailure: true);
						break;
					}
					type = type.BaseType;
				}
			}
			if (func == null)
			{
				func = EqualityComparer<T>.Default.Equals;
			}
			return func;
		}

		public static T GetAttribute<T>(this Type type, bool inherit) where T : Attribute
		{
			object[] customAttributes = type.GetCustomAttributes(typeof(T), inherit);
			if (customAttributes.Length == 0)
			{
				return null;
			}
			return (T)customAttributes[0];
		}

		public static bool ImplementsOrInherits(this Type type, Type to)
		{
			return to.IsAssignableFrom(type);
		}

		public static bool ImplementsOpenGenericType(this Type candidateType, Type openGenericType)
		{
			if (openGenericType.IsInterface)
			{
				return candidateType.ImplementsOpenGenericInterface(openGenericType);
			}
			return candidateType.ImplementsOpenGenericClass(openGenericType);
		}

		public static bool ImplementsOpenGenericInterface(this Type candidateType, Type openGenericInterfaceType)
		{
			if (candidateType == openGenericInterfaceType)
			{
				return true;
			}
			if (candidateType.IsGenericType && candidateType.GetGenericTypeDefinition() == openGenericInterfaceType)
			{
				return true;
			}
			Type[] interfaces = candidateType.GetInterfaces();
			for (int i = 0; i < interfaces.Length; i++)
			{
				if (interfaces[i].ImplementsOpenGenericInterface(openGenericInterfaceType))
				{
					return true;
				}
			}
			return false;
		}

		public static bool ImplementsOpenGenericClass(this Type candidateType, Type openGenericType)
		{
			if (candidateType.IsGenericType && candidateType.GetGenericTypeDefinition() == openGenericType)
			{
				return true;
			}
			Type baseType = candidateType.BaseType;
			if (baseType != null && baseType.ImplementsOpenGenericClass(openGenericType))
			{
				return true;
			}
			return false;
		}

		public static Type[] GetArgumentsOfInheritedOpenGenericType(this Type candidateType, Type openGenericType)
		{
			if (openGenericType.IsInterface)
			{
				return candidateType.GetArgumentsOfInheritedOpenGenericInterface(openGenericType);
			}
			return candidateType.GetArgumentsOfInheritedOpenGenericClass(openGenericType);
		}

		public static Type[] GetArgumentsOfInheritedOpenGenericClass(this Type candidateType, Type openGenericType)
		{
			if (candidateType.IsGenericType && candidateType.GetGenericTypeDefinition() == openGenericType)
			{
				return candidateType.GetGenericArguments();
			}
			Type baseType = candidateType.BaseType;
			if (baseType != null)
			{
				return baseType.GetArgumentsOfInheritedOpenGenericClass(openGenericType);
			}
			return null;
		}

		public static Type[] GetArgumentsOfInheritedOpenGenericInterface(this Type candidateType, Type openGenericInterfaceType)
		{
			if ((openGenericInterfaceType == GenericListInterface || openGenericInterfaceType == GenericCollectionInterface) && candidateType.IsArray)
			{
				return new Type[1] { candidateType.GetElementType() };
			}
			if (candidateType == openGenericInterfaceType)
			{
				return candidateType.GetGenericArguments();
			}
			if (candidateType.IsGenericType && candidateType.GetGenericTypeDefinition() == openGenericInterfaceType)
			{
				return candidateType.GetGenericArguments();
			}
			Type[] interfaces = candidateType.GetInterfaces();
			foreach (Type type in interfaces)
			{
				if (type.IsGenericType)
				{
					Type[] argumentsOfInheritedOpenGenericInterface = type.GetArgumentsOfInheritedOpenGenericInterface(openGenericInterfaceType);
					if (argumentsOfInheritedOpenGenericInterface != null)
					{
						return argumentsOfInheritedOpenGenericInterface;
					}
				}
			}
			return null;
		}

		public static MethodInfo GetOperatorMethod(this Type type, Operator op, Type leftOperand, Type rightOperand)
		{
			string text;
			switch (op)
			{
			case Operator.Equality:
				text = "op_Equality";
				break;
			case Operator.Inequality:
				text = "op_Inequality";
				break;
			case Operator.Addition:
				text = "op_Addition";
				break;
			case Operator.Subtraction:
				text = "op_Subtraction";
				break;
			case Operator.Multiply:
				text = "op_Multiply";
				break;
			case Operator.Division:
				text = "op_Division";
				break;
			case Operator.LessThan:
				text = "op_LessThan";
				break;
			case Operator.GreaterThan:
				text = "op_GreaterThan";
				break;
			case Operator.LessThanOrEqual:
				text = "op_LessThanOrEqual";
				break;
			case Operator.GreaterThanOrEqual:
				text = "op_GreaterThanOrEqual";
				break;
			case Operator.Modulus:
				text = "op_Modulus";
				break;
			case Operator.RightShift:
				text = "op_RightShift";
				break;
			case Operator.LeftShift:
				text = "op_LeftShift";
				break;
			case Operator.BitwiseAnd:
				text = "op_BitwiseAnd";
				break;
			case Operator.BitwiseOr:
				text = "op_BitwiseOr";
				break;
			case Operator.ExclusiveOr:
				text = "op_ExclusiveOr";
				break;
			case Operator.BitwiseComplement:
				text = "op_OnesComplement";
				break;
			case Operator.LogicalNot:
				text = "op_LogicalNot";
				break;
			case Operator.LogicalAnd:
			case Operator.LogicalOr:
				return null;
			default:
				throw new NotImplementedException();
			}
			Type[] twoLengthTypeArray_Cached = TwoLengthTypeArray_Cached;
			lock (twoLengthTypeArray_Cached)
			{
				twoLengthTypeArray_Cached[0] = leftOperand;
				twoLengthTypeArray_Cached[1] = rightOperand;
				try
				{
					MethodInfo method = type.GetMethod(text, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, twoLengthTypeArray_Cached, null);
					if (method != null && method.ReturnType != typeof(bool))
					{
						return null;
					}
					return method;
				}
				catch (AmbiguousMatchException)
				{
					MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (MethodInfo methodInfo in methods)
					{
						if (!(methodInfo.Name != text) && !(methodInfo.ReturnType != typeof(bool)))
						{
							ParameterInfo[] parameters = methodInfo.GetParameters();
							if (parameters.Length == 2 && parameters[0].ParameterType.IsAssignableFrom(leftOperand) && parameters[1].ParameterType.IsAssignableFrom(rightOperand))
							{
								return methodInfo;
							}
						}
					}
					return null;
				}
			}
		}

		public static MethodInfo GetOperatorMethod(this Type type, Operator op)
		{
			string methodName;
			switch (op)
			{
			case Operator.Equality:
				methodName = "op_Equality";
				break;
			case Operator.Inequality:
				methodName = "op_Inequality";
				break;
			case Operator.Addition:
				methodName = "op_Addition";
				break;
			case Operator.Subtraction:
				methodName = "op_Subtraction";
				break;
			case Operator.Multiply:
				methodName = "op_Multiply";
				break;
			case Operator.Division:
				methodName = "op_Division";
				break;
			case Operator.LessThan:
				methodName = "op_LessThan";
				break;
			case Operator.GreaterThan:
				methodName = "op_GreaterThan";
				break;
			case Operator.LessThanOrEqual:
				methodName = "op_LessThanOrEqual";
				break;
			case Operator.GreaterThanOrEqual:
				methodName = "op_GreaterThanOrEqual";
				break;
			case Operator.Modulus:
				methodName = "op_Modulus";
				break;
			case Operator.RightShift:
				methodName = "op_RightShift";
				break;
			case Operator.LeftShift:
				methodName = "op_LeftShift";
				break;
			case Operator.BitwiseAnd:
				methodName = "op_BitwiseAnd";
				break;
			case Operator.BitwiseOr:
				methodName = "op_BitwiseOr";
				break;
			case Operator.ExclusiveOr:
				methodName = "op_ExclusiveOr";
				break;
			case Operator.BitwiseComplement:
				methodName = "op_OnesComplement";
				break;
			case Operator.LogicalNot:
				methodName = "op_LogicalNot";
				break;
			case Operator.LogicalAnd:
			case Operator.LogicalOr:
				return null;
			default:
				throw new NotImplementedException();
			}
			return type.GetAllMembers<MethodInfo>(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == methodName);
		}

		public static MethodInfo[] GetOperatorMethods(this Type type, Operator op)
		{
			string methodName;
			switch (op)
			{
			case Operator.Equality:
				methodName = "op_Equality";
				break;
			case Operator.Inequality:
				methodName = "op_Inequality";
				break;
			case Operator.Addition:
				methodName = "op_Addition";
				break;
			case Operator.Subtraction:
				methodName = "op_Subtraction";
				break;
			case Operator.Multiply:
				methodName = "op_Multiply";
				break;
			case Operator.Division:
				methodName = "op_Division";
				break;
			case Operator.LessThan:
				methodName = "op_LessThan";
				break;
			case Operator.GreaterThan:
				methodName = "op_GreaterThan";
				break;
			case Operator.LessThanOrEqual:
				methodName = "op_LessThanOrEqual";
				break;
			case Operator.GreaterThanOrEqual:
				methodName = "op_GreaterThanOrEqual";
				break;
			case Operator.Modulus:
				methodName = "op_Modulus";
				break;
			case Operator.RightShift:
				methodName = "op_RightShift";
				break;
			case Operator.LeftShift:
				methodName = "op_LeftShift";
				break;
			case Operator.BitwiseAnd:
				methodName = "op_BitwiseAnd";
				break;
			case Operator.BitwiseOr:
				methodName = "op_BitwiseOr";
				break;
			case Operator.ExclusiveOr:
				methodName = "op_ExclusiveOr";
				break;
			case Operator.BitwiseComplement:
				methodName = "op_OnesComplement";
				break;
			case Operator.LogicalNot:
				methodName = "op_LogicalNot";
				break;
			case Operator.LogicalAnd:
			case Operator.LogicalOr:
				return null;
			default:
				throw new NotImplementedException();
			}
			return (from x in type.GetAllMembers<MethodInfo>(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)
				where x.Name == methodName
				select x).ToArray();
		}

		public static IEnumerable<MemberInfo> GetAllMembers(this Type type, BindingFlags flags = BindingFlags.Default)
		{
			Type currentType = type;
			if ((flags & BindingFlags.DeclaredOnly) == BindingFlags.DeclaredOnly)
			{
				MemberInfo[] members = currentType.GetMembers(flags);
				for (int i = 0; i < members.Length; i++)
				{
					yield return members[i];
				}
				yield break;
			}
			flags |= BindingFlags.DeclaredOnly;
			do
			{
				MemberInfo[] members = currentType.GetMembers(flags);
				for (int i = 0; i < members.Length; i++)
				{
					yield return members[i];
				}
				currentType = currentType.BaseType;
			}
			while (currentType != null);
		}

		public static IEnumerable<MemberInfo> GetAllMembers(this Type type, string name, BindingFlags flags = BindingFlags.Default)
		{
			foreach (MemberInfo allMember in type.GetAllMembers(flags))
			{
				if (!(allMember.Name != name))
				{
					yield return allMember;
				}
			}
		}

		public static IEnumerable<T> GetAllMembers<T>(this Type type, BindingFlags flags = BindingFlags.Default) where T : MemberInfo
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (type == typeof(object))
			{
				yield break;
			}
			Type currentType = type;
			if ((flags & BindingFlags.DeclaredOnly) == BindingFlags.DeclaredOnly)
			{
				MemberInfo[] members = currentType.GetMembers(flags);
				for (int i = 0; i < members.Length; i++)
				{
					T val = members[i] as T;
					if (val != null)
					{
						yield return val;
					}
				}
				yield break;
			}
			flags |= BindingFlags.DeclaredOnly;
			do
			{
				MemberInfo[] members = currentType.GetMembers(flags);
				for (int i = 0; i < members.Length; i++)
				{
					T val2 = members[i] as T;
					if (val2 != null)
					{
						yield return val2;
					}
				}
				currentType = currentType.BaseType;
			}
			while (currentType != null);
		}

		public static Type GetGenericBaseType(this Type type, Type baseType)
		{
			int depthCount;
			return type.GetGenericBaseType(baseType, out depthCount);
		}

		public static Type GetGenericBaseType(this Type type, Type baseType, out int depthCount)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (baseType == null)
			{
				throw new ArgumentNullException("baseType");
			}
			if (!baseType.IsGenericType)
			{
				throw new ArgumentException("Type " + baseType.Name + " is not a generic type.");
			}
			if (!type.InheritsFrom(baseType))
			{
				throw new ArgumentException("Type " + type.Name + " does not inherit from " + baseType.Name + ".");
			}
			Type type2 = type;
			depthCount = 0;
			while (type2 != null && (!type2.IsGenericType || type2.GetGenericTypeDefinition() != baseType))
			{
				depthCount++;
				type2 = type2.BaseType;
			}
			if (type2 == null)
			{
				throw new ArgumentException(type.Name + " is assignable from " + baseType.Name + ", but base type was not found?");
			}
			return type2;
		}

		public static IEnumerable<Type> GetBaseTypes(this Type type, bool includeSelf = false)
		{
			IEnumerable<Type> enumerable = type.GetBaseClasses(includeSelf).Concat(type.GetInterfaces());
			if (includeSelf && type.IsInterface)
			{
				enumerable.Concat(new Type[1] { type });
			}
			return enumerable;
		}

		public static IEnumerable<Type> GetBaseClasses(this Type type, bool includeSelf = false)
		{
			if (!(type == null) && !(type.BaseType == null))
			{
				if (includeSelf)
				{
					yield return type;
				}
				Type current = type.BaseType;
				while (current != null)
				{
					yield return current;
					current = current.BaseType;
				}
			}
		}

		private static string TypeNameGauntlet(this Type type)
		{
			string text = type.Name;
			string value = string.Empty;
			if (TypeNameAlternatives.TryGetValue(text, out value))
			{
				text = value;
			}
			return text;
		}

		public static string GetNiceName(this Type type)
		{
			if (type.IsNested && !type.IsGenericParameter)
			{
				return type.DeclaringType.GetNiceName() + "." + GetCachedNiceName(type);
			}
			return GetCachedNiceName(type);
		}

		public static string GetNiceFullName(this Type type)
		{
			if (type.IsNested && !type.IsGenericParameter)
			{
				return type.DeclaringType.GetNiceFullName() + "." + GetCachedNiceName(type);
			}
			string text = GetCachedNiceName(type);
			if (type.Namespace != null)
			{
				text = type.Namespace + "." + text;
			}
			return text;
		}

		public static string GetCompilableNiceName(this Type type)
		{
			return type.GetNiceName().Replace('<', '_').Replace('>', '_')
				.TrimEnd(new char[1] { '_' });
		}

		public static string GetCompilableNiceFullName(this Type type)
		{
			return type.GetNiceFullName().Replace('<', '_').Replace('>', '_')
				.TrimEnd(new char[1] { '_' });
		}

		public static T GetCustomAttribute<T>(this Type type, bool inherit) where T : Attribute
		{
			object[] customAttributes = type.GetCustomAttributes(typeof(T), inherit);
			if (customAttributes.Length == 0)
			{
				return null;
			}
			return customAttributes[0] as T;
		}

		public static T GetCustomAttribute<T>(this Type type) where T : Attribute
		{
			return type.GetCustomAttribute<T>(inherit: false);
		}

		public static IEnumerable<T> GetCustomAttributes<T>(this Type type) where T : Attribute
		{
			return type.GetCustomAttributes<T>(inherit: false);
		}

		public static IEnumerable<T> GetCustomAttributes<T>(this Type type, bool inherit) where T : Attribute
		{
			object[] attrs = type.GetCustomAttributes(typeof(T), inherit);
			for (int i = 0; i < attrs.Length; i++)
			{
				yield return attrs[i] as T;
			}
		}

		public static bool IsDefined<T>(this Type type) where T : Attribute
		{
			return type.IsDefined(typeof(T), inherit: false);
		}

		public static bool IsDefined<T>(this Type type, bool inherit) where T : Attribute
		{
			return type.IsDefined(typeof(T), inherit);
		}

		public static bool InheritsFrom<TBase>(this Type type)
		{
			return type.InheritsFrom(typeof(TBase));
		}

		public static bool InheritsFrom(this Type type, Type baseType)
		{
			if (baseType.IsAssignableFrom(type))
			{
				return true;
			}
			if (type.IsInterface && !baseType.IsInterface)
			{
				return false;
			}
			if (baseType.IsInterface)
			{
				return type.GetInterfaces().Contains(baseType);
			}
			Type type2 = type;
			while (type2 != null)
			{
				if (type2 == baseType)
				{
					return true;
				}
				if (baseType.IsGenericTypeDefinition && type2.IsGenericType && type2.GetGenericTypeDefinition() == baseType)
				{
					return true;
				}
				type2 = type2.BaseType;
			}
			return false;
		}

		public static int GetInheritanceDistance(this Type type, Type baseType)
		{
			Type type2;
			Type type3;
			if (type.IsAssignableFrom(baseType))
			{
				type2 = type;
				type3 = baseType;
			}
			else
			{
				if (!baseType.IsAssignableFrom(type))
				{
					throw new ArgumentException("Cannot assign types '" + type.GetNiceName() + "' and '" + baseType.GetNiceName() + "' to each other.");
				}
				type2 = baseType;
				type3 = type;
			}
			Type type4 = type3;
			int num = 0;
			if (type2.IsInterface)
			{
				while (type4 != null && type4 != typeof(object))
				{
					num++;
					type4 = type4.BaseType;
					Type[] interfaces = type4.GetInterfaces();
					for (int i = 0; i < interfaces.Length; i++)
					{
						if (interfaces[i] == type2)
						{
							type4 = null;
							break;
						}
					}
				}
			}
			else
			{
				while (type4 != type2 && type4 != null && type4 != typeof(object))
				{
					num++;
					type4 = type4.BaseType;
				}
			}
			return num;
		}

		public static bool HasParamaters(this MethodInfo methodInfo, IList<Type> paramTypes, bool inherit = true)
		{
			ParameterInfo[] parameters = methodInfo.GetParameters();
			if (parameters.Length == paramTypes.Count)
			{
				for (int i = 0; i < parameters.Length; i++)
				{
					if (inherit && !paramTypes[i].InheritsFrom(parameters[i].ParameterType))
					{
						return false;
					}
					if (parameters[i].ParameterType != paramTypes[i])
					{
						return false;
					}
				}
				return true;
			}
			return false;
		}

		public static Type GetReturnType(this MemberInfo memberInfo)
		{
			FieldInfo fieldInfo = memberInfo as FieldInfo;
			if (fieldInfo != null)
			{
				return fieldInfo.FieldType;
			}
			PropertyInfo propertyInfo = memberInfo as PropertyInfo;
			if (propertyInfo != null)
			{
				return propertyInfo.PropertyType;
			}
			MethodInfo methodInfo = memberInfo as MethodInfo;
			if (methodInfo != null)
			{
				return methodInfo.ReturnType;
			}
			EventInfo eventInfo = memberInfo as EventInfo;
			if (eventInfo != null)
			{
				return eventInfo.EventHandlerType;
			}
			return null;
		}

		public static object GetMemberValue(this MemberInfo member, object obj)
		{
			if (member is FieldInfo)
			{
				return (member as FieldInfo).GetValue(obj);
			}
			if (member is PropertyInfo)
			{
				return (member as PropertyInfo).GetGetMethod(nonPublic: true).Invoke(obj, null);
			}
			throw new ArgumentException("Can't get the value of a " + member.GetType().Name);
		}

		public static void SetMemberValue(this MemberInfo member, object obj, object value)
		{
			if (member is FieldInfo)
			{
				(member as FieldInfo).SetValue(obj, value);
				return;
			}
			if (member is PropertyInfo)
			{
				MethodInfo setMethod = (member as PropertyInfo).GetSetMethod(nonPublic: true);
				if (setMethod != null)
				{
					setMethod.Invoke(obj, new object[1] { value });
					return;
				}
				throw new ArgumentException("Property " + member.Name + " has no setter");
			}
			throw new ArgumentException("Can't set the value of a " + member.GetType().Name);
		}

		public static bool TryInferGenericParameters(this Type genericTypeDefinition, out Type[] inferredParams, params Type[] knownParameters)
		{
			if (genericTypeDefinition == null)
			{
				throw new ArgumentNullException("genericTypeDefinition");
			}
			if (knownParameters == null)
			{
				throw new ArgumentNullException("knownParameters");
			}
			if (!genericTypeDefinition.IsGenericType)
			{
				throw new ArgumentException("The genericTypeDefinition parameter must be a generic type.");
			}
			lock (GenericConstraintsSatisfaction_LOCK)
			{
				Dictionary<Type, Type> genericConstraintsSatisfactionInferredParameters = GenericConstraintsSatisfactionInferredParameters;
				genericConstraintsSatisfactionInferredParameters.Clear();
				HashSet<Type> genericConstraintsSatisfactionTypesToCheck = GenericConstraintsSatisfactionTypesToCheck;
				genericConstraintsSatisfactionTypesToCheck.Clear();
				List<Type> genericConstraintsSatisfactionTypesToCheck_ToAdd = GenericConstraintsSatisfactionTypesToCheck_ToAdd;
				genericConstraintsSatisfactionTypesToCheck_ToAdd.Clear();
				for (int i = 0; i < knownParameters.Length; i++)
				{
					genericConstraintsSatisfactionTypesToCheck.Add(knownParameters[i]);
				}
				Type[] genericArguments = genericTypeDefinition.GetGenericArguments();
				if (!genericTypeDefinition.IsGenericTypeDefinition)
				{
					Type[] array = genericArguments;
					genericTypeDefinition = genericTypeDefinition.GetGenericTypeDefinition();
					genericArguments = genericTypeDefinition.GetGenericArguments();
					int num = 0;
					for (int j = 0; j < array.Length; j++)
					{
						if (!array[j].IsGenericParameter && (!array[j].IsGenericType || array[j].IsFullyConstructedGenericType()))
						{
							genericConstraintsSatisfactionInferredParameters[genericArguments[j]] = array[j];
						}
						else
						{
							num++;
						}
					}
					if (num == knownParameters.Length)
					{
						int num2 = 0;
						for (int k = 0; k < array.Length; k++)
						{
							if (array[k].IsGenericParameter)
							{
								array[k] = knownParameters[num2++];
							}
						}
						if (genericTypeDefinition.AreGenericConstraintsSatisfiedBy(array))
						{
							inferredParams = array;
							return true;
						}
					}
				}
				if (genericArguments.Length == knownParameters.Length && genericTypeDefinition.AreGenericConstraintsSatisfiedBy(knownParameters))
				{
					inferredParams = knownParameters;
					return true;
				}
				Type[] array2 = genericArguments;
				foreach (Type type in array2)
				{
					Type[] genericParameterConstraints = type.GetGenericParameterConstraints();
					foreach (Type type2 in genericParameterConstraints)
					{
						foreach (Type item in genericConstraintsSatisfactionTypesToCheck)
						{
							if (!type2.IsGenericType)
							{
								continue;
							}
							Type genericTypeDefinition2 = type2.GetGenericTypeDefinition();
							Type[] genericArguments2 = type2.GetGenericArguments();
							Type[] array3;
							if (item.IsGenericType && genericTypeDefinition2 == item.GetGenericTypeDefinition())
							{
								array3 = item.GetGenericArguments();
							}
							else if (genericTypeDefinition2.IsInterface && item.ImplementsOpenGenericInterface(genericTypeDefinition2))
							{
								array3 = item.GetArgumentsOfInheritedOpenGenericInterface(genericTypeDefinition2);
							}
							else
							{
								if (!genericTypeDefinition2.IsClass || !item.ImplementsOpenGenericClass(genericTypeDefinition2))
								{
									continue;
								}
								array3 = item.GetArgumentsOfInheritedOpenGenericClass(genericTypeDefinition2);
							}
							genericConstraintsSatisfactionInferredParameters[type] = item;
							genericConstraintsSatisfactionTypesToCheck_ToAdd.Add(item);
							for (int n = 0; n < genericArguments2.Length; n++)
							{
								if (genericArguments2[n].IsGenericParameter)
								{
									genericConstraintsSatisfactionInferredParameters[genericArguments2[n]] = array3[n];
									genericConstraintsSatisfactionTypesToCheck_ToAdd.Add(array3[n]);
								}
							}
						}
						foreach (Type item2 in genericConstraintsSatisfactionTypesToCheck_ToAdd)
						{
							genericConstraintsSatisfactionTypesToCheck.Add(item2);
						}
						genericConstraintsSatisfactionTypesToCheck_ToAdd.Clear();
					}
				}
				if (genericConstraintsSatisfactionInferredParameters.Count == genericArguments.Length)
				{
					inferredParams = new Type[genericConstraintsSatisfactionInferredParameters.Count];
					for (int num3 = 0; num3 < genericArguments.Length; num3++)
					{
						inferredParams[num3] = genericConstraintsSatisfactionInferredParameters[genericArguments[num3]];
					}
					if (genericTypeDefinition.AreGenericConstraintsSatisfiedBy(inferredParams))
					{
						return true;
					}
				}
				inferredParams = null;
				return false;
			}
		}

		public static bool AreGenericConstraintsSatisfiedBy(this Type genericType, params Type[] parameters)
		{
			if (genericType == null)
			{
				throw new ArgumentNullException("genericType");
			}
			if (parameters == null)
			{
				throw new ArgumentNullException("parameters");
			}
			if (!genericType.IsGenericType)
			{
				throw new ArgumentException("The genericTypeDefinition parameter must be a generic type.");
			}
			return AreGenericConstraintsSatisfiedBy(genericType.GetGenericArguments(), parameters);
		}

		public static bool AreGenericConstraintsSatisfiedBy(this MethodBase genericMethod, params Type[] parameters)
		{
			if (genericMethod == null)
			{
				throw new ArgumentNullException("genericMethod");
			}
			if (parameters == null)
			{
				throw new ArgumentNullException("parameters");
			}
			if (!genericMethod.IsGenericMethod)
			{
				throw new ArgumentException("The genericMethod parameter must be a generic method.");
			}
			return AreGenericConstraintsSatisfiedBy(genericMethod.GetGenericArguments(), parameters);
		}

		public static bool AreGenericConstraintsSatisfiedBy(Type[] definitions, Type[] parameters)
		{
			if (definitions.Length != parameters.Length)
			{
				return false;
			}
			lock (GenericConstraintsSatisfaction_LOCK)
			{
				Dictionary<Type, Type> genericConstraintsSatisfactionResolvedMap = GenericConstraintsSatisfactionResolvedMap;
				genericConstraintsSatisfactionResolvedMap.Clear();
				for (int i = 0; i < definitions.Length; i++)
				{
					Type genericParameterDefinition = definitions[i];
					Type parameterType = parameters[i];
					if (!genericParameterDefinition.GenericParameterIsFulfilledBy(parameterType, genericConstraintsSatisfactionResolvedMap))
					{
						return false;
					}
				}
				return true;
			}
		}

		public static bool GenericParameterIsFulfilledBy(this Type genericParameterDefinition, Type parameterType)
		{
			lock (GenericConstraintsSatisfaction_LOCK)
			{
				GenericConstraintsSatisfactionResolvedMap.Clear();
				return genericParameterDefinition.GenericParameterIsFulfilledBy(parameterType, GenericConstraintsSatisfactionResolvedMap);
			}
		}

		private static bool GenericParameterIsFulfilledBy(this Type genericParameterDefinition, Type parameterType, Dictionary<Type, Type> resolvedMap, HashSet<Type> processedParams = null)
		{
			if (genericParameterDefinition == null)
			{
				throw new ArgumentNullException("genericParameterDefinition");
			}
			if (parameterType == null)
			{
				throw new ArgumentNullException("parameterType");
			}
			if (resolvedMap == null)
			{
				throw new ArgumentNullException("resolvedMap");
			}
			if (!genericParameterDefinition.IsGenericParameter && genericParameterDefinition == parameterType)
			{
				return true;
			}
			if (!genericParameterDefinition.IsGenericParameter)
			{
				return false;
			}
			if (processedParams == null)
			{
				processedParams = GenericConstraintsSatisfactionProcessedParams;
				processedParams.Clear();
			}
			processedParams.Add(genericParameterDefinition);
			GenericParameterAttributes genericParameterAttributes = genericParameterDefinition.GenericParameterAttributes;
			if (genericParameterAttributes != GenericParameterAttributes.None)
			{
				if ((genericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == GenericParameterAttributes.NotNullableValueTypeConstraint)
				{
					if (!parameterType.IsValueType || (parameterType.IsGenericType && parameterType.GetGenericTypeDefinition() == typeof(Nullable<>)))
					{
						return false;
					}
				}
				else if ((genericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) == GenericParameterAttributes.ReferenceTypeConstraint && parameterType.IsValueType)
				{
					return false;
				}
				if ((genericParameterAttributes & GenericParameterAttributes.DefaultConstructorConstraint) == GenericParameterAttributes.DefaultConstructorConstraint && (parameterType.IsAbstract || (!parameterType.IsValueType && parameterType.GetConstructor(Type.EmptyTypes) == null)))
				{
					return false;
				}
			}
			if (resolvedMap.ContainsKey(genericParameterDefinition) && !parameterType.IsAssignableFrom(resolvedMap[genericParameterDefinition]))
			{
				return false;
			}
			Type[] genericParameterConstraints = genericParameterDefinition.GetGenericParameterConstraints();
			for (int i = 0; i < genericParameterConstraints.Length; i++)
			{
				Type type = genericParameterConstraints[i];
				if (type.IsGenericParameter && resolvedMap.ContainsKey(type))
				{
					type = resolvedMap[type];
				}
				if (type.IsGenericParameter)
				{
					if (!type.GenericParameterIsFulfilledBy(parameterType, resolvedMap, processedParams))
					{
						return false;
					}
					continue;
				}
				if (type.IsClass || type.IsInterface || type.IsValueType)
				{
					if (type.IsGenericType)
					{
						Type genericTypeDefinition = type.GetGenericTypeDefinition();
						Type[] genericArguments = type.GetGenericArguments();
						Type[] array;
						if (parameterType.IsGenericType && genericTypeDefinition == parameterType.GetGenericTypeDefinition())
						{
							array = parameterType.GetGenericArguments();
						}
						else if (genericTypeDefinition.IsClass)
						{
							if (!parameterType.ImplementsOpenGenericClass(genericTypeDefinition))
							{
								return false;
							}
							array = parameterType.GetArgumentsOfInheritedOpenGenericClass(genericTypeDefinition);
						}
						else
						{
							if (!parameterType.ImplementsOpenGenericInterface(genericTypeDefinition))
							{
								return false;
							}
							array = parameterType.GetArgumentsOfInheritedOpenGenericInterface(genericTypeDefinition);
						}
						for (int j = 0; j < genericArguments.Length; j++)
						{
							Type type2 = genericArguments[j];
							Type type3 = array[j];
							if (type2.IsGenericParameter && resolvedMap.ContainsKey(type2))
							{
								type2 = resolvedMap[type2];
							}
							if (type2.IsGenericParameter)
							{
								if (!processedParams.Contains(type2) && !type2.GenericParameterIsFulfilledBy(type3, resolvedMap, processedParams))
								{
									return false;
								}
							}
							else if (type2 != type3 && !type2.IsAssignableFrom(type3))
							{
								return false;
							}
						}
					}
					else if (!type.IsAssignableFrom(parameterType))
					{
						return false;
					}
					continue;
				}
				throw new Exception("Unknown parameter constraint type! " + type.GetNiceName());
			}
			resolvedMap[genericParameterDefinition] = parameterType;
			return true;
		}

		public static string GetGenericConstraintsString(this Type type, bool useFullTypeNames = false)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (!type.IsGenericTypeDefinition)
			{
				throw new ArgumentException("Type '" + type.GetNiceName() + "' is not a generic type definition!");
			}
			Type[] genericArguments = type.GetGenericArguments();
			string[] array = new string[genericArguments.Length];
			for (int i = 0; i < genericArguments.Length; i++)
			{
				array[i] = genericArguments[i].GetGenericParameterConstraintsString(useFullTypeNames);
			}
			return string.Join(" ", array);
		}

		public static string GetGenericParameterConstraintsString(this Type type, bool useFullTypeNames = false)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (!type.IsGenericParameter)
			{
				throw new ArgumentException("Type '" + type.GetNiceName() + "' is not a generic parameter!");
			}
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = false;
			GenericParameterAttributes genericParameterAttributes = type.GenericParameterAttributes;
			if ((genericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == GenericParameterAttributes.NotNullableValueTypeConstraint)
			{
				stringBuilder.Append("where ").Append(type.Name).Append(" : struct");
				flag = true;
			}
			else if ((genericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) == GenericParameterAttributes.ReferenceTypeConstraint)
			{
				stringBuilder.Append("where ").Append(type.Name).Append(" : class");
				flag = true;
			}
			if ((genericParameterAttributes & GenericParameterAttributes.DefaultConstructorConstraint) == GenericParameterAttributes.DefaultConstructorConstraint)
			{
				if (flag)
				{
					stringBuilder.Append(", new()");
				}
				else
				{
					stringBuilder.Append("where ").Append(type.Name).Append(" : new()");
					flag = true;
				}
			}
			Type[] genericParameterConstraints = type.GetGenericParameterConstraints();
			if (genericParameterConstraints.Length != 0)
			{
				foreach (Type type2 in genericParameterConstraints)
				{
					if (flag)
					{
						stringBuilder.Append(", ");
						if (useFullTypeNames)
						{
							stringBuilder.Append(type2.GetNiceFullName());
						}
						else
						{
							stringBuilder.Append(type2.GetNiceName());
						}
						continue;
					}
					stringBuilder.Append("where ").Append(type.Name).Append(" : ");
					if (useFullTypeNames)
					{
						stringBuilder.Append(type2.GetNiceFullName());
					}
					else
					{
						stringBuilder.Append(type2.GetNiceName());
					}
					flag = true;
				}
			}
			return stringBuilder.ToString();
		}

		public static bool GenericArgumentsContainsTypes(this Type type, params Type[] types)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (!type.IsGenericType)
			{
				return false;
			}
			bool[] array = new bool[types.Length];
			Type[] genericArguments = type.GetGenericArguments();
			Stack<Type> genericArgumentsContainsTypes_ArgsToCheckCached = GenericArgumentsContainsTypes_ArgsToCheckCached;
			lock (genericArgumentsContainsTypes_ArgsToCheckCached)
			{
				genericArgumentsContainsTypes_ArgsToCheckCached.Clear();
				for (int i = 0; i < genericArguments.Length; i++)
				{
					genericArgumentsContainsTypes_ArgsToCheckCached.Push(genericArguments[i]);
				}
				while (genericArgumentsContainsTypes_ArgsToCheckCached.Count > 0)
				{
					Type type2 = genericArgumentsContainsTypes_ArgsToCheckCached.Pop();
					for (int j = 0; j < types.Length; j++)
					{
						Type type3 = types[j];
						if (type3 == type2)
						{
							array[j] = true;
						}
						else if (type3.IsGenericTypeDefinition && type2.IsGenericType && !type2.IsGenericTypeDefinition && type2.GetGenericTypeDefinition() == type3)
						{
							array[j] = true;
						}
					}
					bool flag = true;
					for (int k = 0; k < array.Length; k++)
					{
						if (!array[k])
						{
							flag = false;
							break;
						}
					}
					if (flag)
					{
						return true;
					}
					if (type2.IsGenericType)
					{
						Type[] genericArguments2 = type2.GetGenericArguments();
						foreach (Type item in genericArguments2)
						{
							genericArgumentsContainsTypes_ArgsToCheckCached.Push(item);
						}
					}
				}
			}
			return false;
		}

		public static bool IsFullyConstructedGenericType(this Type type)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (type.IsGenericTypeDefinition)
			{
				return false;
			}
			if (type.HasElementType)
			{
				Type elementType = type.GetElementType();
				if (elementType.IsGenericParameter || !elementType.IsFullyConstructedGenericType())
				{
					return false;
				}
			}
			Type[] genericArguments = type.GetGenericArguments();
			foreach (Type type2 in genericArguments)
			{
				if (type2.IsGenericParameter)
				{
					return false;
				}
				if (!type2.IsFullyConstructedGenericType())
				{
					return false;
				}
			}
			return !type.IsGenericTypeDefinition;
		}

		public static bool IsNullableType(this Type type)
		{
			if (!type.IsPrimitive && !type.IsValueType)
			{
				return !type.IsEnum;
			}
			return false;
		}

		public static ulong GetEnumBitmask(object value, Type enumType)
		{
			if (!enumType.IsEnum)
			{
				throw new ArgumentException("enumType");
			}
			try
			{
				return Convert.ToUInt64(value, CultureInfo.InvariantCulture);
			}
			catch (OverflowException)
			{
				return (ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture);
			}
		}

		public static Type[] SafeGetTypes(this Assembly assembly)
		{
			try
			{
				return assembly.GetTypes();
			}
			catch
			{
				return Type.EmptyTypes;
			}
		}

		public static bool SafeIsDefined(this Assembly assembly, Type attribute, bool inherit)
		{
			try
			{
				return assembly.IsDefined(attribute, inherit);
			}
			catch
			{
				return false;
			}
		}

		public static object[] SafeGetCustomAttributes(this Assembly assembly, Type type, bool inherit)
		{
			try
			{
				return assembly.GetCustomAttributes(type, inherit);
			}
			catch
			{
				return new object[0];
			}
		}
	}
	public static class UnityExtensions
	{
		private static readonly ValueGetter<Object, IntPtr> UnityObjectCachedPtrFieldGetter;

		static UnityExtensions()
		{
			FieldInfo field = typeof(Object).GetField("m_CachedPtr", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				UnityObjectCachedPtrFieldGetter = EmitUtilities.CreateInstanceFieldGetter<Object, IntPtr>(field);
			}
		}

		public static bool SafeIsUnityNull(this Object obj)
		{
			if (obj == null)
			{
				return true;
			}
			if (UnityObjectCachedPtrFieldGetter == null)
			{
				throw new NotSupportedException("Could not find the field 'm_CachedPtr' in the class UnityEngine.Object; cannot perform a special null check.");
			}
			return UnityObjectCachedPtrFieldGetter(ref obj) == IntPtr.Zero;
		}
	}
	public interface ICache : IDisposable
	{
		object Value { get; }
	}
	public sealed class Cache<T> : ICache, IDisposable where T : class, new()
	{
		private static readonly bool IsNotificationReceiver = typeof(ICacheNotificationReceiver).IsAssignableFrom(typeof(T));

		private static object[] FreeValues = new object[4];

		private bool isFree;

		private static volatile int THREAD_LOCK_TOKEN = 0;

		private static int maxCacheSize = 5;

		public T Value;

		public static int MaxCacheSize
		{
			get
			{
				return maxCacheSize;
			}
			set
			{
				maxCacheSize = Math.Max(1, value);
			}
		}

		public bool IsFree => isFree;

		object ICache.Value => Value;

		private Cache()
		{
			Value = new T();
			isFree = false;
		}

		public static Cache<T> Claim()
		{
			Cache<T> cache = null;
			while (Interlocked.CompareExchange(ref THREAD_LOCK_TOKEN, 1, 0) != 0)
			{
			}
			object[] freeValues = FreeValues;
			int num = freeValues.Length;
			for (int i = 0; i < num; i++)
			{
				cache = (Cache<T>)freeValues[i];
				if (cache != null)
				{
					freeValues[i] = null;
					cache.isFree = false;
					break;
				}
			}
			THREAD_LOCK_TOKEN = 0;
			if (cache == null)
			{
				cache = new Cache<T>();
			}
			if (IsNotificationReceiver)
			{
				(cache.Value as ICacheNotificationReceiver).OnClaimed();
			}
			return cache;
		}

		public static void Release(Cache<T> cache)
		{
			if (cache == null)
			{
				throw new ArgumentNullException("cache");
			}
			if (cache.isFree)
			{
				return;
			}
			if (IsNotificationReceiver)
			{
				(cache.Value as ICacheNotificationReceiver).OnFreed();
			}
			while (Interlocked.CompareExchange(ref THREAD_LOCK_TOKEN, 1, 0) != 0)
			{
			}
			if (cache.isFree)
			{
				THREAD_LOCK_TOKEN = 0;
				return;
			}
			cache.isFree = true;
			object[] freeValues = FreeValues;
			int num = freeValues.Length;
			bool flag = false;
			for (int i = 0; i < num; i++)
			{
				if (freeValues[i] == null)
				{
					freeValues[i] = cache;
					flag = true;
					break;
				}
			}
			if (!flag && num < MaxCacheSize)
			{
				object[] array = new object[num * 2];
				for (int j = 0; j < num; j++)
				{
					array[j] = freeValues[j];
				}
				array[num] = cache;
				FreeValues = array;
			}
			THREAD_LOCK_TOKEN = 0;
		}

		public static implicit operator T(Cache<T> cache)
		{
			if (cache == null)
			{
				return null;
			}
			return cache.Value;
		}

		public void Release()
		{
			Release(this);
		}

		void IDisposable.Dispose()
		{
			Release(this);
		}
	}
	[Serializable]
	public class DoubleLookupDictionary<TFirstKey, TSecondKey, TValue> : Dictionary<TFirstKey, Dictionary<TSecondKey, TValue>>
	{
		private readonly IEqualityComparer<TSecondKey> secondKeyComparer;

		public new Dictionary<TSecondKey, TValue> this[TFirstKey firstKey]
		{
			get
			{
				if (!TryGetValue(firstKey, out var value))
				{
					value = new Dictionary<TSecondKey, TValue>(secondKeyComparer);
					Add(firstKey, value);
				}
				return value;
			}
		}

		public DoubleLookupDictionary()
		{
			secondKeyComparer = EqualityComparer<TSecondKey>.Default;
		}

		public DoubleLookupDictionary(IEqualityComparer<TFirstKey> firstKeyComparer, IEqualityComparer<TSecondKey> secondKeyComparer)
			: base(firstKeyComparer)
		{
			this.secondKeyComparer = secondKeyComparer;
		}

		public int InnerCount(TFirstKey firstKey)
		{
			if (TryGetValue(firstKey, out var value))
			{
				return value.Count;
			}
			return 0;
		}

		public int TotalInnerCount()
		{
			int num = 0;
			if (base.Count > 0)
			{
				foreach (Dictionary<TSecondKey, TValue> value in base.Values)
				{
					num += value.Count;
				}
			}
			return num;
		}

		public bool ContainsKeys(TFirstKey firstKey, TSecondKey secondKey)
		{
			if (TryGetValue(firstKey, out var value))
			{
				return value.ContainsKey(secondKey);
			}
			return false;
		}

		public bool TryGetInnerValue(TFirstKey firstKey, TSecondKey secondKey, out TValue value)
		{
			if (TryGetValue(firstKey, out var value2) && value2.TryGetValue(secondKey, out value))
			{
				return true;
			}
			value = default(TValue);
			return false;
		}

		public TValue AddInner(TFirstKey firstKey, TSecondKey secondKey, TValue value)
		{
			if (ContainsKeys(firstKey, secondKey))
			{
				throw new ArgumentException("An element with the same keys already exists in the " + GetType().GetNiceName() + ".");
			}
			return this[firstKey][secondKey] = value;
		}

		public bool RemoveInner(TFirstKey firstKey, TSecondKey secondKey)
		{
			if (TryGetValue(firstKey, out var value))
			{
				bool result = value.Remove(secondKey);
				if (value.Count == 0)
				{
					Remove(firstKey);
				}
				return result;
			}
			return false;
		}

		public void RemoveWhere(Func<TValue, bool> predicate)
		{
			List<TFirstKey> list = new List<TFirstKey>();
			List<TSecondKey> list2 = new List<TSecondKey>();
			foreach (KeyValuePair<TFirstKey, Dictionary<TSecondKey, TValue>> item in this.GFIterator())
			{
				foreach (KeyValuePair<TSecondKey, TValue> item2 in item.Value.GFIterator())
				{
					if (predicate(item2.Value))
					{
						list.Add(item.Key);
						list2.Add(item2.Key);
					}
				}
			}
			for (int i = 0; i < list.Count; i++)
			{
				RemoveInner(list[i], list2[i]);
			}
		}
	}
	public delegate object WeakValueGetter(ref object instance);
	public delegate void WeakValueSetter(ref object instance, object value);
	public delegate FieldType WeakValueGetter<FieldType>(ref object instance);
	public delegate void WeakValueSetter<FieldType>(ref object instance, FieldType value);
	public delegate FieldType ValueGetter<InstanceType, FieldType>(ref InstanceType instance);
	public delegate void ValueSetter<InstanceType, FieldType>(ref InstanceType instance, FieldType value);
	public static class EmitUtilities
	{
		public delegate void InstanceRefMethodCaller<InstanceType>(ref InstanceType instance);

		public delegate void InstanceRefMethodCaller<InstanceType, TArg1>(ref InstanceType instance, TArg1 arg1);

		private static Assembly EngineAssembly = typeof(Object).Assembly;

		public static bool CanEmit => true;

		private static bool EmitIsIllegalForMember(MemberInfo member)
		{
			if (member.DeclaringType != null)
			{
				return member.DeclaringType.Assembly == EngineAssembly;
			}
			return false;
		}

		public static Func<FieldType> CreateStaticFieldGetter<FieldType>(FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (!fieldInfo.IsStatic)
			{
				throw new ArgumentException("Field must be static.");
			}
			fieldInfo = fieldInfo.DeAliasField();
			if (fieldInfo.IsLiteral)
			{
				FieldType value = (FieldType)fieldInfo.GetValue(null);
				return () => value;
			}
			if (EmitIsIllegalForMember(fieldInfo))
			{
				return () => (FieldType)fieldInfo.GetValue(null);
			}
			DynamicMethod dynamicMethod = new DynamicMethod(fieldInfo.ReflectedType.FullName + ".get_" + fieldInfo.Name, typeof(FieldType), new Type[0], restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldsfld, fieldInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return (Func<FieldType>)dynamicMethod.CreateDelegate(typeof(Func<FieldType>));
		}

		public static Func<object> CreateWeakStaticFieldGetter(FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (!fieldInfo.IsStatic)
			{
				throw new ArgumentException("Field must be static.");
			}
			fieldInfo = fieldInfo.DeAliasField();
			if (EmitIsIllegalForMember(fieldInfo))
			{
				return () => fieldInfo.GetValue(null);
			}
			DynamicMethod dynamicMethod = new DynamicMethod(fieldInfo.ReflectedType.FullName + ".get_" + fieldInfo.Name, typeof(object), new Type[0], restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldsfld, fieldInfo);
			if (fieldInfo.FieldType.IsValueType)
			{
				iLGenerator.Emit(OpCodes.Box, fieldInfo.FieldType);
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (Func<object>)dynamicMethod.CreateDelegate(typeof(Func<object>));
		}

		public static Action<FieldType> CreateStaticFieldSetter<FieldType>(FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (!fieldInfo.IsStatic)
			{
				throw new ArgumentException("Field must be static.");
			}
			fieldInfo = fieldInfo.DeAliasField();
			if (fieldInfo.IsLiteral)
			{
				throw new ArgumentException("Field cannot be constant.");
			}
			if (EmitIsIllegalForMember(fieldInfo))
			{
				return delegate(FieldType value)
				{
					fieldInfo.SetValue(null, value);
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(fieldInfo.ReflectedType.FullName + ".set_" + fieldInfo.Name, null, new Type[1] { typeof(FieldType) }, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Stsfld, fieldInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return (Action<FieldType>)dynamicMethod.CreateDelegate(typeof(Action<FieldType>));
		}

		public static Action<object> CreateWeakStaticFieldSetter(FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (!fieldInfo.IsStatic)
			{
				throw new ArgumentException("Field must be static.");
			}
			fieldInfo = fieldInfo.DeAliasField();
			if (EmitIsIllegalForMember(fieldInfo))
			{
				return delegate(object value)
				{
					fieldInfo.SetValue(null, value);
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(fieldInfo.ReflectedType.FullName + ".set_" + fieldInfo.Name, null, new Type[1] { typeof(object) }, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			if (fieldInfo.FieldType.IsValueType)
			{
				iLGenerator.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Castclass, fieldInfo.FieldType);
			}
			iLGenerator.Emit(OpCodes.Stsfld, fieldInfo);
			iLGenerator.Emit(OpCodes.Ret);
			return (Action<object>)dynamicMethod.CreateDelegate(typeof(Action<object>));
		}

		public static ValueGetter<InstanceType, FieldType> CreateInstanceFieldGetter<InstanceType, FieldType>(FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (fieldInfo.IsStatic)
			{
				throw new ArgumentException("Field cannot be static.");
			}
			fieldInfo = fieldInfo.DeAliasField();
			if (EmitIsIllegalForMember(fieldInfo))
			{
				return delegate(ref InstanceType classInstance)
				{
					return (FieldType)fieldInfo.GetValue(classInstance);
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(fieldInfo.ReflectedType.FullName + ".get_" + fieldInfo.Name, typeof(FieldType), new Type[1] { typeof(InstanceType).MakeByRefType() }, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (typeof(InstanceType).IsValueType)
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldfld, fieldInfo);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Ldfld, fieldInfo);
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (ValueGetter<InstanceType, FieldType>)dynamicMethod.CreateDelegate(typeof(ValueGetter<InstanceType, FieldType>));
		}

		public static WeakValueGetter<FieldType> CreateWeakInstanceFieldGetter<FieldType>(Type instanceType, FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (instanceType == null)
			{
				throw new ArgumentNullException("instanceType");
			}
			if (fieldInfo.IsStatic)
			{
				throw new ArgumentException("Field cannot be static.");
			}
			fieldInfo = fieldInfo.DeAliasField();
			if (EmitIsIllegalForMember(fieldInfo))
			{
				return delegate(ref object classInstance)
				{
					return (FieldType)fieldInfo.GetValue(classInstance);
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(fieldInfo.ReflectedType.FullName + ".get_" + fieldInfo.Name, typeof(FieldType), new Type[1] { typeof(object).MakeByRefType() }, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (instanceType.IsValueType)
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Unbox_Any, instanceType);
				iLGenerator.Emit(OpCodes.Ldfld, fieldInfo);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Castclass, instanceType);
				iLGenerator.Emit(OpCodes.Ldfld, fieldInfo);
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (WeakValueGetter<FieldType>)dynamicMethod.CreateDelegate(typeof(WeakValueGetter<FieldType>));
		}

		public static WeakValueGetter CreateWeakInstanceFieldGetter(Type instanceType, FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (instanceType == null)
			{
				throw new ArgumentNullException("instanceType");
			}
			if (fieldInfo.IsStatic)
			{
				throw new ArgumentException("Field cannot be static.");
			}
			fieldInfo = fieldInfo.DeAliasField();
			if (EmitIsIllegalForMember(fieldInfo))
			{
				return delegate(ref object classInstance)
				{
					return fieldInfo.GetValue(classInstance);
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(fieldInfo.ReflectedType.FullName + ".get_" + fieldInfo.Name, typeof(object), new Type[1] { typeof(object).MakeByRefType() }, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (instanceType.IsValueType)
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Unbox_Any, instanceType);
				iLGenerator.Emit(OpCodes.Ldfld, fieldInfo);
				if (fieldInfo.FieldType.IsValueType)
				{
					iLGenerator.Emit(OpCodes.Box, fieldInfo.FieldType);
				}
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Castclass, instanceType);
				iLGenerator.Emit(OpCodes.Ldfld, fieldInfo);
				if (fieldInfo.FieldType.IsValueType)
				{
					iLGenerator.Emit(OpCodes.Box, fieldInfo.FieldType);
				}
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (WeakValueGetter)dynamicMethod.CreateDelegate(typeof(WeakValueGetter));
		}

		public static ValueSetter<InstanceType, FieldType> CreateInstanceFieldSetter<InstanceType, FieldType>(FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (fieldInfo.IsStatic)
			{
				throw new ArgumentException("Field cannot be static.");
			}
			fieldInfo = fieldInfo.DeAliasField();
			if (EmitIsIllegalForMember(fieldInfo))
			{
				return delegate(ref InstanceType classInstance, FieldType value)
				{
					if (typeof(InstanceType).IsValueType)
					{
						object obj = classInstance;
						fieldInfo.SetValue(obj, value);
						classInstance = (InstanceType)obj;
					}
					else
					{
						fieldInfo.SetValue(classInstance, value);
					}
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(fieldInfo.ReflectedType.FullName + ".set_" + fieldInfo.Name, null, new Type[2]
			{
				typeof(InstanceType).MakeByRefType(),
				typeof(FieldType)
			}, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (typeof(InstanceType).IsValueType)
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldarg_1);
				iLGenerator.Emit(OpCodes.Stfld, fieldInfo);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Ldarg_1);
				iLGenerator.Emit(OpCodes.Stfld, fieldInfo);
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (ValueSetter<InstanceType, FieldType>)dynamicMethod.CreateDelegate(typeof(ValueSetter<InstanceType, FieldType>));
		}

		public static WeakValueSetter<FieldType> CreateWeakInstanceFieldSetter<FieldType>(Type instanceType, FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (instanceType == null)
			{
				throw new ArgumentNullException("instanceType");
			}
			if (fieldInfo.IsStatic)
			{
				throw new ArgumentException("Field cannot be static.");
			}
			fieldInfo = fieldInfo.DeAliasField();
			if (EmitIsIllegalForMember(fieldInfo))
			{
				return delegate(ref object classInstance, FieldType value)
				{
					fieldInfo.SetValue(classInstance, value);
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(fieldInfo.ReflectedType.FullName + ".set_" + fieldInfo.Name, null, new Type[2]
			{
				typeof(object).MakeByRefType(),
				typeof(FieldType)
			}, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (instanceType.IsValueType)
			{
				LocalBuilder local = iLGenerator.DeclareLocal(instanceType);
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Unbox_Any, instanceType);
				iLGenerator.Emit(OpCodes.Stloc, local);
				iLGenerator.Emit(OpCodes.Ldloca_S, local);
				iLGenerator.Emit(OpCodes.Ldarg_1);
				iLGenerator.Emit(OpCodes.Stfld, fieldInfo);
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldloc, local);
				iLGenerator.Emit(OpCodes.Box, instanceType);
				iLGenerator.Emit(OpCodes.Stind_Ref);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Castclass, instanceType);
				iLGenerator.Emit(OpCodes.Ldarg_1);
				iLGenerator.Emit(OpCodes.Stfld, fieldInfo);
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (WeakValueSetter<FieldType>)dynamicMethod.CreateDelegate(typeof(WeakValueSetter<FieldType>));
		}

		public static WeakValueSetter CreateWeakInstanceFieldSetter(Type instanceType, FieldInfo fieldInfo)
		{
			if (fieldInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			if (instanceType == null)
			{
				throw new ArgumentNullException("instanceType");
			}
			if (fieldInfo.IsStatic)
			{
				throw new ArgumentException("Field cannot be static.");
			}
			fieldInfo = fieldInfo.DeAliasField();
			if (EmitIsIllegalForMember(fieldInfo))
			{
				return delegate(ref object classInstance, object value)
				{
					fieldInfo.SetValue(classInstance, value);
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(fieldInfo.ReflectedType.FullName + ".set_" + fieldInfo.Name, null, new Type[2]
			{
				typeof(object).MakeByRefType(),
				typeof(object)
			}, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (instanceType.IsValueType)
			{
				LocalBuilder local = iLGenerator.DeclareLocal(instanceType);
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Unbox_Any, instanceType);
				iLGenerator.Emit(OpCodes.Stloc, local);
				iLGenerator.Emit(OpCodes.Ldloca_S, local);
				iLGenerator.Emit(OpCodes.Ldarg_1);
				if (fieldInfo.FieldType.IsValueType)
				{
					iLGenerator.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
				}
				else
				{
					iLGenerator.Emit(OpCodes.Castclass, fieldInfo.FieldType);
				}
				iLGenerator.Emit(OpCodes.Stfld, fieldInfo);
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldloc, local);
				iLGenerator.Emit(OpCodes.Box, instanceType);
				iLGenerator.Emit(OpCodes.Stind_Ref);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Castclass, instanceType);
				iLGenerator.Emit(OpCodes.Ldarg_1);
				if (fieldInfo.FieldType.IsValueType)
				{
					iLGenerator.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
				}
				else
				{
					iLGenerator.Emit(OpCodes.Castclass, fieldInfo.FieldType);
				}
				iLGenerator.Emit(OpCodes.Stfld, fieldInfo);
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (WeakValueSetter)dynamicMethod.CreateDelegate(typeof(WeakValueSetter));
		}

		public static WeakValueGetter CreateWeakInstancePropertyGetter(Type instanceType, PropertyInfo propertyInfo)
		{
			if (propertyInfo == null)
			{
				throw new ArgumentNullException("propertyInfo");
			}
			if (instanceType == null)
			{
				throw new ArgumentNullException("instanceType");
			}
			propertyInfo = propertyInfo.DeAliasProperty();
			if (propertyInfo.GetIndexParameters().Length != 0)
			{
				throw new ArgumentException("Property must not have any index parameters");
			}
			MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true);
			if (getMethod == null)
			{
				throw new ArgumentException("Property must have a getter.");
			}
			if (getMethod.IsStatic)
			{
				throw new ArgumentException("Property cannot be static.");
			}
			if (EmitIsIllegalForMember(propertyInfo))
			{
				return delegate(ref object classInstance)
				{
					return propertyInfo.GetValue(classInstance, null);
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(propertyInfo.ReflectedType.FullName + ".get_" + propertyInfo.Name, typeof(object), new Type[1] { typeof(object).MakeByRefType() }, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (instanceType.IsValueType)
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Unbox_Any, instanceType);
				if (getMethod.IsVirtual || getMethod.IsAbstract)
				{
					iLGenerator.Emit(OpCodes.Callvirt, getMethod);
				}
				else
				{
					iLGenerator.Emit(OpCodes.Call, getMethod);
				}
				if (propertyInfo.PropertyType.IsValueType)
				{
					iLGenerator.Emit(OpCodes.Box, propertyInfo.PropertyType);
				}
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Castclass, instanceType);
				if (getMethod.IsVirtual || getMethod.IsAbstract)
				{
					iLGenerator.Emit(OpCodes.Callvirt, getMethod);
				}
				else
				{
					iLGenerator.Emit(OpCodes.Call, getMethod);
				}
				if (propertyInfo.PropertyType.IsValueType)
				{
					iLGenerator.Emit(OpCodes.Box, propertyInfo.PropertyType);
				}
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (WeakValueGetter)dynamicMethod.CreateDelegate(typeof(WeakValueGetter));
		}

		public static WeakValueSetter CreateWeakInstancePropertySetter(Type instanceType, PropertyInfo propertyInfo)
		{
			if (propertyInfo == null)
			{
				throw new ArgumentNullException("propertyInfo");
			}
			if (instanceType == null)
			{
				throw new ArgumentNullException("instanceType");
			}
			propertyInfo = propertyInfo.DeAliasProperty();
			if (propertyInfo.GetIndexParameters().Length != 0)
			{
				throw new ArgumentException("Property must not have any index parameters");
			}
			MethodInfo setMethod = propertyInfo.GetSetMethod(nonPublic: true);
			if (setMethod.IsStatic)
			{
				throw new ArgumentException("Property cannot be static.");
			}
			if (EmitIsIllegalForMember(propertyInfo))
			{
				return delegate(ref object classInstance, object value)
				{
					propertyInfo.SetValue(classInstance, value, null);
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(propertyInfo.ReflectedType.FullName + ".set_" + propertyInfo.Name, null, new Type[2]
			{
				typeof(object).MakeByRefType(),
				typeof(object)
			}, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (instanceType.IsValueType)
			{
				LocalBuilder local = iLGenerator.DeclareLocal(instanceType);
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Unbox_Any, instanceType);
				iLGenerator.Emit(OpCodes.Stloc, local);
				iLGenerator.Emit(OpCodes.Ldloca_S, local);
				iLGenerator.Emit(OpCodes.Ldarg_1);
				if (propertyInfo.PropertyType.IsValueType)
				{
					iLGenerator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
				}
				else
				{
					iLGenerator.Emit(OpCodes.Castclass, propertyInfo.PropertyType);
				}
				if (setMethod.IsVirtual || setMethod.IsAbstract)
				{
					iLGenerator.Emit(OpCodes.Callvirt, setMethod);
				}
				else
				{
					iLGenerator.Emit(OpCodes.Call, setMethod);
				}
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldloc, local);
				iLGenerator.Emit(OpCodes.Box, instanceType);
				iLGenerator.Emit(OpCodes.Stind_Ref);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Castclass, instanceType);
				iLGenerator.Emit(OpCodes.Ldarg_1);
				if (propertyInfo.PropertyType.IsValueType)
				{
					iLGenerator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
				}
				else
				{
					iLGenerator.Emit(OpCodes.Castclass, propertyInfo.PropertyType);
				}
				if (setMethod.IsVirtual || setMethod.IsAbstract)
				{
					iLGenerator.Emit(OpCodes.Callvirt, setMethod);
				}
				else
				{
					iLGenerator.Emit(OpCodes.Call, setMethod);
				}
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (WeakValueSetter)dynamicMethod.CreateDelegate(typeof(WeakValueSetter));
		}

		public static Action<PropType> CreateStaticPropertySetter<PropType>(PropertyInfo propertyInfo)
		{
			if (propertyInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			propertyInfo = propertyInfo.DeAliasProperty();
			if (propertyInfo.GetIndexParameters().Length != 0)
			{
				throw new ArgumentException("Property must not have any index parameters");
			}
			MethodInfo setMethod = propertyInfo.GetSetMethod(nonPublic: true);
			if (setMethod == null)
			{
				throw new ArgumentException("Property must have a set method.");
			}
			if (!setMethod.IsStatic)
			{
				throw new ArgumentException("Property must be static.");
			}
			if (EmitIsIllegalForMember(propertyInfo))
			{
				return delegate(PropType value)
				{
					propertyInfo.SetValue(null, value, null);
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(propertyInfo.ReflectedType.FullName + ".set_" + propertyInfo.Name, null, new Type[1] { typeof(PropType) }, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Call, setMethod);
			iLGenerator.Emit(OpCodes.Ret);
			return (Action<PropType>)dynamicMethod.CreateDelegate(typeof(Action<PropType>));
		}

		public static Func<PropType> CreateStaticPropertyGetter<PropType>(PropertyInfo propertyInfo)
		{
			if (propertyInfo == null)
			{
				throw new ArgumentNullException("propertyInfo");
			}
			propertyInfo = propertyInfo.DeAliasProperty();
			if (propertyInfo.GetIndexParameters().Length != 0)
			{
				throw new ArgumentException("Property must not have any index parameters");
			}
			MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true);
			if (getMethod == null)
			{
				throw new ArgumentException("Property must have a get method.");
			}
			if (!getMethod.IsStatic)
			{
				throw new ArgumentException("Property must be static.");
			}
			if (EmitIsIllegalForMember(propertyInfo))
			{
				return () => (PropType)propertyInfo.GetValue(null, null);
			}
			DynamicMethod dynamicMethod = new DynamicMethod(propertyInfo.ReflectedType.FullName + ".get_" + propertyInfo.Name, typeof(PropType), new Type[0], restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			iLGenerator.Emit(OpCodes.Call, getMethod);
			Type returnType = propertyInfo.GetReturnType();
			if (returnType.IsValueType && !typeof(PropType).IsValueType)
			{
				iLGenerator.Emit(OpCodes.Box, returnType);
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (Func<PropType>)dynamicMethod.CreateDelegate(typeof(Func<PropType>));
		}

		public static ValueSetter<InstanceType, PropType> CreateInstancePropertySetter<InstanceType, PropType>(PropertyInfo propertyInfo)
		{
			if (propertyInfo == null)
			{
				throw new ArgumentNullException("fieldInfo");
			}
			propertyInfo = propertyInfo.DeAliasProperty();
			if (propertyInfo.GetIndexParameters().Length != 0)
			{
				throw new ArgumentException("Property must not have any index parameters");
			}
			MethodInfo setMethod = propertyInfo.GetSetMethod(nonPublic: true);
			if (setMethod == null)
			{
				throw new ArgumentException("Property must have a set method.");
			}
			if (setMethod.IsStatic)
			{
				throw new ArgumentException("Property cannot be static.");
			}
			if (EmitIsIllegalForMember(propertyInfo))
			{
				return delegate(ref InstanceType classInstance, PropType value)
				{
					if (typeof(InstanceType).IsValueType)
					{
						object obj = classInstance;
						propertyInfo.SetValue(obj, value, null);
						classInstance = (InstanceType)obj;
					}
					else
					{
						propertyInfo.SetValue(classInstance, value, null);
					}
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(propertyInfo.ReflectedType.FullName + ".set_" + propertyInfo.Name, null, new Type[2]
			{
				typeof(InstanceType).MakeByRefType(),
				typeof(PropType)
			}, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (typeof(InstanceType).IsValueType)
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldarg_1);
				iLGenerator.Emit(OpCodes.Callvirt, setMethod);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Ldarg_1);
				iLGenerator.Emit(OpCodes.Callvirt, setMethod);
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (ValueSetter<InstanceType, PropType>)dynamicMethod.CreateDelegate(typeof(ValueSetter<InstanceType, PropType>));
		}

		public static ValueGetter<InstanceType, PropType> CreateInstancePropertyGetter<InstanceType, PropType>(PropertyInfo propertyInfo)
		{
			if (propertyInfo == null)
			{
				throw new ArgumentNullException("propertyInfo");
			}
			propertyInfo = propertyInfo.DeAliasProperty();
			if (propertyInfo.GetIndexParameters().Length != 0)
			{
				throw new ArgumentException("Property must not have any index parameters");
			}
			MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true);
			if (getMethod == null)
			{
				throw new ArgumentException("Property must have a get method.");
			}
			if (getMethod.IsStatic)
			{
				throw new ArgumentException("Property cannot be static.");
			}
			if (EmitIsIllegalForMember(propertyInfo))
			{
				return delegate(ref InstanceType classInstance)
				{
					return (PropType)propertyInfo.GetValue(classInstance, null);
				};
			}
			DynamicMethod dynamicMethod = new DynamicMethod(propertyInfo.ReflectedType.FullName + ".get_" + propertyInfo.Name, typeof(PropType), new Type[1] { typeof(InstanceType).MakeByRefType() }, restrictedSkipVisibility: true);
			ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
			if (typeof(InstanceType).IsValueType)
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Callvirt, getMethod);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Ldind_Ref);
				iLGenerator.Emit(OpCodes.Callvirt, getMethod);
			}
			iLGenerator.Emit(OpCodes.Ret);
			return (ValueGetter<InstanceType, PropType>)dynamicMethod.CreateDelegate(typeof(ValueGetter<InstanceType, PropType>));
		}

		public static Func<InstanceType, ReturnType> CreateMethodReturner<InstanceType, ReturnType>(MethodInfo methodInfo)
		{
			if (methodInfo == null)
			{
				throw new ArgumentNullException("methodInfo");
			}
			if (methodInfo.IsStatic)
			{
				throw new ArgumentException("Given method '" + methodInfo.Name + "' is static when it has to be an instance method.");
			}
			methodInfo = methodInfo.DeAliasMethod();
			return (Func<InstanceType, ReturnType>)Delegate.CreateDelegate(typeof(Func<InstanceType, ReturnType>), methodInfo);
		}

		public static Action CreateStaticMethodCaller(MethodInfo methodInfo)
		{
			if (methodInfo == null)
			{
				throw new ArgumentNullException("methodInfo");
			}
			if (!methodInfo.IsStatic)
			{
				throw new ArgumentException("Given method '" + methodInfo.Name + "' is an instance method when it has to be static.");
			}
			if (methodInfo.GetParameters().Length != 0)
			{
				throw new ArgumentException("Given method cannot have any parameters.");
			}
			methodInfo = methodInfo.DeAliasMethod();
			return (Action)Delegate.Cr

plugins/Octokit/Octokit.dll

Decompiled 3 days ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Octokit;
using Octokit.Caching;
using Octokit.Clients;
using Octokit.Helpers;
using Octokit.Internal;
using Octokit.Models.Request.Enterprise;
using Octokit.Models.Response;
using Octokit.Reflection;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[assembly: InternalsVisibleTo("Octokit.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f1e6b635f0c0b44c03d712e4f2cf789ddb54d7f74a9b34e2ece3aafb6afbfd46ec2b033f4104ef88f6afec226c5c647f453852ba3847fd9e37727c7dcb54e24731a288a107457a2c3e8b26ab04c25b206797be48cfe7a2b2c427422d0b0dd18c82111f21798f997e5d33ecc25c677744709c3785e0e650d6e0456a034a31acc4")]
[assembly: AssemblyCompany("GitHub")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright GitHub 2017")]
[assembly: AssemblyDescription("An async-based GitHub API client library for .NET and .NET Core")]
[assembly: AssemblyFileVersion("14.0.0.0")]
[assembly: AssemblyInformationalVersion("14.0.0+7fa5b0fe4a18c9b981b21290c3ca9320b2d6415b")]
[assembly: AssemblyProduct("Octokit")]
[assembly: AssemblyTitle("Octokit")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/octokit/octokit.net")]
[assembly: AssemblyVersion("14.0.0.0")]
public class CopilotLicenseClient : ApiClient, ICopilotLicenseClient
{
	public CopilotLicenseClient(IApiConnection apiConnection)
		: base(apiConnection)
	{
	}

	[ManualRoute("DELETE", "/orgs/{org}/copilot/billing/selected_users")]
	public async Task<CopilotSeatAllocation> Remove(string organization, string userName)
	{
		Ensure.ArgumentNotNull(organization, "organization");
		Ensure.ArgumentNotNull(userName, "userName");
		UserSeatAllocation userSeatAllocation = new UserSeatAllocation();
		userSeatAllocation.SelectedUsernames = new string[1] { userName };
		UserSeatAllocation userSeatAllocation2 = userSeatAllocation;
		return await Remove(organization, userSeatAllocation2);
	}

	[ManualRoute("DELETE", "/orgs/{org}/copilot/billing/selected_users")]
	public async Task<CopilotSeatAllocation> Remove(string organization, UserSeatAllocation userSeatAllocation)
	{
		Ensure.ArgumentNotNull(organization, "organization");
		Ensure.ArgumentNotNull(userSeatAllocation, "userSeatAllocation");
		return await base.ApiConnection.Delete<CopilotSeatAllocation>(ApiUrls.CopilotBillingLicense(organization), userSeatAllocation);
	}

	[ManualRoute("POST", "/orgs/{org}/copilot/billing/selected_users")]
	public async Task<CopilotSeatAllocation> Assign(string organization, string userName)
	{
		Ensure.ArgumentNotNull(organization, "organization");
		Ensure.ArgumentNotNull(userName, "userName");
		UserSeatAllocation userSeatAllocation = new UserSeatAllocation();
		userSeatAllocation.SelectedUsernames = new string[1] { userName };
		UserSeatAllocation userSeatAllocation2 = userSeatAllocation;
		return await Assign(organization, userSeatAllocation2);
	}

	[ManualRoute("POST", "/orgs/{org}/copilot/billing/selected_users")]
	public async Task<CopilotSeatAllocation> Assign(string organization, UserSeatAllocation userSeatAllocation)
	{
		Ensure.ArgumentNotNull(organization, "organization");
		Ensure.ArgumentNotNull(userSeatAllocation, "userSeatAllocation");
		return await base.ApiConnection.Post<CopilotSeatAllocation>(ApiUrls.CopilotBillingLicense(organization), userSeatAllocation);
	}

	[ManualRoute("GET", "/orgs/{org}/copilot/billing/seats")]
	public async Task<IReadOnlyList<CopilotSeats>> GetAll(string organization, ApiOptions options)
	{
		Ensure.ArgumentNotNull(organization, "organization");
		ApiOptionsExtended options2 = new ApiOptionsExtended
		{
			PageSize = options.PageSize
		};
		return await base.ApiConnection.GetAll<CopilotSeats>(ApiUrls.CopilotAllocatedLicenses(organization), options2);
	}
}
namespace Octokit
{
	public enum AuthenticationType
	{
		Anonymous,
		Basic,
		Oauth,
		Bearer
	}
	public class ActionsArtifactsClient : ApiClient, IActionsArtifactsClient
	{
		public ActionsArtifactsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/repos/{owner}/{repository}/actions/artifacts")]
		public Task<ListArtifactsResponse> ListArtifacts(string owner, string repository, ListArtifactsRequest listArtifactsRequest = null)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repository, "repository");
			return base.ApiConnection.Get<ListArtifactsResponse>(ApiUrls.ListArtifacts(owner, repository), listArtifactsRequest?.ToParametersDictionary());
		}

		[ManualRoute("GET", "/repos/{owner}/{repository}/actions/artifacts/{artifact_id}")]
		public Task<Artifact> GetArtifact(string owner, string repository, long artifactId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repository, "repository");
			Ensure.ArgumentNotNullOrDefault(artifactId, "artifactId");
			return base.ApiConnection.Get<Artifact>(ApiUrls.Artifact(owner, repository, artifactId), null);
		}

		[ManualRoute("DELETE", "/repos/{owner}/{repository}/actions/artifacts/{artifact_id}")]
		public Task DeleteArtifact(string owner, string repository, long artifactId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repository, "repository");
			Ensure.ArgumentNotNullOrDefault(artifactId, "artifactId");
			return base.ApiConnection.Delete(ApiUrls.Artifact(owner, repository, artifactId), null);
		}

		[ManualRoute("GET", "/repos/{owner}/{repository}/actions/artifacts/{artifact_id}/{archive_format}")]
		public Task<Stream> DownloadArtifact(string owner, string repository, long artifactId, string archiveFormat)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repository, "repository");
			Ensure.ArgumentNotNullOrDefault(artifactId, "artifactId");
			Ensure.ArgumentNotNullOrEmptyString(repository, "archiveFormat");
			return base.ApiConnection.GetRawStream(ApiUrls.DownloadArtifact(owner, repository, artifactId, archiveFormat), null);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}/artifacts")]
		public Task<ListArtifactsResponse> ListWorkflowArtifacts(string owner, string repository, long runId, ListArtifactsRequest listArtifactsRequest = null)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repository, "repository");
			Ensure.ArgumentNotNullOrDefault(runId, "runId");
			return base.ApiConnection.Get<ListArtifactsResponse>(ApiUrls.ListWorkflowArtifacts(owner, repository, runId), listArtifactsRequest?.ToParametersDictionary());
		}
	}
	public class ActionsCacheClient : ApiClient, IActionsCacheClient
	{
		public ActionsCacheClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}
	}
	public class ActionsClient : ApiClient, IActionsClient
	{
		public IActionsArtifactsClient Artifacts { get; private set; }

		public IActionsCacheClient Cache { get; private set; }

		public IActionsOidcClient Oidc { get; private set; }

		public IActionsPermissionsClient Permissions { get; private set; }

		public IActionsSelfHostedRunnerGroupsClient SelfHostedRunnerGroups { get; private set; }

		public IActionsSelfHostedRunnersClient SelfHostedRunners { get; private set; }

		public IActionsWorkflowsClient Workflows { get; private set; }

		public ActionsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
			Artifacts = new ActionsArtifactsClient(apiConnection);
			Cache = new ActionsCacheClient(apiConnection);
			Oidc = new ActionsOidcClient(apiConnection);
			Permissions = new ActionsPermissionsClient(apiConnection);
			SelfHostedRunnerGroups = new ActionsSelfHostedRunnerGroupsClient(apiConnection);
			SelfHostedRunners = new ActionsSelfHostedRunnersClient(apiConnection);
			Workflows = new ActionsWorkflowsClient(apiConnection);
		}
	}
	public class ActionsPermissionsClient : ApiClient, IActionsPermissionsClient
	{
		public ActionsPermissionsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}
	}
	public class ActionsSelfHostedRunnerGroupsClient : ApiClient, IActionsSelfHostedRunnerGroupsClient
	{
		public ActionsSelfHostedRunnerGroupsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/enterprises/{enterprise}/actions/runner-groups/{runner_group_id}")]
		public async Task<RunnerGroup> GetRunnerGroupForEnterprise(string enterprise, long runnerGroupId)
		{
			Ensure.ArgumentNotNullOrEmptyString(enterprise, "enterprise");
			return await base.ApiConnection.Get<RunnerGroup>(ApiUrls.ActionsGetEnterpriseRunnerGroup(enterprise, runnerGroupId)).ConfigureAwait(continueOnCapturedContext: false);
		}

		[ManualRoute("GET", "/orgs/{org}/actions/runner-groups/{runner_group_id}")]
		public async Task<RunnerGroup> GetRunnerGroupForOrganization(string org, long runnerGroupId)
		{
			Ensure.ArgumentNotNullOrEmptyString(org, "org");
			return await base.ApiConnection.Get<RunnerGroup>(ApiUrls.ActionsGetOrganizationRunnerGroup(org, runnerGroupId)).ConfigureAwait(continueOnCapturedContext: false);
		}

		[ManualRoute("GET", "/enterprises/{enterprise}/actions/runner-groups")]
		public Task<RunnerGroupResponse> ListAllRunnerGroupsForEnterprise(string enterprise)
		{
			return ListAllRunnerGroupsForEnterprise(enterprise, ApiOptions.None);
		}

		[ManualRoute("GET", "/enterprises/{enterprise}/actions/runner-groups")]
		public async Task<RunnerGroupResponse> ListAllRunnerGroupsForEnterprise(string enterprise, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(enterprise, "enterprise");
			IReadOnlyList<RunnerGroupResponse> readOnlyList = await base.ApiConnection.GetAll<RunnerGroupResponse>(ApiUrls.ActionsListEnterpriseRunnerGroups(enterprise), options).ConfigureAwait(continueOnCapturedContext: false);
			return new RunnerGroupResponse((readOnlyList.Count > 0) ? readOnlyList[0].TotalCount : 0, readOnlyList.SelectMany((RunnerGroupResponse x) => x.RunnerGroups).ToList());
		}

		[ManualRoute("GET", "/orgs/{org}/actions/runner-groups")]
		public Task<RunnerGroupResponse> ListAllRunnerGroupsForOrganization(string org)
		{
			return ListAllRunnerGroupsForOrganization(org, ApiOptions.None);
		}

		[ManualRoute("GET", "/orgs/{org}/actions/runner-groups")]
		public async Task<RunnerGroupResponse> ListAllRunnerGroupsForOrganization(string org, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(org, "org");
			IReadOnlyList<RunnerGroupResponse> readOnlyList = await base.ApiConnection.GetAll<RunnerGroupResponse>(ApiUrls.ActionsListOrganizationRunnerGroups(org), options).ConfigureAwait(continueOnCapturedContext: false);
			return new RunnerGroupResponse((readOnlyList.Count > 0) ? readOnlyList[0].TotalCount : 0, readOnlyList.SelectMany((RunnerGroupResponse x) => x.RunnerGroups).ToList());
		}

		[ManualRoute("GET", "/enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/runners")]
		public Task<RunnerResponse> ListAllRunnersForEnterpriseRunnerGroup(string enterprise, long runnerGroupId)
		{
			return ListAllRunnersForEnterpriseRunnerGroup(enterprise, runnerGroupId, ApiOptions.None);
		}

		[ManualRoute("GET", "/enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/runners")]
		public async Task<RunnerResponse> ListAllRunnersForEnterpriseRunnerGroup(string enterprise, long runnerGroupId, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(enterprise, "enterprise");
			IReadOnlyList<RunnerResponse> readOnlyList = await base.ApiConnection.GetAll<RunnerResponse>(ApiUrls.ActionsListSelfHostedRunnersForEnterpriseRunnerGroup(enterprise, runnerGroupId), options).ConfigureAwait(continueOnCapturedContext: false);
			return new RunnerResponse((readOnlyList.Count > 0) ? readOnlyList.Max((RunnerResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((RunnerResponse x) => x.Runners).ToList());
		}

		[ManualRoute("GET", "/orgs/{org}/actions/runner-groups/{runner_group_id}/runners")]
		public Task<RunnerResponse> ListAllRunnersForOrganizationRunnerGroup(string organization, long runnerGroupId)
		{
			return ListAllRunnersForOrganizationRunnerGroup(organization, runnerGroupId, ApiOptions.None);
		}

		[ManualRoute("GET", "/orgs/{org}/actions/runner-groups/{runner_group_id}/runners")]
		public async Task<RunnerResponse> ListAllRunnersForOrganizationRunnerGroup(string organization, long runnerGroupId, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(organization, "organization");
			IReadOnlyList<RunnerResponse> readOnlyList = await base.ApiConnection.GetAll<RunnerResponse>(ApiUrls.ActionsListSelfHostedRunnersForOrganizationRunnerGroup(organization, runnerGroupId), options).ConfigureAwait(continueOnCapturedContext: false);
			return new RunnerResponse((readOnlyList.Count > 0) ? readOnlyList.Max((RunnerResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((RunnerResponse x) => x.Runners).ToList());
		}

		[ManualRoute("GET", "/enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/organizations")]
		public Task<OrganizationsResponse> ListAllRunnerGroupOrganizationsForEnterprise(string enterprise, long runnerGroupId)
		{
			return ListAllRunnerGroupOrganizationsForEnterprise(enterprise, runnerGroupId, ApiOptions.None);
		}

		[ManualRoute("GET", "/enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/organizations")]
		public async Task<OrganizationsResponse> ListAllRunnerGroupOrganizationsForEnterprise(string enterprise, long runnerGroupId, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(enterprise, "enterprise");
			IReadOnlyList<OrganizationsResponse> readOnlyList = await base.ApiConnection.GetAll<OrganizationsResponse>(ApiUrls.ActionsListEnterpriseRunnerGroupOrganizations(enterprise, runnerGroupId), options).ConfigureAwait(continueOnCapturedContext: false);
			return new OrganizationsResponse((readOnlyList.Count > 0) ? readOnlyList.Max((OrganizationsResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((OrganizationsResponse x) => x.Organizations).ToList());
		}

		[ManualRoute("GET", "/orgs/{org}/actions/runner-groups/{runner_group_id}/repositories")]
		public Task<RepositoriesResponse> ListAllRunnerGroupRepositoriesForOrganization(string org, long runnerGroupId)
		{
			return ListAllRunnerGroupRepositoriesForOrganization(org, runnerGroupId, ApiOptions.None);
		}

		[ManualRoute("GET", "/orgs/{org}/actions/runner-groups/{runner_group_id}/repositories")]
		public async Task<RepositoriesResponse> ListAllRunnerGroupRepositoriesForOrganization(string org, long runnerGroupId, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(org, "org");
			IReadOnlyList<RepositoriesResponse> readOnlyList = await base.ApiConnection.GetAll<RepositoriesResponse>(ApiUrls.ActionsListOrganizationRunnerGroupRepositories(org, runnerGroupId), options).ConfigureAwait(continueOnCapturedContext: false);
			return new RepositoriesResponse((readOnlyList.Count > 0) ? readOnlyList.Max((RepositoriesResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((RepositoriesResponse x) => x.Repositories).ToList());
		}
	}
	public class ActionsSelfHostedRunnersClient : ApiClient, IActionsSelfHostedRunnersClient
	{
		public ActionsSelfHostedRunnersClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/enterprises/{enterprise}/actions/runners")]
		public Task<RunnerResponse> ListAllRunnersForEnterprise(string enterprise)
		{
			return ListAllRunnersForEnterprise(enterprise, ApiOptions.None);
		}

		[ManualRoute("GET", "/enterprises/{enterprise}/actions/runners")]
		public async Task<RunnerResponse> ListAllRunnersForEnterprise(string enterprise, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(enterprise, "enterprise");
			Ensure.ArgumentNotNull(options, "options");
			IReadOnlyList<RunnerResponse> readOnlyList = await base.ApiConnection.GetAll<RunnerResponse>(ApiUrls.ActionsListSelfHostedRunnersForEnterprise(enterprise), options).ConfigureAwait(continueOnCapturedContext: false);
			return new RunnerResponse((readOnlyList.Count > 0) ? readOnlyList[0].TotalCount : 0, readOnlyList.SelectMany((RunnerResponse x) => x.Runners).ToList());
		}

		[ManualRoute("GET", "/orgs/{org}/actions/runners")]
		public Task<RunnerResponse> ListAllRunnersForOrganization(string organization)
		{
			return ListAllRunnersForOrganization(organization, ApiOptions.None);
		}

		[ManualRoute("GET", "/orgs/{org}/actions/runners")]
		public async Task<RunnerResponse> ListAllRunnersForOrganization(string organization, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(organization, "organization");
			IReadOnlyList<RunnerResponse> readOnlyList = await base.ApiConnection.GetAll<RunnerResponse>(ApiUrls.ActionsListSelfHostedRunnersForOrganization(organization), options).ConfigureAwait(continueOnCapturedContext: false);
			return new RunnerResponse((readOnlyList.Count > 0) ? readOnlyList.Max((RunnerResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((RunnerResponse x) => x.Runners).ToList());
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runners")]
		public Task<RunnerResponse> ListAllRunnersForRepository(string owner, string name)
		{
			return ListAllRunnersForRepository(owner, name, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runners")]
		public async Task<RunnerResponse> ListAllRunnersForRepository(string owner, string name, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			IReadOnlyList<RunnerResponse> readOnlyList = await base.ApiConnection.GetAll<RunnerResponse>(ApiUrls.ActionsListSelfHostedRunnersForRepository(owner, name), options).ConfigureAwait(continueOnCapturedContext: false);
			return new RunnerResponse((readOnlyList.Count > 0) ? readOnlyList.Max((RunnerResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((RunnerResponse x) => x.Runners).ToList());
		}

		[ManualRoute("GET", "/enterprises/{enterprise}/actions/runners/downloads")]
		public Task<IReadOnlyList<RunnerApplication>> ListAllRunnerApplicationsForEnterprise(string enterprise)
		{
			return ListAllRunnerApplicationsForEnterprise(enterprise, ApiOptions.None);
		}

		[ManualRoute("GET", "/enterprises/{enterprise}/actions/runners/downloads")]
		public async Task<IReadOnlyList<RunnerApplication>> ListAllRunnerApplicationsForEnterprise(string enterprise, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(enterprise, "enterprise");
			return await base.ApiConnection.GetAll<RunnerApplication>(ApiUrls.ActionsListRunnerApplicationsForEnterprise(enterprise), options).ConfigureAwait(continueOnCapturedContext: false);
		}

		[ManualRoute("GET", "/orgs/{org}/actions/runners/downloads")]
		public Task<IReadOnlyList<RunnerApplication>> ListAllRunnerApplicationsForOrganization(string organization)
		{
			return ListAllRunnerApplicationsForOrganization(organization, ApiOptions.None);
		}

		[ManualRoute("GET", "/orgs/{org}/actions/runners/downloads")]
		public async Task<IReadOnlyList<RunnerApplication>> ListAllRunnerApplicationsForOrganization(string organization, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(organization, "organization");
			return await base.ApiConnection.GetAll<RunnerApplication>(ApiUrls.ActionsListRunnerApplicationsForOrganization(organization), options).ConfigureAwait(continueOnCapturedContext: false);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runners/downloads")]
		public Task<IReadOnlyList<RunnerApplication>> ListAllRunnerApplicationsForRepository(string owner, string repo)
		{
			return ListAllRunnerApplicationsForRepository(owner, repo, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runners/downloads")]
		public async Task<IReadOnlyList<RunnerApplication>> ListAllRunnerApplicationsForRepository(string owner, string repo, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repo, "repo");
			return await base.ApiConnection.GetAll<RunnerApplication>(ApiUrls.ActionsListRunnerApplicationsForRepository(owner, repo), options).ConfigureAwait(continueOnCapturedContext: false);
		}

		[ManualRoute("DELETE", "/enterprises/{enterprise}/actions/runners/{runner_id}")]
		public Task DeleteEnterpriseRunner(string enterprise, long runnerId)
		{
			Ensure.ArgumentNotNullOrEmptyString(enterprise, "enterprise");
			return base.ApiConnection.Delete(ApiUrls.ActionsDeleteEnterpriseRunner(enterprise, runnerId));
		}

		[ManualRoute("DELETE", "/orgs/{org}/actions/runners/{runner_id}")]
		public Task DeleteOrganizationRunner(string organization, long runnerId)
		{
			Ensure.ArgumentNotNullOrEmptyString(organization, "organization");
			return base.ApiConnection.Delete(ApiUrls.ActionsDeleteOrganizationRunner(organization, runnerId));
		}

		[ManualRoute("DELETE", "/repos/{owner}/{repo}/actions/runners/{runner_id}")]
		public Task DeleteRepositoryRunner(string owner, string repo, long runnerId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repo, "repo");
			return base.ApiConnection.Delete(ApiUrls.ActionsDeleteRepositoryRunner(owner, repo, runnerId));
		}

		[ManualRoute("POST", "/enterprises/{enterprise}/actions/runners/registration-token")]
		public Task<AccessToken> CreateEnterpriseRegistrationToken(string enterprise)
		{
			return CreateEnterpriseRegistrationToken(enterprise, CancellationToken.None);
		}

		[ManualRoute("POST", "/enterprises/{enterprise}/actions/runners/registration-token")]
		public Task<AccessToken> CreateEnterpriseRegistrationToken(string enterprise, CancellationToken cancellationToken = default(CancellationToken))
		{
			Ensure.ArgumentNotNullOrEmptyString(enterprise, "enterprise");
			return base.ApiConnection.Post<AccessToken>(ApiUrls.ActionsCreateEnterpriseRegistrationToken(enterprise), cancellationToken);
		}

		[ManualRoute("POST", "/orgs/{org}/actions/runners/registration-token")]
		public Task<AccessToken> CreateOrganizationRegistrationToken(string organization)
		{
			return CreateOrganizationRegistrationToken(organization, CancellationToken.None);
		}

		[ManualRoute("POST", "/orgs/{org}/actions/runners/registration-token")]
		public Task<AccessToken> CreateOrganizationRegistrationToken(string organization, CancellationToken cancellationToken)
		{
			Ensure.ArgumentNotNullOrEmptyString(organization, "organization");
			return base.ApiConnection.Post<AccessToken>(ApiUrls.ActionsCreateOrganizationRegistrationToken(organization), cancellationToken);
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/actions/runners/registration-token")]
		public Task<AccessToken> CreateRepositoryRegistrationToken(string owner, string repo)
		{
			return CreateRepositoryRegistrationToken(owner, repo, CancellationToken.None);
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/actions/runners/registration-token")]
		public Task<AccessToken> CreateRepositoryRegistrationToken(string owner, string repo, CancellationToken cancellationToken)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repo, "repo");
			return base.ApiConnection.Post<AccessToken>(ApiUrls.ActionsCreateRepositoryRegistrationToken(owner, repo), cancellationToken);
		}
	}
	public class ActionsWorkflowJobsClient : ApiClient, IActionsWorkflowJobsClient
	{
		public ActionsWorkflowJobsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/actions/jobs/{job_id}/rerun")]
		public Task Rerun(string owner, string name, long jobId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Post(ApiUrls.ActionsRerunWorkflowJob(owner, name, jobId));
		}

		[ManualRoute("GET", "\n/repos/{owner}/{repo}/actions/jobs/{job_id}")]
		public Task<WorkflowJob> Get(string owner, string name, long jobId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Get<WorkflowJob>(ApiUrls.ActionsGetWorkflowJob(owner, name, jobId));
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/jobs/{job_id}/logs")]
		public async Task<string> GetLogs(string owner, string name, long jobId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return (await base.Connection.Get<string>(ApiUrls.ActionsGetWorkflowJobLogs(owner, name, jobId), null).ConfigureAwait(continueOnCapturedContext: false)).Body;
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}/jobs")]
		public Task<WorkflowJobsResponse> List(string owner, string name, long runId)
		{
			return List(owner, name, runId, new WorkflowRunJobsRequest(), ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}/jobs")]
		public Task<WorkflowJobsResponse> List(string owner, string name, long runId, WorkflowRunJobsRequest workflowRunJobsRequest)
		{
			return List(owner, name, runId, workflowRunJobsRequest, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}/jobs")]
		public async Task<WorkflowJobsResponse> List(string owner, string name, long runId, WorkflowRunJobsRequest workflowRunJobsRequest, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(workflowRunJobsRequest, "workflowRunJobsRequest");
			IReadOnlyList<WorkflowJobsResponse> readOnlyList = await base.ApiConnection.GetAll<WorkflowJobsResponse>(ApiUrls.ActionsListWorkflowJobs(owner, name, runId), workflowRunJobsRequest.ToParametersDictionary(), options).ConfigureAwait(continueOnCapturedContext: false);
			return new WorkflowJobsResponse((readOnlyList.Count > 0) ? readOnlyList.Max((WorkflowJobsResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((WorkflowJobsResponse x) => x.Jobs).ToList());
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs")]
		public Task<WorkflowJobsResponse> List(string owner, string name, long runId, int attemptNumber)
		{
			return List(owner, name, runId, attemptNumber, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs")]
		public async Task<WorkflowJobsResponse> List(string owner, string name, long runId, int attemptNumber, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			IReadOnlyList<WorkflowJobsResponse> readOnlyList = await base.ApiConnection.GetAll<WorkflowJobsResponse>(ApiUrls.ActionsListWorkflowJobs(owner, name, runId, attemptNumber), null, options).ConfigureAwait(continueOnCapturedContext: false);
			return new WorkflowJobsResponse((readOnlyList.Count > 0) ? readOnlyList.Max((WorkflowJobsResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((WorkflowJobsResponse x) => x.Jobs).ToList());
		}
	}
	public class ActionsWorkflowRunsClient : ApiClient, IActionsWorkflowRunsClient
	{
		public ActionsWorkflowRunsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs")]
		public Task<WorkflowRunsResponse> List(string owner, string name)
		{
			return List(owner, name, new WorkflowRunsRequest(), ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs")]
		public Task<WorkflowRunsResponse> List(string owner, string name, WorkflowRunsRequest workflowRunsRequest)
		{
			return List(owner, name, workflowRunsRequest, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs")]
		public async Task<WorkflowRunsResponse> List(string owner, string name, WorkflowRunsRequest workflowRunsRequest, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(workflowRunsRequest, "workflowRunsRequest");
			Ensure.ArgumentNotNull(options, "options");
			IReadOnlyList<WorkflowRunsResponse> readOnlyList = await base.ApiConnection.GetAll<WorkflowRunsResponse>(ApiUrls.ActionsWorkflowRuns(owner, name), workflowRunsRequest.ToParametersDictionary(), options).ConfigureAwait(continueOnCapturedContext: false);
			return new WorkflowRunsResponse((readOnlyList.Count > 0) ? readOnlyList.Max((WorkflowRunsResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((WorkflowRunsResponse x) => x.WorkflowRuns).ToList());
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}")]
		public Task<WorkflowRun> Get(string owner, string name, long runId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Get<WorkflowRun>(ApiUrls.ActionsWorkflowRun(owner, name, runId), null);
		}

		[ManualRoute("DELETE", "/repos/{owner}/{repo}/actions/runs/{run_id}")]
		public Task Delete(string owner, string name, long runId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Delete(ApiUrls.ActionsWorkflowRun(owner, name, runId));
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}/approvals")]
		public Task<IReadOnlyList<EnvironmentApprovals>> GetReviewHistory(string owner, string name, long runId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.GetAll<EnvironmentApprovals>(ApiUrls.ActionsWorkflowRunApprovals(owner, name, runId));
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/actions/runs/{run_id}/approve")]
		public Task Approve(string owner, string name, long runId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Post(ApiUrls.ActionsApproveWorkflowRun(owner, name, runId));
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}")]
		public Task<WorkflowRun> GetAttempt(string owner, string name, long runId, long attemptNumber)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Get<WorkflowRun>(ApiUrls.ActionsWorkflowRunAttempt(owner, name, runId, attemptNumber), null);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}")]
		public async Task<byte[]> GetAttemptLogs(string owner, string name, long runId, long attemptNumber)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return (await base.Connection.GetRaw(ApiUrls.ActionsGetWorkflowRunAttemptLogs(owner, name, runId, attemptNumber), null).ConfigureAwait(continueOnCapturedContext: false)).Body;
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/actions/runs/{run_id}/cancel")]
		public Task Cancel(string owner, string name, long runId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Post(ApiUrls.ActionsCancelWorkflowRun(owner, name, runId));
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}/logs")]
		public async Task<byte[]> GetLogs(string owner, string name, long runId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return (await base.Connection.GetRaw(ApiUrls.ActionsGetWorkflowRunLogs(owner, name, runId), null).ConfigureAwait(continueOnCapturedContext: false)).Body;
		}

		[ManualRoute("DELETE", "/repos/{owner}/{repo}/actions/runs/{run_id}/logs")]
		public Task DeleteLogs(string owner, string name, long runId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Delete(ApiUrls.ActionsGetWorkflowRunLogs(owner, name, runId));
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments")]
		public Task<Deployment> ReviewPendingDeployments(string owner, string name, long runId, PendingDeploymentReview review)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(review, "review");
			return base.ApiConnection.Post<Deployment>(ApiUrls.ActionsWorkflowRunPendingDeployments(owner, name, runId), review);
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/actions/runs/{run_id}/rerun")]
		public Task Rerun(string owner, string name, long runId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Post(ApiUrls.ActionsRerunWorkflowRun(owner, name, runId));
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/actions/runs/{run_id}/rerun-failed-jobs")]
		public Task RerunFailedJobs(string owner, string name, long runId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Post(ApiUrls.ActionsRerunWorkflowRunFailedJobs(owner, name, runId));
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/runs/{run_id}/timing")]
		public Task<WorkflowRunUsage> GetUsage(string owner, string name, long runId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Get<WorkflowRunUsage>(ApiUrls.ActionsGetWorkflowRunUsage(owner, name, runId), null);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs")]
		public Task<WorkflowRunsResponse> ListByWorkflow(string owner, string name, long workflowId)
		{
			return ListByWorkflow(owner, name, workflowId, new WorkflowRunsRequest(), ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs")]
		public Task<WorkflowRunsResponse> ListByWorkflow(string owner, string name, long workflowId, WorkflowRunsRequest workflowRunsRequest)
		{
			return ListByWorkflow(owner, name, workflowId, workflowRunsRequest, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs")]
		public async Task<WorkflowRunsResponse> ListByWorkflow(string owner, string name, long workflowId, WorkflowRunsRequest workflowRunsRequest, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(workflowRunsRequest, "workflowRunsRequest");
			Ensure.ArgumentNotNull(options, "options");
			IReadOnlyList<WorkflowRunsResponse> readOnlyList = await base.ApiConnection.GetAll<WorkflowRunsResponse>(ApiUrls.ActionsListWorkflowRuns(owner, name, workflowId), workflowRunsRequest.ToParametersDictionary(), options).ConfigureAwait(continueOnCapturedContext: false);
			return new WorkflowRunsResponse((readOnlyList.Count > 0) ? readOnlyList.Max((WorkflowRunsResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((WorkflowRunsResponse x) => x.WorkflowRuns).ToList());
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs")]
		public Task<WorkflowRunsResponse> ListByWorkflow(string owner, string name, string workflowFileName)
		{
			return ListByWorkflow(owner, name, workflowFileName, new WorkflowRunsRequest(), ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs")]
		public Task<WorkflowRunsResponse> ListByWorkflow(string owner, string name, string workflowFileName, WorkflowRunsRequest workflowRunsRequest)
		{
			return ListByWorkflow(owner, name, workflowFileName, workflowRunsRequest, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs")]
		public async Task<WorkflowRunsResponse> ListByWorkflow(string owner, string name, string workflowFileName, WorkflowRunsRequest workflowRunsRequest, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(workflowFileName, "workflowFileName");
			Ensure.ArgumentNotNull(workflowRunsRequest, "workflowRunsRequest");
			Ensure.ArgumentNotNull(options, "options");
			IReadOnlyList<WorkflowRunsResponse> readOnlyList = await base.ApiConnection.GetAll<WorkflowRunsResponse>(ApiUrls.ActionsListWorkflowRuns(owner, name, workflowFileName), workflowRunsRequest.ToParametersDictionary(), options).ConfigureAwait(continueOnCapturedContext: false);
			return new WorkflowRunsResponse((readOnlyList.Count > 0) ? readOnlyList.Max((WorkflowRunsResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((WorkflowRunsResponse x) => x.WorkflowRuns).ToList());
		}
	}
	public class ActionsWorkflowsClient : ApiClient, IActionsWorkflowsClient
	{
		public IActionsWorkflowJobsClient Jobs { get; private set; }

		public IActionsWorkflowRunsClient Runs { get; private set; }

		public ActionsWorkflowsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
			Jobs = new ActionsWorkflowJobsClient(apiConnection);
			Runs = new ActionsWorkflowRunsClient(apiConnection);
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches")]
		public Task CreateDispatch(string owner, string name, string workflowFileName, CreateWorkflowDispatch createDispatch)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(workflowFileName, "workflowFileName");
			Ensure.ArgumentNotNull(createDispatch, "createDispatch");
			return base.ApiConnection.Post<object>(ApiUrls.ActionsDispatchWorkflow(owner, name, workflowFileName), createDispatch);
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches")]
		public Task CreateDispatch(string owner, string name, long workflowId, CreateWorkflowDispatch createDispatch)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(createDispatch, "createDispatch");
			return base.ApiConnection.Post<object>(ApiUrls.ActionsDispatchWorkflow(owner, name, workflowId), createDispatch);
		}

		[ManualRoute("POST", "/repositories/{id}/actions/workflows/{workflow_id}/dispatches")]
		public Task CreateDispatch(long repositoryId, string workflowFileName, CreateWorkflowDispatch createDispatch)
		{
			Ensure.ArgumentNotNullOrEmptyString(workflowFileName, "workflowFileName");
			Ensure.ArgumentNotNull(createDispatch, "createDispatch");
			return base.ApiConnection.Post<object>(ApiUrls.ActionsDispatchWorkflow(repositoryId, workflowFileName), createDispatch);
		}

		[ManualRoute("POST", "/repositories/{id}/actions/workflows/{workflow_id}/dispatches")]
		public Task CreateDispatch(long repositoryId, long workflowId, CreateWorkflowDispatch createDispatch)
		{
			Ensure.ArgumentNotNull(createDispatch, "createDispatch");
			return base.ApiConnection.Post<object>(ApiUrls.ActionsDispatchWorkflow(repositoryId, workflowId), createDispatch);
		}

		[ManualRoute("PUT", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/disable")]
		public Task Disable(string owner, string name, string workflowFileName)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(workflowFileName, "workflowFileName");
			return base.ApiConnection.Put(ApiUrls.ActionsDisableWorkflow(owner, name, workflowFileName));
		}

		[ManualRoute("PUT", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/disable")]
		public Task Disable(string owner, string name, long workflowId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Put(ApiUrls.ActionsDisableWorkflow(owner, name, workflowId));
		}

		[ManualRoute("PUT", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable")]
		public Task Enable(string owner, string name, string workflowFileName)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(workflowFileName, "workflowFileName");
			return base.ApiConnection.Put(ApiUrls.ActionsEnableWorkflow(owner, name, workflowFileName));
		}

		[ManualRoute("PUT", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable")]
		public Task Enable(string owner, string name, long workflowId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Put(ApiUrls.ActionsEnableWorkflow(owner, name, workflowId));
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}")]
		public Task<Workflow> Get(string owner, string name, string workflowFileName)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(workflowFileName, "workflowFileName");
			return base.ApiConnection.Get<Workflow>(ApiUrls.ActionsGetWorkflow(owner, name, workflowFileName), null);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}")]
		public Task<Workflow> Get(string owner, string name, long workflowId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Get<Workflow>(ApiUrls.ActionsGetWorkflow(owner, name, workflowId), null);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/timing")]
		public Task<WorkflowUsage> GetUsage(string owner, string name, string workflowFileName)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(workflowFileName, "workflowFileName");
			return base.ApiConnection.Get<WorkflowUsage>(ApiUrls.ActionsGetWorkflowUsage(owner, name, workflowFileName), null);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/workflows/{workflow_id}/timing")]
		public Task<WorkflowUsage> GetUsage(string owner, string name, long workflowId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Get<WorkflowUsage>(ApiUrls.ActionsGetWorkflowUsage(owner, name, workflowId), null);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/workflows")]
		public Task<WorkflowsResponse> List(string owner, string name)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return List(owner, name, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/actions/workflows")]
		public async Task<WorkflowsResponse> List(string owner, string name, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(options, "options");
			IReadOnlyList<WorkflowsResponse> readOnlyList = await base.ApiConnection.GetAll<WorkflowsResponse>(ApiUrls.ActionsListWorkflows(owner, name), null, options).ConfigureAwait(continueOnCapturedContext: false);
			return new WorkflowsResponse((readOnlyList.Count > 0) ? readOnlyList.Max((WorkflowsResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((WorkflowsResponse x) => x.Workflows).ToList());
		}
	}
	public class ActivitiesClient : ApiClient, IActivitiesClient
	{
		public IEventsClient Events { get; private set; }

		public IStarredClient Starring { get; private set; }

		public IWatchedClient Watching { get; private set; }

		public IFeedsClient Feeds { get; private set; }

		public INotificationsClient Notifications { get; private set; }

		public ActivitiesClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
			Events = new EventsClient(apiConnection);
			Starring = new StarredClient(apiConnection);
			Watching = new WatchedClient(apiConnection);
			Feeds = new FeedsClient(apiConnection);
			Notifications = new NotificationsClient(apiConnection);
		}
	}
	public abstract class ApiClient
	{
		protected IApiConnection ApiConnection { get; private set; }

		protected IConnection Connection { get; private set; }

		protected ApiClient(IApiConnection apiConnection)
		{
			Ensure.ArgumentNotNull(apiConnection, "apiConnection");
			ApiConnection = apiConnection;
			Connection = apiConnection.Connection;
		}
	}
	public class ApiPagination : IApiPagination
	{
		public async Task<IReadOnlyList<T>> GetAllPages<T>(Func<Task<IReadOnlyPagedCollection<T>>> getFirstPage, Uri uri)
		{
			Ensure.ArgumentNotNull(getFirstPage, "getFirstPage");
			try
			{
				IReadOnlyPagedCollection<T> readOnlyPagedCollection = await getFirstPage().ConfigureAwait(continueOnCapturedContext: false);
				List<T> allItems = new List<T>(readOnlyPagedCollection);
				while ((readOnlyPagedCollection = await readOnlyPagedCollection.GetNextPage().ConfigureAwait(continueOnCapturedContext: false)) != null)
				{
					allItems.AddRange(readOnlyPagedCollection);
				}
				return new ReadOnlyCollection<T>(allItems);
			}
			catch (NotFoundException)
			{
				throw new NotFoundException(string.Format(CultureInfo.InvariantCulture, "{0} was not found.", uri.OriginalString), HttpStatusCode.NotFound);
			}
		}
	}
	public class AssigneesClient : ApiClient, IAssigneesClient
	{
		public AssigneesClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/assignees")]
		public Task<IReadOnlyList<User>> GetAllForRepository(string owner, string name)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return GetAllForRepository(owner, name, ApiOptions.None);
		}

		[ManualRoute("GET", "/repositories/{id}/assignees")]
		public Task<IReadOnlyList<User>> GetAllForRepository(long repositoryId)
		{
			return GetAllForRepository(repositoryId, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/assignees")]
		public Task<IReadOnlyList<User>> GetAllForRepository(string owner, string name, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(options, "options");
			Uri uri = ApiUrls.Assignees(owner, name);
			return base.ApiConnection.GetAll<User>(uri, null, options);
		}

		[ManualRoute("GET", "/repositories/{id}/assignees")]
		public Task<IReadOnlyList<User>> GetAllForRepository(long repositoryId, ApiOptions options)
		{
			Ensure.ArgumentNotNull(options, "options");
			Uri uri = ApiUrls.Assignees(repositoryId);
			return base.ApiConnection.GetAll<User>(uri, null, options);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/assignees/{username}")]
		public async Task<bool> CheckAssignee(string owner, string name, string assignee)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(assignee, "assignee");
			try
			{
				return (await base.Connection.Get<object>(ApiUrls.CheckAssignee(owner, name, assignee), null, null).ConfigureAwait(continueOnCapturedContext: false)).HttpResponse.IsTrue();
			}
			catch (NotFoundException)
			{
				return false;
			}
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/issues/{issue_number}/assignees")]
		public Task<Issue> AddAssignees(string owner, string name, long issueNumber, AssigneesUpdate assignees)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(assignees, "assignees");
			return base.ApiConnection.Post<Issue>(ApiUrls.IssueAssignees(owner, name, issueNumber), assignees);
		}

		[ManualRoute("DELETE", "/repos/{owner}/{repo}/issues/{issue_number}/assignees")]
		public Task<Issue> RemoveAssignees(string owner, string name, long issueNumber, AssigneesUpdate assignees)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(assignees, "assignees");
			return base.ApiConnection.Delete<Issue>(ApiUrls.IssueAssignees(owner, name, issueNumber), assignees);
		}

		[ManualRoute("GET", "/repositories/{id}/assignees/{username}")]
		public async Task<bool> CheckAssignee(long repositoryId, string assignee)
		{
			Ensure.ArgumentNotNullOrEmptyString(assignee, "assignee");
			try
			{
				return (await base.Connection.Get<object>(ApiUrls.CheckAssignee(repositoryId, assignee), null, null).ConfigureAwait(continueOnCapturedContext: false)).HttpResponse.IsTrue();
			}
			catch (NotFoundException)
			{
				return false;
			}
		}
	}
	public class AuthorizationsClient : ApiClient, IAuthorizationsClient
	{
		public AuthorizationsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/authorizations")]
		public Task<IReadOnlyList<Authorization>> GetAll()
		{
			return GetAll(ApiOptions.None);
		}

		[ManualRoute("GET", "/authorizations")]
		public Task<IReadOnlyList<Authorization>> GetAll(ApiOptions options)
		{
			Ensure.ArgumentNotNull(options, "options");
			return base.ApiConnection.GetAll<Authorization>(ApiUrls.Authorizations(), options);
		}

		[ManualRoute("GET", "/authorizations/{id}")]
		public Task<Authorization> Get(long authorizationId)
		{
			return base.ApiConnection.Get<Authorization>(ApiUrls.Authorizations(authorizationId), null);
		}

		[ManualRoute("POST", "/authorizations")]
		public Task<ApplicationAuthorization> Create(NewAuthorization newAuthorization)
		{
			Ensure.ArgumentNotNull(newAuthorization, "newAuthorization");
			var data = new
			{
				scopes = newAuthorization.Scopes,
				note = newAuthorization.Note,
				note_url = newAuthorization.NoteUrl,
				fingerprint = newAuthorization.Fingerprint
			};
			Uri uri = ApiUrls.Authorizations();
			return base.ApiConnection.Post<ApplicationAuthorization>(uri, data);
		}

		[ManualRoute("POST", "/authorizations")]
		public Task<ApplicationAuthorization> Create(NewAuthorization newAuthorization, string twoFactorAuthenticationCode)
		{
			Ensure.ArgumentNotNull(newAuthorization, "newAuthorization");
			Ensure.ArgumentNotNullOrEmptyString(twoFactorAuthenticationCode, "twoFactorAuthenticationCode");
			var data = new
			{
				scopes = newAuthorization.Scopes,
				note = newAuthorization.Note,
				note_url = newAuthorization.NoteUrl,
				fingerprint = newAuthorization.Fingerprint
			};
			Uri uri = ApiUrls.Authorizations();
			return base.ApiConnection.Post<ApplicationAuthorization>(uri, data, null, twoFactorAuthenticationCode);
		}

		[ManualRoute("POST", "/authorizations")]
		public Task<ApplicationAuthorization> Create(string clientId, string clientSecret, NewAuthorization newAuthorization)
		{
			Ensure.ArgumentNotNullOrEmptyString(clientId, "clientId");
			Ensure.ArgumentNotNullOrEmptyString(clientSecret, "clientSecret");
			Ensure.ArgumentNotNull(newAuthorization, "newAuthorization");
			var data = new
			{
				client_id = clientId,
				client_secret = clientSecret,
				scopes = newAuthorization.Scopes,
				note = newAuthorization.Note,
				note_url = newAuthorization.NoteUrl,
				fingerprint = newAuthorization.Fingerprint
			};
			Uri uri = ApiUrls.Authorizations();
			return base.ApiConnection.Post<ApplicationAuthorization>(uri, data);
		}

		[ManualRoute("POST", "/authorizations")]
		public Task<ApplicationAuthorization> Create(string clientId, string clientSecret, NewAuthorization newAuthorization, string twoFactorAuthenticationCode)
		{
			Ensure.ArgumentNotNullOrEmptyString(clientId, "clientId");
			Ensure.ArgumentNotNullOrEmptyString(clientSecret, "clientSecret");
			Ensure.ArgumentNotNull(newAuthorization, "newAuthorization");
			Ensure.ArgumentNotNullOrEmptyString(twoFactorAuthenticationCode, "twoFactorAuthenticationCode");
			var data = new
			{
				client_id = clientId,
				client_secret = clientSecret,
				scopes = newAuthorization.Scopes,
				note = newAuthorization.Note,
				note_url = newAuthorization.NoteUrl,
				fingerprint = newAuthorization.Fingerprint
			};
			Uri uri = ApiUrls.Authorizations();
			return base.ApiConnection.Post<ApplicationAuthorization>(uri, data, null, null, twoFactorAuthenticationCode);
		}

		[ManualRoute("PUT", "/authorizations/clients/{id}")]
		public Task<ApplicationAuthorization> GetOrCreateApplicationAuthentication(string clientId, string clientSecret, NewAuthorization newAuthorization)
		{
			Ensure.ArgumentNotNullOrEmptyString(clientId, "clientId");
			Ensure.ArgumentNotNullOrEmptyString(clientSecret, "clientSecret");
			Ensure.ArgumentNotNull(newAuthorization, "newAuthorization");
			var data = new
			{
				client_secret = clientSecret,
				scopes = newAuthorization.Scopes,
				note = newAuthorization.Note,
				note_url = newAuthorization.NoteUrl,
				fingerprint = newAuthorization.Fingerprint
			};
			Uri uri = ApiUrls.AuthorizationsForClient(clientId);
			return base.ApiConnection.Put<ApplicationAuthorization>(uri, data);
		}

		[ManualRoute("PUT", "/authorizations/clients/{id}")]
		public async Task<ApplicationAuthorization> GetOrCreateApplicationAuthentication(string clientId, string clientSecret, NewAuthorization newAuthorization, string twoFactorAuthenticationCode)
		{
			Ensure.ArgumentNotNullOrEmptyString(clientId, "clientId");
			Ensure.ArgumentNotNullOrEmptyString(clientSecret, "clientSecret");
			Ensure.ArgumentNotNull(newAuthorization, "newAuthorization");
			Ensure.ArgumentNotNullOrEmptyString(twoFactorAuthenticationCode, "twoFactorAuthenticationCode");
			var data = new
			{
				client_secret = clientSecret,
				scopes = newAuthorization.Scopes,
				note = newAuthorization.Note,
				note_url = newAuthorization.NoteUrl,
				fingerprint = newAuthorization.Fingerprint
			};
			try
			{
				Uri uri = ApiUrls.AuthorizationsForClient(clientId);
				return await base.ApiConnection.Put<ApplicationAuthorization>(uri, data, twoFactorAuthenticationCode).ConfigureAwait(continueOnCapturedContext: false);
			}
			catch (AuthorizationException innerException)
			{
				throw new TwoFactorChallengeFailedException(twoFactorAuthenticationCode, innerException);
			}
		}

		[ManualRoute("POST", "/applications/{client_id}/token")]
		public Task<ApplicationAuthorization> CheckApplicationAuthentication(string clientId, string accessToken)
		{
			Ensure.ArgumentNotNullOrEmptyString(clientId, "clientId");
			Ensure.ArgumentNotNullOrEmptyString(accessToken, "accessToken");
			var data = new
			{
				access_token = accessToken
			};
			Uri uri = ApiUrls.ApplicationAuthorization(clientId);
			return base.ApiConnection.Post<ApplicationAuthorization>(uri, data);
		}

		[ManualRoute("PATCH", "/applications/{client_id}/token")]
		public Task<ApplicationAuthorization> ResetApplicationAuthentication(string clientId, string accessToken)
		{
			Ensure.ArgumentNotNullOrEmptyString(clientId, "clientId");
			Ensure.ArgumentNotNullOrEmptyString(accessToken, "accessToken");
			var data = new
			{
				access_token = accessToken
			};
			Uri uri = ApiUrls.ApplicationAuthorization(clientId);
			return base.ApiConnection.Patch<ApplicationAuthorization>(uri, data);
		}

		[ManualRoute("DELETE", "/applications/{client_id}/token")]
		public Task RevokeApplicationAuthentication(string clientId, string accessToken)
		{
			Ensure.ArgumentNotNullOrEmptyString(clientId, "clientId");
			Ensure.ArgumentNotNullOrEmptyString(accessToken, "accessToken");
			var data = new
			{
				access_token = accessToken
			};
			Uri uri = ApiUrls.ApplicationAuthorization(clientId);
			return base.ApiConnection.Delete(uri, data);
		}

		[ManualRoute("PATCH", "/authorizations/{id}")]
		public Task<Authorization> Update(long authorizationId, AuthorizationUpdate authorizationUpdate)
		{
			Ensure.ArgumentNotNull(authorizationUpdate, "authorizationUpdate");
			return base.ApiConnection.Patch<Authorization>(ApiUrls.Authorizations(authorizationId), authorizationUpdate);
		}

		[ManualRoute("DELETE", "/authorizations/{id}")]
		public Task Delete(long authorizationId)
		{
			return base.ApiConnection.Delete(ApiUrls.Authorizations(authorizationId));
		}

		[ManualRoute("DELETE", "/authorizations/{id}")]
		public Task Delete(long authorizationId, string twoFactorAuthenticationCode)
		{
			return base.ApiConnection.Delete(ApiUrls.Authorizations(authorizationId), twoFactorAuthenticationCode);
		}
	}
	public class AutolinksClient : ApiClient, IAutolinksClient
	{
		public AutolinksClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/autolinks/{autolinkId}")]
		public Task<Autolink> Get(string owner, string repo, int autolinkId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repo, "repo");
			return base.ApiConnection.Get<Autolink>(ApiUrls.AutolinksGet(owner, repo, autolinkId));
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/autolinks")]
		public Task<IReadOnlyList<Autolink>> GetAll(string owner, string repo)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repo, "repo");
			return GetAll(owner, repo, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/autolinks")]
		public Task<IReadOnlyList<Autolink>> GetAll(string owner, string repo, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repo, "repo");
			Ensure.ArgumentNotNull(options, "options");
			return base.ApiConnection.GetAll<Autolink>(ApiUrls.AutolinksGetAll(owner, repo), options);
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/autolinks")]
		public Task<Autolink> Create(string owner, string repo, AutolinkRequest autolink)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repo, "repo");
			Ensure.ArgumentNotNull(autolink, "autolink");
			return base.ApiConnection.Post<Autolink>(ApiUrls.AutolinksCreate(owner, repo), autolink);
		}

		[ManualRoute("DELETE", "/repos/{owner}/{repo}/autolinks/{autolinkId}")]
		public Task Delete(string owner, string repo, int autolinkId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repo, "repo");
			return base.ApiConnection.Delete(ApiUrls.AutolinksDelete(owner, repo, autolinkId));
		}
	}
	public class BlobsClient : ApiClient, IBlobsClient
	{
		public BlobsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/git/blobs/{file_sha}")]
		public Task<Blob> Get(string owner, string name, string reference)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			return base.ApiConnection.Get<Blob>(ApiUrls.Blob(owner, name, reference));
		}

		[ManualRoute("GET", "/repositories/{id}/git/blobs/{file_sha}")]
		public Task<Blob> Get(long repositoryId, string reference)
		{
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			return base.ApiConnection.Get<Blob>(ApiUrls.Blob(repositoryId, reference));
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/git/blobs")]
		public Task<BlobReference> Create(string owner, string name, NewBlob newBlob)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(newBlob, "newBlob");
			return base.ApiConnection.Post<BlobReference>(ApiUrls.Blobs(owner, name), newBlob);
		}

		[ManualRoute("POST", "/repositories/{id}/git/blobs")]
		public Task<BlobReference> Create(long repositoryId, NewBlob newBlob)
		{
			Ensure.ArgumentNotNull(newBlob, "newBlob");
			return base.ApiConnection.Post<BlobReference>(ApiUrls.Blobs(repositoryId), newBlob);
		}
	}
	public class CheckRunsClient : ApiClient, ICheckRunsClient
	{
		public CheckRunsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/check-runs")]
		public Task<CheckRun> Create(string owner, string name, NewCheckRun newCheckRun)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(newCheckRun, "newCheckRun");
			return base.ApiConnection.Post<CheckRun>(ApiUrls.CheckRuns(owner, name), newCheckRun);
		}

		[ManualRoute("POST", "/repositories/{id}/check-runs")]
		public Task<CheckRun> Create(long repositoryId, NewCheckRun newCheckRun)
		{
			Ensure.ArgumentNotNull(newCheckRun, "newCheckRun");
			return base.ApiConnection.Post<CheckRun>(ApiUrls.CheckRuns(repositoryId), newCheckRun);
		}

		[ManualRoute("PATCH", "/repos/{owner}/{repo}/check-runs/{check_run_id}")]
		public Task<CheckRun> Update(string owner, string name, long checkRunId, CheckRunUpdate checkRunUpdate)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(checkRunUpdate, "checkRunUpdate");
			return base.ApiConnection.Patch<CheckRun>(ApiUrls.CheckRun(owner, name, checkRunId), checkRunUpdate);
		}

		[ManualRoute("PATCH", "/repositories/{id}/check-runs/{check_run_id}")]
		public Task<CheckRun> Update(long repositoryId, long checkRunId, CheckRunUpdate checkRunUpdate)
		{
			Ensure.ArgumentNotNull(checkRunUpdate, "checkRunUpdate");
			return base.ApiConnection.Patch<CheckRun>(ApiUrls.CheckRun(repositoryId, checkRunId), checkRunUpdate);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/commits/{commit_sha}/check-runs")]
		public Task<CheckRunsResponse> GetAllForReference(string owner, string name, string reference)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			return GetAllForReference(owner, name, reference, new CheckRunRequest(), ApiOptions.None);
		}

		[ManualRoute("GET", "/repositories/{id}/commits/{commit_sha}/check-runs")]
		public Task<CheckRunsResponse> GetAllForReference(long repositoryId, string reference)
		{
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			return GetAllForReference(repositoryId, reference, new CheckRunRequest(), ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/commits/{commit_sha}/check-runs")]
		public Task<CheckRunsResponse> GetAllForReference(string owner, string name, string reference, CheckRunRequest checkRunRequest)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			Ensure.ArgumentNotNull(checkRunRequest, "checkRunRequest");
			return GetAllForReference(owner, name, reference, checkRunRequest, ApiOptions.None);
		}

		[ManualRoute("GET", "/repositories/{id}/commits/{commit_sha}/check-runs")]
		public Task<CheckRunsResponse> GetAllForReference(long repositoryId, string reference, CheckRunRequest checkRunRequest)
		{
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			Ensure.ArgumentNotNull(checkRunRequest, "checkRunRequest");
			return GetAllForReference(repositoryId, reference, checkRunRequest, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/commits/{commit_sha}/check-runs")]
		public async Task<CheckRunsResponse> GetAllForReference(string owner, string name, string reference, CheckRunRequest checkRunRequest, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			Ensure.ArgumentNotNull(checkRunRequest, "checkRunRequest");
			Ensure.ArgumentNotNull(options, "options");
			IReadOnlyList<CheckRunsResponse> readOnlyList = await base.ApiConnection.GetAll<CheckRunsResponse>(ApiUrls.CheckRunsForReference(owner, name, reference), checkRunRequest.ToParametersDictionary(), options).ConfigureAwait(continueOnCapturedContext: false);
			return new CheckRunsResponse((readOnlyList.Count > 0) ? readOnlyList.Max((CheckRunsResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((CheckRunsResponse x) => x.CheckRuns).ToList());
		}

		[ManualRoute("GET", "/repositories/{id}/commits/{commit_sha}/check-runs")]
		public async Task<CheckRunsResponse> GetAllForReference(long repositoryId, string reference, CheckRunRequest checkRunRequest, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			Ensure.ArgumentNotNull(checkRunRequest, "checkRunRequest");
			Ensure.ArgumentNotNull(options, "options");
			IReadOnlyList<CheckRunsResponse> readOnlyList = await base.ApiConnection.GetAll<CheckRunsResponse>(ApiUrls.CheckRunsForReference(repositoryId, reference), checkRunRequest.ToParametersDictionary(), options).ConfigureAwait(continueOnCapturedContext: false);
			return new CheckRunsResponse((readOnlyList.Count > 0) ? readOnlyList.Max((CheckRunsResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((CheckRunsResponse x) => x.CheckRuns).ToList());
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/check-suite/{check_suite_id}/check-runs")]
		public Task<CheckRunsResponse> GetAllForCheckSuite(string owner, string name, long checkSuiteId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return GetAllForCheckSuite(owner, name, checkSuiteId, new CheckRunRequest(), ApiOptions.None);
		}

		[ManualRoute("GET", "/repositories/{id}/check-suites/{check_suite_id}/check-runs")]
		public Task<CheckRunsResponse> GetAllForCheckSuite(long repositoryId, long checkSuiteId)
		{
			return GetAllForCheckSuite(repositoryId, checkSuiteId, new CheckRunRequest(), ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/check-suite/{check_suite_id}/check-runs")]
		public Task<CheckRunsResponse> GetAllForCheckSuite(string owner, string name, long checkSuiteId, CheckRunRequest checkRunRequest)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(checkRunRequest, "checkRunRequest");
			return GetAllForCheckSuite(owner, name, checkSuiteId, checkRunRequest, ApiOptions.None);
		}

		[ManualRoute("GET", "/repositories/{id}/check-suites/{check_suite_id}/check-runs")]
		public Task<CheckRunsResponse> GetAllForCheckSuite(long repositoryId, long checkSuiteId, CheckRunRequest checkRunRequest)
		{
			Ensure.ArgumentNotNull(checkRunRequest, "checkRunRequest");
			return GetAllForCheckSuite(repositoryId, checkSuiteId, checkRunRequest, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/check-suite/{check_suite_id}/check-runs")]
		public async Task<CheckRunsResponse> GetAllForCheckSuite(string owner, string name, long checkSuiteId, CheckRunRequest checkRunRequest, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(checkRunRequest, "checkRunRequest");
			Ensure.ArgumentNotNull(options, "options");
			IReadOnlyList<CheckRunsResponse> readOnlyList = await base.ApiConnection.GetAll<CheckRunsResponse>(ApiUrls.CheckRunsForCheckSuite(owner, name, checkSuiteId), checkRunRequest.ToParametersDictionary(), options).ConfigureAwait(continueOnCapturedContext: false);
			return new CheckRunsResponse((readOnlyList.Count > 0) ? readOnlyList.Max((CheckRunsResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((CheckRunsResponse x) => x.CheckRuns).ToList());
		}

		[ManualRoute("GET", "/repositories/{id}/check-suites/{check_suite_id}/check-runs")]
		public async Task<CheckRunsResponse> GetAllForCheckSuite(long repositoryId, long checkSuiteId, CheckRunRequest checkRunRequest, ApiOptions options)
		{
			Ensure.ArgumentNotNull(checkRunRequest, "checkRunRequest");
			Ensure.ArgumentNotNull(options, "options");
			IReadOnlyList<CheckRunsResponse> readOnlyList = await base.ApiConnection.GetAll<CheckRunsResponse>(ApiUrls.CheckRunsForCheckSuite(repositoryId, checkSuiteId), checkRunRequest.ToParametersDictionary(), options).ConfigureAwait(continueOnCapturedContext: false);
			return new CheckRunsResponse((readOnlyList.Count > 0) ? readOnlyList.Max((CheckRunsResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((CheckRunsResponse x) => x.CheckRuns).ToList());
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/check-runs/{check_run_id}")]
		public Task<CheckRun> Get(string owner, string name, long checkRunId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Get<CheckRun>(ApiUrls.CheckRun(owner, name, checkRunId), null);
		}

		[ManualRoute("GET", "/repositories/{id}/check-runs/{check_run_id}")]
		public Task<CheckRun> Get(long repositoryId, long checkRunId)
		{
			return base.ApiConnection.Get<CheckRun>(ApiUrls.CheckRun(repositoryId, checkRunId), null);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/check-runs/{check_run_id}/annotations")]
		public Task<IReadOnlyList<CheckRunAnnotation>> GetAllAnnotations(string owner, string name, long checkRunId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return GetAllAnnotations(owner, name, checkRunId, ApiOptions.None);
		}

		[ManualRoute("GET", "/repositories/{id}/check-runs/{check_run_id}/annotations")]
		public Task<IReadOnlyList<CheckRunAnnotation>> GetAllAnnotations(long repositoryId, long checkRunId)
		{
			return GetAllAnnotations(repositoryId, checkRunId, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/check-runs/{check_run_id}/annotations")]
		public Task<IReadOnlyList<CheckRunAnnotation>> GetAllAnnotations(string owner, string name, long checkRunId, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(options, "options");
			return base.ApiConnection.GetAll<CheckRunAnnotation>(ApiUrls.CheckRunAnnotations(owner, name, checkRunId), null, options);
		}

		[ManualRoute("GET", "/repositories/{id}/check-runs/{check_run_id}/annotations")]
		public Task<IReadOnlyList<CheckRunAnnotation>> GetAllAnnotations(long repositoryId, long checkRunId, ApiOptions options)
		{
			Ensure.ArgumentNotNull(options, "options");
			return base.ApiConnection.GetAll<CheckRunAnnotation>(ApiUrls.CheckRunAnnotations(repositoryId, checkRunId), null, options);
		}
	}
	public class ChecksClient : IChecksClient
	{
		public ICheckRunsClient Run { get; private set; }

		public ICheckSuitesClient Suite { get; private set; }

		public ChecksClient(IApiConnection apiConnection)
		{
			Run = new CheckRunsClient(apiConnection);
			Suite = new CheckSuitesClient(apiConnection);
		}
	}
	public class CheckSuitesClient : ApiClient, ICheckSuitesClient
	{
		public CheckSuitesClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/check-suites/{id}")]
		public Task<CheckSuite> Get(string owner, string repoName, long checkSuiteId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repoName, "repoName");
			return base.ApiConnection.Get<CheckSuite>(ApiUrls.CheckSuite(owner, repoName, checkSuiteId), null);
		}

		[ManualRoute("GET", "/repositories/{id}/check-suites/{check_suite_id}")]
		public Task<CheckSuite> Get(long repositoryId, long checkSuiteId)
		{
			return base.ApiConnection.Get<CheckSuite>(ApiUrls.CheckSuite(repositoryId, checkSuiteId), null);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/commits/{ref}/check-suites")]
		public Task<CheckSuitesResponse> GetAllForReference(string owner, string repoName, string reference)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repoName, "repoName");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			return GetAllForReference(owner, repoName, reference, new CheckSuiteRequest(), ApiOptions.None);
		}

		[ManualRoute("GET", "/repositories/{id}/commits/{ref}/check-suites")]
		public Task<CheckSuitesResponse> GetAllForReference(long repositoryId, string reference)
		{
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			return GetAllForReference(repositoryId, reference, new CheckSuiteRequest(), ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/commits/{ref}/check-suites")]
		public Task<CheckSuitesResponse> GetAllForReference(string owner, string repoName, string reference, CheckSuiteRequest request)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repoName, "repoName");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			Ensure.ArgumentNotNull(request, "request");
			return GetAllForReference(owner, repoName, reference, request, ApiOptions.None);
		}

		[ManualRoute("GET", "/repositories/{id}/commits/{ref}/check-suites")]
		public Task<CheckSuitesResponse> GetAllForReference(long repositoryId, string reference, CheckSuiteRequest request)
		{
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			Ensure.ArgumentNotNull(request, "request");
			return GetAllForReference(repositoryId, reference, request, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/commits/{ref}/check-suites")]
		public async Task<CheckSuitesResponse> GetAllForReference(string owner, string repoName, string reference, CheckSuiteRequest request, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repoName, "repoName");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			Ensure.ArgumentNotNull(request, "request");
			Ensure.ArgumentNotNull(options, "options");
			IReadOnlyList<CheckSuitesResponse> readOnlyList = await base.ApiConnection.GetAll<CheckSuitesResponse>(ApiUrls.CheckSuitesForReference(owner, repoName, reference), request.ToParametersDictionary(), options).ConfigureAwait(continueOnCapturedContext: false);
			return new CheckSuitesResponse((readOnlyList.Count > 0) ? readOnlyList.Max((CheckSuitesResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((CheckSuitesResponse x) => x.CheckSuites).ToList());
		}

		[ManualRoute("GET", "/repositories/{id}/commits/{ref}/check-suites")]
		public async Task<CheckSuitesResponse> GetAllForReference(long repositoryId, string reference, CheckSuiteRequest request, ApiOptions options)
		{
			Ensure.ArgumentNotNull(request, "request");
			Ensure.ArgumentNotNull(options, "options");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			IReadOnlyList<CheckSuitesResponse> readOnlyList = await base.ApiConnection.GetAll<CheckSuitesResponse>(ApiUrls.CheckSuitesForReference(repositoryId, reference), request.ToParametersDictionary(), options).ConfigureAwait(continueOnCapturedContext: false);
			return new CheckSuitesResponse((readOnlyList.Count > 0) ? readOnlyList.Max((CheckSuitesResponse x) => x.TotalCount) : 0, readOnlyList.SelectMany((CheckSuitesResponse x) => x.CheckSuites).ToList());
		}

		[ManualRoute("PATCH", "/repos/{owner}/{repo}/check-suites/preferences")]
		public Task<CheckSuitePreferencesResponse> UpdatePreferences(string owner, string repoName, CheckSuitePreferences preferences)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repoName, "repoName");
			Ensure.ArgumentNotNull(preferences, "preferences");
			return base.ApiConnection.Patch<CheckSuitePreferencesResponse>(ApiUrls.CheckSuitePreferences(owner, repoName), preferences);
		}

		[ManualRoute("GET", "/repositories/{id}/check-suites/preferences")]
		public Task<CheckSuitePreferencesResponse> UpdatePreferences(long repositoryId, CheckSuitePreferences preferences)
		{
			Ensure.ArgumentNotNull(preferences, "preferences");
			return base.ApiConnection.Patch<CheckSuitePreferencesResponse>(ApiUrls.CheckSuitePreferences(repositoryId), preferences);
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/check-suites")]
		public Task<CheckSuite> Create(string owner, string repoName, NewCheckSuite newCheckSuite)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repoName, "repoName");
			Ensure.ArgumentNotNull(newCheckSuite, "newCheckSuite");
			return base.ApiConnection.Post<CheckSuite>(ApiUrls.CheckSuites(owner, repoName), newCheckSuite);
		}

		[ManualRoute("GET", "/repositories/{id}/check-suites")]
		public Task<CheckSuite> Create(long repositoryId, NewCheckSuite newCheckSuite)
		{
			Ensure.ArgumentNotNull(newCheckSuite, "newCheckSuite");
			return base.ApiConnection.Post<CheckSuite>(ApiUrls.CheckSuites(repositoryId), newCheckSuite);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/check-suites/{2}/rerequest")]
		public async Task<bool> Rerequest(string owner, string repoName, long checkSuiteId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repoName, "repoName");
			HttpStatusCode httpStatusCode = await base.Connection.Post(ApiUrls.CheckSuiteRerequest(owner, repoName, checkSuiteId)).ConfigureAwait(continueOnCapturedContext: false);
			if (httpStatusCode != HttpStatusCode.Created)
			{
				throw new ApiException("Invalid Status Code returned. Expected a 201", httpStatusCode);
			}
			return httpStatusCode == HttpStatusCode.Created;
		}

		[ManualRoute("GET", "/repositories/{id}/check-suites/{2}/rerequest")]
		public async Task<bool> Rerequest(long repositoryId, long checkSuiteId)
		{
			HttpStatusCode httpStatusCode = await base.Connection.Post(ApiUrls.CheckSuiteRerequest(repositoryId, checkSuiteId)).ConfigureAwait(continueOnCapturedContext: false);
			if (httpStatusCode != HttpStatusCode.Created)
			{
				throw new ApiException("Invalid Status Code returned. Expected a 201", httpStatusCode);
			}
			return httpStatusCode == HttpStatusCode.Created;
		}
	}
	[DebuggerDisplay("{DebuggerDisplay,nq}")]
	public class Codespace
	{
		public long Id { get; private set; }

		public string Name { get; private set; }

		public User Owner { get; private set; }

		public User BillableOwner { get; private set; }

		public Repository Repository { get; private set; }

		public Machine Machine { get; private set; }

		public DateTime CreatedAt { get; private set; }

		public DateTime UpdatedAt { get; private set; }

		public DateTime LastUsedAt { get; private set; }

		public StringEnum<CodespaceState> State { get; private set; }

		public string Url { get; private set; }

		public string MachinesUrl { get; private set; }

		public string WebUrl { get; private set; }

		public string StartUrl { get; private set; }

		public string StopUrl { get; private set; }

		public StringEnum<CodespaceLocation> Location { get; private set; }

		internal string DebuggerDisplay => string.Format(CultureInfo.CurrentCulture, "Codespace: Id: {0}", Id);

		public Codespace(long id, string name, User owner, User billableOwner, Repository repository, Machine machine, DateTime createdAt, DateTime updatedAt, DateTime lastUsedAt, StringEnum<CodespaceState> state, string url, string machinesUrl, string webUrl, string startUrl, string stopUrl, StringEnum<CodespaceLocation> location)
		{
			Id = id;
			Name = name;
			Owner = owner;
			BillableOwner = billableOwner;
			Repository = repository;
			Machine = machine;
			CreatedAt = createdAt;
			UpdatedAt = updatedAt;
			LastUsedAt = lastUsedAt;
			State = state;
			Url = url;
			MachinesUrl = machinesUrl;
			WebUrl = webUrl;
			StartUrl = startUrl;
			StopUrl = stopUrl;
			Location = location;
		}

		public Codespace()
		{
		}
	}
	public class CodespacesClient : ApiClient, ICodespacesClient
	{
		public CodespacesClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/user/codespaces")]
		public Task<CodespacesCollection> GetAll()
		{
			return base.ApiConnection.Get<CodespacesCollection>(ApiUrls.Codespaces());
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/codespaces")]
		public Task<CodespacesCollection> GetForRepository(string owner, string repo)
		{
			return base.ApiConnection.Get<CodespacesCollection>(ApiUrls.CodespacesForRepository(owner, repo));
		}

		[ManualRoute("GET", "/user/codespaces/{codespace_name}")]
		public Task<Codespace> Get(string codespaceName)
		{
			return base.ApiConnection.Get<Codespace>(ApiUrls.Codespace(codespaceName));
		}

		[ManualRoute("POST", "/user/codespaces/{codespace_name}/start")]
		public Task<Codespace> Start(string codespaceName)
		{
			return base.ApiConnection.Post<Codespace>(ApiUrls.CodespaceStart(codespaceName));
		}

		[ManualRoute("POST", "/user/codespaces/{codespace_name}/stop")]
		public Task<Codespace> Stop(string codespaceName)
		{
			return base.ApiConnection.Post<Codespace>(ApiUrls.CodespaceStop(codespaceName));
		}

		[ManualRoute("GET", "/repos/{repoOwner}/{repoName}/machines")]
		public Task<MachinesCollection> GetAvailableMachinesForRepo(string repoOwner, string repoName, string reference = null)
		{
			Ensure.ArgumentNotNullOrEmptyString(repoOwner, "repoOwner");
			Ensure.ArgumentNotNullOrEmptyString(repoName, "repoName");
			return base.ApiConnection.Get<MachinesCollection>(ApiUrls.GetAvailableMachinesForRepo(repoOwner, repoName, reference));
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/codespaces")]
		public Task<Codespace> Create(string owner, string repo, NewCodespace newCodespace)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(repo, "repo");
			return base.ApiConnection.Post<Codespace>(ApiUrls.CreateCodespace(owner, repo), newCodespace);
		}
	}
	[DebuggerDisplay("{DebuggerDisplay,nq}")]
	public class CodespacesCollection
	{
		[Parameter(Key = "total_count")]
		public int Count { get; private set; }

		[Parameter(Key = "codespaces")]
		public IReadOnlyList<Codespace> Codespaces { get; private set; } = new List<Codespace>();


		internal string DebuggerDisplay => string.Format(CultureInfo.CurrentCulture, "CodespacesCollection: Count: {0}", Count);

		public CodespacesCollection(IReadOnlyList<Codespace> codespaces, int count)
		{
			Codespaces = codespaces;
			Count = count;
		}

		public CodespacesCollection()
		{
		}
	}
	public enum CodespaceState
	{
		[Parameter(Value = "Unknown")]
		Unknown,
		[Parameter(Value = "Created")]
		Created,
		[Parameter(Value = "Queued")]
		Queued,
		[Parameter(Value = "Provisioning")]
		Provisioning,
		[Parameter(Value = "Available")]
		Available,
		[Parameter(Value = "Awaiting")]
		Awaiting,
		[Parameter(Value = "Unavailable")]
		Unavailable,
		[Parameter(Value = "Deleted")]
		Deleted,
		[Parameter(Value = "Moved")]
		Moved,
		[Parameter(Value = "Shutdown")]
		Shutdown,
		[Parameter(Value = "Archived")]
		Archived,
		[Parameter(Value = "Starting")]
		Starting,
		[Parameter(Value = "ShuttingDown")]
		ShuttingDown,
		[Parameter(Value = "Failed")]
		Failed,
		[Parameter(Value = "Exporting")]
		Exporting,
		[Parameter(Value = "Updating")]
		Updating,
		[Parameter(Value = "Rebuilding")]
		Rebuilding
	}
	public class CommitCommentReactionsClient : ApiClient, ICommitCommentReactionsClient
	{
		public CommitCommentReactionsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/comments/{comment_id}/reactions")]
		public Task<Reaction> Create(string owner, string name, long commentId, NewReaction reaction)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(reaction, "reaction");
			return base.ApiConnection.Post<Reaction>(ApiUrls.CommitCommentReactions(owner, name, commentId), reaction);
		}

		[ManualRoute("POST", "/repositories/{id}/comments/{comment_id}/reactions")]
		public Task<Reaction> Create(long repositoryId, long commentId, NewReaction reaction)
		{
			Ensure.ArgumentNotNull(reaction, "reaction");
			return base.ApiConnection.Post<Reaction>(ApiUrls.CommitCommentReactions(repositoryId, commentId), reaction);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/comments/{comment_id}/reactions")]
		public Task<IReadOnlyList<Reaction>> GetAll(string owner, string name, long commentId)
		{
			return GetAll(owner, name, commentId, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/comments/{comment_id}/reactions")]
		public Task<IReadOnlyList<Reaction>> GetAll(string owner, string name, long commentId, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(options, "options");
			return base.ApiConnection.GetAll<Reaction>(ApiUrls.CommitCommentReactions(owner, name, commentId), null, options);
		}

		[ManualRoute("GET", "/repositories/{id}/comments/{comment_id}/reactions")]
		public Task<IReadOnlyList<Reaction>> GetAll(long repositoryId, long commentId)
		{
			return GetAll(repositoryId, commentId, ApiOptions.None);
		}

		[ManualRoute("GET", "/repositories/{id}/comments/{comment_id}/reactions")]
		public Task<IReadOnlyList<Reaction>> GetAll(long repositoryId, long commentId, ApiOptions options)
		{
			Ensure.ArgumentNotNull(options, "options");
			return base.ApiConnection.GetAll<Reaction>(ApiUrls.CommitCommentReactions(repositoryId, commentId), null, options);
		}

		[ManualRoute("DELETE", "/repos/{owner}/{repo}/comments/{comment_id}/reactions/{reaction_id}")]
		public Task Delete(string owner, string name, long commentId, long reactionId)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return base.ApiConnection.Delete(ApiUrls.CommitCommentReaction(owner, name, commentId, reactionId));
		}

		[ManualRoute("DELETE", "/repositories/{id}/comments/{comment_id}/reactions/{reaction_id}")]
		public Task Delete(long repositoryId, long commentId, long reactionId)
		{
			return base.ApiConnection.Delete(ApiUrls.CommitCommentReaction(repositoryId, commentId, reactionId));
		}
	}
	public class CommitsClient : ApiClient, ICommitsClient
	{
		public CommitsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/git/commits/{commit_sha}")]
		public Task<Commit> Get(string owner, string name, string reference)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			return base.ApiConnection.Get<Commit>(ApiUrls.Commit(owner, name, reference));
		}

		[ManualRoute("GET", "/repositories/{id}/git/commits/{commit_sha}")]
		public Task<Commit> Get(long repositoryId, string reference)
		{
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			return base.ApiConnection.Get<Commit>(ApiUrls.Commit(repositoryId, reference));
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/git/commits")]
		public Task<Commit> Create(string owner, string name, NewCommit commit)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(commit, "commit");
			return base.ApiConnection.Post<Commit>(ApiUrls.CreateCommit(owner, name), commit);
		}

		[ManualRoute("POST", "/repositories/{id}/git/commits")]
		public Task<Commit> Create(long repositoryId, NewCommit commit)
		{
			Ensure.ArgumentNotNull(commit, "commit");
			return base.ApiConnection.Post<Commit>(ApiUrls.CreateCommit(repositoryId), commit);
		}
	}
	public class CommitStatusClient : ApiClient, ICommitStatusClient
	{
		public CommitStatusClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/commits/{ref}/statuses")]
		public Task<IReadOnlyList<CommitStatus>> GetAll(string owner, string name, string reference)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			return GetAll(owner, name, reference, ApiOptions.None);
		}

		[ManualRoute("GET", "/repositories/{id}/commits/{ref}/statuses")]
		public Task<IReadOnlyList<CommitStatus>> GetAll(long repositoryId, string reference)
		{
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			return GetAll(repositoryId, reference, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/commits/{ref}/statuses")]
		public Task<IReadOnlyList<CommitStatus>> GetAll(string owner, string name, string reference, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			Ensure.ArgumentNotNull(options, "options");
			return base.ApiConnection.GetAll<CommitStatus>(ApiUrls.CommitStatuses(owner, name, reference), options);
		}

		[ManualRoute("GET", "/repositories/{id}/commits/{ref}/statuses")]
		public Task<IReadOnlyList<CommitStatus>> GetAll(long repositoryId, string reference, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			Ensure.ArgumentNotNull(options, "options");
			return base.ApiConnection.GetAll<CommitStatus>(ApiUrls.CommitStatuses(repositoryId, reference), options);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/commits/{ref}/status")]
		public Task<CombinedCommitStatus> GetCombined(string owner, string name, string reference)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			return base.ApiConnection.Get<CombinedCommitStatus>(ApiUrls.CombinedCommitStatus(owner, name, reference));
		}

		[ManualRoute("GET", "/repositories/{id}/commits/{ref}/status")]
		public Task<CombinedCommitStatus> GetCombined(long repositoryId, string reference)
		{
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			return base.ApiConnection.Get<CombinedCommitStatus>(ApiUrls.CombinedCommitStatus(repositoryId, reference));
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/statuses/{sha}")]
		public Task<CommitStatus> Create(string owner, string name, string reference, NewCommitStatus newCommitStatus)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			Ensure.ArgumentNotNull(newCommitStatus, "newCommitStatus");
			return base.ApiConnection.Post<CommitStatus>(ApiUrls.CreateCommitStatus(owner, name, reference), newCommitStatus);
		}

		[ManualRoute("POST", "/repositories/{id}/statuses/{sha}")]
		public Task<CommitStatus> Create(long repositoryId, string reference, NewCommitStatus newCommitStatus)
		{
			Ensure.ArgumentNotNullOrEmptyString(reference, "reference");
			Ensure.ArgumentNotNull(newCommitStatus, "newCommitStatus");
			return base.ApiConnection.Post<CommitStatus>(ApiUrls.CreateCommitStatus(repositoryId, reference), newCommitStatus);
		}
	}
	public class CopilotClient : ApiClient, ICopilotClient
	{
		public ICopilotLicenseClient Licensing { get; private set; }

		public CopilotClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
			Licensing = new CopilotLicenseClient(apiConnection);
		}

		[ManualRoute("GET", "/orgs/{org}/copilot/billing")]
		public async Task<BillingSettings> GetSummaryForOrganization(string organization)
		{
			Ensure.ArgumentNotNull(organization, "organization");
			return await base.ApiConnection.Get<BillingSettings>(ApiUrls.CopilotBillingSettings(organization));
		}
	}
	public interface ICopilotClient
	{
		ICopilotLicenseClient Licensing { get; }

		Task<BillingSettings> GetSummaryForOrganization(string organization);
	}
	public interface ICopilotLicenseClient
	{
		Task<CopilotSeatAllocation> Remove(string organization, string userName);

		Task<CopilotSeatAllocation> Remove(string organization, UserSeatAllocation userSeatAllocation);

		Task<CopilotSeatAllocation> Assign(string organization, string userName);

		Task<CopilotSeatAllocation> Assign(string organization, UserSeatAllocation userSeatAllocation);

		Task<IReadOnlyList<CopilotSeats>> GetAll(string organization, ApiOptions options);
	}
	public class DependencyGraphClient : IDependencyGraphClient
	{
		public IDependencyReviewClient DependencyReview { get; private set; }

		public IDependencySubmissionClient DependencySubmission { get; private set; }

		public DependencyGraphClient(IApiConnection apiConnection)
		{
			DependencyReview = new DependencyReviewClient(apiConnection);
			DependencySubmission = new DependencySubmissionClient(apiConnection);
		}
	}
	public class DependencyReviewClient : ApiClient, IDependencyReviewClient
	{
		public DependencyReviewClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/dependency-graph/compare/{base}...{head}")]
		public Task<IReadOnlyList<DependencyDiff>> GetAll(string owner, string name, string @base, string head)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNullOrEmptyString(@base, "base");
			Ensure.ArgumentNotNullOrEmptyString(head, "head");
			return base.ApiConnection.GetAll<DependencyDiff>(ApiUrls.DependencyReview(owner, name, @base, head));
		}

		[ManualRoute("GET", "/repositories/{id}/dependency-graph/compare/{base}...{head}")]
		public Task<IReadOnlyList<DependencyDiff>> GetAll(long repositoryId, string @base, string head)
		{
			Ensure.ArgumentNotNullOrEmptyString(@base, "base");
			Ensure.ArgumentNotNullOrEmptyString(head, "head");
			return base.ApiConnection.GetAll<DependencyDiff>(ApiUrls.DependencyReview(repositoryId, @base, head));
		}
	}
	public class DependencySubmissionClient : ApiClient, IDependencySubmissionClient
	{
		public DependencySubmissionClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/dependency-graph/snapshots")]
		public Task<DependencySnapshotSubmission> Create(string owner, string name, NewDependencySnapshot snapshot)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(snapshot, "snapshot");
			JsonObject data = ConvertToJsonObject(snapshot);
			return base.ApiConnection.Post<DependencySnapshotSubmission>(ApiUrls.DependencySubmission(owner, name), data);
		}

		[ManualRoute("POST", "/repositories/{id}/dependency-graph/snapshots")]
		public Task<DependencySnapshotSubmission> Create(long repositoryId, NewDependencySnapshot snapshot)
		{
			Ensure.ArgumentNotNull(snapshot, "snapshot");
			JsonObject data = ConvertToJsonObject(snapshot);
			return base.ApiConnection.Post<DependencySnapshotSubmission>(ApiUrls.DependencySubmission(repositoryId), data);
		}

		private JsonObject ConvertToJsonObject(NewDependencySnapshot snapshot)
		{
			JsonObject jsonObject = new JsonObject();
			jsonObject.Add("version", snapshot.Version);
			jsonObject.Add("sha", snapshot.Sha);
			jsonObject.Add("ref", snapshot.Ref);
			jsonObject.Add("scanned", snapshot.Scanned);
			jsonObject.Add("job", snapshot.Job);
			jsonObject.Add("detector", snapshot.Detector);
			if (snapshot.Metadata != null)
			{
				JsonObject jsonObject2 = new JsonObject();
				foreach (KeyValuePair<string, object> metadatum in snapshot.Metadata)
				{
					jsonObject2.Add(metadatum.Key, metadatum.Value);
				}
				jsonObject.Add("metadata", jsonObject2);
			}
			if (snapshot.Manifests != null)
			{
				JsonObject jsonObject3 = new JsonObject();
				foreach (KeyValuePair<string, NewDependencySnapshotManifest> manifest in snapshot.Manifests)
				{
					NewDependencySnapshotManifest value = manifest.Value;
					JsonObject jsonObject4 = new JsonObject();
					jsonObject4.Add("name", value.Name);
					if (value.File.SourceLocation != null)
					{
						var value2 = new { value.File.SourceLocation };
						jsonObject4.Add("file", value2);
					}
					if (value.Metadata != null)
					{
						jsonObject4.Add("metadata", value.Metadata);
					}
					if (value.Resolved != null)
					{
						JsonObject jsonObject5 = new JsonObject();
						foreach (KeyValuePair<string, NewDependencySnapshotResolvedDependency> item in value.Resolved)
						{
							jsonObject5.Add(item.Key, item.Value);
						}
						jsonObject4.Add("resolved", jsonObject5);
					}
					jsonObject3.Add(manifest.Key, jsonObject4);
				}
				jsonObject.Add("manifests", jsonObject3);
			}
			return jsonObject;
		}
	}
	public class DeploymentEnvironmentsClient : ApiClient, IRepositoryDeployEnvironmentsClient
	{
		public DeploymentEnvironmentsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/environments")]
		public Task<DeploymentEnvironmentsResponse> GetAll(string owner, string name)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return GetAll(owner, name, ApiOptions.None);
		}

		[ManualRoute("GET", "/repositories/{id}/environments")]
		public Task<DeploymentEnvironmentsResponse> GetAll(long repositoryId)
		{
			return GetAll(repositoryId, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/environments")]
		public Task<DeploymentEnvironmentsResponse> GetAll(string owner, string name, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(options, "options");
			Dictionary<string, string> dictionary = null;
			if (options != ApiOptions.None)
			{
				dictionary = new Dictionary<string, string>();
				dictionary.Add("per_page", options.PageSize.ToString());
				dictionary.Add("page", options.StartPage.ToString());
			}
			if (dictionary != null)
			{
				return base.ApiConnection.Get<DeploymentEnvironmentsResponse>(ApiUrls.DeploymentEnvironments(owner, name), dictionary);
			}
			return base.ApiConnection.Get<DeploymentEnvironmentsResponse>(ApiUrls.DeploymentEnvironments(owner, name));
		}

		[ManualRoute("GET", "/repositories/{id}/environments")]
		public Task<DeploymentEnvironmentsResponse> GetAll(long repositoryId, ApiOptions options)
		{
			Ensure.ArgumentNotNull(options, "options");
			Dictionary<string, string> dictionary = null;
			if (options != ApiOptions.None)
			{
				dictionary = new Dictionary<string, string>();
				dictionary.Add("per_page", options.PageSize.ToString());
				dictionary.Add("page", options.StartPage.ToString());
			}
			if (dictionary != null)
			{
				return base.ApiConnection.Get<DeploymentEnvironmentsResponse>(ApiUrls.DeploymentEnvironments(repositoryId), dictionary);
			}
			return base.ApiConnection.Get<DeploymentEnvironmentsResponse>(ApiUrls.DeploymentEnvironments(repositoryId));
		}
	}
	public class DeploymentsClient : ApiClient, IDeploymentsClient
	{
		public IDeploymentStatusClient Status { get; set; }

		public DeploymentsClient(IApiConnection apiConnection)
			: base(apiConnection)
		{
			Status = new DeploymentStatusClient(apiConnection);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/deployments")]
		public Task<IReadOnlyList<Deployment>> GetAll(string owner, string name)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			return GetAll(owner, name, ApiOptions.None);
		}

		[ManualRoute("GET", "/repositories/{id}/deployments")]
		public Task<IReadOnlyList<Deployment>> GetAll(long repositoryId)
		{
			return GetAll(repositoryId, ApiOptions.None);
		}

		[ManualRoute("GET", "/repos/{owner}/{repo}/deployments")]
		public Task<IReadOnlyList<Deployment>> GetAll(string owner, string name, ApiOptions options)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(options, "options");
			return base.ApiConnection.GetAll<Deployment>(ApiUrls.Deployments(owner, name), null, options);
		}

		[ManualRoute("GET", "/repositories/{id}/deployments")]
		public Task<IReadOnlyList<Deployment>> GetAll(long repositoryId, ApiOptions options)
		{
			Ensure.ArgumentNotNull(options, "options");
			return base.ApiConnection.GetAll<Deployment>(ApiUrls.Deployments(repositoryId), options);
		}

		[ManualRoute("POST", "/repos/{owner}/{repo}/deployments")]
		public Task<Deployment> Create(string owner, string name, NewDeployment newDeployment)
		{
			Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
			Ensure.ArgumentNotNullOrEmptyString(name, "name");
			Ensure.ArgumentNotNull(newDeployment, "newDeployment");
			return base.ApiConnection.Post<Deployment>(ApiUrls.Deployments(owner, name), newDeployment);
		}

		[ManualRoute("POST", "/repositories/{id}/deployments")]
		public Task<Deployment> Create(long repositoryId, NewDeployment newDeployment)
		{
			Ensure.ArgumentNotNull(newDeployment, "newDeployment");
			return base.ApiConnection.Post<Deployment>(ApiUrls.Deploy