Decompiled source of Custom Car Mod v1.0.0

Distance.CustomCar.dll

Decompiled 5 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Distance.CustomCar.Data.Car;
using Distance.CustomCar.Data.Errors;
using Distance.CustomCar.Data.Materials;
using Events;
using Events.Car;
using Events.MainMenu;
using HarmonyLib;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Distance.ModTemplate")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Distance.ModTemplate")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7bcb2908-b003-45d9-be68-50cba5217603")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
public static class GameObjectExtensions
{
	public static string FullName(this GameObject obj)
	{
		if (!Object.op_Implicit((Object)(object)obj.transform.parent))
		{
			return ((Object)obj).name;
		}
		return ((Component)obj.transform.parent).gameObject.FullName() + "/" + ((Object)obj).name;
	}
}
namespace Distance.CustomCar
{
	public class Assets
	{
		private string _filePath = null;

		private string RootDirectory { get; }

		private string FileName { get; set; }

		private string FilePath => _filePath ?? Path.Combine(Path.Combine(RootDirectory, "Assets"), FileName);

		public object Bundle { get; private set; }

		private Assets()
		{
		}

		public Assets(string fileName)
		{
			RootDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			FileName = fileName;
			if (!File.Exists(FilePath))
			{
				Mod.Log.LogInfo((object)("Couldn't find requested asset bundle at " + FilePath));
			}
			else
			{
				Bundle = Load();
			}
		}

		public static Assets FromUnsafePath(string filePath)
		{
			if (!File.Exists(filePath))
			{
				Mod.Log.LogInfo((object)("Could not find requested asset bundle at " + filePath));
				return null;
			}
			Assets assets = new Assets
			{
				_filePath = filePath,
				FileName = Path.GetFileName(filePath)
			};
			assets.Bundle = assets.Load();
			if (assets.Bundle == null)
			{
				return null;
			}
			return assets;
		}

		private object Load()
		{
			try
			{
				object result = AssetBundleBridge.LoadFrom(FilePath);
				Mod.Log.LogInfo((object)("Loaded asset bundle " + FilePath));
				return result;
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)ex);
				return null;
			}
		}
	}
	internal static class AssetBundleBridge
	{
		public static Type AssetBundleType => Kernel.FindTypeByFullName("UnityEngine.AssetBundle", "UnityEngine");

		private static MethodInfo LoadFromFile => AssetBundleType.GetMethod("LoadFromFile", new Type[1] { typeof(string) });

		public static object LoadFrom(string path)
		{
			MethodInfo loadFromFile = LoadFromFile;
			object[] parameters = new string[1] { path };
			return loadFromFile.Invoke(null, parameters);
		}
	}
	internal static class Kernel
	{
		internal static Type FindTypeByFullName(string fullName, string assemblyFilter)
		{
			IEnumerable<Assembly> enumerable = from a in AppDomain.CurrentDomain.GetAssemblies()
				where a.GetName().Name.Contains(assemblyFilter)
				select a;
			foreach (Assembly item in enumerable)
			{
				Type type = item.GetTypes().FirstOrDefault((Type t) => t.FullName == fullName);
				if ((object)type == null)
				{
					continue;
				}
				return type;
			}
			Mod.Log.LogInfo((object)("Type " + fullName + " wasn't found in the main AppDomain at this moment."));
			throw new Exception("Type " + fullName + " wasn't found in the main AppDomain at this moment.");
		}
	}
	public class FileSystem
	{
		public string RootDirectory { get; }

		public string VirtualFileSystemRoot => Path.Combine(RootDirectory, "Data");

		public FileSystem()
		{
			RootDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			if (!Directory.Exists(VirtualFileSystemRoot))
			{
				Directory.CreateDirectory(VirtualFileSystemRoot);
			}
		}

		public bool FileExists(string path)
		{
			string path2 = Path.Combine(VirtualFileSystemRoot, path);
			return File.Exists(path2);
		}

		public bool DirectoryExists(string path)
		{
			string path2 = Path.Combine(VirtualFileSystemRoot, path);
			return Directory.Exists(path2);
		}

		public bool PathExists(string path)
		{
			return FileExists(path) || DirectoryExists(path);
		}

		public byte[] ReadAllBytes(string filePath)
		{
			string text = Path.Combine(VirtualFileSystemRoot, filePath);
			if (!File.Exists(text))
			{
				Mod.Log.LogInfo((object)("Couldn't read a file for path '" + text + "'. File does not exist."));
				return null;
			}
			return File.ReadAllBytes(text);
		}

		public FileStream CreateFile(string filePath, bool overwrite = false)
		{
			string text = Path.Combine(VirtualFileSystemRoot, filePath);
			if (File.Exists(text))
			{
				if (!overwrite)
				{
					Mod.Log.LogInfo((object)("Couldn't create a mod VFS file for path '" + text + "'. The file already exists."));
					return null;
				}
				Mod.Log.LogInfo((object)("Couldn't delete a mod VFS file for path '" + text + "'. File does not exist."));
				RemoveFile(filePath);
			}
			try
			{
				return File.Create(text);
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)("Couldn't create a mod VFS file for path '" + text + "'."));
				Mod.Log.LogInfo((object)ex);
				return null;
			}
		}

		public void RemoveFile(string filePath)
		{
			string text = Path.Combine(VirtualFileSystemRoot, filePath);
			if (!File.Exists(text))
			{
				Mod.Log.LogInfo((object)("Couldn't delete a mod VFS file for path '" + text + "'. File does not exist."));
				return;
			}
			try
			{
				File.Delete(text);
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)("Couldn't delete a mod VFS file for path '" + text + "'."));
				Mod.Log.LogInfo((object)ex);
			}
		}

		public void IterateOver(string directoryPath, Action<string, bool> action, bool sort = true)
		{
			string text = Path.Combine(VirtualFileSystemRoot, directoryPath);
			if (!Directory.Exists(text))
			{
				Mod.Log.LogInfo((object)("Cannot iterate over directory at '" + text + "'. It doesn't exist."));
				return;
			}
			List<string> list = Directory.GetFiles(text).ToList();
			list.AddRange(Directory.GetDirectories(text));
			if (sort)
			{
				list = list.OrderBy((string x) => x).ToList();
			}
			foreach (string item in list)
			{
				try
				{
					bool arg = Directory.Exists(item);
					action(item, arg);
				}
				catch (Exception ex)
				{
					Mod.Log.LogInfo((object)("Action for the element at path '" + item + "' failed. See file system exception log for details."));
					Mod.Log.LogInfo((object)ex);
					break;
				}
			}
		}

		public List<string> GetDirectories(string directoryPath, string searchPattern)
		{
			string text = Path.Combine(VirtualFileSystemRoot, directoryPath);
			if (!Directory.Exists(text))
			{
				Mod.Log.LogInfo((object)("Cannot get directories in directory at '" + text + "'. It doesn't exist."));
				return null;
			}
			return Directory.GetDirectories(text, searchPattern).ToList();
		}

		public List<string> GetDirectories(string directoryPath)
		{
			return GetDirectories(directoryPath, "*");
		}

		public List<string> GetFiles(string directoryPath, string searchPattern)
		{
			string text = Path.Combine(VirtualFileSystemRoot, directoryPath);
			if (!Directory.Exists(text))
			{
				Mod.Log.LogInfo((object)("Cannot get files in directory at '" + text + "'. It doesn't exist."));
				return null;
			}
			return Directory.GetFiles(text, searchPattern).ToList();
		}

		public List<string> GetFiles(string directoryPath)
		{
			return GetFiles(directoryPath, "*");
		}

		public FileStream OpenFile(string filePath, FileMode fileMode, FileAccess fileAccess, FileShare fileShare)
		{
			string text = Path.Combine(VirtualFileSystemRoot, filePath);
			if (!File.Exists(text))
			{
				Mod.Log.LogInfo((object)("Couldn't open a VFS file. The requested file: '" + text + "' does not exist."));
				return null;
			}
			try
			{
				return File.Open(text, fileMode, fileAccess, fileShare);
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)("Couldn't open a VFS file for path '" + text + "'."));
				Mod.Log.LogInfo((object)ex);
				return null;
			}
		}

		public FileStream OpenFile(string filePath)
		{
			return OpenFile(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
		}

		public string CreateDirectory(string directoryName)
		{
			string text = Path.Combine(VirtualFileSystemRoot, directoryName);
			try
			{
				Directory.CreateDirectory(text);
				return text;
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)("Couldn't create a VFS directory for path '" + text + "'."));
				Mod.Log.LogInfo((object)ex);
				return string.Empty;
			}
		}

		public void RemoveDirectory(string directoryPath)
		{
			string text = Path.Combine(VirtualFileSystemRoot, directoryPath);
			if (!Directory.Exists(text))
			{
				Mod.Log.LogInfo((object)("Couldn't remove a VFS directory for path '" + text + "'. Directory does not exist."));
				return;
			}
			try
			{
				Directory.Delete(text, recursive: true);
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)("Couldn't remove a VFS directory for path '" + text + "'."));
				Mod.Log.LogInfo((object)ex);
			}
		}

		public static string GetValidFileName(string dirtyFileName, string replaceInvalidCharsWith = "_")
		{
			return Regex.Replace(dirtyFileName, "[^\\w\\s\\.]", replaceInvalidCharsWith, RegexOptions.None);
		}

		public static string GetValidFileNameToLower(string dirtyFileName, string replaceInvalidCharsWith = "_")
		{
			return GetValidFileName(dirtyFileName, replaceInvalidCharsWith).ToLower();
		}
	}
	public sealed class MessageBox
	{
		private readonly string Message = "";

		private readonly string Title = "";

		private float Time = 0f;

		private ButtonType Buttons = (ButtonType)0;

		private Action Confirm;

		private Action Cancel;

		private MessageBox(string message, string title)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Message = message;
			Title = title;
			Confirm = EmptyAction;
			Cancel = EmptyAction;
		}

		public static MessageBox Create(string content, string title = "")
		{
			return new MessageBox(content, title);
		}

		public MessageBox SetButtons(MessageButtons buttons)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			Buttons = (ButtonType)buttons;
			return this;
		}

		public MessageBox SetTimeout(float delay)
		{
			Time = delay;
			return this;
		}

		public MessageBox OnConfirm(Action action)
		{
			Confirm = action;
			return this;
		}

		public MessageBox OnCancel(Action action)
		{
			Cancel = action;
			return this;
		}

		public void Show()
		{
			//IL_001e: 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)
			//IL_0042: Expected O, but got Unknown
			//IL_0042: Expected O, but got Unknown
			G.Sys.MenuPanelManager_.ShowMessage(Message, Title, (OnButtonClicked)delegate
			{
				Confirm();
			}, (OnButtonClicked)delegate
			{
				Cancel();
			}, Buttons, false, (Pivot)4, Time);
		}

		private void EmptyAction()
		{
		}
	}
	[Flags]
	public enum MessageButtons
	{
		Ok = 0,
		OkCancel = 1,
		YesNo = 2
	}
	[BepInPlugin("Distance.CustomCar", "Custom Car", "1.0")]
	public sealed class Mod : BaseUnityPlugin
	{
		private const string modGUID = "Distance.CustomCar";

		private const string modName = "Custom Car";

		private const string modVersion = "1.0";

		public static string UseTrumpetKey = "Use Trumpet Horn";

		private static readonly Harmony harmony = new Harmony("Distance.CustomCar");

		public static ManualLogSource Log = new ManualLogSource("Custom Car");

		public static Mod Instance;

		private bool displayErrors_ = true;

		public static ConfigEntry<bool> UseTrumpetHorn { get; set; }

		public static int DefaultCarCount { get; private set; }

		public static int ModdedCarCount => TotalCarCount - DefaultCarCount;

		public static int TotalCarCount { get; private set; }

		public ErrorList Errors { get; set; }

		public ProfileCarColors CarColors { get; set; }

		private void Awake()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Log = Logger.CreateLogSource("Distance.CustomCar");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Thanks for using Custom Cars!");
			Errors = new ErrorList(((BaseUnityPlugin)this).Logger);
			CarColors = ((Component)this).gameObject.AddComponent<ProfileCarColors>();
			UseTrumpetHorn = ((BaseUnityPlugin)this).Config.Bind<bool>("General", UseTrumpetKey, false, new ConfigDescription("Custom car models will use the encryptor horn (the \"doot!\" trumpet).", (AcceptableValueBase)null, new object[0]));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading...");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded!");
		}

		public void Start()
		{
			ProfileManager profileManager_ = G.Sys.ProfileManager_;
			DefaultCarCount = profileManager_.CarInfos_.Length;
			CarInfos carInfos = new CarInfos();
			carInfos.CollectInfos();
			CarBuilder carBuilder = new CarBuilder();
			carBuilder.CreateCars(carInfos);
			TotalCarCount = profileManager_.CarInfos_.Length;
			CarColors.LoadAll();
			Errors.Show();
		}

		private void OnEnable()
		{
			StaticEvent<Data>.Subscribe((Delegate<Data>)OnMainMenuLoaded);
		}

		private void OnDisable()
		{
			StaticEvent<Data>.Unsubscribe((Delegate<Data>)OnMainMenuLoaded);
		}

		private void OnMainMenuLoaded(Data _)
		{
			if (displayErrors_)
			{
				Errors.Show();
				displayErrors_ = false;
			}
		}

		private void OnConfigChanged(object sender, EventArgs e)
		{
			SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
			if (val != null)
			{
			}
		}
	}
	public class ProfileCarColors : MonoBehaviour
	{
		internal Settings Config;

		public event Action<ProfileCarColors> OnChanged;

		protected void Load()
		{
			Config = new Settings("CustomCars");
		}

		protected void Awake()
		{
			Load();
			Save();
		}

		protected Section Profile(string profileName)
		{
			return Config.GetOrCreate(profileName, new Section());
		}

		protected Section Vehicle(string profileName, string vehicleName)
		{
			return Profile(profileName).GetOrCreate(vehicleName, new Section());
		}

		protected CarColors GetCarColors(string profileName, string vehicleName)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_007f: 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)
			Section vehicle = Vehicle(profileName, vehicleName);
			CarColors val = default(CarColors);
			val.primary_ = GetColor(vehicle, "primary", Colors.whiteSmoke);
			val.secondary_ = GetColor(vehicle, "secondary", Colors.darkGray);
			val.glow_ = GetColor(vehicle, "glow", Colors.cyan);
			val.sparkle_ = GetColor(vehicle, "sparkle", Colors.lightSlateGray);
			CarColors val2 = val;
			SetCarColors(profileName, vehicleName, val2);
			return val2;
		}

		protected Color GetColor(Section vehicle, string category, Color defaultColor)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			Section orCreate = vehicle.GetOrCreate(category, new Section());
			float orCreate2 = orCreate.GetOrCreate("r", defaultColor.r);
			float orCreate3 = orCreate.GetOrCreate("g", defaultColor.g);
			float orCreate4 = orCreate.GetOrCreate("b", defaultColor.b);
			float orCreate5 = orCreate.GetOrCreate("a", defaultColor.a);
			return new Color(orCreate2, orCreate3, orCreate4, orCreate5);
		}

		protected void SetCarColors(string profileName, string vehicleName, CarColors colors)
		{
			//IL_0011: 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_0029: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			Section section = Vehicle(profileName, vehicleName);
			section["primary"] = ToSection(colors.primary_);
			section["secondary"] = ToSection(colors.secondary_);
			section["glow"] = ToSection(colors.glow_);
			section["sparkle"] = ToSection(colors.sparkle_);
			Section section2 = Profile(profileName);
			section2[vehicleName] = section;
			Config[profileName] = section2;
		}

		protected Section ToSection(Color color)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			return new Section
			{
				["r"] = color.r,
				["g"] = color.g,
				["b"] = color.b,
				["a"] = color.a
			};
		}

		protected void Save()
		{
			Config.Save();
			this.OnChanged?.Invoke(this);
		}

		public void LoadAll()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			ProfileManager profileManager_ = G.Sys.ProfileManager_;
			List<Profile> profiles_ = profileManager_.profiles_;
			foreach (Profile item in profiles_)
			{
				CarColors[] array = (CarColors[])(object)new CarColors[Mod.TotalCarCount];
				for (int i = 0; i < profileManager_.CarInfos_.Length; i++)
				{
					if (i < Mod.DefaultCarCount)
					{
						array[i] = item.carColorsList_[i];
						continue;
					}
					CarInfo val = profileManager_.CarInfos_[i];
					CarColors carColors = GetCarColors(item.FileName_, val.name_);
					array[i] = carColors;
				}
				item.carColorsList_ = array;
			}
		}

		public void SaveAll()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			ProfileManager profileManager_ = G.Sys.ProfileManager_;
			List<Profile> profiles_ = profileManager_.profiles_;
			foreach (Profile item in profiles_)
			{
				for (int i = 0; i < profileManager_.CarInfos_.Length; i++)
				{
					if (i >= Mod.DefaultCarCount)
					{
						CarInfo val = profileManager_.CarInfos_[i];
						CarColors colors = item.carColorsList_[i];
						SetCarColors(item.FileName_, val.name_, colors);
					}
				}
			}
			Save();
		}
	}
	public class Section : Dictionary<string, object>
	{
		public bool Dirty { get; protected set; }

		public new object this[string key]
		{
			get
			{
				if (!ContainsKey(key))
				{
					return null;
				}
				return base[key];
			}
			set
			{
				if (!ContainsKey(key))
				{
					Add(key, value);
					this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, base[key]));
				}
				else
				{
					object oldValue = base[key];
					base[key] = value;
					this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, oldValue, base[key]));
				}
				Dirty = true;
			}
		}

		public event EventHandler<SettingsChangedEventArgs> ValueChanged;

		public T GetItem<T>(string key)
		{
			//IL_0084: Expected O, but got Unknown
			if (!ContainsKey(key))
			{
				Mod.Log.LogInfo((object)("The key requested doesn't exist in store: '" + key + "'."));
				throw new KeyNotFoundException("The key requested doesn't exist in store: '" + key + "'.");
			}
			try
			{
				object obj = this[key];
				JToken val = (JToken)((obj is JToken) ? obj : null);
				if (val != null)
				{
					return val.ToObject<T>();
				}
				return (T)Convert.ChangeType(this[key], typeof(T));
			}
			catch (JsonException val2)
			{
				JsonException val3 = val2;
				Mod.Log.LogInfo((object)$"Failed to convert a JSON token to the requested type. String: {key} \n{val3}");
				throw new SettingsException("Failed to convert a JSON token to the requested type.", key, isJsonFailure: true, (Exception)(object)val3);
			}
			catch (Exception ex)
			{
				try
				{
					return (T)Enum.ToObject(typeof(T), (long)this[key]);
				}
				catch
				{
					Mod.Log.LogInfo((object)$".NET type conversion exception has been thrown. String: {key} \n{ex}");
					throw new SettingsException(".NET type conversion exception has been thrown.", key, isJsonFailure: false, ex);
				}
			}
		}

		public T GetOrCreate<T>(string key) where T : new()
		{
			if (!ContainsKey(key))
			{
				this[key] = new T();
				this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, this[key]));
			}
			return GetItem<T>(key);
		}

		public T GetOrCreate<T>(string key, T defaultValue)
		{
			if (!ContainsKey(key))
			{
				this[key] = defaultValue;
				this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, this[key]));
			}
			return GetItem<T>(key);
		}

		public bool ContainsKey<T>(string key)
		{
			try
			{
				GetItem<T>(key);
				return true;
			}
			catch
			{
				return false;
			}
		}
	}
	public class Settings : Section
	{
		private string FileName { get; }

		private string RootDirectory { get; }

		private string SettingsDirectory => Path.Combine(RootDirectory, "Settings");

		private string FilePath => Path.Combine(SettingsDirectory, FileName);

		public Settings(string fileName)
		{
			//IL_0084: Expected O, but got Unknown
			RootDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			FileName = fileName + ".json";
			Mod.Log.LogInfo((object)("Settings instance for '" + FilePath + "' initializing..."));
			if (File.Exists(FilePath))
			{
				using StreamReader streamReader = new StreamReader(FilePath);
				string text = streamReader.ReadToEnd();
				Section section = null;
				try
				{
					section = JsonConvert.DeserializeObject<Section>(text);
				}
				catch (JsonException val)
				{
					JsonException val2 = val;
					Mod.Log.LogInfo((object)val2);
				}
				catch (Exception ex)
				{
					Mod.Log.LogInfo((object)ex);
				}
				Mod.Log.LogInfo((object)"Just Deserialized the json");
				if (section != null)
				{
					foreach (string key in section.Keys)
					{
						Add(key, section[key]);
					}
				}
			}
			base.Dirty = false;
		}

		public void Save(bool formatJson = true)
		{
			//IL_0057: Expected O, but got Unknown
			if (!Directory.Exists(SettingsDirectory))
			{
				Directory.CreateDirectory(SettingsDirectory);
			}
			try
			{
				using (StreamWriter streamWriter = new StreamWriter(FilePath, append: false))
				{
					streamWriter.WriteLine(JsonConvert.SerializeObject((object)this, (Formatting)1));
				}
				base.Dirty = false;
			}
			catch (JsonException val)
			{
				JsonException val2 = val;
				Mod.Log.LogInfo((object)val2);
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)ex);
			}
		}

		public void SaveIfDirty(bool formatJson = true)
		{
			if (base.Dirty)
			{
				Save(formatJson);
			}
		}
	}
	public class SettingsChangedEventArgs : EventArgs
	{
		public string Key { get; }

		public object OldValue { get; }

		public object NewValue { get; }

		public SettingsChangedEventArgs(string key, object oldValue = null, object newValue = null)
		{
			Key = key;
			OldValue = oldValue;
			NewValue = newValue;
		}
	}
	public class SettingsException : Exception
	{
		public string Key { get; }

		public bool IsJsonFailure { get; }

		public SettingsException(string message, string key, bool isJsonFailure, Exception innerException)
			: base(message, innerException)
		{
			Key = key;
			IsJsonFailure = isJsonFailure;
		}

		public SettingsException(string message, string key, bool isJsonFailure)
			: this(message, key, isJsonFailure, null)
		{
		}
	}
}
namespace Distance.CustomCar.Patches
{
	[HarmonyPatch(typeof(CarAudio), "OnCarHornEvent")]
	internal static class OnCarHornEvent
	{
		[HarmonyPrefix]
		internal static bool Prefix(CarAudio __instance, Data data)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			int num = G.Sys.ProfileManager_.knownCars_[__instance.carLogic_.PlayerData_.CarName_];
			if (num >= Mod.DefaultCarCount && Mod.UseTrumpetHorn.Value)
			{
				__instance.phantom_.SetRTPCValue("Horn_volume", Mathf.Clamp01(data.hornPercent_ + 0.5f));
				__instance.phantom_.Play("SpookyHorn", 0f, true);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(GadgetWithAnimation), "SetAnimationStateValues")]
	internal static class GadgetWithAnimation__SetAnimationStateValues
	{
		[HarmonyPrefix]
		internal static bool Prefix(GadgetWithAnimation __instance)
		{
			Animation componentInChildren = ((Component)__instance).GetComponentInChildren<Animation>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				return PatchAnimations(componentInChildren, __instance.animationName_);
			}
			return false;
		}

		private static bool PatchAnimations(Animation animation, string name)
		{
			if (Object.op_Implicit((Object)(object)animation))
			{
				if (!ChangeBlendModeToBlend(((Component)animation).transform, name))
				{
					return true;
				}
				AnimationState val = animation[name];
				if (TrackedReference.op_Implicit((TrackedReference)(object)val))
				{
					val.layer = 3;
					val.blendMode = (AnimationBlendMode)0;
					val.wrapMode = (WrapMode)8;
					val.enabled = true;
					val.weight = 1f;
					val.speed = 0f;
				}
			}
			return false;
		}

		private static bool ChangeBlendModeToBlend(Transform obj, string animationName)
		{
			for (int i = 0; i < obj.childCount; i++)
			{
				string text = ((Object)((Component)obj.GetChild(i)).gameObject).name.ToLower();
				if (!text.StartsWith("#"))
				{
					continue;
				}
				text = text.Remove(0, 1);
				string[] array = text.Split(new char[1] { ';' });
				if (array.Length == 1)
				{
					if (array[0] == "additive")
					{
						return false;
					}
					if (array[0] == "blend")
					{
						return true;
					}
				}
				if (array[1] == animationName.ToLower())
				{
					if (array[0] == "additive")
					{
						return false;
					}
					if (array[0] == "blend")
					{
						return true;
					}
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Profile), "Awake")]
	internal static class Profile__Awake
	{
		[HarmonyPostfix]
		internal static void Postfix(Profile __instance)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			CarColors[] array = (CarColors[])(object)new CarColors[G.Sys.ProfileManager_.carInfos_.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = G.Sys.ProfileManager_.carInfos_[i].colors_;
			}
			__instance.carColorsList_ = array;
		}
	}
	[HarmonyPatch(typeof(Profile), "Save")]
	internal static class Profile__Save
	{
		[HarmonyPostfix]
		internal static void Postfix()
		{
			Mod.Instance.CarColors.SaveAll();
		}
	}
	[HarmonyPatch(typeof(Profile), "SetColorsForAllCars", new Type[] { typeof(CarColors) })]
	internal static class Profile__SetColorsForAllCars
	{
		[HarmonyPrefix]
		internal static bool Prefix(Profile __instance, CarColors cc)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			CarColors[] array = (CarColors[])(object)new CarColors[G.Sys.ProfileManager_.carInfos_.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = cc;
			}
			__instance.carColorsList_ = array;
			__instance.dataModified_ = true;
			return false;
		}
	}
}
namespace Distance.CustomCar.Data.Materials
{
	public class MaterialInfos
	{
		public Material material;

		public int diffuseIndex = -1;

		public int normalIndex = -1;

		public int emitIndex = -1;

		public void ReplaceMaterialInRenderer(Renderer renderer, int materialIndex)
		{
			if (!((Object)(object)material == (Object)null) && !((Object)(object)renderer == (Object)null) && materialIndex < renderer.materials.Length)
			{
				ref Material reference = ref renderer.materials[materialIndex];
				Material val = Object.Instantiate<Material>(material);
				if (diffuseIndex >= 0)
				{
					val.SetTexture(diffuseIndex, reference.GetTexture("_MainTex"));
				}
				if (emitIndex >= 0)
				{
					val.SetTexture(emitIndex, reference.GetTexture("_EmissionMap"));
				}
				if (normalIndex >= 0)
				{
					val.SetTexture(normalIndex, reference.GetTexture("_BumpMap"));
				}
				renderer.materials[materialIndex] = val;
			}
		}
	}
	public class MaterialPropertyExport
	{
		public string fromName;

		public string toName;

		public int fromID = -1;

		public int toID = -1;

		public PropertyType type;
	}
	public class MaterialPropertyInfo
	{
		public string shaderName;

		public string name;

		public int diffuseIndex = -1;

		public int normalIndex = -1;

		public int emitIndex = -1;

		public MaterialPropertyInfo(string _shaderName, string _name, int _diffuseIndex, int _normalIndex, int _emitIndex)
		{
			shaderName = _shaderName;
			name = _name;
			diffuseIndex = _diffuseIndex;
			normalIndex = _normalIndex;
			emitIndex = _emitIndex;
		}
	}
	public enum PropertyType
	{
		Color,
		ColorArray,
		Float,
		FloatArray,
		Int,
		Matrix,
		MatrixArray,
		Texture,
		Vector,
		VectorArray
	}
}
namespace Distance.CustomCar.Data.Errors
{
	public class ErrorList : List<string>
	{
		private readonly ManualLogSource logger_;

		public ErrorList(ManualLogSource logger)
		{
			logger_ = logger;
		}

		public new void Add(string value)
		{
			base.Add(value);
			logger_.LogInfo((object)value);
		}

		public void Add(Exception value)
		{
			base.Add(value.ToString());
			logger_.LogInfo((object)value);
		}

		public void Show()
		{
			if (this.Any())
			{
				string arg = ((base.Count < 15) ? string.Join(Environment.NewLine, ToArray()) : "There were too many errors when loading custom cars to be displayed here, please check the logs in your mod installation directory.");
				MessageBox.Create($"Can't load the cars correctly: {base.Count} error(s)\n{arg}", "CUSTOM CARS - ERRORS").SetButtons(MessageButtons.Ok).Show();
			}
		}
	}
}
namespace Distance.CustomCar.Data.Car
{
	public class CarBuilder
	{
		private CarInfos infos_;

		public void CreateCars(CarInfos infos)
		{
			infos_ = infos;
			Dictionary<string, GameObject> dictionary = LoadAssetsBundles();
			List<CreateCarReturnInfos> list = new List<CreateCarReturnInfos>();
			foreach (KeyValuePair<string, GameObject> item in dictionary)
			{
				try
				{
					Mod.Log.LogInfo((object)("Creating car prefab for " + item.Key + " ..."));
					CreateCarReturnInfos createCarReturnInfos = CreateCar(item.Value);
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item.Key.Substring(0, item.Key.LastIndexOf('(') - 1));
					((Object)createCarReturnInfos.car).name = fileNameWithoutExtension;
					list.Add(createCarReturnInfos);
				}
				catch (Exception value)
				{
					Mod.Log.LogInfo((object)("Could not load car prefab: " + item.Key));
					Mod.Instance.Errors.Add("Could not load car prefab: " + item.Key);
					Mod.Instance.Errors.Add(value);
				}
			}
			RegisterCars(list);
		}

		private void RegisterCars(List<CreateCarReturnInfos> carsInfos)
		{
			//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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_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)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			Mod.Log.LogInfo((object)$"Registering {carsInfos.Count} car(s)...");
			ProfileManager profileManager_ = G.Sys.ProfileManager_;
			CarInfo[] array = ICollectionEx.ToArray<CarInfo>((ICollection<CarInfo>)profileManager_.carInfos_);
			profileManager_.carInfos_ = (CarInfo[])(object)new CarInfo[array.Length + carsInfos.Count];
			ref Dictionary<string, int> unlockedCars_ = ref profileManager_.unlockedCars_;
			ref Dictionary<string, int> knownCars_ = ref profileManager_.knownCars_;
			for (int i = 0; i < profileManager_.carInfos_.Length; i++)
			{
				if (i < array.Length)
				{
					profileManager_.carInfos_[i] = array[i];
					continue;
				}
				int index = i - array.Length;
				CarInfo val = new CarInfo
				{
					name_ = ((Object)carsInfos[index].car).name,
					prefabs_ = new CarPrefabs
					{
						carPrefab_ = carsInfos[index].car
					},
					colors_ = carsInfos[index].colors
				};
				if (!knownCars_.ContainsKey(val.name_) && !unlockedCars_.ContainsKey(val.name_))
				{
					unlockedCars_.Add(val.name_, i);
					knownCars_.Add(val.name_, i);
				}
				else
				{
					Mod.Instance.Errors.Add("A car with the name " + val.name_ + " is already registered, rename the car file if they're the same.");
					Mod.Log.LogInfo((object)("Generating unique name for car " + val.name_));
					string text = $"#{Guid.NewGuid():B}";
					Mod.Log.LogInfo((object)("Using GUID: " + text));
					val.name_ = "[FFFF00]![-] " + val.name_ + " " + text;
					unlockedCars_.Add(val.name_, i);
					knownCars_.Add(val.name_, i);
				}
				profileManager_.carInfos_[i] = val;
			}
			CarColors[] array2 = (CarColors[])(object)new CarColors[array.Length + carsInfos.Count];
			for (int j = 0; j < array2.Length; j++)
			{
				array2[j] = G.Sys.ProfileManager_.carInfos_[j].colors_;
			}
			for (int k = 0; k < profileManager_.ProfileCount_; k++)
			{
				Profile profile = profileManager_.GetProfile(k);
				CarColors[] carColorsList_ = profile.carColorsList_;
				for (int l = 0; l < carColorsList_.Length && l < array2.Length; l++)
				{
					array2[l] = carColorsList_[l];
				}
				profile.carColorsList_ = array2;
			}
		}

		private Dictionary<string, GameObject> LoadAssetsBundles()
		{
			Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>();
			DirectoryInfo localFolder = GetLocalFolder("Assets");
			DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(Resource.personalDistanceDirPath_, "CustomCars"));
			if (!directoryInfo.Exists)
			{
				try
				{
					directoryInfo.Create();
				}
				catch (Exception ex)
				{
					Mod.Instance.Errors.Add("Could not create the following folder: " + directoryInfo.FullName);
					Mod.Log.LogInfo((object)("Could not create the following folder: " + directoryInfo.FullName));
					Mod.Instance.Errors.Add(ex);
					Mod.Log.LogInfo((object)ex);
				}
			}
			foreach (FileInfo item in from x in ArrayEx.Concat<FileInfo>(localFolder.GetFiles("*", SearchOption.AllDirectories), directoryInfo.GetFiles("*", SearchOption.AllDirectories))
				orderby x.Name
				select x)
			{
				try
				{
					Assets assets = Assets.FromUnsafePath(item.FullName);
					object bundle = assets.Bundle;
					AssetBundle val = (AssetBundle)((bundle is AssetBundle) ? bundle : null);
					int num = 0;
					foreach (string item2 in from name in val.GetAllAssetNames()
						where name.EndsWith(".prefab", StringComparison.InvariantCultureIgnoreCase)
						select name)
					{
						GameObject value = val.LoadAsset<GameObject>(item2);
						string key = item.FullName + " (" + item2 + ")";
						if (!dictionary.ContainsKey(key))
						{
							dictionary.Add(key, value);
							num++;
						}
					}
					if (num == 0)
					{
						Mod.Instance.Errors.Add("Can't find a prefab in the asset bundle: " + item.FullName);
						Mod.Log.LogInfo((object)("Can't find a prefab in the asset bundle: " + item.FullName));
					}
				}
				catch (Exception ex2)
				{
					Mod.Instance.Errors.Add("Could not load assets file: " + item.FullName);
					Mod.Log.LogInfo((object)("Could not load assets file: " + item.FullName));
					Mod.Instance.Errors.Add(ex2);
					Mod.Log.LogInfo((object)ex2);
				}
			}
			try
			{
				DirectoryInfo directoryInfo2 = new DirectoryInfo(Path.Combine(Directory.GetParent(Directory.GetParent(Path.GetDirectoryName(Assembly.GetCallingAssembly().Location)).ToString()).ToString(), "Assets"));
				foreach (FileInfo item3 in from x in ArrayEx.Concat<FileInfo>(directoryInfo2.GetFiles("*", SearchOption.AllDirectories), directoryInfo.GetFiles("*", SearchOption.AllDirectories))
					orderby x.Name
					select x)
				{
					try
					{
						Assets assets2 = Assets.FromUnsafePath(item3.FullName);
						object bundle2 = assets2.Bundle;
						AssetBundle val2 = (AssetBundle)((bundle2 is AssetBundle) ? bundle2 : null);
						int num2 = 0;
						foreach (string item4 in from name in val2.GetAllAssetNames()
							where name.EndsWith(".prefab", StringComparison.InvariantCultureIgnoreCase)
							select name)
						{
							GameObject value2 = val2.LoadAsset<GameObject>(item4);
							string key2 = item3.FullName + " (" + item4 + ")";
							if (!dictionary.ContainsKey(key2))
							{
								dictionary.Add(key2, value2);
								num2++;
							}
						}
						if (num2 == 0)
						{
							Mod.Instance.Errors.Add("Can't find a prefab in the asset bundle: " + item3.FullName);
							Mod.Log.LogInfo((object)("Can't find a prefab in the asset bundle: " + item3.FullName));
						}
					}
					catch (Exception ex3)
					{
						Mod.Instance.Errors.Add("Could not load assets file: " + item3.FullName);
						Mod.Log.LogInfo((object)("Could not load assets file: " + item3.FullName));
						Mod.Instance.Errors.Add(ex3);
						Mod.Log.LogInfo((object)ex3);
					}
				}
			}
			catch (Exception ex4)
			{
				Mod.Log.LogInfo((object)"Could not find assets file in the top level directory. This is not bad, this just means no cars were downloaded from the Thunderstore");
				Mod.Log.LogInfo((object)ex4);
			}
			return dictionary;
		}

		public DirectoryInfo GetLocalFolder(string dir)
		{
			FileSystem fileSystem = new FileSystem();
			return new DirectoryInfo(Path.GetDirectoryName(Path.Combine(fileSystem.RootDirectory, dir + (dir.EndsWith($"{Path.DirectorySeparatorChar}") ? string.Empty : $"{Path.DirectorySeparatorChar}"))));
		}

		private CreateCarReturnInfos CreateCar(GameObject car)
		{
			//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)
			CreateCarReturnInfos createCarReturnInfos = new CreateCarReturnInfos();
			GameObject val = Object.Instantiate<GameObject>(infos_.baseCar);
			((Object)val).name = ((Object)car).name;
			Object.DontDestroyOnLoad((Object)(object)val);
			val.SetActive(false);
			RemoveOldCar(val);
			GameObject car2 = AddNewCarOnPrefab(val, car);
			SetCarDatas(val, car2);
			createCarReturnInfos.car = val;
			createCarReturnInfos.colors = LoadDefaultColors(car2);
			return createCarReturnInfos;
		}

		private void RemoveOldCar(GameObject obj)
		{
			List<GameObject> list = new List<GameObject>();
			for (int i = 0; i < obj.transform.childCount; i++)
			{
				GameObject gameObject = ((Component)obj.transform.GetChild(i)).gameObject;
				if (((Object)gameObject).name.IndexOf("wheel", StringComparison.InvariantCultureIgnoreCase) >= 0)
				{
					list.Add(gameObject);
				}
			}
			if (list.Count != 4)
			{
				Mod.Instance.Errors.Add($"Found {list.Count} wheels on base prefabs, expected 4");
				Mod.Log.LogInfo((object)$"Found {list.Count} wheels on base prefabs, expected 4");
			}
			Transform val = obj.transform.Find("Refractor");
			if ((Object)(object)val == (Object)null)
			{
				Mod.Instance.Errors.Add("Can't find the Refractor object on the base car prefab");
				Mod.Log.LogInfo((object)"Can't find the Refractor object on the base car prefab");
				return;
			}
			Object.Destroy((Object)(object)((Component)val).gameObject);
			foreach (GameObject item in list)
			{
				Object.Destroy((Object)(object)item);
			}
		}

		private GameObject AddNewCarOnPrefab(GameObject obj, GameObject car)
		{
			return Object.Instantiate<GameObject>(car, obj.transform);
		}

		private void SetCarDatas(GameObject obj, GameObject car)
		{
			SetColorChanger(obj.GetComponent<ColorChanger>(), car);
			SetCarVisuals(obj.GetComponent<CarVisuals>(), car);
		}

		private void SetColorChanger(ColorChanger colorChanger, GameObject car)
		{
			if ((Object)(object)colorChanger == (Object)null)
			{
				Mod.Instance.Errors.Add("Can't find the ColorChanger component on the base car");
				Mod.Log.LogInfo((object)"Can't find the ColorChanger component on the base car");
				return;
			}
			colorChanger.rendererChangers_ = (RendererChanger[])(object)new RendererChanger[0];
			Renderer[] componentsInChildren = car.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				ReplaceMaterials(val);
				if ((Object)(object)colorChanger != (Object)null)
				{
					AddMaterialColorChanger(colorChanger, ((Component)val).transform);
				}
			}
		}

		private void ReplaceMaterials(Renderer renderer)
		{
			string[] array = new string[renderer.materials.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = "wheel";
			}
			List<MaterialPropertyExport>[] array2 = new List<MaterialPropertyExport>[renderer.materials.Length];
			for (int j = 0; j < array2.Length; j++)
			{
				array2[j] = new List<MaterialPropertyExport>();
			}
			FillMaterialInfos(renderer, array, array2);
			Material[] array3 = ICollectionEx.ToArray<Material>((ICollection<Material>)renderer.materials);
			for (int k = 0; k < renderer.materials.Length; k++)
			{
				if (!infos_.materials.TryGetValue(array[k], out var value))
				{
					Mod.Instance.Errors.Add("Can't find the material " + array[k] + " on " + ((Component)renderer).gameObject.FullName());
					Mod.Log.LogInfo((object)("Can't find the material " + array[k] + " on " + ((Component)renderer).gameObject.FullName()));
				}
				else
				{
					if (value == null || (Object)(object)value.material == (Object)null)
					{
						continue;
					}
					Material val = Object.Instantiate<Material>(value.material);
					if (value.diffuseIndex >= 0)
					{
						val.SetTexture(value.diffuseIndex, renderer.materials[k].GetTexture("_MainTex"));
					}
					if (value.normalIndex >= 0)
					{
						val.SetTexture(value.normalIndex, renderer.materials[k].GetTexture("_BumpMap"));
					}
					if (value.emitIndex >= 0)
					{
						val.SetTexture(value.emitIndex, renderer.materials[k].GetTexture("_EmissionMap"));
					}
					foreach (MaterialPropertyExport item in array2[k])
					{
						CopyMaterialProperty(renderer.materials[k], val, item);
					}
					array3[k] = val;
				}
			}
			renderer.materials = array3;
		}

		private void FillMaterialInfos(Renderer renderer, string[] matNames, List<MaterialPropertyExport>[] materialProperties)
		{
			int childCount = ((Component)renderer).transform.childCount;
			for (int i = 0; i < childCount; i++)
			{
				string text = ((Object)((Component)renderer).transform.GetChild(i)).name.ToLower();
				if (!text.StartsWith("#"))
				{
					continue;
				}
				text = text.Remove(0, 1);
				string[] array = text.Split(new char[1] { ';' });
				if (array.Length == 0)
				{
					continue;
				}
				if (array[0].Contains("mat"))
				{
					int result;
					if (array.Length != 3)
					{
						Mod.Instance.Errors.Add(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 2 arguments");
						Mod.Log.LogInfo((object)(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 2 arguments"));
					}
					else if (!int.TryParse(array[1], out result))
					{
						Mod.Instance.Errors.Add("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number");
						Mod.Log.LogInfo((object)("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number"));
					}
					else if (result < matNames.Length)
					{
						matNames[result] = array[2];
					}
				}
				else
				{
					if (!array[0].Contains("export"))
					{
						continue;
					}
					int result2;
					if (array.Length != 5)
					{
						Mod.Instance.Errors.Add(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 4 arguments");
						Mod.Log.LogInfo((object)(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 4 arguments"));
					}
					else if (!int.TryParse(array[1], out result2))
					{
						Mod.Instance.Errors.Add("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number");
						Mod.Log.LogInfo((object)("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number"));
					}
					else
					{
						if (result2 >= matNames.Length)
						{
							continue;
						}
						MaterialPropertyExport materialPropertyExport = new MaterialPropertyExport();
						bool flag = false;
						foreach (PropertyType value in Enum.GetValues(typeof(PropertyType)))
						{
							if (array[2] == value.ToString().ToLower())
							{
								flag = true;
								materialPropertyExport.type = value;
								break;
							}
						}
						if (!flag)
						{
							Mod.Instance.Errors.Add("The property " + array[2] + " on " + ((Component)renderer).gameObject.FullName() + " is not valid");
							Mod.Log.LogInfo((object)("The property " + array[2] + " on " + ((Component)renderer).gameObject.FullName() + " is not valid"));
						}
						else
						{
							if (!int.TryParse(array[3], out materialPropertyExport.fromID))
							{
								materialPropertyExport.fromName = array[3];
							}
							if (!int.TryParse(array[4], out materialPropertyExport.toID))
							{
								materialPropertyExport.toName = array[4];
							}
							materialProperties[result2].Add(materialPropertyExport);
						}
					}
				}
			}
		}

		private void CopyMaterialProperty(Material from, Material to, MaterialPropertyExport property)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			int num = property.fromID;
			if (num == -1)
			{
				num = Shader.PropertyToID(property.fromName);
			}
			int num2 = property.toID;
			if (num2 == -1)
			{
				num2 = Shader.PropertyToID(property.toName);
			}
			switch (property.type)
			{
			case PropertyType.Color:
				to.SetColor(num2, from.GetColor(num));
				break;
			case PropertyType.ColorArray:
				to.SetColorArray(num2, from.GetColorArray(num));
				break;
			case PropertyType.Float:
				to.SetFloat(num2, from.GetFloat(num));
				break;
			case PropertyType.FloatArray:
				to.SetFloatArray(num2, from.GetFloatArray(num));
				break;
			case PropertyType.Int:
				to.SetInt(num2, from.GetInt(num));
				break;
			case PropertyType.Matrix:
				to.SetMatrix(num2, from.GetMatrix(num));
				break;
			case PropertyType.MatrixArray:
				to.SetMatrixArray(num2, from.GetMatrixArray(num));
				break;
			case PropertyType.Texture:
				to.SetTexture(num2, from.GetTexture(num));
				break;
			case PropertyType.Vector:
				to.SetVector(num2, from.GetVector(num));
				break;
			case PropertyType.VectorArray:
				to.SetVectorArray(num2, from.GetVectorArray(num));
				break;
			}
		}

		private void AddMaterialColorChanger(ColorChanger colorChanger, Transform transform)
		{
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			Renderer component = ((Component)transform).GetComponent<Renderer>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			List<UniformChanger> list = new List<UniformChanger>();
			for (int i = 0; i < transform.childCount; i++)
			{
				GameObject gameObject = ((Component)transform.GetChild(i)).gameObject;
				string text = ((Object)gameObject).name.ToLower();
				if (!text.StartsWith("#"))
				{
					continue;
				}
				text = text.Remove(0, 1);
				string[] array = text.Split(new char[1] { ';' });
				if (array.Length != 0 && array[0].Contains("color"))
				{
					if (array.Length != 6)
					{
						Mod.Instance.Errors.Add(array[0] + " property on " + ((Component)transform).gameObject.FullName() + " must have 5 arguments");
						Mod.Log.LogInfo((object)(array[0] + " property on " + ((Component)transform).gameObject.FullName() + " must have 5 arguments"));
						continue;
					}
					UniformChanger val = new UniformChanger();
					int.TryParse(array[1], out var result);
					val.materialIndex_ = result;
					val.colorType_ = ColorType(array[2]);
					val.name_ = UniformName(array[3]);
					float.TryParse(array[4], out var result2);
					val.mul_ = result2;
					val.alpha_ = string.Equals(array[5], "true", StringComparison.InvariantCultureIgnoreCase);
					list.Add(val);
				}
			}
			if (list.Count != 0)
			{
				RendererChanger item = new RendererChanger
				{
					renderer_ = component,
					uniformChangers_ = list.ToArray()
				};
				List<RendererChanger> list2 = colorChanger.rendererChangers_.ToList();
				list2.Add(item);
				colorChanger.rendererChangers_ = list2.ToArray();
			}
		}

		private ColorType ColorType(string name)
		{
			//IL_0044: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			name = name.ToLower();
			return (ColorType)(name switch
			{
				"primary" => 0, 
				"secondary" => 1, 
				"glow" => 2, 
				"sparkle" => 3, 
				_ => 0, 
			});
		}

		private SupportedUniform UniformName(string name)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			name = name.ToLower();
			return (SupportedUniform)(name switch
			{
				"color" => 0, 
				"color2" => 1, 
				"emitcolor" => 2, 
				"reflectcolor" => 4, 
				"speccolor" => 5, 
				_ => 0, 
			});
		}

		private void SetCarVisuals(CarVisuals visuals, GameObject car)
		{
			if ((Object)(object)visuals == (Object)null)
			{
				Mod.Instance.Errors.Add("Can't find the CarVisuals component on the base car");
				Mod.Log.LogInfo((object)"Can't find the CarVisuals component on the base car");
				return;
			}
			SkinnedMeshRenderer componentInChildren = car.GetComponentInChildren<SkinnedMeshRenderer>();
			MakeMeshSkinned(componentInChildren);
			visuals.carBodyRenderer_ = componentInChildren;
			List<JetFlame> list = new List<JetFlame>();
			List<JetFlame> list2 = new List<JetFlame>();
			List<JetFlame> list3 = new List<JetFlame>();
			PlaceJets(car, list, list2, list3);
			visuals.boostJetFlames_ = list.ToArray();
			visuals.wingJetFlames_ = list2.ToArray();
			visuals.rotationJetFlames_ = list3.ToArray();
			visuals.driverPosition_ = FindCarDriver(car.transform);
			PlaceCarWheelsVisuals(visuals, car);
		}

		private void MakeMeshSkinned(SkinnedMeshRenderer renderer)
		{
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			Mesh sharedMesh = renderer.sharedMesh;
			if ((Object)(object)sharedMesh == (Object)null)
			{
				Mod.Instance.Errors.Add("The mesh on " + ((Component)renderer).gameObject.FullName() + " is null");
				Mod.Log.LogInfo((object)("The mesh on " + ((Component)renderer).gameObject.FullName() + " is null"));
			}
			else if (!sharedMesh.isReadable)
			{
				Mod.Instance.Errors.Add("Can't read the car mesh " + ((Object)sharedMesh).name + " on " + ((Component)renderer).gameObject.FullName() + "You must allow reading on it's unity inspector !");
				Mod.Log.LogInfo((object)("Can't read the car mesh " + ((Object)sharedMesh).name + " on " + ((Component)renderer).gameObject.FullName() + "You must allow reading on it's unity inspector !"));
			}
			else if (sharedMesh.vertices.Length != sharedMesh.boneWeights.Length)
			{
				BoneWeight[] array = (BoneWeight[])(object)new BoneWeight[sharedMesh.vertices.Length];
				for (int i = 0; i < array.Length; i++)
				{
					((BoneWeight)(ref array[i])).weight0 = 1f;
				}
				sharedMesh.boneWeights = array;
				Transform transform = ((Component)renderer).transform;
				sharedMesh.bindposes = (Matrix4x4[])(object)new Matrix4x4[1] { transform.worldToLocalMatrix * ((Component)renderer).transform.localToWorldMatrix };
				renderer.bones = (Transform[])(object)new Transform[1] { transform };
			}
		}

		private void PlaceJets(GameObject obj, List<JetFlame> boostJets, List<JetFlame> wingJets, List<JetFlame> rotationJets)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			int childCount = obj.transform.childCount;
			for (int i = 0; i < childCount; i++)
			{
				GameObject gameObject = GameObjectEx.GetChild(obj, i).gameObject;
				string text = ((Object)gameObject).name.ToLower();
				if ((Object)(object)infos_.boostJet != (Object)null && text.Contains("boostjet"))
				{
					GameObject val = Object.Instantiate<GameObject>(infos_.boostJet, gameObject.transform);
					val.transform.localPosition = Vector3.zero;
					val.transform.localRotation = Quaternion.identity;
					boostJets.Add(val.GetComponentInChildren<JetFlame>());
				}
				else if ((Object)(object)infos_.wingJet != (Object)null && text.Contains("wingjet"))
				{
					GameObject val2 = Object.Instantiate<GameObject>(infos_.wingJet, gameObject.transform);
					val2.transform.localPosition = Vector3.zero;
					val2.transform.localRotation = Quaternion.identity;
					wingJets.Add(val2.GetComponentInChildren<JetFlame>());
					ListEx.Last<JetFlame>(wingJets).rotationAxis_ = JetDirection(gameObject.transform);
				}
				else if ((Object)(object)infos_.rotationJet != (Object)null && text.Contains("rotationjet"))
				{
					GameObject val3 = Object.Instantiate<GameObject>(infos_.rotationJet, gameObject.transform);
					val3.transform.localPosition = Vector3.zero;
					val3.transform.localRotation = Quaternion.identity;
					rotationJets.Add(val3.GetComponentInChildren<JetFlame>());
					ListEx.Last<JetFlame>(rotationJets).rotationAxis_ = JetDirection(gameObject.transform);
				}
				else if ((Object)(object)infos_.wingTrail != (Object)null && text.Contains("wingtrail"))
				{
					GameObject val4 = Object.Instantiate<GameObject>(infos_.wingTrail, gameObject.transform);
					val4.transform.localPosition = Vector3.zero;
					val4.transform.localRotation = Quaternion.identity;
				}
				else
				{
					PlaceJets(gameObject, boostJets, wingJets, rotationJets);
				}
			}
		}

		private Vector3 JetDirection(Transform transform)
		{
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			int childCount = transform.childCount;
			for (int i = 0; i < childCount; i++)
			{
				string text = ((Object)((Component)transform.GetChild(i)).gameObject).name.ToLower();
				if (!text.StartsWith("#"))
				{
					continue;
				}
				text = text.Remove(0, 1);
				string[] array = text.Split(new char[1] { ';' });
				if (array.Length != 0 && array[0].Contains("dir") && array.Length >= 2)
				{
					if (array[1] == "front")
					{
						return new Vector3(-1f, 0f, 0f);
					}
					if (array[1] == "back")
					{
						return new Vector3(1f, 0f, 0f);
					}
					if (array[1] == "left")
					{
						return new Vector3(0f, 1f, -1f);
					}
					if (array[1] == "right")
					{
						return new Vector3(0f, -1f, 1f);
					}
					if (array.Length == 4 && array[0].Contains("dir"))
					{
						Vector3 zero = Vector3.zero;
						float.TryParse(array[1], out zero.x);
						float.TryParse(array[2], out zero.y);
						float.TryParse(array[3], out zero.z);
						return zero;
					}
				}
			}
			return Vector3.zero;
		}

		private Transform FindCarDriver(Transform parent)
		{
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				Transform val = ((((Object)((Component)child).gameObject).name.IndexOf("driverposition", StringComparison.InvariantCultureIgnoreCase) >= 0) ? child : FindCarDriver(child));
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private void PlaceCarWheelsVisuals(CarVisuals visual, GameObject car)
		{
			for (int i = 0; i < car.transform.childCount; i++)
			{
				GameObject gameObject = ((Component)car.transform.GetChild(i)).gameObject;
				string text = ((Object)gameObject).name.ToLower();
				if (!text.Contains("wheel"))
				{
					continue;
				}
				CarWheelVisuals val = gameObject.AddComponent<CarWheelVisuals>();
				MeshRenderer[] componentsInChildren = gameObject.GetComponentsInChildren<MeshRenderer>();
				foreach (MeshRenderer val2 in componentsInChildren)
				{
					if (((Object)((Component)val2).gameObject).name.IndexOf("tire", StringComparison.InvariantCultureIgnoreCase) >= 0)
					{
						val.tire_ = val2;
						break;
					}
				}
				if (text.Contains("front"))
				{
					if (text.Contains("left"))
					{
						visual.wheelFL_ = val;
					}
					else if (text.Contains("right"))
					{
						visual.wheelFR_ = val;
					}
				}
				else if (text.Contains("back"))
				{
					if (text.Contains("left"))
					{
						visual.wheelBL_ = val;
					}
					else if (text.Contains("right"))
					{
						visual.wheelBR_ = val;
					}
				}
			}
		}

		private CarColors LoadDefaultColors(GameObject car)
		{
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			CarColors val2 = default(CarColors);
			for (int i = 0; i < car.transform.childCount; i++)
			{
				GameObject gameObject = ((Component)car.transform.GetChild(i)).gameObject;
				string text = ((Object)gameObject).name.ToLower();
				if (!text.Contains("defaultcolor"))
				{
					continue;
				}
				for (int j = 0; j < gameObject.transform.childCount; j++)
				{
					GameObject gameObject2 = ((Component)gameObject.transform.GetChild(j)).gameObject;
					string text2 = ((Object)gameObject2).name.ToLower();
					if (!text2.StartsWith("#"))
					{
						continue;
					}
					text2 = text2.Remove(0, 1);
					string[] array = text2.Split(new char[1] { ';' });
					if (array.Length == 2)
					{
						Color val = ColorEx.HexToColor(array[1], byte.MaxValue);
						val.a = 1f;
						if (array[0] == "primary")
						{
							val2.primary_ = val;
						}
						else if (array[0] == "secondary")
						{
							val2.secondary_ = val;
						}
						else if (array[0] == "glow")
						{
							val2.glow_ = val;
						}
						else if (array[0] == "sparkle")
						{
							val2.sparkle_ = val;
						}
					}
				}
			}
			return infos_.defaultColors;
		}
	}
	public class CarInfos
	{
		public Dictionary<string, MaterialInfos> materials = new Dictionary<string, MaterialInfos>();

		public GameObject boostJet = null;

		public GameObject wingJet = null;

		public GameObject rotationJet = null;

		public GameObject wingTrail = null;

		public GameObject baseCar = null;

		public CarColors defaultColors;

		public void CollectInfos()
		{
			GetBaseCar();
			GetJetsAndTrail();
			GetMaterials();
		}

		private void GetBaseCar()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			GameObject carPrefab_ = G.Sys.ProfileManager_.carInfos_[0].prefabs_.carPrefab_;
			if ((Object)(object)carPrefab_ == (Object)null)
			{
				Mod.Instance.Errors.Add("Can't find the refractor base car prefab");
				return;
			}
			baseCar = carPrefab_;
			defaultColors = G.Sys.ProfileManager_.carInfos_[0].colors_;
		}

		private void GetJetsAndTrail()
		{
			if ((Object)(object)baseCar == (Object)null)
			{
				return;
			}
			JetFlame[] componentsInChildren = baseCar.GetComponentsInChildren<JetFlame>();
			foreach (JetFlame val in componentsInChildren)
			{
				switch (((Object)((Component)val).gameObject).name)
				{
				case "BoostJetFlameCenter":
					boostJet = ((Component)val).gameObject;
					break;
				case "JetFlameBackLeft":
					rotationJet = ((Component)val).gameObject;
					break;
				case "WingJetFlameLeft1":
					wingJet = ((Component)val).gameObject;
					break;
				}
			}
			wingTrail = ((Component)baseCar.GetComponentInChildren<WingTrail>()).gameObject;
			if ((Object)(object)boostJet == (Object)null)
			{
				Mod.Instance.Errors.Add("No valid BoostJet found on Refractor");
			}
			if ((Object)(object)rotationJet == (Object)null)
			{
				Mod.Instance.Errors.Add("No valid RotationJet found on Refractor");
			}
			if ((Object)(object)wingJet == (Object)null)
			{
				Mod.Instance.Errors.Add("No valid WingJet found on Refractor");
			}
			if ((Object)(object)wingTrail == (Object)null)
			{
				Mod.Instance.Errors.Add("No valid WingTrail found on Refractor");
			}
		}

		private void GetMaterials()
		{
			List<MaterialPropertyInfo> list = new List<MaterialPropertyInfo>
			{
				new MaterialPropertyInfo("Custom/LaserCut/CarPaint", "carpaint", 5, -1, -1),
				new MaterialPropertyInfo("Custom/LaserCut/CarWindow", "carwindow", -1, 218, 219),
				new MaterialPropertyInfo("Custom/Reflective/Bump Glow LaserCut", "wheel", 5, 218, 255),
				new MaterialPropertyInfo("Custom/LaserCut/CarPaintBump", "carpaintbump", 5, 218, -1),
				new MaterialPropertyInfo("Custom/Reflective/Bump Glow Interceptor Special", "interceptor", 5, 218, 255),
				new MaterialPropertyInfo("Custom/LaserCut/CarWindowTrans2Sided", "transparentglow", -1, 218, 219)
			};
			CarInfo[] carInfos_ = G.Sys.ProfileManager_.carInfos_;
			foreach (CarInfo val in carInfos_)
			{
				GameObject carPrefab_ = val.prefabs_.carPrefab_;
				Renderer[] componentsInChildren = carPrefab_.GetComponentsInChildren<Renderer>();
				foreach (Renderer val2 in componentsInChildren)
				{
					Material[] array = val2.materials;
					foreach (Material val3 in array)
					{
						foreach (MaterialPropertyInfo item in list)
						{
							if (!materials.ContainsKey(item.name) && ((Object)val3.shader).name == item.shaderName)
							{
								MaterialInfos value = new MaterialInfos
								{
									material = val3,
									diffuseIndex = item.diffuseIndex,
									normalIndex = item.normalIndex,
									emitIndex = item.emitIndex
								};
								materials.Add(item.name, value);
							}
						}
					}
				}
			}
			foreach (MaterialPropertyInfo item2 in list)
			{
				if (!materials.ContainsKey(item2.name))
				{
					Mod.Instance.Errors.Add("Can't find the material: " + item2.name + " - shader: " + item2.shaderName);
				}
			}
			materials.Add("donotreplace", new MaterialInfos());
		}
	}
	public class CreateCarReturnInfos
	{
		public GameObject car;

		public CarColors colors;
	}
}

Newtonsoft.Json.dll

Decompiled 5 days ago
using System;
using System.Collections;
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.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq.JsonPath;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Json.NET Unity3D")]
[assembly: AllowPartiallyTrustedCallers]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Schema")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests")]
[assembly: InternalsVisibleTo("Assembly-CSharp")]
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
[assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Newtonsoft")]
[assembly: AssemblyProduct("Json.NET")]
[assembly: AssemblyCopyright("Copyright © James Newton-King 2008")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")]
[assembly: AssemblyFileVersion("9.0.1.19813")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyVersion("9.0.0.0")]
namespace Newtonsoft.Json
{
	public enum ConstructorHandling
	{
		Default,
		AllowNonPublicDefaultConstructor
	}
	public enum DateFormatHandling
	{
		IsoDateFormat,
		MicrosoftDateFormat
	}
	public enum DateParseHandling
	{
		None,
		DateTime,
		DateTimeOffset
	}
	public enum DateTimeZoneHandling
	{
		Local,
		Utc,
		Unspecified,
		RoundtripKind
	}
	[Flags]
	public enum DefaultValueHandling
	{
		Include = 0,
		Ignore = 1,
		Populate = 2,
		IgnoreAndPopulate = 3
	}
	public enum FloatFormatHandling
	{
		String,
		Symbol,
		DefaultValue
	}
	public enum FloatParseHandling
	{
		Double,
		Decimal
	}
	public enum Formatting
	{
		None,
		Indented
	}
	public interface IArrayPool<T>
	{
		T[] Rent(int minimumLength);

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

		int LinePosition { get; }

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

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

		public JsonArrayAttribute()
		{
		}

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

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

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		private Type _namingStrategyType;

		private object[] _namingStrategyParameters;

		public string Id { get; set; }

		public string Title { get; set; }

		public string Description { get; set; }

		public Type ItemConverterType { get; set; }

		public object[] ItemConverterParameters { get; set; }

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

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

		internal NamingStrategy NamingStrategyInstance { get; set; }

		public bool IsReference
		{
			get
			{
				return _isReference ?? false;
			}
			set
			{
				_isReference = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference ?? false;
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling ?? ReferenceLoopHandling.Error;
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling ?? TypeNameHandling.None;
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		protected JsonContainerAttribute()
		{
		}

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

		public static readonly string False = "false";

		public static readonly string Null = "null";

		public static readonly string Undefined = "undefined";

		public static readonly string PositiveInfinity = "Infinity";

		public static readonly string NegativeInfinity = "-Infinity";

		public static readonly string NaN = "NaN";

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

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

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

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

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

		public static string ToString(bool value)
		{
			if (!value)
			{
				return False;
			}
			return True;
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public static void PopulateObject(string value, object target, JsonSerializerSettings settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			using JsonReader jsonReader = new JsonTextReader(new StringReader(value));
			jsonSerializer.Populate(jsonReader, target);
			if (jsonReader.Read() && jsonReader.TokenType != JsonToken.Comment)
			{
				throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object.");
			}
		}
	}
	public abstract class JsonConverter
	{
		public virtual bool CanRead => true;

		public virtual bool CanWrite => true;

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

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

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

		public Type ConverterType => _converterType;

		public object[] ConverterParameters { get; private set; }

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

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

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

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

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

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

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

		public bool ReadData { get; set; }

		public JsonExtensionDataAttribute()
		{
			WriteData = true;
			ReadData = true;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonIgnoreAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonObjectAttribute : JsonContainerAttribute
	{
		private MemberSerialization _memberSerialization;

		internal Required? _itemRequired;

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

		public Required ItemRequired
		{
			get
			{
				return _itemRequired ?? Required.Default;
			}
			set
			{
				_itemRequired = value;
			}
		}

		public JsonObjectAttribute()
		{
		}

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

		public JsonObjectAttribute(string id)
			: base(id)
		{
		}
	}
	internal enum JsonContainerType
	{
		None,
		Object,
		Array,
		Constructor
	}
	internal struct JsonPosition
	{
		private static readonly char[] SpecialCharacters = new char[6] { '.', ' ', '[', ']', '(', ')' };

		internal JsonContainerType Type;

		internal int Position;

		internal string PropertyName;

		internal bool HasIndex;

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

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

		internal void WriteTo(StringBuilder sb)
		{
			switch (Type)
			{
			case JsonContainerType.Object:
			{
				string propertyName = PropertyName;
				if (propertyName.IndexOfAny(SpecialCharacters) != -1)
				{
					sb.Append("['");
					sb.Append(propertyName);
					sb.Append("']");
					break;
				}
				if (sb.Length > 0)
				{
					sb.Append('.');
				}
				sb.Append(propertyName);
				break;
			}
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				sb.Append('[');
				sb.Append(Position);
				sb.Append(']');
				break;
			}
		}

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

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

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

		internal DefaultValueHandling? _defaultValueHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal bool? _isReference;

		internal int? _order;

		internal Required? _required;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		public Type ItemConverterType { get; set; }

		public object[] ItemConverterParameters { get; set; }

		public Type NamingStrategyType { get; set; }

		public object[] NamingStrategyParameters { get; set; }

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling ?? NullValueHandling.Include;
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling ?? DefaultValueHandling.Include;
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling ?? ReferenceLoopHandling.Error;
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling ?? ObjectCreationHandling.Auto;
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling ?? TypeNameHandling.None;
			}
			set
			{
				_typeNameHandling = value;
			}
		}

		public bool IsReference
		{
			get
			{
				return _isReference ?? false;
			}
			set
			{
				_isReference = value;
			}
		}

		public int Order
		{
			get
			{
				return _order ?? 0;
			}
			set
			{
				_order = value;
			}
		}

		public Required Required
		{
			get
			{
				return _required ?? Required.Default;
			}
			set
			{
				_required = value;
			}
		}

		public string PropertyName { get; set; }

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling ?? ReferenceLoopHandling.Error;
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling ?? TypeNameHandling.None;
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference ?? false;
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public JsonPropertyAttribute()
		{
		}

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

		private JsonToken _tokenType;

		private object _value;

		internal char _quoteChar;

		internal State _currentState;

		private JsonPosition _currentPosition;

		private CultureInfo _culture;

		private DateTimeZoneHandling _dateTimeZoneHandling;

		private int? _maxDepth;

		private bool _hasExceededMaxDepth;

		internal DateParseHandling _dateParseHandling;

		internal FloatParseHandling _floatParseHandling;

		private string _dateFormatString;

		private List<JsonPosition> _stack;

		protected State CurrentState => _currentState;

		public bool CloseInput { get; set; }

		public bool SupportMultipleContent { get; set; }

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

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

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

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

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

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

		public virtual JsonToken TokenType => _tokenType;

		public virtual object Value => _value;

		public virtual Type ValueType
		{
			get
			{
				if (_value == null)
				{
					return null;
				}
				return _value.GetType();
			}
		}

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

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

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

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

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

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

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

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

		public abstract bool Read();

		public virtual int? ReadAsInt32()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
				if (!(Value is int))
				{
					SetToken(JsonToken.Integer, Convert.ToInt32(Value, CultureInfo.InvariantCulture), updateIndex: false);
				}
				return (int)Value;
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadInt32String(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

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

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

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

		internal byte[] ReadArrayIntoByteArray()
		{
			List<byte> list = new List<byte>();
			while (true)
			{
				JsonToken contentToken = GetContentToken();
				switch (contentToken)
				{
				case JsonToken.None:
					throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
				case JsonToken.Integer:
					break;
				case JsonToken.EndArray:
				{
					byte[] array = list.ToArray();
					SetToken(JsonToken.Bytes, array, updateIndex: false);
					return array;
				}
				default:
					throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
				}
				list.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
			}
		}

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

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

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

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

		public virtual decimal? ReadAsDecimal()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
				if (!(Value is decimal))
				{
					SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture), updateIndex: false);
				}
				return (decimal)Value;
			case JsonToken.String:
				return ReadDecimalString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		private void SetFinished()
		{
			if (SupportMultipleContent)
			{
				_currentState = State.Start;
			}
			else
			{
				_currentState = State.Finished;
			}
		}

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

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

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

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

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

		internal bool ReadAndMoveToContent()
		{
			if (Read())
			{
				return MoveToContent();
			}
			return false;
		}

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

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

		public int LinePosition { get; private set; }

		public string Path { get; private set; }

		public JsonReaderException()
		{
		}

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

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

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

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

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

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

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

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

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

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

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

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

		internal static JsonSerializationException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			return new JsonSerializationException(message, ex);
		}
	}
	public class JsonSerializer
	{
		internal TypeNameHandling _typeNameHandling;

		internal FormatterAssemblyStyle _typeNameAssemblyFormat;

		internal PreserveReferencesHandling _preserveReferencesHandling;

		internal ReferenceLoopHandling _referenceLoopHandling;

		internal MissingMemberHandling _missingMemberHandling;

		internal ObjectCreationHandling _objectCreationHandling;

		internal NullValueHandling _nullValueHandling;

		internal DefaultValueHandling _defaultValueHandling;

		internal ConstructorHandling _constructorHandling;

		internal MetadataPropertyHandling _metadataPropertyHandling;

		internal JsonConverterCollection _converters;

		internal IContractResolver _contractResolver;

		internal ITraceWriter _traceWriter;

		internal IEqualityComparer _equalityComparer;

		internal SerializationBinder _binder;

		internal StreamingContext _context;

		private IReferenceResolver _referenceResolver;

		private Formatting? _formatting;

		private DateFormatHandling? _dateFormatHandling;

		private DateTimeZoneHandling? _dateTimeZoneHandling;

		private DateParseHandling? _dateParseHandling;

		private FloatFormatHandling? _floatFormatHandling;

		private FloatParseHandling? _floatParseHandling;

		private StringEscapeHandling? _stringEscapeHandling;

		private CultureInfo _culture;

		private int? _maxDepth;

		private bool _maxDepthSet;

		private bool? _checkAdditionalContent;

		private string _dateFormatString;

		private bool _dateFormatStringSet;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public virtual Formatting Formatting
		{
			get
			{
				return _formatting ?? Formatting.None;
			}
			set
			{
				_formatting = value;
			}
		}

		public virtual DateFormatHandling DateFormatHandling
		{
			get
			{
				return _dateFormatHandling ?? DateFormatHandling.IsoDateFormat;
			}
			set
			{
				_dateFormatHandling = value;
			}
		}

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

		public virtual DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling ?? DateParseHandling.DateTime;
			}
			set
			{
				_dateParseHandling = value;
			}
		}

		public virtual FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling ?? FloatParseHandling.Double;
			}
			set
			{
				_floatParseHandling = value;
			}
		}

		public virtual FloatFormatHandling FloatFormatHandling
		{
			get
			{
				return _floatFormatHandling ?? FloatFormatHandling.String;
			}
			set
			{
				_floatFormatHandling = value;
			}
		}

		public virtual StringEscapeHandling StringEscapeHandling
		{
			get
			{
				return _stringEscapeHandling ?? StringEscapeHandling.Default;
			}
			set
			{
				_stringEscapeHandling = value;
			}
		}

		public virtual string DateFormatString
		{
			get
			{
				return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
			}
			set
			{
				_dateFormatString = value;
				_dateFormatStringSet = true;
			}
		}

		public virtual CultureInfo Culture
		{
			get
			{
				return _culture ?? JsonSerializerSettings.DefaultCulture;
			}
			set
			{
				_culture = value;
			}
		}

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

		public virtual bool CheckAdditionalContent
		{
			get
			{
				return _checkAdditionalContent ?? false;
			}
			set
			{
				_checkAdditionalContent = value;
			}
		}

		public virtual event EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs> Error;

		internal bool IsCheckAdditionalContentSet()
		{
			return _checkAdditionalContent.HasValue;
		}

		public JsonSerializer()
		{
			_referenceLoopHandling = ReferenceLoopHandling.Error;
			_missingMemberHandling = MissingMemberHandling.Ignore;
			_nullValueHandling = NullValueHandling.Include;
			_defaultValueHandling = DefaultValueHandling.Include;
			_objectCreationHandling = ObjectCreationHandling.Auto;
			_preserveReferencesHandling = PreserveReferencesHandling.None;
			_constructorHandling = ConstructorHandling.Default;
			_typeNameHandling = TypeNameHandling.None;
			_metadataPropertyHandling = MetadataPropertyHandling.Default;
			_context = JsonSerializerSettings.DefaultContext;
			_binder = DefaultSerializationBinder.Instance;
			_culture = JsonSerializerSettings.DefaultCulture;
			_contractResolver = DefaultContractResolver.Instance;
		}

		public static JsonSerializer Create()
		{
			return new JsonSerializer();
		}

		public static JsonSerializer Create(JsonSerializerSettings settings)
		{
			JsonSerializer jsonSerializer = Create();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		public static JsonSerializer CreateDefault()
		{
			return Create(JsonConvert.DefaultSettings?.Invoke());
		}

		public static JsonSerializer CreateDefault(JsonSerializerSettings settings)
		{
			JsonSerializer jsonSerializer = CreateDefault();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings)
		{
			if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
			{
				for (int i = 0; i < settings.Converters.Count; i++)
				{
					serializer.Converters.Insert(i, settings.Converters[i]);
				}
			}
			if (settings._typeNameHandling.HasValue)
			{
				serializer.TypeNameHandling = settings.TypeNameHandling;
			}
			if (settings._metadataPropertyHandling.HasValue)
			{
				serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling;
			}
			if (settings._typeNameAssemblyFormat.HasValue)
			{
				serializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat;
			}
			if (settings._preserveReferencesHandling.HasValue)
			{
				serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
			}
			if (settings._referenceLoopHandling.HasValue)
			{
				serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
			}
			if (settings._missingMemberHandling.HasValue)
			{
				serializer.MissingMemberHandling = settings.MissingMemberHandling;
			}
			if (settings._objectCreationHandling.HasValue)
			{
				serializer.ObjectCreationHandling = settings.ObjectCreationHandling;
			}
			if (settings._nullValueHandling.HasValue)
			{
				serializer.NullValueHandling = settings.NullValueHandling;
			}
			if (settings._defaultValueHandling.HasValue)
			{
				serializer.DefaultValueHandling = settings.DefaultValueHandling;
			}
			if (settings._constructorHandling.HasValue)
			{
				serializer.ConstructorHandling = settings.ConstructorHandling;
			}
			if (settings._context.HasValue)
			{
				serializer.Context = settings.Context;
			}
			if (settings._checkAdditionalContent.HasValue)
			{
				serializer._checkAdditionalContent = settings._checkAdditionalContent;
			}
			if (settings.Error != null)
			{
				serializer.Error += settings.Error;
			}
			if (settings.ContractResolver != null)
			{
				serializer.ContractResolver = settings.ContractResolver;
			}
			if (settings.ReferenceResolverProvider != null)
			{
				serializer.ReferenceResolver = settings.ReferenceResolverProvider();
			}
			if (settings.TraceWriter != null)
			{
				serializer.TraceWriter = settings.TraceWriter;
			}
			if (settings.EqualityComparer != null)
			{
				serializer.EqualityComparer = settings.EqualityComparer;
			}
			if (settings.Binder != null)
			{
				serializer.Binder = settings.Binder;
			}
			if (settings._formatting.HasValue)
			{
				serializer._formatting = settings._formatting;
			}
			if (settings._dateFormatHandling.HasValue)
			{
				serializer._dateFormatHandling = settings._dateFormatHandling;
			}
			if (settings._dateTimeZoneHandling.HasValue)
			{
				serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling;
			}
			if (settings._dateParseHandling.HasValue)
			{
				serializer._dateParseHandling = settings._dateParseHandling;
			}
			if (settings._dateFormatStringSet)
			{
				serializer._dateFormatString = settings._dateFormatString;
				serializer._dateFormatStringSet = settings._dateFormatStringSet;
			}
			if (settings._floatFormatHandling.HasValue)
			{
				serializer._floatFormatHandling = settings._floatFormatHandling;
			}
			if (settings._floatParseHandling.HasValue)
			{
				serializer._floatParseHandling = settings._floatParseHandling;
			}
			if (settings._stringEscapeHandling.HasValue)
			{
				serializer._stringEscapeHandling = settings._stringEscapeHandling;
			}
			if (settings._culture != null)
			{
				serializer._culture = settings._culture;
			}
			if (settings._maxDepthSet)
			{
				serializer._maxDepth = settings._maxDepth;
				serializer._maxDepthSet = settings._maxDepthSet;
			}
		}

		public void Populate(TextReader reader, object target)
		{
			Populate(new JsonTextReader(reader), target);
		}

		public void Populate(JsonReader reader, object target)
		{
			PopulateInternal(reader, target);
		}

		internal virtual void PopulateInternal(JsonReader reader, object target)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			ValidationUtils.ArgumentNotNull(target, "target");
			SetupReader(reader, out var previousCulture, out var previousDateTimeZoneHandling, out var previousDateParseHandling, out var previousFloatParseHandling, out var previousMaxDepth, out var previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonReader(reader) : null);
			new JsonSerializerInternalReader(this).Populate(traceJsonReader ?? reader, target);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
		}

		public object Deserialize(JsonReader reader)
		{
			return Deserialize(reader, null);
		}

		public object Deserialize(TextReader reader, Type objectType)
		{
			return Deserialize(new JsonTextReader(reader), objectType);
		}

		public T Deserialize<T>(JsonReader reader)
		{
			return (T)Deserialize(reader, typeof(T));
		}

		public object Deserialize(JsonReader reader, Type objectType)
		{
			return DeserializeInternal(reader, objectType);
		}

		internal virtual object DeserializeInternal(JsonReader reader, Type objectType)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			SetupReader(reader, out var previousCulture, out var previousDateTimeZoneHandling, out var previousDateParseHandling, out var previousFloatParseHandling, out var previousMaxDepth, out var previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonReader(reader) : null);
			object result = new JsonSerializerInternalReader(this).Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
			return result;
		}

		private void SetupReader(JsonReader reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString)
		{
			if (_culture != null && !_culture.Equals(reader.Culture))
			{
				previousCulture = reader.Culture;
				reader.Culture = _culture;
			}
			else
			{
				previousCulture = null;
			}
			if (_dateTimeZoneHandling.HasValue && reader.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				previousDateTimeZoneHandling = reader.DateTimeZoneHandling;
				reader.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			else
			{
				previousDateTimeZoneHandling = null;
			}
			if (_dateParseHandling.HasValue && reader.DateParseHandling != _dateParseHandling)
			{
				previousDateParseHandling = reader.DateParseHandling;
				reader.DateParseHandling = _dateParseHandling.GetValueOrDefault();
			}
			else
			{
				previousDateParseHandling = null;
			}
			if (_floatParseHandling.HasValue && reader.FloatParseHandling != _floatParseHandling)
			{
				previousFloatParseHandling = reader.FloatParseHandling;
				reader.FloatParseHandling = _floatParseHandling.GetValueOrDefault();
			}
			else
			{
				previousFloatParseHandling = null;
			}
			if (_maxDepthSet && reader.MaxDepth != _maxDepth)
			{
				previousMaxDepth = reader.MaxDepth;
				reader.MaxDepth = _maxDepth;
			}
			else
			{
				previousMaxDepth = null;
			}
			if (_dateFormatStringSet && reader.DateFormatString != _dateFormatString)
			{
				previousDateFormatString = reader.DateFormatString;
				reader.DateFormatString = _dateFormatString;
			}
			else
			{
				previousDateFormatString = null;
			}
			if (reader is JsonTextReader jsonTextReader && _contractResolver is DefaultContractResolver defaultContractResolver)
			{
				jsonTextReader.NameTable = defaultContractResolver.GetState().NameTable;
			}
		}

		private void ResetReader(JsonReader reader, CultureInfo previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string previousDateFormatString)
		{
			if (previousCulture != null)
			{
				reader.Culture = previousCulture;
			}
			if (previousDateTimeZoneHandling.HasValue)
			{
				reader.DateTimeZoneHandling = previousDateTimeZoneHandling.GetValueOrDefault();
			}
			if (previousDateParseHandling.HasValue)
			{
				reader.DateParseHandling = previousDateParseHandling.GetValueOrDefault();
			}
			if (previousFloatParseHandling.HasValue)
			{
				reader.FloatParseHandling = previousFloatParseHandling.GetValueOrDefault();
			}
			if (_maxDepthSet)
			{
				reader.MaxDepth = previousMaxDepth;
			}
			if (_dateFormatStringSet)
			{
				reader.DateFormatString = previousDateFormatString;
			}
			if (reader is JsonTextReader jsonTextReader)
			{
				jsonTextReader.NameTable = null;
			}
		}

		public void Serialize(TextWriter textWriter, object value)
		{
			Serialize(new JsonTextWriter(textWriter), value);
		}

		public void Serialize(JsonWriter jsonWriter, object value, Type objectType)
		{
			SerializeInternal(jsonWriter, value, objectType);
		}

		public void Serialize(TextWriter textWriter, object value, Type objectType)
		{
			Serialize(new JsonTextWriter(textWriter), value, objectType);
		}

		public void Serialize(JsonWriter jsonWriter, object value)
		{
			SerializeInternal(jsonWriter, value, null);
		}

		internal virtual void SerializeInternal(JsonWriter jsonWriter, object value, Type objectType)
		{
			ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");
			Formatting? formatting = null;
			if (_formatting.HasValue && jsonWriter.Formatting != _formatting)
			{
				formatting = jsonWriter.Formatting;
				jsonWriter.Formatting = _formatting.GetValueOrDefault();
			}
			DateFormatHandling? dateFormatHandling = null;
			if (_dateFormatHandling.HasValue && jsonWriter.DateFormatHandling != _dateFormatHandling)
			{
				dateFormatHandling = jsonWriter.DateFormatHandling;
				jsonWriter.DateFormatHandling = _dateFormatHandling.GetValueOrDefault();
			}
			DateTimeZoneHandling? dateTimeZoneHandling = null;
			if (_dateTimeZoneHandling.HasValue && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				dateTimeZoneHandling = jsonWriter.DateTimeZoneHandling;
				jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			FloatFormatHandling? floatFormatHandling = null;
			if (_floatFormatHandling.HasValue && jsonWriter.FloatFormatHandling != _floatFormatHandling)
			{
				floatFormatHandling = jsonWriter.FloatFormatHandling;
				jsonWriter.FloatFormatHandling = _floatFormatHandling.GetValueOrDefault();
			}
			StringEscapeHandling? stringEscapeHandling = null;
			if (_stringEscapeHandling.HasValue && jsonWriter.StringEscapeHandling != _stringEscapeHandling)
			{
				stringEscapeHandling = jsonWriter.StringEscapeHandling;
				jsonWriter.StringEscapeHandling = _stringEscapeHandling.GetValueOrDefault();
			}
			CultureInfo cultureInfo = null;
			if (_culture != null && !_culture.Equals(jsonWriter.Culture))
			{
				cultureInfo = jsonWriter.Culture;
				jsonWriter.Culture = _culture;
			}
			string dateFormatString = null;
			if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString)
			{
				dateFormatString = jsonWriter.DateFormatString;
				jsonWriter.DateFormatString = _dateFormatString;
			}
			TraceJsonWriter traceJsonWriter = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonWriter(jsonWriter) : null);
			new JsonSerializerInternalWriter(this).Serialize(traceJsonWriter ?? jsonWriter, value, objectType);
			if (traceJsonWriter != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonWriter.GetSerializedJsonMessage(), null);
			}
			if (formatting.HasValue)
			{
				jsonWriter.Formatting = formatting.GetValueOrDefault();
			}
			if (dateFormatHandling.HasValue)
			{
				jsonWriter.DateFormatHandling = dateFormatHandling.GetValueOrDefault();
			}
			if (dateTimeZoneHandling.HasValue)
			{
				jsonWriter.DateTimeZoneHandling = dateTimeZoneHandling.GetValueOrDefault();
			}
			if (floatFormatHandling.HasValue)
			{
				jsonWriter.FloatFormatHandling = floatFormatHandling.GetValueOrDefault();
			}
			if (stringEscapeHandling.HasValue)
			{
				jsonWriter.StringEscapeHandling = stringEscapeHandling.GetValueOrDefault();
			}
			if (_dateFormatStringSet)
			{
				jsonWriter.DateFormatString = dateFormatString;
			}
			if (cultureInfo != null)
			{
				jsonWriter.Culture = cultureInfo;
			}
		}

		internal IReferenceResolver GetReferenceResolver()
		{
			if (_referenceResolver == null)
			{
				_referenceResolver = new DefaultReferenceResolver();
			}
			return _referenceResolver;
		}

		internal JsonConverter GetMatchingConverter(Type type)
		{
			return GetMatchingConverter(_converters, type);
		}

		internal static JsonConverter GetMatchingConverter(IList<JsonConverter> converters, Type objectType)
		{
			if (converters != null)
			{
				for (int i = 0; i < converters.Count; i++)
				{
					JsonConverter jsonConverter = converters[i];
					if (jsonConverter.CanConvert(objectType))
					{
						return jsonConverter;
					}
				}
			}
			return null;
		}

		internal void OnError(Newtonsoft.Json.Serialization.ErrorEventArgs e)
		{
			this.Error?.Invoke(this, e);
		}
	}
	public class JsonSerializerSettings
	{
		internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error;

		internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore;

		internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include;

		internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include;

		internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto;

		internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None;

		internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default;

		internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None;

		internal const MetadataPropertyHandling DefaultMetadataPropertyHandling = MetadataPropertyHandling.Default;

		internal const FormatterAssemblyStyle DefaultTypeNameAssemblyFormat = FormatterAssemblyStyle.Simple;

		internal static readonly StreamingContext DefaultContext;

		internal const Formatting DefaultFormatting = Formatting.None;

		internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat;

		internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;

		internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime;

		internal const FloatParseHandling DefaultFloatParseHandling = FloatParseHandling.Double;

		internal const FloatFormatHandling DefaultFloatFormatHandling = FloatFormatHandling.String;

		internal const StringEscapeHandling DefaultStringEscapeHandling = StringEscapeHandling.Default;

		internal const FormatterAssemblyStyle DefaultFormatterAssemblyStyle = FormatterAssemblyStyle.Simple;

		internal static readonly CultureInfo DefaultCulture;

		internal const bool DefaultCheckAdditionalContent = false;

		internal const string DefaultDateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";

		internal Formatting? _formatting;

		internal DateFormatHandling? _dateFormatHandling;

		internal DateTimeZoneHandling? _dateTimeZoneHandling;

		internal DateParseHandling? _dateParseHandling;

		internal FloatFormatHandling? _floatFormatHandling;

		internal FloatParseHandling? _floatParseHandling;

		internal StringEscapeHandling? _stringEscapeHandling;

		internal CultureInfo _culture;

		internal bool? _checkAdditionalContent;

		internal int? _maxDepth;

		internal bool _maxDepthSet;

		internal string _dateFormatString;

		internal bool _dateFormatStringSet;

		internal FormatterAssemblyStyle? _typeNameAssemblyFormat;

		internal DefaultValueHandling? _defaultValueHandling;

		internal PreserveReferencesHandling? _preserveReferencesHandling;

		internal NullValueHandling? _nullValueHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal MissingMemberHandling? _missingMemberHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal StreamingContext? _context;

		internal ConstructorHandling? _constructorHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal MetadataPropertyHandling? _metadataPropertyHandling;

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling ?? ReferenceLoopHandling.Error;
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling ?? MissingMemberHandling.Ignore;
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling ?? ObjectCreationHandling.Auto;
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling ?? NullValueHandling.Include;
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling ?? DefaultValueHandling.Include;
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public IList<JsonConverter> Converters { get; set; }

		public PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling ?? PreserveReferencesHandling.None;
			}
			set
			{
				_preserveReferencesHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling ?? TypeNameHandling.None;
			}
			set
			{
				_typeNameHandling = value;
			}
		}

		public MetadataPropertyHandling MetadataPropertyHandling
		{
			get
			{
				return _metadataPropertyHandling ?? MetadataPropertyHandling.Default;
			}
			set
			{
				_metadataPropertyHandling = value;
			}
		}

		public FormatterAssemblyStyle TypeNameAssemblyFormat
		{
			get
			{
				return _typeNameAssemblyFormat ?? FormatterAssemblyStyle.Simple;
			}
			set
			{
				_typeNameAssemblyFormat = value;
			}
		}

		public ConstructorHandling ConstructorHandling
		{
			get
			{
				return _constructorHandling ?? ConstructorHandling.Default;
			}
			set
			{
				_constructorHandling = value;
			}
		}

		public IContractResolver ContractResolver { get; set; }

		public IEqualityComparer EqualityComparer { get; set; }

		[Obsolete("ReferenceResolver property is obsolete. Use the ReferenceResolverProvider property to set the IReferenceResolver: settings.ReferenceResolverProvider = () => resolver")]
		public IReferenceResolver ReferenceResolver
		{
			get
			{
				if (ReferenceResolverProvider == null)
				{
					return null;
				}
				return ReferenceResolverProvider();
			}
			set
			{
				ReferenceResolverProvider = ((value != null) ? ((Func<IReferenceResolver>)(() => value)) : null);
			}
		}

		public Func<IReferenceResolver> ReferenceResolverProvider { get; set; }

		public ITraceWriter TraceWriter { get; set; }

		public SerializationBinder Binder { get; set; }

		public EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs> Error { get; set; }

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

		public string DateFormatString
		{
			get
			{
				return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
			}
			set
			{
				_dateFormatString = value;
				_dateFormatStringSet = true;
			}
		}

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

		public Formatting Formatting
		{
			get
			{
				return _formatting ?? Formatting.None;
			}
			set
			{
				_formatting = value;
			}
		}

		public DateFormatHandling DateFormatHandling
		{
			get
			{
				return _dateFormatHandling ?? DateFormatHandling.IsoDateFormat;
			}
			set
			{
				_dateFormatHandling = value;
			}
		}

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

		public DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling ?? DateParseHandling.DateTime;
			}
			set
			{
				_dateParseHandling = value;
			}
		}

		public FloatFormatHandling FloatFormatHandling
		{
			get
			{
				return _floatFormatHandling ?? FloatFormatHandling.String;
			}
			set
			{
				_floatFormatHandling = value;
			}
		}

		public FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling ?? FloatParseHandling.Double;
			}
			set
			{
				_floatParseHandling = value;
			}
		}

		public StringEscapeHandling StringEscapeHandling
		{
			get
			{
				return _stringEscapeHandling ?? StringEscapeHandling.Default;
			}
			set
			{
				_stringEscapeHandling = value;
			}
		}

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

		public bool CheckAdditionalContent
		{
			get
			{
				return _checkAdditionalContent ?? false;
			}
			set
			{
				_checkAdditionalContent = value;
			}
		}

		static JsonSerializerSettings()
		{
			DefaultContext = default(StreamingContext);
			DefaultCulture = CultureInfo.InvariantCulture;
		}

		public JsonSerializerSettings()
		{
			Converters = new List<JsonConverter>();
		}
	}
	internal enum ReadType
	{
		Read,
		ReadAsInt32,
		ReadAsBytes,
		ReadAsString,
		ReadAsDecimal,
		ReadAsDateTime,
		ReadAsDateTimeOffset,
		ReadAsDouble,
		ReadAsBoolean
	}
	public class JsonTextReader : JsonReader, IJsonLineInfo
	{
		private const char UnicodeReplacementChar = '\ufffd';

		private const int MaximumJavascriptIntegerCharacterLength = 380;

		private readonly TextReader _reader;

		private char[] _chars;

		private int _charsUsed;

		private int _charPos;

		private int _lineStartPos;

		private int _lineNumber;

		private bool _isEndOfFile;

		private StringBuffer _stringBuffer;

		private StringReference _stringReference;

		private IArrayPool<char> _arrayPool;

		internal PropertyNameTable NameTable;

		public IArrayPool<char> ArrayPool
		{
			get
			{
				return _arrayPool;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				_arrayPool = value;
			}
		}

		public int LineNumber
		{
			get
			{
				if (base.CurrentState == State.Start && LinePosition == 0 && TokenType != JsonToken.Comment)
				{
					return 0;
				}
				return _lineNumber;
			}
		}

		public int LinePosition => _charPos - _lineStartPos;

		public JsonTextReader(TextReader reader)
		{
			if (reader == null)
			{
				throw new ArgumentNullException("reader");
			}
			_reader = reader;
			_lineNumber = 1;
		}

		private void EnsureBufferNotEmpty()
		{
			if (_stringBuffer.IsEmpty)
			{
				_stringBuffer = new StringBuffer(_arrayPool, 1024);
			}
		}

		private void OnNewLine(int pos)
		{
			_lineNumber++;
			_lineStartPos = pos;
		}

		private void ParseString(char quote, ReadType readType)
		{
			_charPos++;
			ShiftBufferIfNeeded();
			ReadStringIntoBuffer(quote);
			SetPostValueState(updateIndex: true);
			switch (readType)
			{
			case ReadType.ReadAsBytes:
			{
				Guid g;
				byte[] value2 = ((_stringReference.Length == 0) ? new byte[0] : ((_stringReference.Length != 36 || !ConvertUtils.TryConvertGuid(_stringReference.ToString(), out g)) ? Convert.FromBase64CharArray(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length) : g.ToByteArray()));
				SetToken(JsonToken.Bytes, value2, updateIndex: false);
				return;
			}
			case ReadType.ReadAsString:
			{
				string value = _stringReference.ToString();
				SetToken(JsonToken.String, value, updateIndex: false);
				_quoteChar = quote;
				return;
			}
			case ReadType.ReadAsInt32:
			case ReadType.ReadAsDecimal:
			case ReadType.ReadAsBoolean:
				return;
			}
			if (_dateParseHandling != 0)
			{
				DateTimeOffset dt2;
				if (readType switch
				{
					ReadType.ReadAsDateTime => 1, 
					ReadType.ReadAsDateTimeOffset => 2, 
					_ => (int)_dateParseHandling, 
				} == 1)
				{
					if (DateTimeUtils.TryParseDateTime(_stringReference, base.DateTimeZoneHandling, base.DateFormatString, base.Culture, out var dt))
					{
						SetToken(JsonToken.Date, dt, updateIndex: false);
						return;
					}
				}
				else if (DateTimeUtils.TryParseDateTimeOffset(_stringReference, base.DateFormatString, base.Culture, out dt2))
				{
					SetToken(JsonToken.Date, dt2, updateIndex: false);
					return;
				}
			}
			SetToken(JsonToken.String, _stringReference.ToString(), updateIndex: false);
			_quoteChar = quote;
		}

		private static void BlockCopyChars(char[] src, int srcOffset, char[] dst, int dstOffset, int count)
		{
			Buffer.BlockCopy(src, srcOffset * 2, dst, dstOffset * 2, count * 2);
		}

		private void ShiftBufferIfNeeded()
		{
			int num = _chars.Length;
			if ((double)(num - _charPos) <= (double)num * 0.1)
			{
				int num2 = _charsUsed - _charPos;
				if (num2 > 0)
				{
					BlockCopyChars(_chars, _charPos, _chars, 0, num2);
				}
				_lineStartPos -= _charPos;
				_charPos = 0;
				_charsUsed = num2;
				_chars[_charsUsed] = '\0';
			}
		}

		private int ReadData(bool append)
		{
			return ReadData(append, 0);
		}

		private int ReadData(bool append, int charsRequired)
		{
			if (_isEndOfFile)
			{
				return 0;
			}
			if (_charsUsed + charsRequired >= _chars.Length - 1)
			{
				if (append)
				{
					int minSize = Math.Max(_chars.Length * 2, _charsUsed + charsRequired + 1);
					char[] array = BufferUtils.RentBuffer(_arrayPool, minSize);
					BlockCopyChars(_chars, 0, array, 0, _chars.Length);
					BufferUtils.ReturnBuffer(_arrayPool, _chars);
					_chars = array;
				}
				else
				{
					int num = _charsUsed - _charPos;
					if (num + charsRequired + 1 >= _chars.Length)
					{
						char[] array2 = BufferUtils.RentBuffer(_arrayPool, num + charsRequired + 1);
						if (num > 0)
						{
							BlockCopyChars(_chars, _charPos, array2, 0, num);
						}
						BufferUtils.ReturnBuffer(_arrayPool, _chars);
						_chars = array2;
					}
					else if (num > 0)
					{
						BlockCopyChars(_chars, _charPos, _chars, 0, num);
					}
					_lineStartPos -= _charPos;
					_charPos = 0;
					_charsUsed = num;
				}
			}
			int count = _chars.Length - _charsUsed - 1;
			int num2 = _reader.Read(_chars, _charsUsed, count);
			_charsUsed += num2;
			if (num2 == 0)
			{
				_isEndOfFile = true;
			}
			_chars[_charsUsed] = '\0';
			return num2;
		}

		private bool EnsureChars(int relativePosition, bool append)
		{
			if (_charPos + relativePosition >= _charsUsed)
			{
				return ReadChars(relativePosition, append);
			}
			return true;
		}

		private bool ReadChars(int relativePosition, bool append)
		{
			if (_isEndOfFile)
			{
				return false;
			}
			int num = _charPos + relativePosition - _charsUsed + 1;
			int num2 = 0;
			do
			{
				int num3 = ReadData(append, num - num2);
				if (num3 == 0)
				{
					break;
				}
				num2 += num3;
			}
			while (num2 < num);
			if (num2 < num)
			{
				return false;
			}
			return true;
		}

		public override bool Read()
		{
			EnsureBuffer();
			do
			{
				switch (_currentState)
				{
				case State.Start:
				case State.Property:
				case State.ArrayStart:
				case State.Array:
				case State.ConstructorStart:
				case State.Constructor:
					return ParseValue();
				case State.ObjectStart:
				case State.Object:
					return ParseObject();
				case State.PostValue:
					break;
				case State.Finished:
					if (EnsureChars(0, append: false))
					{
						EatWhitespace(oneOrMore: false);
						if (_isEndOfFile)
						{
							SetToken(JsonToken.None);
							return false;
						}
						if (_chars[_charPos] == '/')
						{
							ParseComment(setToken: true);
							return true;
						}
						throw JsonReaderException.Create(this, "Additional text encountered after finished reading JSON content: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
					}
					SetToken(JsonToken.None);
					return false;
				default:
					throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState));
				}
			}
			while (!ParsePostValue());
			return true;
		}

		public override int? ReadAsInt32()
		{
			return (int?)ReadNumberValue(ReadType.ReadAsInt32);
		}

		public override DateTime? ReadAsDateTime()
		{
			return (DateTime?)ReadStringValue(ReadType.ReadAsDateTime);
		}

		public override string ReadAsString()
		{
			return (string)ReadStringValue(ReadType.ReadAsString);
		}

		public override byte[] ReadAsBytes()
		{
			EnsureBuffer();
			bool flag = false;
			switch (_currentState)
			{
			case State.Start:
			case State.Property:
			case State.ArrayStart:
			case State.Array:
			case State.PostValue:
			case State.ConstructorStart:
			case State.Constructor:
				while (true)
				{
					char c = _chars[_charPos];
					switch (c)
					{
					case '\0':
						if (ReadNullChar())
						{
							SetToken(JsonToken.None, null, updateIndex: false);
							return null;
						}
						break;
					case '"':
					case '\'':
					{
						ParseString(c, ReadType.ReadAsBytes);
						byte[] array = (byte[])Value;
						if (flag)
						{
							ReaderReadAndAssert();
							if (TokenType != JsonToken.EndObject)
							{
								throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
							}
							SetToken(JsonToken.Bytes, array, updateIndex: false);
						}
						return array;
					}
					case '{':
						_charPos++;
						SetToken(JsonToken.StartObject);
						ReadIntoWrappedTypeObject();
						flag = true;
						break;
					case '[':
						_charPos++;
						SetToken(JsonToken.StartArray);
						return ReadArrayIntoByteArray();
					case 'n':
						HandleNull();
						return null;
					case '/':
						ParseComment(setToken: false);
						break;
					case ',':
						ProcessValueComma();
						break;
					case ']':
						_charPos++;
						if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue)
						{
							SetToken(JsonToken.EndArray);
							return null;
						}
						throw CreateUnexpectedCharacterException(c);
					case '\r':
						ProcessCarriageReturn(append: false);
						break;
					case '\n':
						ProcessLineFeed();
						break;
					case '\t':
					case ' ':
						_charPos++;
						break;
					default:
						_charPos++;
						if (!char.IsWhiteSpace(c))
						{
							throw CreateUnexpectedCharacterException(c);
						}
						break;
					}
				}
			case State.Finished:
				ReadFinished();
				return null;
			default:
				throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState));
			}
		}

		private object ReadStringValue(ReadType readType)
		{
			EnsureBuffer();
			switch (_currentState)
			{
			case State.Start:
			case State.Property:
			case State.ArrayStart:
			case State.Array:
			case State.PostValue:
			case State.ConstructorStart:
			case State.Constructor:
				while (true)
				{
					char c = _chars[_charPos];
					switch (c)
					{
					case '\0':
						if (ReadNullChar())
						{
							SetToken(JsonToken.None, null, updateIndex: false);
							return null;
						}
						break;
					case '"':
					case '\'':
						ParseString(c, readType);
						switch (readType)
						{
						case ReadType.ReadAsBytes:
							return Value;
						case ReadType.ReadAsString:
							return Value;
						case ReadType.ReadAsDateTime:
							if (Value is DateTime)
							{
								return (DateTime)Value;
							}
							return ReadDateTimeString((string)Value);
						case ReadType.ReadAsDateTimeOffset:
							if (Value is DateTimeOffset)
							{
								return (DateTimeOffset)Value;
							}
							return ReadDateTimeOffsetString((string)Value);
						default:
							throw new ArgumentOutOfRangeException("readType");
						}
					case '-':
						if (EnsureChars(1, append: true) && _chars[_charPos + 1] == 'I')
						{
							return ParseNumberNegativeInfinity(readType);
						}
						ParseNumber(readType);
						return Value;
					case '.':
					case '0':
					case '1':
					case '2':
					case '3':
					case '4':
					case '5':
					case '6':
					case '7':
					case '8':
					case '9':
						if (readType != ReadType.ReadAsString)
						{
							_charPos++;
							throw CreateUnexpectedCharacterException(c);
						}
						ParseNumber(ReadType.ReadAsString);
						return Value;
					case 'f':
					case 't':
					{
						if (readType != ReadType.ReadAsString)
						{
							_charPos++;
							throw CreateUnexpectedCharacterException(c);
						}
						string text = ((c == 't') ? JsonConvert.True : JsonConvert.False);
						if (!MatchValueWithTrailingSeparator(text))
						{
							throw CreateUnexpectedCharacterException(_chars[_charPos]);
						}
						SetToken(JsonToken.String, text);
						return text;
					}
					case 'I':
						return ParseNumberPositiveInfinity(readType);
					case 'N':
						return ParseNumberNaN(readType);
					case 'n':
						HandleNull();
						return null;
					case '/':
						ParseComment(setToken: false);
						break;
					case ',':
						ProcessValueComma();
						break;
					case ']':
						_charPos++;
						if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue)
						{
							SetToken(JsonToken.EndArray);
							return null;
						}
						throw CreateUnexpectedCharacterException(c);
					case '\r':
						ProcessCarriageReturn(append: false);
						break;
					case '\n':
						ProcessLineFeed();
						break;
					case '\t':
					case ' ':
						_charPos++;
						break;
					default:
						_charPos++;
						if (!char.IsWhiteSpace(c))
						{
							throw CreateUnexpectedCharacterException(c);
						}
						break;
					}
				}
			case State.Finished:
				ReadFinished();
				return null;
			default:
				throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState));
			}
		}

		private JsonReaderException CreateUnexpectedCharacterException(char c)
		{
			return JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, c));
		}

		public override bool? ReadAsBoolean()
		{
			EnsureBuffer();
			switch (_currentState)
			{
			case State.Start:
			case State.Property:
			case State.ArrayStart:
			case State.Array:
			case State.PostValue:
			case State.ConstructorStart:
			case State.Constructor:
				while (true)
				{
					char c = _chars[_charPos];
					switch (c)
					{
					case '\0':
						if (ReadNullChar())
						{
							SetToken(JsonToken.None, null, updateIndex: false);
							return null;
						}
						break;
					case '"':
					case '\'':
						ParseString(c, ReadType.Read);
						return ReadBooleanString(_stringReference.ToString());
					case 'n':
						HandleNull();
						return null;
					case '-':
					case '.':
					case '0':
					case '1':
					case '2':
					case '3':
					case '4':
					case '5':
					case '6':
					case '7':
					case '8':
					case '9':
					{
						ParseNumber(ReadType.Read);
						bool flag2 = Convert.ToBoolean(Value, CultureInfo.InvariantCulture);
						SetToken(JsonToken.Boolean, flag2, updateIndex: false);
						return flag2;
					}
					case 'f':
					case 't':
					{
						bool flag = c == 't';
						string value = (flag ? JsonConvert.True : JsonConvert.False);
						if (!MatchValueWithTrailingSeparator(value))
						{
							throw CreateUnexpectedCharacterException(_chars[_charPos]);
						}
						SetToken(JsonToken.Boolean, flag);
						return flag;
					}
					case '/':
						ParseComment(setToken: false);
						break;
					case ',':
						ProcessValueComma();
						break;
					case ']':
						_charPos++;
						if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue)
						{
							SetToken(JsonToken.EndArray);
							return null;
						}
						throw CreateUnexpectedCharacterException(c);
					case '\r':
						ProcessCarriageReturn(append: false);
						break;
					case '\n':
						ProcessLineFeed();
						break;
					case '\t':
					case ' ':
						_charPos++;
						break;
					default:
						_charPos++;
						if (!char.IsWhiteSpace(c))
						{
							throw CreateUnexpectedCharacterException(c);
						}
						break;
					}
				}
			case State.Finished:
				ReadFinished();
				return null;
			default:
				throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState));
			}
		}

		private void ProcessValueComma()
		{
			_charPos++;
			if (_currentState != State.PostValue)
			{
				SetToken(JsonToken.Undefined);
				throw CreateUnexpectedCharacterException(',');
			}
			SetStateBasedOnCurrent();
		}

		private object ReadNumberValue(ReadType readType)
		{
			EnsureBuffer();
			switch (_currentState)
			{
			case State.Start:
			case State.Property:
			case State.ArrayStart:
			case State.Array:
			case State.PostValue:
			case State.ConstructorStart:
			case State.Constructor:
				while (true)
				{
					char c = _chars[_charPos];
					switch (c)
					{
					case '\0':
						if (ReadNullChar())
						{
							SetToken(JsonToken.None, null, updateIndex: false);
							return null;
						}
						break;
					case '"':
					case '\'':
						ParseString(c, readType);
						return readType switch
						{
							ReadType.ReadAsInt32 => ReadInt32String(_stringReference.ToString()), 
							ReadType.ReadAsDecimal => ReadDecimalString(_stringReference.ToString()), 
							ReadType.ReadAsDouble => ReadDoubleString(_stringReference.ToString()), 
							_ => throw new ArgumentOutOfRangeException("readType"), 
						};
					case 'n':
						HandleNull();
						return null;
					case 'N':
						return ParseNumberNaN(readType);
					case 'I':
						return ParseNumberPositiveInfinity(readType);
					case '-':
						if (EnsureChars(1, append: true) && _chars[_charPos + 1] == 'I')
						{
							return ParseNumberNegativeInfinity(readType);
						}
						ParseNumber(readType);
						return Value;
					case '.':
					case '0':
					case '1':
					case '2':
					case '3':
					case '4':
					case '5':
					case '6':
					case '7':
					case '8':
					case '9':
						ParseNumber(readType);
						return Value;
					case '/':
						ParseComment(setToken: false);
						break;
					case ',':
						ProcessValueComma();
						break;
					case ']':
						_charPos++;
						if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue)
						{
							SetToken(JsonToken.EndArray);
							return null;
						}
						throw CreateUnexpectedCharacterException(c);
					case '\r':
						ProcessCarriageReturn(append: false);
						break;
					case '\n':
						ProcessLineFeed();
						break;
					case '\t':
					case ' ':
						_charPos++;
						break;
					default:
						_charPos++;
						if (!char.IsWhiteSpace(c))
						{
							throw CreateUnexpectedCharacterException(c);
						}
						break;
					}
				}
			case State.Finished:
				ReadFinished();
				return null;
			default:
				throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState));
			}
		}

		public override DateTimeOffset? ReadAsDateTimeOffset()
		{
			return (DateTimeOffset?)ReadStringValue(ReadType.ReadAsDateTimeOffset);
		}

		public override decimal? ReadAsDecimal()
		{
			return (decimal?)ReadNumberValue(ReadType.ReadAsDecimal);
		}

		public override double? ReadAsDouble()
		{
			return (double?)ReadNumberValue(ReadType.ReadAsDouble);
		}

		private void HandleNull()
		{
			if (EnsureChars(1, append: true))
			{
				if (_chars[_charPos + 1] == 'u')
				{
					ParseNull();
					return;
				}
				_charPos += 2;
				throw CreateUnexpectedCharacterException(_chars[_charPos - 1]);
			}
			_charPos = _charsUsed;
			throw CreateUnexpectedEndException();
		}

		private void ReadF

System.Runtime.Serialization.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

[assembly: AssemblyTitle("System.Runtime.Serialization.dll")]
[assembly: AssemblyDescription("System.Runtime.Serialization.dll")]
[assembly: AssemblyDefaultAlias("System.Runtime.Serialization.dll")]
[assembly: AssemblyCompany("MONO development team")]
[assembly: AssemblyProduct("MONO Common language infrastructure")]
[assembly: AssemblyCopyright("(c) various MONO Authors")]
[assembly: SatelliteContractVersion("2.0.5.0")]
[assembly: AssemblyInformationalVersion("3.0.40818.0")]
[assembly: AssemblyFileVersion("3.0.40818.0")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyDelaySign(true)]
[assembly: AssemblyKeyFile("../silverlight.pub")]
[assembly: InternalsVisibleTo("System.ServiceModel, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
[assembly: InternalsVisibleTo("System.ServiceModel.Web, PublicKey=00240000048000009400000006020000002400005253413100040000010001008D56C76F9E8649383049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B37AB")]
[assembly: ComVisible(false)]
[assembly: CompilationRelaxations(CompilationRelaxations.NoStringInterning)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("2.0.5.0")]
namespace System.Runtime.Serialization
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
	public sealed class CollectionDataContractAttribute : Attribute
	{
		private string name;

		private string ns;

		private string item_name;

		private string key_name;

		private string value_name;

		private bool is_reference;

		public string Name
		{
			get
			{
				return name;
			}
			set
			{
				name = value;
			}
		}

		public string Namespace
		{
			get
			{
				return ns;
			}
			set
			{
				ns = value;
			}
		}

		public string ItemName
		{
			get
			{
				return item_name;
			}
			set
			{
				item_name = value;
			}
		}

		public string KeyName
		{
			get
			{
				return key_name;
			}
			set
			{
				key_name = value;
			}
		}

		public string ValueName
		{
			get
			{
				return value_name;
			}
			set
			{
				value_name = value;
			}
		}

		public bool IsReference { get; set; }
	}
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module, Inherited = false, AllowMultiple = true)]
	public sealed class ContractNamespaceAttribute : Attribute
	{
		private string clr_ns;

		private string contract_ns;

		public string ClrNamespace
		{
			get
			{
				return clr_ns;
			}
			set
			{
				clr_ns = value;
			}
		}

		public string ContractNamespace => contract_ns;

		public ContractNamespaceAttribute(string ns)
		{
			contract_ns = ns;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, Inherited = false, AllowMultiple = false)]
	public sealed class DataContractAttribute : Attribute
	{
		private string name;

		private string ns;

		public string Name
		{
			get
			{
				return name;
			}
			set
			{
				name = value;
			}
		}

		public string Namespace
		{
			get
			{
				return ns;
			}
			set
			{
				ns = value;
			}
		}

		public bool IsReference { get; set; }
	}
	public sealed class DataContractSerializer : XmlObjectSerializer
	{
		private const string xmlns = "http://www.w3.org/2000/xmlns/";

		private Type type;

		private bool ignore_ext;

		private bool preserve_refs;

		private StreamingContext context;

		private ReadOnlyCollection<Type> known_runtime_types;

		private KnownTypeCollection known_types;

		private IDataContractSurrogate surrogate;

		private int max_items = 65536;

		private bool names_filled;

		private XmlDictionaryString root_name;

		private XmlDictionaryString root_ns;

		public bool IgnoreExtensionDataObject => ignore_ext;

		public ReadOnlyCollection<Type> KnownTypes => known_runtime_types;

		public IDataContractSurrogate DataContractSurrogate => surrogate;

		public int MaxItemsInObjectGraph => max_items;

		public bool PreserveObjectReferences => preserve_refs;

		public DataContractSerializer(Type type)
			: this(type, Type.EmptyTypes)
		{
		}

		public DataContractSerializer(Type type, IEnumerable<Type> knownTypes)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			this.type = type;
			known_types = new KnownTypeCollection();
			PopulateTypes(knownTypes);
			known_types.TryRegister(type);
			XmlQualifiedName qName = known_types.GetQName(type);
			FillDictionaryString(qName.Name, qName.Namespace);
		}

		public DataContractSerializer(Type type, string rootName, string rootNamespace)
			: this(type, rootName, rootNamespace, Type.EmptyTypes)
		{
		}

		public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace)
			: this(type, rootName, rootNamespace, Type.EmptyTypes)
		{
		}

		public DataContractSerializer(Type type, string rootName, string rootNamespace, IEnumerable<Type> knownTypes)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (rootName == null)
			{
				throw new ArgumentNullException("rootName");
			}
			if (rootNamespace == null)
			{
				throw new ArgumentNullException("rootNamespace");
			}
			this.type = type;
			PopulateTypes(knownTypes);
			FillDictionaryString(rootName, rootNamespace);
		}

		public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace, IEnumerable<Type> knownTypes)
		{
			if ((object)type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (rootName == null)
			{
				throw new ArgumentNullException("rootName");
			}
			if (rootNamespace == null)
			{
				throw new ArgumentNullException("rootNamespace");
			}
			this.type = type;
			PopulateTypes(knownTypes);
			root_name = rootName;
			root_ns = rootNamespace;
		}

		public DataContractSerializer(Type type, IEnumerable<Type> knownTypes, int maxObjectsInGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate)
			: this(type, knownTypes)
		{
			Initialize(maxObjectsInGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate);
		}

		public DataContractSerializer(Type type, string rootName, string rootNamespace, IEnumerable<Type> knownTypes, int maxObjectsInGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate)
			: this(type, rootName, rootNamespace, knownTypes)
		{
			Initialize(maxObjectsInGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate);
		}

		public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace, IEnumerable<Type> knownTypes, int maxObjectsInGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate)
			: this(type, rootName, rootNamespace, knownTypes)
		{
			Initialize(maxObjectsInGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate);
		}

		private void PopulateTypes(IEnumerable<Type> knownTypes)
		{
			if (known_types == null)
			{
				known_types = new KnownTypeCollection();
			}
			if (knownTypes != null)
			{
				foreach (Type knownType in knownTypes)
				{
					known_types.TryRegister(knownType);
				}
			}
			Type elementType = type;
			if (type.HasElementType)
			{
				elementType = type.GetElementType();
			}
			object[] customAttributes = elementType.GetCustomAttributes(typeof(KnownTypeAttribute), inherit: true);
			for (int i = 0; i < customAttributes.Length; i++)
			{
				KnownTypeAttribute knownTypeAttribute = (KnownTypeAttribute)customAttributes[i];
				known_types.TryRegister(knownTypeAttribute.Type);
			}
		}

		private void FillDictionaryString(string name, string ns)
		{
			XmlDictionary xmlDictionary = new XmlDictionary();
			root_name = xmlDictionary.Add(name);
			root_ns = xmlDictionary.Add(ns);
			names_filled = true;
		}

		private void Initialize(int maxObjectsInGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences, IDataContractSurrogate dataContractSurrogate)
		{
			if (maxObjectsInGraph < 0)
			{
				throw new ArgumentOutOfRangeException("maxObjectsInGraph must not be negative.");
			}
			max_items = maxObjectsInGraph;
			ignore_ext = ignoreExtensionDataObject;
			preserve_refs = preserveObjectReferences;
			surrogate = dataContractSurrogate;
			PopulateTypes(Type.EmptyTypes);
		}

		[MonoTODO]
		public override bool IsStartObject(XmlDictionaryReader reader)
		{
			throw new NotImplementedException();
		}

		public override bool IsStartObject(XmlReader reader)
		{
			return IsStartObject(XmlDictionaryReader.CreateDictionaryReader(reader));
		}

		public override object ReadObject(XmlReader reader)
		{
			return ReadObject(XmlDictionaryReader.CreateDictionaryReader(reader));
		}

		public override object ReadObject(XmlReader reader, bool verifyObjectName)
		{
			return ReadObject(XmlDictionaryReader.CreateDictionaryReader(reader), verifyObjectName);
		}

		[MonoTODO]
		public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
		{
			int count = known_types.Count;
			known_types.Add(type);
			bool isEmptyElement = reader.IsEmptyElement;
			object result = XmlFormatterDeserializer.Deserialize(reader, type, known_types, surrogate, root_name.Value, root_ns.Value, verifyObjectName);
			while (known_types.Count > count)
			{
				known_types.RemoveAt(count);
			}
			return result;
		}

		private void ReadRootStartElement(XmlReader reader, Type type)
		{
			SerializationMap serializationMap = known_types.FindUserMap(type);
			XmlQualifiedName xmlQualifiedName = ((serializationMap == null) ? KnownTypeCollection.GetPredefinedTypeName(type) : serializationMap.XmlName);
			reader.MoveToContent();
			reader.ReadStartElement(xmlQualifiedName.Name, xmlQualifiedName.Namespace);
			reader.Read();
		}

		public override void WriteObject(XmlWriter writer, object graph)
		{
			XmlDictionaryWriter writer2 = XmlDictionaryWriter.CreateDictionaryWriter(writer);
			WriteObject(writer2, graph);
		}

		[MonoTODO("support arrays; support Serializable; support SharedType; use DataContractSurrogate")]
		public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
		{
			if (graph != null)
			{
				int count = known_types.Count;
				XmlFormatterSerializer.Serialize(writer, graph, known_types, ignore_ext, max_items, root_ns.Value);
				while (known_types.Count > count)
				{
					known_types.RemoveAt(count);
				}
			}
		}

		public override void WriteObjectContent(XmlWriter writer, object graph)
		{
			XmlDictionaryWriter writer2 = XmlDictionaryWriter.CreateDictionaryWriter(writer);
			WriteObjectContent(writer2, graph);
		}

		public override void WriteStartObject(XmlWriter writer, object graph)
		{
			WriteStartObject(XmlDictionaryWriter.CreateDictionaryWriter(writer), graph);
		}

		public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
		{
			Type type = this.type;
			if (root_name.Value == string.Empty)
			{
				throw new InvalidDataContractException("Type '" + this.type.ToString() + "' cannot have a DataContract attribute Name set to null or empty string.");
			}
			if (graph == null)
			{
				if (names_filled)
				{
					writer.WriteStartElement(root_name.Value, root_ns.Value);
				}
				else
				{
					writer.WriteStartElement(root_name, root_ns);
				}
				writer.WriteAttributeString("i", "nil", "http://www.w3.org/2001/XMLSchema-instance", "true");
				return;
			}
			XmlQualifiedName xmlQualifiedName = null;
			XmlQualifiedName qName = known_types.GetQName(type);
			XmlQualifiedName qName2 = known_types.GetQName(graph.GetType());
			known_types.Add(graph.GetType());
			if (names_filled)
			{
				writer.WriteStartElement(root_name.Value, root_ns.Value);
			}
			else
			{
				writer.WriteStartElement(root_name, root_ns);
			}
			if (root_ns.Value != qName.Namespace && qName.Namespace != "http://schemas.microsoft.com/2003/10/Serialization/")
			{
				writer.WriteXmlnsAttribute(null, qName.Namespace);
			}
			if (qName == qName2)
			{
				if (qName.Namespace != "http://schemas.microsoft.com/2003/10/Serialization/" && !type.IsEnum)
				{
					writer.WriteXmlnsAttribute("i", "http://www.w3.org/2001/XMLSchema-instance");
				}
				return;
			}
			known_types.Add(type);
			xmlQualifiedName = KnownTypeCollection.GetPredefinedTypeName(graph.GetType());
			xmlQualifiedName = ((!(xmlQualifiedName == XmlQualifiedName.Empty)) ? new XmlQualifiedName(xmlQualifiedName.Name, "http://www.w3.org/2001/XMLSchema") : qName2);
			writer.WriteStartAttribute("i", "type", "http://www.w3.org/2001/XMLSchema-instance");
			writer.WriteQualifiedName(xmlQualifiedName.Name, xmlQualifiedName.Namespace);
			writer.WriteEndAttribute();
		}

		public override void WriteEndObject(XmlDictionaryWriter writer)
		{
			writer.WriteEndElement();
		}

		public override void WriteEndObject(XmlWriter writer)
		{
			WriteEndObject(XmlDictionaryWriter.CreateDictionaryWriter(writer));
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
	public sealed class DataMemberAttribute : Attribute
	{
		private bool is_required;

		private bool emit_default = true;

		private string name;

		private int order = -1;

		public bool EmitDefaultValue
		{
			get
			{
				return emit_default;
			}
			set
			{
				emit_default = value;
			}
		}

		public bool IsRequired
		{
			get
			{
				return is_required;
			}
			set
			{
				is_required = value;
			}
		}

		public string Name
		{
			get
			{
				return name;
			}
			set
			{
				name = value;
			}
		}

		public int Order
		{
			get
			{
				return order;
			}
			set
			{
				order = value;
			}
		}
	}
	[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
	public sealed class EnumMemberAttribute : Attribute
	{
		private string value;

		public string Value
		{
			get
			{
				return value;
			}
			set
			{
				this.value = value;
			}
		}
	}
	public class ExportOptions
	{
		private IDataContractSurrogate surrogate;

		private KnownTypeCollection known_types;

		public IDataContractSurrogate DataContractSurrogate
		{
			get
			{
				return surrogate;
			}
			set
			{
				surrogate = value;
			}
		}

		public Collection<Type> KnownTypes => known_types;
	}
	public sealed class ExtensionDataObject
	{
		private object target;

		internal ExtensionDataObject(object target)
		{
			this.target = target;
		}
	}
	public interface IDataContractSurrogate
	{
		object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType);

		object GetCustomDataToExport(Type clrType, Type dataContractType);

		Type GetDataContractType(Type type);

		object GetDeserializedObject(object obj, Type targetType);

		void GetKnownCustomDataTypes(Collection<Type> customDataTypes);

		object GetObjectToSerialize(object obj, Type targetType);
	}
	public interface IExtensibleDataObject
	{
		ExtensionDataObject ExtensionData { get; set; }
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
	public sealed class IgnoreDataMemberAttribute : Attribute
	{
	}
	[Serializable]
	public class InvalidDataContractException : Exception
	{
		public InvalidDataContractException()
		{
		}

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

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

		public InvalidDataContractException(string message, Exception innerException)
			: base(message, innerException)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = true, AllowMultiple = true)]
	public sealed class KnownTypeAttribute : Attribute
	{
		private string method_name;

		private Type type;

		public string MethodName => method_name;

		public Type Type => type;

		public KnownTypeAttribute(string methodName)
		{
			method_name = methodName;
		}

		public KnownTypeAttribute(Type type)
		{
			this.type = type;
		}
	}
	internal static class TypeExtensions
	{
		public static T GetCustomAttribute<T>(this Type type, bool inherit)
		{
			object[] customAttributes = type.GetCustomAttributes(typeof(T), inherit);
			return (customAttributes == null || customAttributes.Length != 1) ? default(T) : ((T)customAttributes[0]);
		}
	}
	internal sealed class KnownTypeCollection : Collection<Type>
	{
		internal const string MSSimpleNamespace = "http://schemas.microsoft.com/2003/10/Serialization/";

		internal const string MSArraysNamespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays";

		internal const string DefaultClrNamespaceBase = "http://schemas.datacontract.org/2004/07/";

		private static XmlQualifiedName any_type;

		private static XmlQualifiedName bool_type;

		private static XmlQualifiedName byte_type;

		private static XmlQualifiedName date_type;

		private static XmlQualifiedName decimal_type;

		private static XmlQualifiedName double_type;

		private static XmlQualifiedName float_type;

		private static XmlQualifiedName string_type;

		private static XmlQualifiedName short_type;

		private static XmlQualifiedName int_type;

		private static XmlQualifiedName long_type;

		private static XmlQualifiedName ubyte_type;

		private static XmlQualifiedName ushort_type;

		private static XmlQualifiedName uint_type;

		private static XmlQualifiedName ulong_type;

		private static XmlQualifiedName any_uri_type;

		private static XmlQualifiedName base64_type;

		private static XmlQualifiedName duration_type;

		private static XmlQualifiedName qname_type;

		private static XmlQualifiedName char_type;

		private static XmlQualifiedName guid_type;

		private static XmlQualifiedName dbnull_type;

		private List<SerializationMap> contracts = new List<SerializationMap>();

		static KnownTypeCollection()
		{
			string ns = "http://schemas.microsoft.com/2003/10/Serialization/";
			any_type = new XmlQualifiedName("anyType", ns);
			any_uri_type = new XmlQualifiedName("anyURI", ns);
			bool_type = new XmlQualifiedName("boolean", ns);
			base64_type = new XmlQualifiedName("base64Binary", ns);
			date_type = new XmlQualifiedName("dateTime", ns);
			duration_type = new XmlQualifiedName("duration", ns);
			qname_type = new XmlQualifiedName("QName", ns);
			decimal_type = new XmlQualifiedName("decimal", ns);
			double_type = new XmlQualifiedName("double", ns);
			float_type = new XmlQualifiedName("float", ns);
			byte_type = new XmlQualifiedName("byte", ns);
			short_type = new XmlQualifiedName("short", ns);
			int_type = new XmlQualifiedName("int", ns);
			long_type = new XmlQualifiedName("long", ns);
			ubyte_type = new XmlQualifiedName("unsignedByte", ns);
			ushort_type = new XmlQualifiedName("unsignedShort", ns);
			uint_type = new XmlQualifiedName("unsignedInt", ns);
			ulong_type = new XmlQualifiedName("unsignedLong", ns);
			string_type = new XmlQualifiedName("string", ns);
			guid_type = new XmlQualifiedName("guid", ns);
			char_type = new XmlQualifiedName("char", ns);
			dbnull_type = new XmlQualifiedName("DBNull", "http://schemas.microsoft.com/2003/10/Serialization/System");
		}

		internal XmlQualifiedName GetXmlName(Type type)
		{
			SerializationMap serializationMap = FindUserMap(type);
			if (serializationMap != null)
			{
				return serializationMap.XmlName;
			}
			return GetPredefinedTypeName(type);
		}

		internal static XmlQualifiedName GetPredefinedTypeName(Type type)
		{
			XmlQualifiedName primitiveTypeName = GetPrimitiveTypeName(type);
			if (primitiveTypeName != XmlQualifiedName.Empty)
			{
				return primitiveTypeName;
			}
			if ((object)type == typeof(DBNull))
			{
				return dbnull_type;
			}
			return XmlQualifiedName.Empty;
		}

		internal static XmlQualifiedName GetPrimitiveTypeName(Type type)
		{
			if (type.IsGenericType && (object)type.GetGenericTypeDefinition() == typeof(Nullable<>))
			{
				return GetPrimitiveTypeName(type.GetGenericArguments()[0]);
			}
			if (type.IsEnum)
			{
				return XmlQualifiedName.Empty;
			}
			switch (Type.GetTypeCode(type))
			{
			default:
				if ((object)type == typeof(object))
				{
					return any_type;
				}
				if ((object)type == typeof(Guid))
				{
					return guid_type;
				}
				if ((object)type == typeof(TimeSpan))
				{
					return duration_type;
				}
				if ((object)type == typeof(byte[]))
				{
					return base64_type;
				}
				if ((object)type == typeof(Uri))
				{
					return any_uri_type;
				}
				return XmlQualifiedName.Empty;
			case TypeCode.Boolean:
				return bool_type;
			case TypeCode.Byte:
				return ubyte_type;
			case TypeCode.Char:
				return char_type;
			case TypeCode.DateTime:
				return date_type;
			case TypeCode.Decimal:
				return decimal_type;
			case TypeCode.Double:
				return double_type;
			case TypeCode.Int16:
				return short_type;
			case TypeCode.Int32:
				return int_type;
			case TypeCode.Int64:
				return long_type;
			case TypeCode.SByte:
				return byte_type;
			case TypeCode.Single:
				return float_type;
			case TypeCode.String:
				return string_type;
			case TypeCode.UInt16:
				return ushort_type;
			case TypeCode.UInt32:
				return uint_type;
			case TypeCode.UInt64:
				return ulong_type;
			}
		}

		internal static string PredefinedTypeObjectToString(object obj)
		{
			Type type = obj.GetType();
			switch (Type.GetTypeCode(type))
			{
			default:
				if ((object)type == typeof(object))
				{
					return string.Empty;
				}
				if ((object)type == typeof(Guid))
				{
					return XmlConvert.ToString((Guid)obj);
				}
				if ((object)type == typeof(TimeSpan))
				{
					return XmlConvert.ToString((TimeSpan)obj);
				}
				if ((object)type == typeof(byte[]))
				{
					return Convert.ToBase64String((byte[])obj);
				}
				if ((object)type == typeof(Uri))
				{
					return ((Uri)obj).ToString();
				}
				throw new Exception("Internal error: missing predefined type serialization for type " + type.FullName);
			case TypeCode.DBNull:
				return string.Empty;
			case TypeCode.Boolean:
				return XmlConvert.ToString((bool)obj);
			case TypeCode.Byte:
				return XmlConvert.ToString((int)(byte)obj);
			case TypeCode.Char:
				return XmlConvert.ToString((uint)(char)obj);
			case TypeCode.DateTime:
				return XmlConvert.ToString((DateTime)obj, XmlDateTimeSerializationMode.RoundtripKind);
			case TypeCode.Decimal:
				return XmlConvert.ToString((decimal)obj);
			case TypeCode.Double:
				return XmlConvert.ToString((double)obj);
			case TypeCode.Int16:
				return XmlConvert.ToString((short)obj);
			case TypeCode.Int32:
				return XmlConvert.ToString((int)obj);
			case TypeCode.Int64:
				return XmlConvert.ToString((long)obj);
			case TypeCode.SByte:
				return XmlConvert.ToString((sbyte)obj);
			case TypeCode.Single:
				return XmlConvert.ToString((float)obj);
			case TypeCode.String:
				return (string)obj;
			case TypeCode.UInt16:
				return XmlConvert.ToString((int)(ushort)obj);
			case TypeCode.UInt32:
				return XmlConvert.ToString((uint)obj);
			case TypeCode.UInt64:
				return XmlConvert.ToString((ulong)obj);
			}
		}

		internal static Type GetPrimitiveTypeFromName(string name)
		{
			return name switch
			{
				"anyURI" => typeof(Uri), 
				"boolean" => typeof(bool), 
				"base64Binary" => typeof(byte[]), 
				"dateTime" => typeof(DateTime), 
				"duration" => typeof(TimeSpan), 
				"QName" => typeof(XmlQualifiedName), 
				"decimal" => typeof(decimal), 
				"double" => typeof(double), 
				"float" => typeof(float), 
				"byte" => typeof(sbyte), 
				"short" => typeof(short), 
				"int" => typeof(int), 
				"long" => typeof(long), 
				"unsignedByte" => typeof(byte), 
				"unsignedShort" => typeof(ushort), 
				"unsignedInt" => typeof(uint), 
				"unsignedLong" => typeof(ulong), 
				"string" => typeof(string), 
				"anyType" => typeof(object), 
				"guid" => typeof(Guid), 
				"char" => typeof(char), 
				_ => null, 
			};
		}

		internal static object PredefinedTypeStringToObject(string s, string name, XmlReader reader)
		{
			switch (name)
			{
			case "anyURI":
				return new Uri(s, UriKind.RelativeOrAbsolute);
			case "boolean":
				return XmlConvert.ToBoolean(s);
			case "base64Binary":
				return Convert.FromBase64String(s);
			case "dateTime":
				return XmlConvert.ToDateTime(s, XmlDateTimeSerializationMode.RoundtripKind);
			case "duration":
				return XmlConvert.ToTimeSpan(s);
			case "QName":
			{
				int num = s.IndexOf(':');
				string name2 = ((num >= 0) ? s.Substring(num + 1) : s);
				return (num >= 0) ? new XmlQualifiedName(name2, reader.LookupNamespace(s.Substring(0, num))) : new XmlQualifiedName(name2);
			}
			case "decimal":
				return XmlConvert.ToDecimal(s);
			case "double":
				return XmlConvert.ToDouble(s);
			case "float":
				return XmlConvert.ToSingle(s);
			case "byte":
				return XmlConvert.ToSByte(s);
			case "short":
				return XmlConvert.ToInt16(s);
			case "int":
				return XmlConvert.ToInt32(s);
			case "long":
				return XmlConvert.ToInt64(s);
			case "unsignedByte":
				return XmlConvert.ToByte(s);
			case "unsignedShort":
				return XmlConvert.ToUInt16(s);
			case "unsignedInt":
				return XmlConvert.ToUInt32(s);
			case "unsignedLong":
				return XmlConvert.ToUInt64(s);
			case "string":
				return s;
			case "guid":
				return XmlConvert.ToGuid(s);
			case "anyType":
				return s;
			case "char":
				return (char)XmlConvert.ToUInt32(s);
			default:
				throw new Exception("Unanticipated primitive type: " + name);
			}
		}

		protected override void ClearItems()
		{
			Clear();
		}

		protected override void InsertItem(int index, Type type)
		{
			if (TryRegister(type))
			{
				base.InsertItem(index, type);
			}
		}

		protected override void RemoveItem(int index)
		{
			Type type = base[index];
			List<SerializationMap> list = new List<SerializationMap>();
			foreach (SerializationMap contract in contracts)
			{
				if ((object)contract.RuntimeType == type)
				{
					list.Add(contract);
				}
			}
			foreach (SerializationMap item in list)
			{
				contracts.Remove(item);
				base.RemoveItem(index);
			}
		}

		protected override void SetItem(int index, Type type)
		{
			if (index == Count)
			{
				InsertItem(index, type);
				return;
			}
			RemoveItem(index);
			if (TryRegister(type))
			{
				base.InsertItem(index - 1, type);
			}
		}

		internal SerializationMap FindUserMap(XmlQualifiedName qname)
		{
			for (int i = 0; i < contracts.Count; i++)
			{
				if (qname == contracts[i].XmlName)
				{
					return contracts[i];
				}
			}
			return null;
		}

		internal Type GetSerializedType(Type type)
		{
			Type collectionElementType = GetCollectionElementType(type);
			if ((object)collectionElementType == null)
			{
				return type;
			}
			XmlQualifiedName qName = GetQName(type);
			SerializationMap serializationMap = FindUserMap(qName);
			if (serializationMap != null)
			{
				return serializationMap.RuntimeType;
			}
			return type;
		}

		internal SerializationMap FindUserMap(Type type)
		{
			for (int i = 0; i < contracts.Count; i++)
			{
				if ((object)type == contracts[i].RuntimeType)
				{
					return contracts[i];
				}
			}
			return null;
		}

		internal XmlQualifiedName GetQName(Type type)
		{
			if (IsPrimitiveNotEnum(type))
			{
				return GetPrimitiveTypeName(type);
			}
			SerializationMap serializationMap = FindUserMap(type);
			if (serializationMap != null)
			{
				return serializationMap.XmlName;
			}
			if (type.IsEnum)
			{
				return GetEnumQName(type);
			}
			XmlQualifiedName contractQName = GetContractQName(type);
			if (contractQName != null)
			{
				return contractQName;
			}
			if ((object)type.GetInterface("System.Xml.Serialization.IXmlSerializable") != null)
			{
				return GetSerializableQName(type);
			}
			contractQName = GetCollectionContractQName(type);
			if (contractQName != null)
			{
				return contractQName;
			}
			Type collectionElementType = GetCollectionElementType(type);
			if ((object)collectionElementType != null)
			{
				return GetCollectionQName(collectionElementType);
			}
			if (GetAttribute<SerializableAttribute>(type) != null)
			{
				return GetSerializableQName(type);
			}
			return XmlQualifiedName.Empty;
		}

		private XmlQualifiedName GetContractQName(Type type)
		{
			DataContractAttribute attribute = GetAttribute<DataContractAttribute>(type);
			return (attribute != null) ? GetContractQName(type, attribute.Name, attribute.Namespace) : null;
		}

		private XmlQualifiedName GetCollectionContractQName(Type type)
		{
			CollectionDataContractAttribute attribute = GetAttribute<CollectionDataContractAttribute>(type);
			return (attribute != null) ? GetContractQName(type, attribute.Name, attribute.Namespace) : null;
		}

		internal static XmlQualifiedName GetContractQName(Type type, string name, string ns)
		{
			if (name == null)
			{
				name = ((type.Namespace != null && type.Namespace.Length != 0) ? type.FullName.Substring(type.Namespace.Length + 1).Replace('+', '.') : type.Name);
				if (type.IsGenericType)
				{
					name = name.Substring(0, name.IndexOf('`')) + "Of";
					Type[] genericArguments = type.GetGenericArguments();
					foreach (Type type2 in genericArguments)
					{
						name += type2.Name;
					}
				}
			}
			if (ns == null)
			{
				ns = "http://schemas.datacontract.org/2004/07/" + type.Namespace;
			}
			return new XmlQualifiedName(name, ns);
		}

		private XmlQualifiedName GetEnumQName(Type type)
		{
			string text = null;
			string text2 = null;
			if (!type.IsEnum)
			{
				return null;
			}
			DataContractAttribute attribute = GetAttribute<DataContractAttribute>(type);
			if (attribute != null)
			{
				text2 = attribute.Namespace;
				text = attribute.Name;
			}
			if (text2 == null)
			{
				text2 = "http://schemas.datacontract.org/2004/07/" + type.Namespace;
			}
			if (text == null)
			{
				text = ((type.Namespace != null) ? type.FullName.Substring(type.Namespace.Length + 1).Replace('+', '.') : type.Name);
			}
			return new XmlQualifiedName(text, text2);
		}

		private XmlQualifiedName GetCollectionQName(Type element)
		{
			XmlQualifiedName qName = GetQName(element);
			string ns = qName.Namespace;
			if (qName.Namespace == "http://schemas.microsoft.com/2003/10/Serialization/")
			{
				ns = "http://schemas.microsoft.com/2003/10/Serialization/Arrays";
			}
			return new XmlQualifiedName("ArrayOf" + XmlConvert.EncodeLocalName(qName.Name), ns);
		}

		private XmlQualifiedName GetSerializableQName(Type type)
		{
			string text = type.Name;
			if (type.IsGenericType)
			{
				text = text.Substring(0, text.IndexOf('`')) + "Of";
				Type[] genericArguments = type.GetGenericArguments();
				foreach (Type type2 in genericArguments)
				{
					text += GetQName(type2).Name;
				}
			}
			string ns = "http://schemas.datacontract.org/2004/07/" + type.Namespace;
			XmlRootAttribute attribute = GetAttribute<XmlRootAttribute>(type);
			if (attribute != null)
			{
				text = attribute.ElementName;
				ns = attribute.Namespace;
			}
			return new XmlQualifiedName(XmlConvert.EncodeLocalName(text), ns);
		}

		internal bool IsPrimitiveNotEnum(Type type)
		{
			if (type.IsEnum)
			{
				return false;
			}
			if (Type.GetTypeCode(type) != TypeCode.Object)
			{
				return true;
			}
			if ((object)type == typeof(Guid) || (object)type == typeof(object) || (object)type == typeof(TimeSpan) || (object)type == typeof(byte[]) || (object)type == typeof(Uri))
			{
				return true;
			}
			if (type.IsGenericType && (object)type.GetGenericTypeDefinition() == typeof(Nullable<>))
			{
				return IsPrimitiveNotEnum(type.GetGenericArguments()[0]);
			}
			return false;
		}

		internal bool TryRegister(Type type)
		{
			if (IsPrimitiveNotEnum(type))
			{
				return false;
			}
			if (FindUserMap(type) != null)
			{
				return false;
			}
			if (RegisterEnum(type) != null)
			{
				return true;
			}
			if (RegisterContract(type) != null)
			{
				return true;
			}
			if (RegisterIXmlSerializable(type) != null)
			{
				return true;
			}
			if (RegisterDictionary(type) != null)
			{
				return true;
			}
			if (RegisterCollectionContract(type) != null)
			{
				return true;
			}
			if (RegisterCollection(type) != null)
			{
				return true;
			}
			if (GetAttribute<SerializableAttribute>(type) != null)
			{
				RegisterSerializable(type);
				return true;
			}
			RegisterDefaultTypeMap(type);
			return true;
		}

		internal static Type GetCollectionElementType(Type type)
		{
			if (type.IsArray)
			{
				return type.GetElementType();
			}
			Type[] interfaces = type.GetInterfaces();
			Type[] array = interfaces;
			foreach (Type type2 in array)
			{
				if (type2.IsGenericType && type2.GetGenericTypeDefinition().Equals(typeof(ICollection<>)))
				{
					return type2.GetGenericArguments()[0];
				}
			}
			Type[] array2 = interfaces;
			foreach (Type type3 in array2)
			{
				if ((object)type3 == typeof(IList))
				{
					return typeof(object);
				}
			}
			return null;
		}

		internal T GetAttribute<T>(MemberInfo mi) where T : Attribute
		{
			object[] customAttributes = mi.GetCustomAttributes(typeof(T), inherit: false);
			return (customAttributes.Length != 0) ? ((T)customAttributes[0]) : ((T)null);
		}

		private CollectionContractTypeMap RegisterCollectionContract(Type type)
		{
			CollectionDataContractAttribute attribute = GetAttribute<CollectionDataContractAttribute>(type);
			if (attribute == null)
			{
				return null;
			}
			Type collectionElementType = GetCollectionElementType(type);
			if ((object)collectionElementType == null)
			{
				throw new InvalidOperationException($"Type '{type}' is marked as collection contract, but it is not a collection");
			}
			TryRegister(collectionElementType);
			XmlQualifiedName collectionContractQName = GetCollectionContractQName(type);
			CheckStandardQName(collectionContractQName);
			if (FindUserMap(collectionContractQName) != null)
			{
				throw new InvalidOperationException($"Failed to add type {type} to known type collection. There already is a registered type for XML name {collectionContractQName}");
			}
			CollectionContractTypeMap collectionContractTypeMap = new CollectionContractTypeMap(type, attribute, collectionElementType, collectionContractQName, this);
			contracts.Add(collectionContractTypeMap);
			return collectionContractTypeMap;
		}

		private CollectionTypeMap RegisterCollection(Type type)
		{
			Type collectionElementType = GetCollectionElementType(type);
			if ((object)collectionElementType == null)
			{
				return null;
			}
			TryRegister(collectionElementType);
			XmlQualifiedName collectionQName = GetCollectionQName(collectionElementType);
			SerializationMap serializationMap = FindUserMap(collectionQName);
			if (serializationMap != null)
			{
				if (!(serializationMap is CollectionTypeMap collectionTypeMap) || (object)collectionTypeMap.RuntimeType != type)
				{
					throw new InvalidOperationException($"Failed to add type {type} to known type collection. There already is a registered type for XML name {collectionQName}");
				}
				return collectionTypeMap;
			}
			CollectionTypeMap collectionTypeMap2 = new CollectionTypeMap(type, collectionElementType, collectionQName, this);
			contracts.Add(collectionTypeMap2);
			return collectionTypeMap2;
		}

		private static bool TypeImplementsIDictionary(Type type)
		{
			Type[] interfaces = type.GetInterfaces();
			foreach (Type type2 in interfaces)
			{
				if ((object)type2 == typeof(IDictionary) || (type2.IsGenericType && (object)type2.GetGenericTypeDefinition() == typeof(IDictionary<, >)))
				{
					return true;
				}
			}
			return false;
		}

		private DictionaryTypeMap RegisterDictionary(Type type)
		{
			if (!TypeImplementsIDictionary(type))
			{
				return null;
			}
			CollectionDataContractAttribute attribute = GetAttribute<CollectionDataContractAttribute>(type);
			DictionaryTypeMap dictionaryTypeMap = new DictionaryTypeMap(type, attribute, this);
			if (FindUserMap(dictionaryTypeMap.XmlName) != null)
			{
				throw new InvalidOperationException($"Failed to add type {type} to known type collection. There already is a registered type for XML name {dictionaryTypeMap.XmlName}");
			}
			contracts.Add(dictionaryTypeMap);
			TryRegister(dictionaryTypeMap.KeyType);
			TryRegister(dictionaryTypeMap.ValueType);
			return dictionaryTypeMap;
		}

		private SerializationMap RegisterSerializable(Type type)
		{
			XmlQualifiedName serializableQName = GetSerializableQName(type);
			if (FindUserMap(serializableQName) != null)
			{
				throw new InvalidOperationException($"There is already a registered type for XML name {serializableQName}");
			}
			SharedTypeMap sharedTypeMap = new SharedTypeMap(type, serializableQName, this);
			contracts.Add(sharedTypeMap);
			return sharedTypeMap;
		}

		private SerializationMap RegisterIXmlSerializable(Type type)
		{
			if ((object)type.GetInterface("System.Xml.Serialization.IXmlSerializable") == null)
			{
				return null;
			}
			XmlQualifiedName serializableQName = GetSerializableQName(type);
			if (FindUserMap(serializableQName) != null)
			{
				throw new InvalidOperationException($"There is already a registered type for XML name {serializableQName}");
			}
			XmlSerializableMap xmlSerializableMap = new XmlSerializableMap(type, serializableQName, this);
			contracts.Add(xmlSerializableMap);
			return xmlSerializableMap;
		}

		private void CheckStandardQName(XmlQualifiedName qname)
		{
			switch (qname.Namespace)
			{
			case "http://www.w3.org/2001/XMLSchema":
			case "http://www.w3.org/2001/XMLSchema-instance":
			case "http://schemas.microsoft.com/2003/10/Serialization/":
			case "http://schemas.microsoft.com/2003/10/Serialization/Arrays":
				throw new InvalidOperationException($"Namespace {qname.Namespace} is reserved and cannot be used for user serialization");
			}
		}

		private SharedContractMap RegisterContract(Type type)
		{
			XmlQualifiedName contractQName = GetContractQName(type);
			if (contractQName == null)
			{
				return null;
			}
			CheckStandardQName(contractQName);
			if (FindUserMap(contractQName) != null)
			{
				throw new InvalidOperationException($"There is already a registered type for XML name {contractQName}");
			}
			SharedContractMap sharedContractMap = new SharedContractMap(type, contractQName, this);
			contracts.Add(sharedContractMap);
			sharedContractMap.Initialize();
			object[] customAttributes = type.GetCustomAttributes(typeof(KnownTypeAttribute), inherit: true);
			for (int i = 0; i < customAttributes.Length; i++)
			{
				KnownTypeAttribute knownTypeAttribute = (KnownTypeAttribute)customAttributes[i];
				TryRegister(knownTypeAttribute.Type);
			}
			return sharedContractMap;
		}

		private DefaultTypeMap RegisterDefaultTypeMap(Type type)
		{
			DefaultTypeMap defaultTypeMap = new DefaultTypeMap(type, this);
			contracts.Add(defaultTypeMap);
			return defaultTypeMap;
		}

		private EnumMap RegisterEnum(Type type)
		{
			XmlQualifiedName enumQName = GetEnumQName(type);
			if (enumQName == null)
			{
				return null;
			}
			if (FindUserMap(enumQName) != null)
			{
				throw new InvalidOperationException($"There is already a registered type for XML name {enumQName}");
			}
			EnumMap enumMap = new EnumMap(type, enumQName, this);
			contracts.Add(enumMap);
			return enumMap;
		}
	}
	public sealed class NetDataContractSerializer : XmlObjectSerializer, IFormatter
	{
		private const string xmlns = "http://www.w3.org/2000/xmlns/";

		private const string default_ns = "http://schemas.datacontract.org/2004/07/";

		private StreamingContext context;

		private SerializationBinder binder;

		private ISurrogateSelector selector;

		private int max_items = 65536;

		private bool ignore_extensions;

		private FormatterAssemblyStyle ass_style;

		private XmlDictionaryString root_name;

		private XmlDictionaryString root_ns;

		public FormatterAssemblyStyle AssemblyFormat
		{
			get
			{
				return ass_style;
			}
			set
			{
				ass_style = value;
			}
		}

		public SerializationBinder Binder
		{
			get
			{
				return binder;
			}
			set
			{
				binder = value;
			}
		}

		public bool IgnoreExtensionDataObject => ignore_extensions;

		public ISurrogateSelector SurrogateSelector
		{
			get
			{
				return selector;
			}
			set
			{
				selector = value;
			}
		}

		public StreamingContext Context
		{
			get
			{
				return context;
			}
			set
			{
				context = value;
			}
		}

		public int MaxItemsInObjectGraph => max_items;

		public NetDataContractSerializer()
		{
		}

		public NetDataContractSerializer(StreamingContext context)
		{
			this.context = context;
		}

		public NetDataContractSerializer(string rootName, string rootNamespace)
		{
			FillDictionaryString(rootName, rootNamespace);
		}

		public NetDataContractSerializer(XmlDictionaryString rootName, XmlDictionaryString rootNamespace)
		{
			if (rootName == null)
			{
				throw new ArgumentNullException("rootName");
			}
			if (rootNamespace == null)
			{
				throw new ArgumentNullException("rootNamespace");
			}
			root_name = rootName;
			root_ns = rootNamespace;
		}

		public NetDataContractSerializer(StreamingContext context, int maxItemsInObjectGraph, bool ignoreExtensibleDataObject, FormatterAssemblyStyle assemblyFormat, ISurrogateSelector surrogateSelector)
		{
			this.context = context;
			max_items = maxItemsInObjectGraph;
			ignore_extensions = ignoreExtensibleDataObject;
			ass_style = assemblyFormat;
			selector = surrogateSelector;
		}

		public NetDataContractSerializer(string rootName, string rootNamespace, StreamingContext context, int maxItemsInObjectGraph, bool ignoreExtensibleDataObject, FormatterAssemblyStyle assemblyFormat, ISurrogateSelector surrogateSelector)
			: this(context, maxItemsInObjectGraph, ignoreExtensibleDataObject, assemblyFormat, surrogateSelector)
		{
			FillDictionaryString(rootName, rootNamespace);
		}

		public NetDataContractSerializer(XmlDictionaryString rootName, XmlDictionaryString rootNamespace, StreamingContext context, int maxItemsInObjectGraph, bool ignoreExtensibleDataObject, FormatterAssemblyStyle assemblyFormat, ISurrogateSelector surrogateSelector)
			: this(context, maxItemsInObjectGraph, ignoreExtensibleDataObject, assemblyFormat, surrogateSelector)
		{
			if (rootName == null)
			{
				throw new ArgumentNullException("rootName");
			}
			if (rootNamespace == null)
			{
				throw new ArgumentNullException("rootNamespace");
			}
			root_name = rootName;
			root_ns = rootNamespace;
		}

		private void FillDictionaryString(string rootName, string rootNamespace)
		{
			if (rootName == null)
			{
				throw new ArgumentNullException("rootName");
			}
			if (rootNamespace == null)
			{
				throw new ArgumentNullException("rootNamespace");
			}
			XmlDictionary xmlDictionary = new XmlDictionary();
			root_name = xmlDictionary.Add(rootName);
			root_ns = xmlDictionary.Add(rootNamespace);
		}

		public object Deserialize(Stream stream)
		{
			return ReadObject(stream);
		}

		[MonoTODO]
		public override bool IsStartObject(XmlDictionaryReader reader)
		{
			throw new NotImplementedException();
		}

		public override object ReadObject(XmlDictionaryReader reader, bool readContentOnly)
		{
			throw new NotImplementedException();
		}

		public void Serialize(Stream stream, object graph)
		{
			using XmlWriter writer = XmlWriter.Create(stream);
			WriteObject(writer, graph);
		}

		[MonoTODO("support arrays; support Serializable; support SharedType; use DataContractSurrogate")]
		public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
		{
			throw new NotImplementedException();
		}

		public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
		{
			throw new NotImplementedException();
		}

		public override void WriteEndObject(XmlDictionaryWriter writer)
		{
			writer.WriteEndElement();
		}
	}
	internal abstract class SerializationMap
	{
		public const BindingFlags AllInstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		public readonly KnownTypeCollection KnownTypes;

		public readonly Type RuntimeType;

		public bool IsReference;

		public List<DataMemberInfo> Members;

		private Dictionary<Type, XmlQualifiedName> qname_table = new Dictionary<Type, XmlQualifiedName>();

		public virtual bool OutputXsiType => true;

		public XmlQualifiedName XmlName { get; set; }

		protected SerializationMap(Type type, XmlQualifiedName qname, KnownTypeCollection knownTypes)
		{
			KnownTypes = knownTypes;
			RuntimeType = type;
			if (qname.Namespace == null)
			{
				qname = new XmlQualifiedName(qname.Name, "http://schemas.datacontract.org/2004/07/" + type.Namespace);
			}
			XmlName = qname;
			Members = new List<DataMemberInfo>();
		}

		public CollectionDataContractAttribute GetCollectionDataContractAttribute(Type type)
		{
			object[] customAttributes = type.GetCustomAttributes(typeof(CollectionDataContractAttribute), inherit: false);
			return (customAttributes.Length != 0) ? ((CollectionDataContractAttribute)customAttributes[0]) : null;
		}

		public DataMemberAttribute GetDataMemberAttribute(MemberInfo mi)
		{
			object[] customAttributes = mi.GetCustomAttributes(typeof(DataMemberAttribute), inherit: false);
			if (customAttributes.Length == 0)
			{
				return null;
			}
			return (DataMemberAttribute)customAttributes[0];
		}

		private bool IsPrimitive(Type type)
		{
			return Type.GetTypeCode(type) != TypeCode.Object || (object)type == typeof(object);
		}

		public virtual List<DataMemberInfo> GetMembers()
		{
			throw new NotImplementedException($"Implement me for {this}");
		}

		public virtual void Serialize(object graph, XmlFormatterSerializer serializer)
		{
			string text = null;
			if (IsReference)
			{
				text = (string)serializer.References[graph];
				if (text != null)
				{
					serializer.Writer.WriteAttributeString("z", "Ref", "http://schemas.microsoft.com/2003/10/Serialization/", text);
					return;
				}
				text = "i" + (serializer.References.Count + 1);
				serializer.References.Add(graph, text);
			}
			else if (serializer.SerializingObjects.Contains(graph))
			{
				throw new SerializationException($"Circular reference of an object in the object graph was found: '{graph}' of type {graph.GetType()}");
			}
			serializer.SerializingObjects.Add(graph);
			if (text != null)
			{
				serializer.Writer.WriteAttributeString("z", "Id", "http://schemas.microsoft.com/2003/10/Serialization/", text);
			}
			SerializeNonReference(graph, serializer);
			serializer.SerializingObjects.Remove(graph);
		}

		public virtual void SerializeNonReference(object graph, XmlFormatterSerializer serializer)
		{
			foreach (DataMemberInfo member in Members)
			{
				FieldInfo fieldInfo = member.Member as FieldInfo;
				PropertyInfo propertyInfo = (((object)fieldInfo != null) ? null : ((PropertyInfo)member.Member));
				Type type = (((object)fieldInfo == null) ? propertyInfo.PropertyType : fieldInfo.FieldType);
				object graph2 = (((object)fieldInfo == null) ? propertyInfo.GetValue(graph, null) : fieldInfo.GetValue(graph));
				serializer.WriteStartElement(member.XmlName, member.XmlRootNamespace, member.XmlNamespace);
				serializer.Serialize(type, graph2);
				serializer.WriteEndElement();
			}
		}

		public virtual object DeserializeObject(XmlReader reader, XmlFormatterDeserializer deserializer)
		{
			bool isEmptyElement = reader.IsEmptyElement;
			reader.ReadStartElement();
			reader.MoveToContent();
			object result = ((!isEmptyElement) ? DeserializeContent(reader, deserializer) : DeserializeEmptyContent(reader, deserializer));
			reader.MoveToContent();
			if (!isEmptyElement && reader.NodeType == XmlNodeType.EndElement)
			{
				reader.ReadEndElement();
			}
			else if (!isEmptyElement && reader.NodeType != 0)
			{
				IXmlLineInfo xmlLineInfo = reader as IXmlLineInfo;
				throw new SerializationException(string.Format("Deserializing type '{3}'. Expecting state 'EndElement'. Encountered state '{0}' with name '{1}' with namespace '{2}'.{4}", reader.NodeType, reader.Name, reader.NamespaceURI, RuntimeType.FullName, (xmlLineInfo == null || !xmlLineInfo.HasLineInfo()) ? string.Empty : $" {reader.BaseURI}({xmlLineInfo.LineNumber},{xmlLineInfo.LinePosition})"));
			}
			return result;
		}

		public virtual object DeserializeEmptyContent(XmlReader reader, XmlFormatterDeserializer deserializer)
		{
			return DeserializeContent(reader, deserializer, empty: true);
		}

		public virtual object DeserializeContent(XmlReader reader, XmlFormatterDeserializer deserializer)
		{
			return DeserializeContent(reader, deserializer, empty: false);
		}

		private object DeserializeContent(XmlReader reader, XmlFormatterDeserializer deserializer, bool empty)
		{
			object uninitializedObject = FormatterServices.GetUninitializedObject(RuntimeType);
			int num = ((reader.NodeType != 0) ? (reader.Depth - 1) : reader.Depth);
			bool[] array = new bool[Members.Count];
			int num2 = -1;
			int val = -1;
			while (!empty && reader.NodeType == XmlNodeType.Element && reader.Depth > num)
			{
				DataMemberInfo dataMemberInfo = null;
				int i;
				for (i = 0; i < Members.Count && Members[i].Order < 0; i++)
				{
					if (reader.LocalName == Members[i].XmlName && reader.NamespaceURI == Members[i].XmlRootNamespace)
					{
						num2 = i;
						dataMemberInfo = Members[i];
						break;
					}
				}
				for (i = Math.Max(i, val); i < Members.Count; i++)
				{
					if (dataMemberInfo != null)
					{
						break;
					}
					if (reader.LocalName == Members[i].XmlName && reader.NamespaceURI == Members[i].XmlRootNamespace)
					{
						num2 = i;
						val = i;
						dataMemberInfo = Members[i];
						break;
					}
				}
				if (dataMemberInfo == null)
				{
					reader.Skip();
					continue;
				}
				SetValue(dataMemberInfo, uninitializedObject, deserializer.Deserialize(dataMemberInfo.MemberType, reader));
				array[num2] = true;
				reader.MoveToContent();
			}
			for (int j = 0; j < Members.Count; j++)
			{
				if (!array[j] && Members[j].IsRequired)
				{
					throw MissingRequiredMember(Members[j], reader);
				}
			}
			return uninitializedObject;
		}

		protected Exception MissingRequiredMember(DataMemberInfo dmi, XmlReader reader)
		{
			IXmlLineInfo xmlLineInfo = reader as IXmlLineInfo;
			return new ArgumentException($"Data contract member {new XmlQualifiedName(dmi.XmlName, dmi.XmlNamespace)} for the type {RuntimeType} is required, but missing in the input XML.{((xmlLineInfo == null || !xmlLineInfo.HasLineInfo()) ? null : $" {reader.BaseURI}({xmlLineInfo.LineNumber},{xmlLineInfo.LinePosition})")}");
		}

		protected void SetValue(DataMemberInfo dmi, object obj, object value)
		{
			try
			{
				if (dmi.Member is PropertyInfo)
				{
					((PropertyInfo)dmi.Member).SetValue(obj, value, null);
				}
				else
				{
					((FieldInfo)dmi.Member).SetValue(obj, value);
				}
			}
			catch (Exception innerException)
			{
				throw new InvalidOperationException($"Failed to set value of type {value?.GetType()} for property {dmi.Member}", innerException);
			}
		}

		protected DataMemberInfo CreateDataMemberInfo(DataMemberAttribute dma, MemberInfo mi, Type type)
		{
			KnownTypes.Add(type);
			XmlQualifiedName qName = KnownTypes.GetQName(type);
			string @namespace = KnownTypes.GetQName(mi.DeclaringType).Namespace;
			if ((object)KnownTypeCollection.GetPrimitiveTypeFromName(qName.Name) != null)
			{
				return new DataMemberInfo(mi, dma, @namespace, null);
			}
			return new DataMemberInfo(mi, dma, @namespace, qName.Namespace);
		}
	}
	internal class XmlSerializableMap : SerializationMap
	{
		public XmlSerializableMap(Type type, XmlQualifiedName qname, KnownTypeCollection knownTypes)
			: base(type, qname, knownTypes)
		{
		}

		public override void Serialize(object graph, XmlFormatterSerializer serializer)
		{
			if (!(graph is IXmlSerializable xmlSerializable))
			{
				throw new SerializationException();
			}
			xmlSerializable.WriteXml(serializer.Writer);
		}

		public override object DeserializeObject(XmlReader reader, XmlFormatterDeserializer deserializer)
		{
			IXmlSerializable xmlSerializable = (IXmlSerializable)FormatterServices.GetUninitializedObject(RuntimeType);
			xmlSerializable.ReadXml(reader);
			return xmlSerializable;
		}
	}
	internal class SharedContractMap : SerializationMap
	{
		public SharedContractMap(Type type, XmlQualifiedName qname, KnownTypeCollection knownTypes)
			: base(type, qname, knownTypes)
		{
		}

		internal void Initialize()
		{
			Type type = RuntimeType;
			List<DataMemberInfo> list = new List<DataMemberInfo>();
			object[] customAttributes = type.GetCustomAttributes(typeof(DataContractAttribute), inherit: false);
			IsReference = customAttributes.Length > 0 && ((DataContractAttribute)customAttributes[0]).IsReference;
			while ((object)type != null)
			{
				XmlQualifiedName qName = KnownTypes.GetQName(type);
				list = GetMembers(type, qName, declared_only: true);
				list.Sort(DataMemberInfo.DataMemberInfoComparer.Instance);
				Members.InsertRange(0, list);
				list.Clear();
				type = type.BaseType;
			}
		}

		private List<DataMemberInfo> GetMembers(Type type, XmlQualifiedName qname, bool declared_only)
		{
			List<DataMemberInfo> list = new List<DataMemberInfo>();
			BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			if (declared_only)
			{
				bindingFlags |= BindingFlags.DeclaredOnly;
			}
			PropertyInfo[] properties = type.GetProperties(bindingFlags);
			foreach (PropertyInfo propertyInfo in properties)
			{
				DataMemberAttribute dataMemberAttribute = GetDataMemberAttribute(propertyInfo);
				if (dataMemberAttribute != null)
				{
					KnownTypes.TryRegister(propertyInfo.PropertyType);
					SerializationMap serializationMap = KnownTypes.FindUserMap(propertyInfo.PropertyType);
					if (!propertyInfo.CanRead || (!propertyInfo.CanWrite && !(serializationMap is ICollectionTypeMap)))
					{
						throw new InvalidDataContractException($"DataMember property '{propertyInfo}' on type '{propertyInfo.DeclaringType}' must have both getter and setter.");
					}
					list.Add(CreateDataMemberInfo(dataMemberAttribute, propertyInfo, propertyInfo.PropertyType));
				}
			}
			FieldInfo[] fields = type.GetFields(bindingFlags);
			foreach (FieldInfo fieldInfo in fields)
			{
				DataMemberAttribute dataMemberAttribute2 = GetDataMemberAttribute(fieldInfo);
				if (dataMemberAttribute2 != null)
				{
					list.Add(CreateDataMemberInfo(dataMemberAttribute2, fieldInfo, fieldInfo.FieldType));
				}
			}
			return list;
		}

		public override List<DataMemberInfo> GetMembers()
		{
			return Members;
		}
	}
	internal class DefaultTypeMap : SerializationMap
	{
		public DefaultTypeMap(Type type, KnownTypeCollection knownTypes)
			: base(type, KnownTypeCollection.GetContractQName(type, null, null), knownTypes)
		{
			Members.AddRange(GetDefaultMembers());
		}

		private List<DataMemberInfo> GetDefaultMembers()
		{
			List<DataMemberInfo> list = new List<DataMemberInfo>();
			MemberInfo[] members = RuntimeType.GetMembers();
			foreach (MemberInfo memberInfo in members)
			{
				Type type = null;
				type = ((memberInfo is FieldInfo fieldInfo) ? fieldInfo.FieldType : null);
				if (memberInfo is PropertyInfo propertyInfo && propertyInfo.CanRead && propertyInfo.CanWrite && propertyInfo.GetIndexParameters().Length == 0)
				{
					type = propertyInfo.PropertyType;
				}
				if ((object)type != null && memberInfo.GetCustomAttributes(typeof(IgnoreDataMemberAttribute), inherit: false).Length == 0)
				{
					list.Add(new DataMemberInfo(memberInfo, new DataMemberAttribute(), null, null));
				}
			}
			list.Sort(DataMemberInfo.DataMemberInfoComparer.Instance);
			return list;
		}
	}
	internal class CollectionContractTypeMap : CollectionTypeMap
	{
		internal override string CurrentNamespace => base.XmlName.Namespace;

		public CollectionContractTypeMap(Type type, CollectionDataContractAttribute a, Type elementType, XmlQualifiedName qname, KnownTypeCollection knownTypes)
			: base(type, elementType, qname, knownTypes)
		{
			IsReference = a.IsReference;
		}
	}
	internal interface ICollectionTypeMap
	{
	}
	internal class CollectionTypeMap : SerializationMap, ICollectionTypeMap
	{
		private Type element_type;

		internal XmlQualifiedName element_qname;

		private MethodInfo add_method;

		public override bool OutputXsiType => false;

		internal virtual string CurrentNamespace
		{
			get
			{
				string text = element_qname.Namespace;
				if (text == "http://schemas.microsoft.com/2003/10/Serialization/")
				{
					text = "http://schemas.microsoft.com/2003/10/Serialization/Arrays";
				}
				return text;
			}
		}

		public CollectionTypeMap(Type type, Type elementType, XmlQualifiedName qname, KnownTypeCollection knownTypes)
			: base(type, qname, knownTypes)
		{
			element_type = elementType;
			element_qname = KnownTypes.GetQName(element_type);
			Type genericCollectionInterface = GetGenericCollectionInterface(RuntimeType);
			if ((object)genericCollectionInterface == null)
			{
				return;
			}
			if (RuntimeType.IsInterface)
			{
				add_method = RuntimeType.GetMethod("Add", genericCollectionInterface.GetGenericArguments());
				return;
			}
			InterfaceMapping interfaceMap = RuntimeType.GetInterfaceMap(genericCollectionInterface);
			for (int i = 0; i < interfaceMap.InterfaceMethods.Length; i++)
			{
				if (interfaceMap.InterfaceMethods[i].Name == "Add")
				{
					add_method = interfaceMap.TargetMethods[i];
					break;
				}
			}
			if ((object)add_method == null)
			{
				add_method = type.GetMethod("Add", genericCollectionInterface.GetGenericArguments());
			}
		}

		private static Type GetGenericCollectionInterface(Type type)
		{
			Type[] interfaces = type.GetInterfaces();
			foreach (Type type2 in interfaces)
			{
				if (type2.IsGenericType && (object)type2.GetGenericTypeDefinition() == typeof(ICollection<>))
				{
					return type2;
				}
			}
			return null;
		}

		public override void SerializeNonReference(object graph, XmlFormatterSerializer serializer)
		{
			foreach (object item in (IEnumerable)graph)
			{
				serializer.WriteStartElement(element_qname.Name, base.XmlName.Namespace, CurrentNamespace);
				serializer.Serialize(element_type, item);
				serializer.WriteEndElement();
			}
		}

		private object CreateInstance()
		{
			if (RuntimeType.IsArray)
			{
				return new ArrayList();
			}
			if (RuntimeType.IsInterface)
			{
				Type genericCollectionInterface = GetGenericCollectionInterface(RuntimeType);
				if ((object)genericCollectionInterface != null)
				{
					return Activator.CreateInstance(typeof(List<>).MakeGenericType(RuntimeType.GetGenericArguments()[0]));
				}
				return new ArrayList();
			}
			return Activator.CreateInstance(RuntimeType);
		}

		public override object DeserializeEmptyContent(XmlReader reader, XmlFormatterDeserializer deserializer)
		{
			return CreateInstance();
		}

		public override object DeserializeContent(XmlReader reader, XmlFormatterDeserializer deserializer)
		{
			object obj = CreateInstance();
			int num = ((reader.NodeType != 0) ? (reader.Depth - 1) : reader.Depth);
			while (reader.NodeType == XmlNodeType.Element && reader.Depth > num)
			{
				object obj2 = deserializer.Deserialize(element_type, reader);
				if (obj is IList)
				{
					((IList)obj).Add(obj2);
				}
				else
				{
					if ((object)add_method == null)
					{
						throw new NotImplementedException($"Type {RuntimeType} is not supported");
					}
					add_method.Invoke(obj, new object[1] { obj2 });
				}
				reader.MoveToContent();
			}
			if (RuntimeType.IsArray)
			{
				return ((ArrayList)obj).ToArray(element_type);
			}
			return obj;
		}

		public override List<DataMemberInfo> GetMembers()
		{
			throw new NotImplementedException();
		}
	}
	internal class DictionaryTypeMap : SerializationMap, ICollectionTypeMap
	{
		private Type key_type;

		private Type value_type;

		private XmlQualifiedName dict_qname;

		private XmlQualifiedName item_qname;

		private XmlQualifiedName key_qname;

		private XmlQualifiedName value_qname;

		private MethodInfo add_method;

		private CollectionDataContractAttribute a;

		private static readonly XmlQualifiedName kvpair_key_qname = new XmlQualifiedName("Key", "http://schemas.microsoft.com/2003/10/Serialization/Arrays");

		private static readonly XmlQualifiedName kvpair_value_qname = new XmlQualifiedName("Value", "http://schemas.microsoft.com/2003/10/Serialization/Arrays");

		private Type pair_type;

		private PropertyInfo pair_key_property;

		private PropertyInfo pair_value_property;

		private string ContractNamespace => (a == null || string.IsNullOrEmpty(a.Namespace)) ? "http://schemas.microsoft.com/2003/10/Serialization/Arrays" : a.Namespace;

		public Type KeyType => key_type;

		public Type ValueType => value_type;

		internal virtual string CurrentNamespace
		{
			get
			{
				string text = item_qname.Namespace;
				if (text == "http://schemas.microsoft.com/2003/10/Serialization/")
				{
					text = "http://schemas.microsoft.com/2003/10/Serialization/Arrays";
				}
				return text;
			}
		}

		public DictionaryTypeMap(Type type, CollectionDataContractAttribute a, KnownTypeCollection knownTypes)
			: base(type, XmlQualifiedName.Empty, knownTypes)
		{
			this.a = a;
			key_type = typeof(object);
			value_type = typeof(object);
			Type genericDictionaryInterface = GetGenericDictionaryInterface(RuntimeType);
			if ((object)genericDictionaryInterface != null)
			{
				InterfaceMapping interfaceMap = RuntimeType.GetInterfaceMap(genericDictionaryInterface);
				for (int i = 0; i < interfaceMap.InterfaceMethods.Length; i++)
				{
					if (interfaceMap.InterfaceMethods[i].Name == "Add")
					{
						add_method = interfaceMap.TargetMethods[i];
						break;
					}
				}
				Type[] genericArguments = genericDictionaryInterface.GetGenericArguments();
				key_type = genericArguments[0];
				value_type = genericArguments[1];
				if ((object)add_method == null)
				{
					add_method = type.GetMethod("Add", genericArguments);
				}
			}
			base.XmlName = GetDictionaryQName();
			item_qname = GetItemQName();
			key_qname = GetKeyQName();
			value_qname = GetValueQName();
		}

		private static Type GetGenericDictionaryInterface(Type type)
		{
			Type[] interfaces = type.GetInterfaces();
			foreach (Type type2 in interfaces)
			{
				if (type2.IsGenericType && (object)type2.GetGenericTypeDefinition() == typeof(IDictionary<, >))
				{
					return type2;
				}
			}
			return null;
		}

		internal virtual XmlQualifiedName GetDictionaryQName()
		{
			if (a != null && !string.IsNullOrEmpty(a.Name))
			{
				return new XmlQualifiedName(a.Name, ContractNamespace);
			}
			return new XmlQualifiedName("ArrayOf" + GetItemQName().Name, "http://schemas.microsoft.com/2003/10/Serialization/Arrays");
		}

		internal virtual XmlQualifiedName GetItemQName()
		{
			if (a != null && !string.IsNullOrEmpty(a.ItemName))
			{
				return new XmlQualifiedName(a.ItemName, ContractNamespace);
			}
			return new XmlQualifiedName("KeyValueOf" + KnownTypes.GetQName(key_type).Name + KnownTypes.GetQName(value_type).Name, "http://schemas.microsoft.com/2003/10/Serialization/Arrays");
		}

		internal virtual XmlQualifiedName GetKeyQName()
		{
			if (a != null && !string.IsNullOrEmpty(a.KeyName))
			{
				return new XmlQualifiedName(a.KeyName, ContractNamespace);
			}
			return kvpair_key_qname;
		}

		internal virtual XmlQualifiedName GetValueQName()
		{
			if (a != null && !string.IsNullOrEmpty(a.ValueName))
			{
				return new XmlQualifiedName(a.ValueName, ContractNamespace);
			}
			return kvpair_value_qname;
		}

		public override void SerializeNonReference(object graph, XmlFormatterSerializer serializer)
		{
			if ((object)add_method != null)
			{
				if ((object)pair_type == null)
				{
					pair_type = typeof(KeyValuePair<, >).MakeGenericType(add_method.DeclaringType.GetGenericArguments());
					pair_key_property = pair_type.GetProperty("Key");
					pair_value_property = pair_type.GetProperty("Value");
				}
				{
					foreach (object item in (IEnumerable)graph)
					{
						serializer.WriteStartElement(item_qname.Name, item_qname.Namespace, CurrentNamespace);
						serializer.WriteStartElement(key_qname.Name, key_qname.Namespace, CurrentNamespace);
						serializer.Serialize(pair_key_property.PropertyType, pair_key_property.GetValue(item, null));
						serializer.WriteEndElement();
						serializer.WriteStartElement(value_qname.Name, value_qname.Namespace, CurrentNamespace);
						serializer.Serialize(pair_value_property.PropertyType, pair_value_property.GetValue(item, null));
						serializer.WriteEndElement();
						serializer.WriteEndElement();
					}
					return;
				}
			}
			foreach (DictionaryEntry item2 in (IEnumerable)graph)
			{
				serializer.WriteStartElement(item_qname.Name, item_qname.Namespace, CurrentNamespace);
				serializer.WriteStartElement(key_qname.Name, key_qname.Namespace, CurrentNamespace);
				serializer.Serialize(key_type, item2.Key);
				serializer.WriteEndElement();
				serializer.WriteStartElement(value_qname.Name, value_qname.Namespace, CurrentNamespace);
				serializer.Serialize(value_type, item2.Value);
				serializer.WriteEndElement();
				serializer.WriteEndElement();
			}
		}

		private object CreateInstance()
		{
			if (RuntimeType.IsInterface)
			{
				if (RuntimeType.IsGenericType && Array.IndexOf(RuntimeType.GetGenericTypeDefinition().GetInterfaces(), typeof(IDictionary<, >)) >= 0)
				{
					Type[] genericArguments = RuntimeType.GetGenericArguments();
					return Activator.CreateInstance(typeof(Dictionary<, >).MakeGenericType(genericArguments[0], genericArguments[1]));
				}
				return new Hashtable();
			}
			return Activator.CreateInstance(RuntimeType);
		}

		public override object DeserializeEmptyContent(XmlReader reader, XmlFormatterDeserializer deserializer)
		{
			return DeserializeContent(reader, deserializer);
		}

		public override object DeserializeContent(XmlReader reader, XmlFormatterDeserializer deserializer)
		{
			object obj = CreateInstance();
			int num = ((reader.NodeType != 0) ? (reader.Depth - 1) : reader.Depth);
			while (reader.NodeType == XmlNodeType.Element && reader.Depth > num)
			{
				if (reader.IsEmptyElement)
				{
					throw new XmlException($"Unexpected empty element for dictionary entry: name {reader.Name}");
				}
				reader.ReadStartElement();
				reader.MoveToContent();
				object obj2 = deserializer.Deserialize(key_type, reader);
				reader.MoveToContent();
				object obj3 = deserializer.Deserialize(value_type, reader);
				reader.ReadEndElement();
				if (obj is IDictionary)
				{
					((IDictionary)obj).Add(obj2, obj3);
					continue;
				}
				if ((object)add_method != null)
				{
					add_method.Invoke(obj, new object[2] { obj2, obj3 });
					continue;
				}
				throw new NotImplementedException($"Type {RuntimeType} is not supported");
			}
			return obj;
		}

		public override List<DataMemberInfo> GetMembers()
		{
			throw new NotImplementedException();
		}
	}
	internal class SharedTypeMap : SerializationMap
	{
		public SharedTypeMap(Type type, XmlQualifiedName qname, KnownTypeCollection knownTypes)
			: base(type, qname, knownTypes)
		{
			Members = GetMembers(type, base.XmlName, declared_only: false);
		}

		private List<DataMemberInfo> GetMembers(Type type, XmlQualifiedName qname, bool declared_only)
		{
			List<DataMemberInfo> list = new List<DataMemberInfo>();
			BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			if (declared_only)
			{
				bindingFlags |= BindingFlags.DeclaredOnly;
			}
			FieldInfo[] fields = type.GetFields(bindingFlags);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (fieldInfo.GetCustomAttributes(typeof(NonSerializedAttribute), inherit: false).Length <= 0)
				{
					if (fieldInfo.IsInitOnly)
					{
						throw new InvalidDataContractException($"DataMember field {fieldInfo} must not be read-only.");
					}
					DataMemberAttribute dma = new DataMemberAttribute();
					list.Add(CreateDataMemberInfo(dma, fieldInfo, fieldInfo.FieldType));
				}
			}
			list.Sort(DataMemberInfo.DataMemberInfoComparer.Instance);
			return list;
		}

		public override List<DataMemberInfo> GetMembers()
		{
			return Members;
		}
	}
	internal class EnumMap : SerializationMap
	{
		private List<EnumMemberInfo> enum_members;

		private bool flag_attr;

		public EnumMap(Type type, XmlQualifiedName qname, KnownTypeCollection knownTypes)
			: base(type, qname, knownTypes)
		{
			bool flag = false;
			object[] customAttributes = RuntimeType.GetCustomAttributes(typeof(DataContractAttribute), inherit: false);
			if (customAttributes.Length != 0)
			{
				flag = true;
			}
			flag_attr = type.GetCustomAttributes(typeof(FlagsAttribute), inherit: false).Length > 0;
			enum_members = new List<EnumMemberInfo>();
			BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public;
			FieldInfo[] fields = RuntimeType.GetFields(bindingAttr);
			foreach (FieldInfo fieldInfo in fields)
			{
				string name = fieldInfo.Name;
				if (flag)
				{
					EnumMemberAttribute enumMemberAttribute = GetEnumMemberAttribute(fieldInfo);
					if (enumMemberAttribute == null)
					{
						continue;
					}
					if (enumMemberAttribute.Value != null)
					{
						name = enumMemberAttribute.Value;
					}
				}
				enum_members.Add(new EnumMemberInfo(name, fieldInfo.GetValue(null)));
			}
		}

		private EnumMemberAttribute GetEnumMemberAttribute(MemberInfo mi)
		{
			object[] customAttributes = mi.GetCustomAttributes(typeof(EnumMemberAttribute), inherit: false);
			if (customAttributes.Length == 0)
			{
				return null;
			}
			return (EnumMemberAttribute)customAttributes[0];
		}

		public override void Serialize(object graph, XmlFormatterSerializer serializer)
		{
			foreach (EnumMemberInfo enum_member in enum_members)
			{
				if (object.Equals(enum_member.Value, graph))
				{
					serializer.Writer.WriteString(enum_member.XmlName);
					return;
				}
			}
			throw new SerializationException($"Enum value '{graph}' is invalid for type '{RuntimeType}' and cannot be serialized.");
		}

		public override object DeserializeEmptyContent(XmlReader reader, XmlFormatterDeserializer deserializer)
		{
			if (!flag_attr)
			{
				throw new SerializationException($"Enum value '' is invalid for type '{RuntimeType}' and cannot be deserialized.");
			}
			return Enum.ToObject(RuntimeType, 0);
		}

		public override object DeserializeContent(XmlReader reader, XmlFormatterDeserializer deserializer)
		{
			string text = ((reader.NodeType == XmlNodeType.Text) ? reader.ReadContentAsString() : string.Empty);
			if (text != string.Empty)
			{
				foreach (EnumMemberInfo enum_member in enum_members)
				{
					if (enum_member.XmlName == text)
					{
						return enum_member.Value;
					}
				}
			}
			if (!flag_attr)
			{
				throw new SerializationException($"Enum value '{text}' is invalid for type '{RuntimeType}' and cannot be deserialized.");
			}
			return Enum.ToObject(RuntimeType, 0);
		}
	}
	internal struct EnumMemberInfo
	{
		public readonly string XmlName;

		public readonly object Value;

		public EnumMemberInfo(string name, object value)
		{
			XmlName = name;
			Value = value;
		}
	}
	internal class DataMemberInfo
	{
		public class DataMemberInfoComparer : IComparer<DataMemberInfo>, IComparer
		{
			public static readonly DataMemberInfoComparer Instance = new DataMemberInfoComparer();

			private DataMemberInfoComparer()
			{
			}

			public int Compare(object o1, object o2)
			{
				return Compare((DataMemberInfo)o1, (DataMemberInfo)o2);
			}

			public int Compare(DataMemberInfo d1, DataMemberInfo d2)
			{
				if (d1.Order == d2.Order)
				{
					return string.CompareOrdinal(d1.XmlName, d2.XmlName);
				}
				return d1.Order - d2.Order;
			}
		}

		public readonly int Order;

		public readonly bool IsRequired;

		public readonly string XmlName;

		public readonly MemberInfo Member;

		public readonly string XmlNamespace;

		public readonly string XmlRootNamespace;

		public readonly Type MemberType;

		public DataMemberInfo(MemberInfo member, DataMemberAttribute dma, string rootNamespce, string ns)
		{
			if (dma == null)
			{
				throw new ArgumentNullException("dma");
			}
			Order = dma.Order;
			Member = member;
			IsRequired = dma.IsRequired;
			XmlName = ((dma.Name == null) ? member.Name : dma.Name);
			XmlNamespace = ns;
			XmlRootNamespace = rootNamespce;
			if (Member is FieldInfo)
			{
				MemberType = ((FieldInfo)Member).FieldType;
			}
			else
			{
				MemberType = ((PropertyInfo)Member).PropertyType;
			}
		}
	}
	internal class XmlFormatterDeserializer
	{
		private KnownTypeCollection types;

		private IDataContractSurrogate surrogate;

		private Hashtable references = new Hashtable();

		public Hashtable References => references;

		private XmlFormatterDeserializer(KnownTypeCollection knownTypes, IDataContractSurrogate surrogate)
		{
			types = knownTypes;
			this.surrogate = surrogate;
		}

		public static object Deserialize(XmlReader reader, Type type, KnownTypeCollection knownTypes, IDataContractSurrogate surrogate, string name, string ns, bool verifyObjectName)
		{
			reader.MoveToContent();
			if (verifyObjectName && (reader.NodeType != XmlNodeType.Element || reader.LocalName != name || reader.NamespaceURI != ns))
			{
				throw new SerializationException($"Expected element '{name}' in namespace '{ns}', but found {reader.NodeType} node '{reader.LocalName}' in namespace '{reader.NamespaceURI}'");
			}
			return new XmlFormatterDeserializer(knownTypes, surrogate).Deserialize(type, reader);
		}

		private static void Verify(KnownTypeCollection knownTypes, Type type, string name, string Namespace, XmlReader reader)
		{
			XmlQualifiedName xmlQualifiedName = new XmlQualifiedName(reader.Name, reader.NamespaceURI);
			if (xmlQualifiedName.Name == name && xmlQualifiedName.Namespace == Namespace)
			{
				return;
			}
			Type type2 = type;
			while ((object)type2 != null)
			{
				if (knownTypes.GetQName(type2) == xmlQualifiedName)
				{
					return;
				}
				type2 = type2.BaseType;
			}
			XmlQualifiedName qName = knownTypes.GetQName(type);
			throw new SerializationException($"Expecting element '{qName.Name}' from namespace '{qName.Namespace}'. Encountered 'Element' with name '{xmlQualifiedName.Name}', namespace '{xmlQualifiedName.Namespace}'");
		}

		public object Deserialize(Type type, XmlReader reader)
		{
			string attribute = reader.GetAttribute("Id", "http://schemas.microsoft.com/2003/10/Serialization/");
			object obj = DeserializeCore(type, reader);
			if (attribute != null)
			{
				references.Add(attribute, obj);
			}
			return obj;
		}

		public object DeserializeCore(Type type, XmlReader reader)
		{
			XmlQualifiedName xmlQualifiedName = types.GetQName(type);
			string attribute = reader.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance");
			if (attribute != null)
			{
				string[] array = attribute.Split(new char[1] { ':' });
				xmlQualifiedName = ((array.Length <= 1) ? new XmlQualifiedName(attribute, reader.NamespaceURI) : new XmlQualifiedName(array[1], reader.LookupNamespace(reader.NameTable.Get(array[0]))));
			}
			string attribute2 = reader.GetAttribute("Ref", "http://schemas.microsoft.com/2003/10/Serialization/");
			if (attribute2 != null)
			{
				object obj = references[attribute2];
				if (obj == null)
				{
					throw new SerializationException($"Deserialized object with reference Id '{attribute2}' was not found");
				}
				reader.Skip();
				return obj;
			}
			if (reader.GetAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance") == "true")
			{
				reader.Skip();
				if (!type.IsValueType)
				{
					return null;
				}
				if (type.IsGenericType && (object)type.GetGenericTypeDefinition() == typeof(Nullable<>))
				{
					return null;
				}
				throw new SerializationException($"Value type {type} cannot be null.");
			}
			if ((object)KnownTypeCollection.GetPrimitiveTypeFromName(xmlQualifiedName.Name) != null)
			{
				string s;
				if (reader.IsEmptyElement)
				{
					reader.Read();
					if (type.IsValueType)
					{
						return Activator.CreateInstance(type);
					}
					s = string.Empty;
				}
				else
				{
					s = reader.ReadElementContentAsString();
				}
				return KnownTypeCollection.PredefinedTypeStringToObject(s, xmlQualifiedName.Name, reader);
			}
			return DeserializeByMap(xmlQualifiedName, type, reader);
		}

		private object DeserializeByMap(XmlQualifiedName name, Type type, XmlReader reader)
		{
			SerializationMap serializationMap = types.FindUserMap(name);
			if (serializationMap == null && (name.Namespace == "http://schemas.microsoft.com/2003/10/Serialization/Arrays" || name.Namespace.StartsWith("http://schemas.datacontract.org/2004/07/", StringComparison.Ordinal)))
			{
				Type typeFromNamePair = GetTypeFromNamePair(name.Name, name.Namespace);
				types.TryRegister(typeFromNamePair);
				serializationMap = types.FindUserMap(name);
			}
			if (serializationMap == null)
			{
				throw new SerializationException($"Unknown type {type} is used for DataContract with reference of name {name}. Any derived types of a data contract or a data member should be added to KnownTypes.");
			}
			return serializationMap.DeserializeObject(reader, this);
		}

		private Type GetTypeFromNamePair(string name, string ns)
		{
			Type primitiveTypeFromName = KnownTypeCollection.GetPrimitiveTypeFromName(name);
			if ((object)primitiveTypeFromName != null)
			{
				return primitiveTypeFromName;
			}
			if (name.StartsWith("ArrayOf", StringComparison.Ordinal) && ns == "http://schemas.microsoft.com/2003/10/Serialization/Arrays")
			{
				return GetTypeFromNamePair(name.Substring(7), string.Empty).MakeArrayType();
			}
			int length = "http://schemas.datacontract.org/2004/07/".Length;
			string text = ((ns.Length <= length) ? null : ns.Substring(length));
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type[] array = assembly.GetTypes();
				foreach (Type type in array)
				{
					DataContractAttribute customAttribute = type.GetCustomAttribute<DataContractAttribute>(inherit: true);
					if (customAttribute != null && customAttribute.Name == name && customAttribute.Namespace == ns)
					{
						return type;
					}
					if (text != null && type.Name == name && type.Namespace == text)
					{
						return type;
					}
				}
			}
			throw new XmlException($"Type not found; name: {name}, namespace: {ns}");
		}
	}
	internal class XmlFormatterSerializer
	{
		private XmlDictionaryWriter writer;

		private object graph;

		private KnownTypeCollection types;

		private bool save_id;

		private bool ignore_unknown;

		private IDataContractSurrogate surrogate;

		private int max_items;

		private ArrayList objects = new ArrayList();

		private Hashtable references = new Hashtable();

		public ArrayList SerializingObjects => objects;

		public IDictionary References => references;

		public XmlDictionaryWriter Writer => writer;

		public XmlFormatterSerializer(XmlDictionaryWriter writer, KnownTypeCollection types, bool ignoreUnknown, int maxItems, string root_ns)
		{
			this.writer = writer;
			this.types = types;
			ignore_unknown = ignoreUnknown;
			max_items = maxItems;
		}

		public static void Serialize(XmlDictionaryWriter writer, object graph, KnownTypeCollection types, bool ignoreUnknown, int maxItems, string root_ns)
		{
			new XmlFormatterSerializer(writer, types, ignoreUnknown, maxItems, root_ns).Serialize(graph?.GetType(), graph);
		}

		public void Serialize(Type type, object graph)
		{
			if (graph == null)
			{
				writer.WriteAttributeString("nil", "http://www.w3.org/2001/XMLSchema-instance", "true");
				return;
			}
			Type type2 = graph.GetType();
			SerializationMap serializationMap = types.FindUserMap(type2);
			if (serializationMap == null)
			{
				type2 = types.GetSerializedType(type2);
				serializationMap = types.FindUserMap(type2);
			}
			if (serializationMap == null)
			{
				types.Add(type2);
				serializationMap = types.FindUserMap(type2);
			}
			if ((object)type2 != type && (serializationMap == null || serializationMap.OutputXsiType))
			{
				XmlQualifiedName xmlName = types.GetXmlName(type2);
				string localName = xmlName.Name;
				string text = xmlName.Namespace;
				if (xmlName == XmlQualifiedName.Empty)
				{
					localName = XmlConvert.EncodeLocalName(type2.Name);
					text = "http://schemas.datacontract.org/2004/07/" + type2.Namespace;
				}
				else if (xmlName.Namespace == "http://schemas.microsoft.com/2003/10/Serialization/")
				{
					text = "http://www.w3.org/2001/XMLSchema";
				}
				if (writer.LookupPrefix(text) == null)
				{
					writer.WriteXmlnsAttribute(null, text);
				}
				writer.WriteStartAttribute("type", "http://www.w3.org/2001/XMLSchema-instance");
				writer.WriteQualifiedName(localName, text);
				writer.WriteEndAttribute();
			}
			XmlQualifiedName predefinedTypeName = KnownTypeCollection.GetPredefinedTypeName(type2);
			if (predefinedTypeName != XmlQualifiedName.Empty)
			{
				SerializePrimitive(type, graph, predefinedTypeName);
			}
			else
			{
				serializationMap.Serialize(graph, this);
			}
		}

		public void SerializePrimitive(Type type, object graph, XmlQualifiedName qname)
		{
			writer.WriteString(KnownTypeCollection.PredefinedTypeObjectToString(graph));
		}

		public void WriteStartElement(string rootName, string rootNamespace, string currentNamespace)
		{
			writer.WriteStartElement(rootName, rootNamespace);
			if (!string.IsNullOrEmpty(currentNamespace) && currentNamespace != rootNamespace)
			{
				writer.WriteXmlnsAttribute(null, currentNamespace);
			}
		}

		public void WriteEndElement()
		{
			writer.WriteEndElement();
		}
	}
	public abstract class XmlObjectSerializer
	{
		private IDataContractSurrogate surrogate;

		private SerializationBinder binder;

		private ISurrogateSelector selector;

		private int max_items = 65536;

		public virtual bool IsStartObject(XmlReader reader)
		{
			return IsStartObject(XmlDictionaryReader.CreateDictionaryReader(reader));
		}

		public abstract bool IsStartObject(XmlDictionaryReader reader);

		public virtual object ReadObject(Stream stream)
		{
			return ReadObject(XmlReader.Create(stream));
		}

		public virtual object ReadObject(XmlReader reader)
		{
			return ReadObject(XmlDictionaryReader.CreateDictionaryReader(reader));
		}

		public virtual object ReadObject(XmlDictionaryReader reader)
		{
			return ReadObject(reader, readContentOnly: true);
		}

		public virtual object ReadObject(XmlReader reader, bool readContentOnly)
		{
			return ReadObject(XmlDictionaryReader.CreateDictionaryReader(reader), readContentOnly);
		}

		[MonoTODO]
		public abstract object ReadObject(XmlDictionaryReader reader, bool readContentOnly);

		public virtual void WriteObject(Stream stream, object graph)
		{
			using XmlWriter writer = XmlDictionaryWriter.CreateTextWriter(stream);
			WriteObject(writer, graph);
		}

		public virtual void WriteObject(XmlWriter writer, object graph)
		{
			WriteObject(XmlDictionaryWriter.CreateDictionaryWriter(writer), graph);
		}

		public virtual void WriteStartObject(XmlWriter writer, object graph)
		{
			WriteStartObject(XmlDictionaryWriter.CreateDictionaryWriter(writer), graph);
		}

		public virtual void WriteObject(XmlDictionaryWriter writer, object graph)
		{
			WriteStartObject(writer, graph);
			WriteObjectContent(writer, graph);
			WriteEndObject(writer);
		}

		public abstract void WriteStartObject(XmlDictionaryWriter writer, object graph);

		public virtual void WriteObjectContent(XmlWriter writer, object graph)
		{
			WriteObjectContent(XmlDictionaryWriter.CreateDictionaryWriter(writer), graph);
		}

		public abstract void WriteObjectContent(XmlDictionaryWriter writer, object graph);

		public virtual void WriteEndObject(XmlWriter writer)
		{
			WriteEndObject(XmlDictionaryWriter.CreateDictionaryWriter(writer));
		}

		public abstract void WriteEndObject(XmlDictionaryWriter writer);
	}
}
namespace System.Xml
{
	public interface IStreamProvider
	{
		Stream GetStream();

		void ReleaseStream(Stream stream);
	}
	public interface IXmlBinaryReaderInitializer
	{
		void SetInput(Stream stream, IXmlDictionary dictionary, XmlDictionaryReaderQuotas quota, XmlBinaryReaderSession session, OnXmlDictionaryReaderClose onClose);

		void SetInput(byte[] buffer, int offset, int count, IXmlDictionary dictionary, XmlDictionaryReaderQuotas quota, XmlBinaryReaderSession session, OnXmlDictionaryReaderClose onClose);
	}
	public interface IXmlBinaryWriterInitializer
	{
		void SetOutput(Stream stream, IXmlDictionary dictionary, XmlBinaryWriterSession session, bool ownsStream);
	}
	public interface IXmlDictionary
	{
		bool TryLookup(int key, out XmlDictionaryString result);

		bool TryLookup(string value, out XmlDictionaryString result);

		bool TryLookup(XmlDictionaryString value, out XmlDictionaryString result);
	}
	public interface IXmlMtomReaderInitializer
	{
		void SetInput(Stream stream, Encoding[] encodings, string contentType, XmlDictionaryReaderQuotas quotas, int maxBufferSize, OnXmlDictionaryReaderClose onClose);

		void SetInput(byte[] buffer, int offset, int count, Encoding[] encodings, string contentType, XmlDictionaryReaderQuotas quotas, int maxBufferSize, OnXmlDictionaryReaderClose onClose);
	}
	public interface IXmlMtomWriterInitializer
	{
		void SetOutput(Stream stream, Encoding encoding, int maxSizeInBytes, string startInfo, string boundary, string startUri, bool writeMessageHeaders, bool ownsStream);
	}
	public interface IXmlTextReaderInitializer
	{
		void SetInput(byte[] buffer, int offset, int count, Encoding encoding, XmlDictionaryReaderQuotas quota, OnXmlDictionaryReaderClose onClose);

		void SetInput(Stream stream, Encoding encoding, XmlDictionaryReaderQuotas quota, OnXmlDictionaryReaderClose onClose);
	}
	public interface IXmlTextWriterInitializer
	{
		void SetOutput(Stream stream, Encoding encoding, bool ownsStream);
	}
	public class UniqueId
	{
		private Guid guid;

		private string id;

		public int CharArrayLength => (id == null) ? 45 : id.Length;

		public bool IsGuid => guid != default(Guid);

		public UniqueId()
			: this(Guid.NewGuid())
		{
		}

		public UniqueId(byte[] id)
			: this(id, 0)
		{
		}

		public UniqueId(Guid id)
		{
			guid = id;
		}

		public UniqueId(string value)
		{
			if (value == null)
			{
				throw new ArgumentNullException("value cannot be null", "value");
			}
			if (value.Length == 0)
			{
				throw new FormatException("UniqueId cannot be zero length");
			}
			id = value;
		}

		public UniqueId(byte[] id, int offset)
		{
			if (id == null)
			{
				throw new ArgumentNullException();
			}
			if (offset < 0)
			{
				throw new ArgumentOutOfRangeException("offset");
			}
			if (offset >= id.Length)
			{
				throw new ArgumentException("id too small.", "offset");
			}
			if (id.Length - offset != 16)
			{
				throw new ArgumentException("id and offset provide less than 16 bytes");
			}
			if (offset == 0)
			{
				guid = new Guid(id);
				return;
			}
			List<byte> list = new List<byte>(id);
			list.RemoveRange(0, offset);
			guid = new Guid(list.ToArray());
		}

		public UniqueId(char[] id, int offset, int count)
		{
			if (id == null)
			{
				throw new ArgumentNullException("id");
			}
			if (offset < 0 || offset >= id.Length)
			{
				throw new ArgumentOutOfRangeException("offset");
			}
			if (count < 0 || id.Length - offset < count)
			{
				throw new ArgumentOutOfRangeException("count");
			}
			if (count == 0)
			{
				throw new FormatException();
			}
			if (count > 8 && id[offset] == 'u' && id[offset + 1] == 'r' && id[offset + 2] == 'n' && id[offset + 3] == ':' && id[offset + 4] == 'u' && id[offset + 5] == 'u' && id[offset + 6] == 'i' && id[offset + 7] == 'd' && id[offset + 8] == ':')
			{
				if (count != 45)
				{
					throw new ArgumentOutOfRangeException("Invalid Guid");
				}
				guid = new Guid(new string(id, offset + 9, count - 9));
			}
			else
			{
				this.id = new string(id, offset, count);
			}
		}

		public override bool Equals(object obj)
		{
			UniqueId uniqueId = obj as UniqueId;
			if (uniqueId == null)
			{
				return false;
			}
			if (IsGuid && uniqueId.IsGuid)
			{
				return guid.Equals(uniqueId.guid);
			}
			return id == uniqueId.id;
		}

		[MonoTODO("Determine semantics when IsGuid==true")]
		public override int GetHashCode()
		{
			return (id == null) ? guid.GetHashCode() : id.GetHashCode();
		}

		public int ToCharArray(char[] array, int offset)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (offset < 0 || offset >= array.Length)
			{
				throw new ArgumentOutOfRangeException("offset");
			}
			string text = ToString();
			text.CopyTo(0, array, offset, text.Length);
			return text.Length;
		}

		public override string ToString()
		{
			if (id == null)
			{
				return "urn:uuid:" + guid;
			}
			return id;
		}

		public bool TryGetGuid(out Guid guid)
		{
			if (IsGuid)
			{
				guid = this.guid;
				return true;
			}
			guid = default(Guid);
			return false;
		}

		public bool TryGetGuid(byte[] buffer, int offset)
		{
			if (!IsGuid)
			{
				return false;
			}
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			if (offset < 0 || offset >= buffer.Length)
			{
				throw new ArgumentOutOfRangeException("offset");
			}
			if (buffer.Length - offset < 16)
			{
				throw new ArgumentOutOfRangeException("offset");
			}
			guid.ToByteArray().CopyTo(buffer, offset);
			return true;
		}

		public static bool operator ==(UniqueId id1, UniqueId id2)
		{
			return object.Equals(id1, id2);
		}

		public static bool operator !=(UniqueId id1, UniqueId id2)
		{
			return !(id1 == id2);
		}
	}
	internal class XmlBinaryDictionaryReader : XmlDictionaryReader, IXmlNamespaceResolver
	{
		internal interface ISource
		{
			int Position { get; }

			BinaryReader Reader { get; }

			int ReadByte();

			int Read(byte[] data, int offset, int count);
		}

		internal class StreamSource : ISource
		{
			private BinaryReader reader;

			public int Position => (int)reader.BaseStream.Position;

			public BinaryReader Reader => reader;

			public StreamSource(Stream stream)
			{
				reader = new BinaryReader(stream);
			}

			public int ReadByte()
			{
				if (reader.PeekChar() < 0)
				{
					return -1;
				}
				return reader.ReadByte();
			}

			public int Read(byte[] data, int offset, int count)
			{
				return reader.Read(data, offset, count);
			}
		}

		private class NodeInfo
		{
			public bool IsAttributeValue;

			public int Position;

			public string Prefix;

			public XmlDictionaryString DictLocalName;

			public XmlDictionaryString DictNS;

			public XmlDictionaryString DictValue;

			public XmlNodeType NodeType;

			public object TypedValue;

			public byte ValueType;

			public int NSSlot;

			private string name = string.Empty;

			private string local_name = string.Empty;

			private string ns = string.Empty;

			private string value;

			public string LocalName
			{
				get
				{
					return (DictLocalName == null) ? local_name : DictLocalName.Value;
				}
				set
				{
					DictLocalName = null;
					local_name = value;
				}
			}

			public string NS
			{
				get
				{
					return (DictNS == null) ? ns : DictNS.Value;
				}
				set
				{
					DictNS = null;
					ns = value;
				}
			}

			public string Name
			{
				get
				{
					if (name.Length == 0)
					{
						name = ((Prefix.Length <= 0) ? LocalName : (Prefix + ":" + LocalName));
					}
					return name;
				}
			}

			public virtual string Value
			{
				get
				{
					switch (ValueType)
					{
					case 0:
					case 2:
					case 152:
					case 154:
					case 156:
					case 168:
					case 182:
					case 184:
					case 186:
						return value;
					case 170:
						return DictValue.Value;
					case 128:
						return "0";
					case 130:
						return "1";
					case 134:
						return "true";
					case 132:
						return "false";
					case 136:
						return XmlConvert.ToString((byte)TypedValue);
					case 138:
						return XmlConvert.ToString((short)TypedValue);
					case 140:
						return XmlConvert.ToString((int)TypedValue);
					case 142:
						return XmlConvert.ToString((long)TypedValue);
					case 144:
						return XmlConvert.ToString((float)TypedValue);
					case 146:
						return XmlConvert.ToString((double)TypedValue);
					case 150:
						return XmlConvert.ToString((DateTime)TypedValue, XmlDateTimeSerializationMode.RoundtripKind);
					case 174:
						return XmlConvert.ToString((TimeSpan)TypedValue);
					case 176:
						return XmlConvert.ToString((Guid)TypedValue);
					case 172:
						return TypedValue.ToString();
					case 158:
					case 160:
					case 162:
						return Convert.ToBase64String((byte[])TypedValue);
					default:
						throw new NotImplementedException("ValueType " + ValueType + " on node " + NodeType);
					}
				}
				set
				{
					this.value = value;
				}
			}

			public NodeInfo()
			{
			}

			public NodeInfo(bool isAttr)
			{
				IsAttributeValue = isAttr;
			}

			public virtual void Reset()
			{
				Position = 0;
				DictLocalName = (DictNS = null);
				string prefix = (Value = string.Empty);
				prefix = (NS = (Prefix = prefix));
				LocalName = prefix;
				NodeType = XmlNodeType.None;
				TypedValue = null;
				ValueType = 0;
				NSSlot = -1;
			}
		}

		private class AttrNodeInfo : NodeInfo
		{
			private XmlBinaryDictionaryReader owner;

			public int ValueIndex;

			public override string Value => owner.attr_values[ValueIndex].Value;

			public AttrNodeInfo(XmlBinaryDictionaryReader owner)
			{
				this.owner = owner;
			}

			public override void Reset()
			{
				base.Reset();
				ValueIndex = -1;
				NodeType = XmlNodeType.Attribute;
			}
		}

		private ISource source;

		private IXmlDictionary dictionary;

		private XmlDictionaryReaderQuotas quota;

		private XmlBinaryReaderSession session;

		private OnXmlDictionaryReaderClose on_close;

		private XmlParserContext context;

		private ReadState state;

		private NodeInfo node;

		private NodeInfo current;

		private List<AttrNodeInfo> attributes = new List<AttrNodeInfo>();

		private List<NodeInfo> attr_values = new List<NodeInfo>();

		private List<NodeInfo> node_stack = new List<NodeInfo>();

		private List<XmlQualifiedName> ns_store = new List<XmlQualifiedName>();

		private Dictionary<int, XmlDictionaryString> ns_dict_store = new Dictionary<int, XmlDictionaryString>();

		private int attr_count;

		private int attr_value_count;

		private int current_attr = -1;

		private int depth;

		private int ns_slot;

		private int next = -1;

		private bool is_next_end_element;

		private byte[] tmp_buffer = new byte[128];

		private UTF8Encoding utf8enc = new UTF8Encoding();

		private int array_item_remaining;

		private byte array_item_type;

		private XmlNodeType array_state;

		public override int AttributeCount => attr_count;

		public override string BaseURI => context.BaseURI;

		public override int Depth => (current == node) ? depth : ((NodeType != XmlNodeType.Attribute) ? (depth + 2) : (depth + 1));

		public override bool EOF => state == ReadState.EndOfFile || state == ReadState.Error;

		public override bool HasValue => Value.Length > 0;

		public override bool IsEmptyElement => false;

		public override XmlNodeType NodeType => current.NodeType;

		public override string Prefix => (current_attr < 0) ? current.Prefix : attributes[current_attr].Prefix;

		public override string LocalName => (current_attr < 0) ? current.LocalName : attributes[current_attr].LocalName;

		public override string Name => (current_attr < 0) ? current.Name : attributes[current_attr].Name;

		public override string NamespaceURI => (current_attr < 0) ? current.NS : attributes[current_attr].NS;

		public override XmlNameTable NameTable => context.NameTable;

		public override XmlDictionaryReaderQuotas Quotas => quota;

		public override ReadState ReadState => state;

		public override string Value => current.Value;

		public XmlBinaryDictionaryReader(byte[] buffer, int offset, int count, IXmlDictionary dictionary, XmlDictionaryReaderQuotas quota, XmlBinaryReaderSession session, OnXmlDictionaryReaderClose onClose)
		{
			source = new StreamSource(new MemoryStream(buffer, offset, count));
			Initialize(dictionary, quota, session, onClose);
		}

		public XmlBinaryDictionaryReader(Stream stream, IXmlDictionary dictionary, XmlDictionaryReaderQuotas quota, XmlBinaryReaderSession session, OnXmlDictionaryReaderClose onClose)
		{
			source = new StreamSource(stream);
			Initialize(dictionary, quota, session, onClose);
		}

		private void Initialize(IXmlDictionary dictionary, XmlDictionaryReaderQuotas quotas, XmlBinaryReaderSession session, OnXmlDictionaryReaderClose onClose)
		{
			if (quotas == null)
			{
				throw new ArgumentNullException("quotas");
			}
			if (dictionary == null)
			{
				dictionary = new XmlDictionary();
			}
			this.dictionary = dictionary;
			quota = quotas;
			if (session == null)
			{
				session = new XmlBinaryReaderSession();
			}
			this.session = session;
			on_close = onClose;
			NameTable nameTable = new NameTable();
			context = new XmlParserContext(nameTable, new XmlNamespaceManager(nameTable), null, XmlSpace.None);
			current = (node = new NodeInfo());
			current.Reset();
			node_stack.Add(node);
		}

		public override void Close()
		{
			if (on_close != null)
			{
				on_close(this);
			}
		}

		public override string GetAttribute(int i)
		{
			if (i >= attr_count)
			{
				throw new ArgumentOutOfRangeException($"Specified attribute index is {i} and should be less than {attr_count}");
			}
			return attributes[i].Value;
		}

		public override string GetAttribute(string name)
		{
			for (int i = 0; i < attr_count; i++)
			{
				if (attributes[i].Name == name)
				{
					return attributes[i].Value;
				}
			}
			return null;
		}

		public override string GetAttribute(string localName, string ns)
		{
			for (int i = 0; i < attr_count; i++)
			{
				if (attributes[i].LocalName == localName && attributes[i].NS == ns)
				{
					return attributes[i].Value;
				}
			}
			return null;
		}

		public IDictionary<string, string> GetNamespacesInScope(XmlNamespaceScope scope)
		{
			return context.NamespaceManager.GetNamespacesInScope(scope);
		}

		public string LookupPrefix(string ns)
		{
			return context.NamespaceManager.LookupPrefix(NameTable.Get(ns));
		}

		public override string LookupNamespace(string prefix)
		{
			return context.NamespaceManager.LookupNamespace(NameTable.Get(prefix));
		}

		public override bool IsArray(out Type type)
		{
			if (array_state == XmlNodeType.Element)
			{
				type = GetArrayType(array_item_type);
				return true;
			}
			type = null;
			return false;
		}

		public override bool MoveToElement()
		{
			bool result = current_attr >= 0;
			current_attr = -1;
			current = node;
			return result;
		}

		public override bool MoveToFirstAttribute()
		{
			if (attr_count == 0)
			{
				return false;
			}
			current_attr = 0;
			current = attributes[current_attr];
			return true;
		}

		public override bool MoveToNextAttribute()
		{
			if (++current_attr < attr_count)
			{
				current = attributes[current_attr];
				return true;
			}
			current_attr--;
			return false;
		}

		public override void MoveToAttribute(int i)
		{
			if (i >= attr_count)
			{
				throw new ArgumentOutOfRangeException($"Specified attribute index is {i} and should be less than {attr_count}");
			}
			current_attr = i;
			current = attributes[i];
		}

		public override bool MoveToAttribute(string name)
		{
			for (int i = 0; i < attributes.Count; i++)
			{
				if (attributes[i].Name == name)
				{
					MoveToAttribute(i);
					return true;
				}
			}
			return false;
		}

		public override bool MoveToAttribute(string localName, string ns)
		{
			for (int i = 0; i < attributes.Count; i++)
			{
				if (attributes[i].LocalName == localName && attributes[i].NS == ns)
				{
					MoveToAttribute(i);
					return true;
				}
			}
			return false;
		}

		public override bool ReadAttributeValue()
		{
			if (current_attr < 0)
			{
				return false;
			}
			int valueIndex = attributes[current_attr].ValueIndex;
			int num = ((current_attr + 1 != attr_count) ? attributes[current_attr + 1].ValueIndex : attr_value_count);
			if (valueIndex == num)
			{
				return false;
			}
			if (!current.IsAttributeValue)
			{
				current = attr_values[valueIndex];
				return true;
			}
			return false;
		}

		public override bool Read()
		{
			switch (state)
			{
			case ReadState.Error:
			case ReadState.EndOfFile:
			case ReadState.Closed:
				return false;
			default:
			{
				state = ReadState.Interactive;
				MoveToElement();
				attr_count = 0;
				attr_value_count = 0;
				ns_slot = 0;
				if (node.NodeType == XmlNodeType.Element)
				{
					if (node_stack.Count <= ++depth)
					{
						if (depth == quota.MaxDepth)
						{
							throw new XmlException($"Binary XML stream quota exceeded. Depth must be less than {quota.MaxDepth}");
						}
						node = new NodeInfo();
						node_stack.Add(node);
					}
					else
					{
						node = node_stack[depth];
						node.Reset();
					}
				}
				current = node;
				if (is_next_end_element)
				{
					is_next_end_element = false;
					node.Reset();
					ProcessEndElement();
					return true;
				}
				switch (array_state)
				{
				case XmlNodeType.Element:
					ReadArrayItem();
					return true;
				case XmlNodeType.Text:
					ShiftToArr