Decompiled source of DDSLoader v1.0.4

DDSLoader.dll

Decompiled 4 months 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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Linq;
using Tavis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("DDSLoader")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Loads the DDS and strings CSV for other mods")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("DDSLoader")]
[assembly: AssemblyTitle("DDSLoader")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DDSLoader
{
	public class DDSDebugHelper
	{
		public static void StartConversation(string ddsTreeId, string participantA, string participantB)
		{
			StartConversation(ddsTreeId, new string[2] { participantA, participantB });
		}

		public static void StartConversation(string ddsTreeId, string[] participants)
		{
			Human val = null;
			List<Human> val2 = new List<Human>();
			foreach (string text in participants)
			{
				if ((Object)(object)val == (Object)null)
				{
					val = GameObject.Find(text).GetComponent<Human>();
				}
				else
				{
					val2.Add(GameObject.Find(text).GetComponent<Human>());
				}
			}
			val.ExecuteConversationTree(Toolbox.Instance.allDDSTrees[ddsTreeId], val2);
		}
	}
	[HarmonyPatch(typeof(Human), "ExecuteConversationTree")]
	public class Human_ExecuteConversationTree
	{
		public static void Postfix(Human __instance, DDSTreeSave newTree, List<Human> otherParticipants)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			if (DDSLoaderPlugin.debugLogConversations.Value)
			{
				ManualLogSource logger = DDSLoaderPlugin.Logger;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(49, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Conversation started: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((DDSComponent)newTree).id);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" started by ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)__instance).name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" and including ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", ((IEnumerable<Human>)otherParticipants.ToArray()).Select((Human other) => ((Object)other).name)));
				}
				logger.LogInfo(val);
			}
			if (DDSLoaderPlugin.debugPauseTreeGUID.Value == ((DDSComponent)newTree).id)
			{
				InterfaceController.Instance.ToggleNotebookButton();
			}
		}
	}
	internal class DDSLoaderHooks
	{
		[HarmonyPatch(typeof(Toolbox), "Start")]
		public class Toolbox_Start
		{
			[Serializable]
			private class CustomSerializableNewspaperArticle
			{
				public bool disabled;

				public int category;

				public string[] followupStories;

				public string[] possibleImages;

				public int context;
			}

			public static void Postfix()
			{
				//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f0: Expected O, but got Unknown
				//IL_0190: Unknown result type (might be due to invalid IL or missing references)
				//IL_0197: Expected O, but got Unknown
				//IL_0249: Unknown result type (might be due to invalid IL or missing references)
				//IL_0250: Expected O, but got Unknown
				//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f7: Expected O, but got Unknown
				//IL_042f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0436: Expected O, but got Unknown
				//IL_051d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0524: Expected O, but got Unknown
				//IL_0578: Unknown result type (might be due to invalid IL or missing references)
				//IL_057f: Expected O, but got Unknown
				//IL_03df: Unknown result type (might be due to invalid IL or missing references)
				//IL_03e5: Invalid comparison between Unknown and I4
				//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0401: Expected O, but got Unknown
				//IL_06d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_06db: Expected O, but got Unknown
				if (DDSLoaderPlugin.debugClearNewspaperArticles.Value)
				{
					Toolbox.Instance.allArticleTrees.Clear();
				}
				bool flag = default(bool);
				string text11 = default(string);
				string text12 = default(string);
				string text13 = default(string);
				string text14 = default(string);
				int num3 = default(int);
				bool flag2 = default(bool);
				string text15 = default(string);
				foreach (DirectoryInfo item in DDSLoaderPlugin.modsToLoadFrom)
				{
					string path = Path.Combine(item.FullName, "DDS", "Trees");
					string path2 = Path.Combine(item.FullName, "DDS", "Messages");
					string path3 = Path.Combine(item.FullName, "DDS", "Blocks");
					if (Directory.Exists(path3))
					{
						string[] files = Directory.GetFiles(path3, "*.block");
						foreach (string text in files)
						{
							try
							{
								DDSBlockSave val = JsonUtility.FromJson<DDSBlockSave>(File.ReadAllText(text));
								Toolbox.Instance.allDDSBlocks.Add(((DDSComponent)val).id, val);
							}
							catch (Exception ex)
							{
								ManualLogSource logger = DDSLoaderPlugin.Logger;
								BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag);
								if (flag)
								{
									((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load: ");
									((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text);
								}
								logger.LogError(val2);
								DDSLoaderPlugin.Logger.LogError((object)ex);
							}
						}
						string[] files2 = Directory.GetFiles(path3, "*.block_patch");
						foreach (string text2 in files2)
						{
							try
							{
								DDSBlockSave val3 = JsonUtility.FromJson<DDSBlockSave>(CreatePatchedJson(text2));
								Toolbox.Instance.allDDSBlocks[((DDSComponent)val3).id] = val3;
							}
							catch (Exception ex2)
							{
								ManualLogSource logger2 = DDSLoaderPlugin.Logger;
								BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag);
								if (flag)
								{
									((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load: ");
									((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text2);
								}
								logger2.LogError(val2);
								DDSLoaderPlugin.Logger.LogError((object)ex2);
							}
						}
					}
					if (Directory.Exists(path2))
					{
						string[] files3 = Directory.GetFiles(path2, "*.msg");
						foreach (string text3 in files3)
						{
							try
							{
								DDSMessageSave val4 = JsonUtility.FromJson<DDSMessageSave>(File.ReadAllText(text3));
								Toolbox.Instance.allDDSMessages.Add(((DDSComponent)val4).id, val4);
							}
							catch (Exception ex3)
							{
								ManualLogSource logger3 = DDSLoaderPlugin.Logger;
								BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag);
								if (flag)
								{
									((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load: ");
									((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text3);
								}
								logger3.LogError(val2);
								DDSLoaderPlugin.Logger.LogError((object)ex3);
							}
						}
						string[] files4 = Directory.GetFiles(path2, "*.msg_patch");
						foreach (string text4 in files4)
						{
							try
							{
								DDSMessageSave val5 = JsonUtility.FromJson<DDSMessageSave>(CreatePatchedJson(text4));
								Toolbox.Instance.allDDSMessages[((DDSComponent)val5).id] = val5;
							}
							catch (Exception ex4)
							{
								ManualLogSource logger4 = DDSLoaderPlugin.Logger;
								BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag);
								if (flag)
								{
									((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load: ");
									((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text4);
								}
								logger4.LogError(val2);
								DDSLoaderPlugin.Logger.LogError((object)ex4);
							}
						}
					}
					if (Directory.Exists(path))
					{
						string[] files5 = Directory.GetFiles(path, "*.tree");
						foreach (string text5 in files5)
						{
							try
							{
								DDSTreeSave val6 = JsonUtility.FromJson<DDSTreeSave>(File.ReadAllText(text5));
								val6.messageRef = new Dictionary<string, DDSMessageSettings>();
								Enumerator<DDSMessageSettings> enumerator2 = val6.messages.GetEnumerator();
								while (enumerator2.MoveNext())
								{
									DDSMessageSettings current2 = enumerator2.Current;
									val6.messageRef.Add(current2.instanceID, current2);
								}
								Toolbox.Instance.allDDSTrees.Add(((DDSComponent)val6).id, val6);
								if ((int)val6.treeType == 3)
								{
									ManualLogSource logger5 = DDSLoaderPlugin.Logger;
									BepInExWarningLogInterpolatedStringHandler val7 = new BepInExWarningLogInterpolatedStringHandler(66, 0, ref flag);
									if (flag)
									{
										((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("Newspaper content is no longer supported - use the official editor");
									}
									logger5.LogWarning(val7);
								}
							}
							catch (Exception ex5)
							{
								ManualLogSource logger6 = DDSLoaderPlugin.Logger;
								BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag);
								if (flag)
								{
									((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load: ");
									((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text5);
								}
								logger6.LogError(val2);
								DDSLoaderPlugin.Logger.LogError((object)ex5);
							}
						}
						string[] files6 = Directory.GetFiles(path, "*.tree_patch");
						foreach (string text6 in files6)
						{
							try
							{
								DDSTreeSave val8 = JsonUtility.FromJson<DDSTreeSave>(CreatePatchedJson(text6));
								val8.messageRef = new Dictionary<string, DDSMessageSettings>();
								Enumerator<DDSMessageSettings> enumerator3 = val8.messages.GetEnumerator();
								while (enumerator3.MoveNext())
								{
									DDSMessageSettings current3 = enumerator3.Current;
									val8.messageRef.Add(current3.instanceID, current3);
								}
								Toolbox.Instance.allDDSTrees[((DDSComponent)val8).id] = val8;
							}
							catch (Exception ex6)
							{
								ManualLogSource logger7 = DDSLoaderPlugin.Logger;
								BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag);
								if (flag)
								{
									((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load: ");
									((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text6);
								}
								logger7.LogError(val2);
								DDSLoaderPlugin.Logger.LogError((object)ex6);
							}
						}
					}
					ManualLogSource logger8 = DDSLoaderPlugin.Logger;
					BepInExInfoLogInterpolatedStringHandler val9 = new BepInExInfoLogInterpolatedStringHandler(36, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val9).AppendLiteral("Loaded DDS Content and Patches For: ");
						((BepInExLogInterpolatedStringHandler)val9).AppendFormatted<string>(item.Parent.Name);
					}
					logger8.LogInfo(val9);
					string text7 = Path.Combine(item.FullName, "Strings", Game.Instance.language);
					string text8 = Path.Combine(item.FullName, "Strings", "English");
					string text9 = (Directory.Exists(text7) ? text7 : (Directory.Exists(text8) ? text8 : ""));
					if (!(text9 != ""))
					{
						continue;
					}
					string[] files7 = Directory.GetFiles(text9, "*.csv", SearchOption.AllDirectories);
					foreach (string path4 in files7)
					{
						string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path4);
						string[] array = File.ReadAllLines(path4);
						foreach (string text10 in array)
						{
							Strings.ParseLine(text10.Trim(), ref text11, ref text12, ref text13, ref text14, ref num3, ref flag2, ref text15, true);
							Strings.LoadIntoDictionary(fileNameWithoutExtension, Strings.stringTable[fileNameWithoutExtension].Count + 1, text11, text13.Replace("\\r\\n", "\r\n"), text14, num3, flag2);
						}
					}
					ManualLogSource logger9 = DDSLoaderPlugin.Logger;
					val9 = new BepInExInfoLogInterpolatedStringHandler(27, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val9).AppendLiteral("Loaded String Content For: ");
						((BepInExLogInterpolatedStringHandler)val9).AppendFormatted<string>(item.Parent.Name);
					}
					logger9.LogInfo(val9);
				}
			}

			private static string CreatePatchedJson(string patchPath)
			{
				FileInfo fileInfo = new FileInfo(patchPath);
				DirectoryInfo directoryInfo = new DirectoryInfo(fileInfo.DirectoryName);
				JToken val = JToken.Parse(File.ReadAllText(Path.Combine(Application.streamingAssetsPath, "DDS", directoryInfo.Name, fileInfo.Name.Split("_")[0])));
				PatchDocument val2 = PatchDocument.Parse(File.ReadAllText(patchPath));
				val2.ApplyTo(val);
				return ((object)val).ToString();
			}

			private static void LoadNewspaperArticle(DDSTreeSave tree, string messagesPath)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Invalid comparison between Unknown and I4
				if ((int)tree.treeType != 3)
				{
				}
			}
		}

		private static Dictionary<string, NewspaperArticle> ddsToArticle;
	}
	[BepInPlugin("DDSLoader", "DDSLoader", "1.0.2")]
	public class DDSLoaderPlugin : BasePlugin
	{
		public static ManualLogSource Logger;

		public static List<DirectoryInfo> modsToLoadFrom = new List<DirectoryInfo>();

		public static ConfigEntry<bool> debugLogConversations;

		public static ConfigEntry<string> debugPauseTreeGUID;

		public static ConfigEntry<bool> debugClearNewspaperArticles;

		public override void Load()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			Logger = ((BasePlugin)this).Log;
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("DDSLoader");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
			}
			log.LogInfo(val);
			Harmony val2 = new Harmony("DDSLoader");
			val2.PatchAll();
			ManualLogSource log2 = ((BasePlugin)this).Log;
			val = new BepInExInfoLogInterpolatedStringHandler(19, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("DDSLoader");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is patched!");
			}
			log2.LogInfo(val);
			debugLogConversations = ((BasePlugin)this).Config.Bind<bool>("Debug", "Enable debugging of conversations", false, (ConfigDescription)null);
			debugPauseTreeGUID = ((BasePlugin)this).Config.Bind<string>("Debug", "Pause when this conversation tree GUID begins", "", (ConfigDescription)null);
			debugClearNewspaperArticles = ((BasePlugin)this).Config.Bind<bool>("Debug", "Clear existing newspaper articles", false, (ConfigDescription)null);
			modsToLoadFrom = (from dirPath in Directory.GetDirectories(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), ".."), "DDSContent", SearchOption.AllDirectories)
				select new DirectoryInfo(dirPath) into dir
				where !File.Exists(Path.Combine(dir.Parent.FullName, "disabled.txt"))
				select dir).ToList();
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "DDSLoader";

		public const string PLUGIN_NAME = "DDSLoader";

		public const string PLUGIN_VERSION = "1.0.2";
	}
}

Newtonsoft.Json.dll

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

[assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")]
[assembly: ComVisible(false)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyFileVersion("5.0.8.16617")]
[assembly: CLSCompliant(true)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: AssemblyProduct("Json.NET")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyTitle("Json.NET")]
[assembly: AssemblyCopyright("Copyright © James Newton-King 2008")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[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: AssemblyVersion("4.5.0.0")]
namespace Newtonsoft.Json.Bson
{
	internal enum BsonBinaryType : byte
	{
		Binary = 0,
		Function = 1,
		[Obsolete("This type has been deprecated in the BSON specification. Use Binary instead.")]
		BinaryOld = 2,
		[Obsolete("This type has been deprecated in the BSON specification. Use Uuid instead.")]
		UuidOld = 3,
		Uuid = 4,
		Md5 = 5,
		UserDefined = 128
	}
	internal class BsonBinaryWriter
	{
		private static readonly Encoding Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);

		private readonly BinaryWriter _writer;

		private byte[] _largeByteBuffer;

		public DateTimeKind DateTimeKindHandling { get; set; }

		public BsonBinaryWriter(BinaryWriter writer)
		{
			DateTimeKindHandling = DateTimeKind.Utc;
			_writer = writer;
		}

		public void Flush()
		{
			_writer.Flush();
		}

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

		public void WriteToken(BsonToken t)
		{
			CalculateSize(t);
			WriteTokenInternal(t);
		}

		private void WriteTokenInternal(BsonToken t)
		{
			switch (t.Type)
			{
			case BsonType.Object:
			{
				BsonObject bsonObject = (BsonObject)t;
				_writer.Write(bsonObject.CalculatedSize);
				foreach (BsonProperty item in bsonObject)
				{
					_writer.Write((sbyte)item.Value.Type);
					WriteString((string)item.Name.Value, item.Name.ByteCount, null);
					WriteTokenInternal(item.Value);
				}
				_writer.Write((byte)0);
				break;
			}
			case BsonType.Array:
			{
				BsonArray bsonArray = (BsonArray)t;
				_writer.Write(bsonArray.CalculatedSize);
				ulong num2 = 0uL;
				foreach (BsonToken item2 in bsonArray)
				{
					_writer.Write((sbyte)item2.Type);
					WriteString(num2.ToString(CultureInfo.InvariantCulture), MathUtils.IntLength(num2), null);
					WriteTokenInternal(item2);
					num2++;
				}
				_writer.Write((byte)0);
				break;
			}
			case BsonType.Integer:
			{
				BsonValue bsonValue3 = (BsonValue)t;
				_writer.Write(Convert.ToInt32(bsonValue3.Value, CultureInfo.InvariantCulture));
				break;
			}
			case BsonType.Long:
			{
				BsonValue bsonValue4 = (BsonValue)t;
				_writer.Write(Convert.ToInt64(bsonValue4.Value, CultureInfo.InvariantCulture));
				break;
			}
			case BsonType.Number:
			{
				BsonValue bsonValue5 = (BsonValue)t;
				_writer.Write(Convert.ToDouble(bsonValue5.Value, CultureInfo.InvariantCulture));
				break;
			}
			case BsonType.String:
			{
				BsonString bsonString = (BsonString)t;
				WriteString((string)bsonString.Value, bsonString.ByteCount, bsonString.CalculatedSize - 4);
				break;
			}
			case BsonType.Boolean:
			{
				BsonValue bsonValue6 = (BsonValue)t;
				_writer.Write((bool)bsonValue6.Value);
				break;
			}
			case BsonType.Date:
			{
				BsonValue bsonValue2 = (BsonValue)t;
				long num = 0L;
				if (bsonValue2.Value is DateTime)
				{
					DateTime dateTime = (DateTime)bsonValue2.Value;
					if (DateTimeKindHandling == DateTimeKind.Utc)
					{
						dateTime = dateTime.ToUniversalTime();
					}
					else if (DateTimeKindHandling == DateTimeKind.Local)
					{
						dateTime = dateTime.ToLocalTime();
					}
					num = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(dateTime, convertToUtc: false);
				}
				else
				{
					DateTimeOffset dateTimeOffset = (DateTimeOffset)bsonValue2.Value;
					num = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(dateTimeOffset.UtcDateTime, dateTimeOffset.Offset);
				}
				_writer.Write(num);
				break;
			}
			case BsonType.Binary:
			{
				BsonBinary bsonBinary = (BsonBinary)t;
				byte[] array = (byte[])bsonBinary.Value;
				_writer.Write(array.Length);
				_writer.Write((byte)bsonBinary.BinaryType);
				_writer.Write(array);
				break;
			}
			case BsonType.Oid:
			{
				BsonValue bsonValue = (BsonValue)t;
				byte[] buffer = (byte[])bsonValue.Value;
				_writer.Write(buffer);
				break;
			}
			case BsonType.Regex:
			{
				BsonRegex bsonRegex = (BsonRegex)t;
				WriteString((string)bsonRegex.Pattern.Value, bsonRegex.Pattern.ByteCount, null);
				WriteString((string)bsonRegex.Options.Value, bsonRegex.Options.ByteCount, null);
				break;
			}
			default:
				throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type));
			case BsonType.Undefined:
			case BsonType.Null:
				break;
			}
		}

		private void WriteString(string s, int byteCount, int? calculatedlengthPrefix)
		{
			if (calculatedlengthPrefix.HasValue)
			{
				_writer.Write(calculatedlengthPrefix.Value);
			}
			WriteUtf8Bytes(s, byteCount);
			_writer.Write((byte)0);
		}

		public void WriteUtf8Bytes(string s, int byteCount)
		{
			if (s != null)
			{
				if (_largeByteBuffer == null)
				{
					_largeByteBuffer = new byte[256];
				}
				if (byteCount <= 256)
				{
					Encoding.GetBytes(s, 0, s.Length, _largeByteBuffer, 0);
					_writer.Write(_largeByteBuffer, 0, byteCount);
				}
				else
				{
					byte[] bytes = Encoding.GetBytes(s);
					_writer.Write(bytes);
				}
			}
		}

		private int CalculateSize(int stringByteCount)
		{
			return stringByteCount + 1;
		}

		private int CalculateSizeWithLength(int stringByteCount, bool includeSize)
		{
			int num = ((!includeSize) ? 1 : 5);
			return num + stringByteCount;
		}

		private int CalculateSize(BsonToken t)
		{
			switch (t.Type)
			{
			case BsonType.Object:
			{
				BsonObject bsonObject = (BsonObject)t;
				int num4 = 4;
				foreach (BsonProperty item in bsonObject)
				{
					int num5 = 1;
					num5 += CalculateSize(item.Name);
					num5 += CalculateSize(item.Value);
					num4 += num5;
				}
				return bsonObject.CalculatedSize = num4 + 1;
			}
			case BsonType.Array:
			{
				BsonArray bsonArray = (BsonArray)t;
				int num2 = 4;
				ulong num3 = 0uL;
				foreach (BsonToken item2 in bsonArray)
				{
					num2++;
					num2 += CalculateSize(MathUtils.IntLength(num3));
					num2 += CalculateSize(item2);
					num3++;
				}
				num2++;
				bsonArray.CalculatedSize = num2;
				return bsonArray.CalculatedSize;
			}
			case BsonType.Integer:
				return 4;
			case BsonType.Long:
				return 8;
			case BsonType.Number:
				return 8;
			case BsonType.String:
			{
				BsonString bsonString = (BsonString)t;
				string text = (string)bsonString.Value;
				bsonString.ByteCount = ((text != null) ? Encoding.GetByteCount(text) : 0);
				bsonString.CalculatedSize = CalculateSizeWithLength(bsonString.ByteCount, bsonString.IncludeLength);
				return bsonString.CalculatedSize;
			}
			case BsonType.Boolean:
				return 1;
			case BsonType.Undefined:
			case BsonType.Null:
				return 0;
			case BsonType.Date:
				return 8;
			case BsonType.Binary:
			{
				BsonBinary bsonBinary = (BsonBinary)t;
				byte[] array = (byte[])bsonBinary.Value;
				bsonBinary.CalculatedSize = 5 + array.Length;
				return bsonBinary.CalculatedSize;
			}
			case BsonType.Oid:
				return 12;
			case BsonType.Regex:
			{
				BsonRegex bsonRegex = (BsonRegex)t;
				int num = 0;
				num += CalculateSize(bsonRegex.Pattern);
				num += CalculateSize(bsonRegex.Options);
				bsonRegex.CalculatedSize = num;
				return bsonRegex.CalculatedSize;
			}
			default:
				throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type));
			}
		}
	}
	public class BsonObjectId
	{
		public byte[] Value { get; private set; }

		public BsonObjectId(byte[] value)
		{
			ValidationUtils.ArgumentNotNull(value, "value");
			if (value.Length != 12)
			{
				throw new ArgumentException("An ObjectId must be 12 bytes", "value");
			}
			Value = value;
		}
	}
}
namespace Newtonsoft.Json
{
	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;

		internal ReadType _readType;

		private JsonPosition _currentPosition;

		private CultureInfo _culture;

		private DateTimeZoneHandling _dateTimeZoneHandling;

		private int? _maxDepth;

		private bool _hasExceededMaxDepth;

		internal DateParseHandling _dateParseHandling;

		internal FloatParseHandling _floatParseHandling;

		private readonly List<JsonPosition> _stack;

		protected State CurrentState => _currentState;

		public bool CloseInput { get; set; }

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

		public DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling;
			}
			set
			{
				_dateTimeZoneHandling = value;
			}
		}

		public DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling;
			}
			set
			{
				_dateParseHandling = value;
			}
		}

		public FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling;
			}
			set
			{
				_floatParseHandling = 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 count = _stack.Count;
				if (IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None)
				{
					return count;
				}
				return count + 1;
			}
		}

		public virtual string Path
		{
			get
			{
				if (_currentPosition.Type == JsonContainerType.None)
				{
					return string.Empty;
				}
				IEnumerable<JsonPosition> positions = ((_currentState == State.ArrayStart || _currentState == State.ConstructorStart || _currentState == State.ObjectStart) ? _stack : _stack.Concat(new JsonPosition[1] { _currentPosition }));
				return JsonPosition.BuildPath(positions);
			}
		}

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

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

		protected JsonReader()
		{
			_currentState = State.Start;
			_stack = new List<JsonPosition>(4);
			_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;
			}
			_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.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 abstract int? ReadAsInt32();

		public abstract string ReadAsString();

		public abstract byte[] ReadAsBytes();

		public abstract decimal? ReadAsDecimal();

		public abstract DateTime? ReadAsDateTime();

		public abstract DateTimeOffset? ReadAsDateTimeOffset();

		internal virtual bool ReadInternal()
		{
			throw new NotImplementedException();
		}

		internal DateTimeOffset? ReadAsDateTimeOffsetInternal()
		{
			_readType = ReadType.ReadAsDateTimeOffset;
			while (ReadInternal())
			{
				JsonToken tokenType = TokenType;
				switch (tokenType)
				{
				case JsonToken.Comment:
					break;
				case JsonToken.Date:
					if (Value is DateTime)
					{
						SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Value));
					}
					return (DateTimeOffset)Value;
				case JsonToken.Null:
					return null;
				case JsonToken.String:
				{
					string text = (string)Value;
					if (string.IsNullOrEmpty(text))
					{
						SetToken(JsonToken.Null);
						return null;
					}
					if (DateTimeOffset.TryParse(text, Culture, DateTimeStyles.RoundtripKind, out var result))
					{
						SetToken(JsonToken.Date, result);
						return result;
					}
					throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, Value));
				}
				case JsonToken.EndArray:
					return null;
				default:
					throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, tokenType));
				}
			}
			SetToken(JsonToken.None);
			return null;
		}

		internal byte[] ReadAsBytesInternal()
		{
			_readType = ReadType.ReadAsBytes;
			JsonToken tokenType;
			do
			{
				if (!ReadInternal())
				{
					SetToken(JsonToken.None);
					return null;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.Comment);
			if (IsWrappedInTypeObject())
			{
				byte[] array = ReadAsBytes();
				ReadInternal();
				SetToken(JsonToken.Bytes, array);
				return array;
			}
			switch (tokenType)
			{
			case JsonToken.String:
			{
				string text = (string)Value;
				byte[] array3 = ((text.Length == 0) ? new byte[0] : Convert.FromBase64String(text));
				SetToken(JsonToken.Bytes, array3);
				return array3;
			}
			case JsonToken.Null:
				return null;
			case JsonToken.Bytes:
				return (byte[])Value;
			case JsonToken.StartArray:
			{
				List<byte> list = new List<byte>();
				while (ReadInternal())
				{
					tokenType = TokenType;
					switch (tokenType)
					{
					case JsonToken.Integer:
						list.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
						break;
					case JsonToken.EndArray:
					{
						byte[] array2 = list.ToArray();
						SetToken(JsonToken.Bytes, array2);
						return array2;
					}
					default:
						throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, tokenType));
					case JsonToken.Comment:
						break;
					}
				}
				throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
			}
			case JsonToken.EndArray:
				return null;
			default:
				throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, tokenType));
			}
		}

		internal decimal? ReadAsDecimalInternal()
		{
			_readType = ReadType.ReadAsDecimal;
			while (ReadInternal())
			{
				JsonToken tokenType = TokenType;
				switch (tokenType)
				{
				case JsonToken.Comment:
					break;
				case JsonToken.Integer:
				case JsonToken.Float:
					if (!(Value is decimal))
					{
						SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture));
					}
					return (decimal)Value;
				case JsonToken.Null:
					return null;
				case JsonToken.String:
				{
					string text = (string)Value;
					if (string.IsNullOrEmpty(text))
					{
						SetToken(JsonToken.Null);
						return null;
					}
					if (decimal.TryParse(text, NumberStyles.Number, Culture, out var result))
					{
						SetToken(JsonToken.Float, result);
						return result;
					}
					throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, Value));
				}
				case JsonToken.EndArray:
					return null;
				default:
					throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, tokenType));
				}
			}
			SetToken(JsonToken.None);
			return null;
		}

		internal int? ReadAsInt32Internal()
		{
			_readType = ReadType.ReadAsInt32;
			while (ReadInternal())
			{
				switch (TokenType)
				{
				case JsonToken.Comment:
					break;
				case JsonToken.Integer:
				case JsonToken.Float:
					if (!(Value is int))
					{
						SetToken(JsonToken.Integer, Convert.ToInt32(Value, CultureInfo.InvariantCulture));
					}
					return (int)Value;
				case JsonToken.Null:
					return null;
				case JsonToken.String:
				{
					string text = (string)Value;
					if (string.IsNullOrEmpty(text))
					{
						SetToken(JsonToken.Null);
						return null;
					}
					if (int.TryParse(text, NumberStyles.Integer, Culture, out var result))
					{
						SetToken(JsonToken.Integer, result);
						return result;
					}
					throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, Value));
				}
				case JsonToken.EndArray:
					return null;
				default:
					throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
				}
			}
			SetToken(JsonToken.None);
			return null;
		}

		internal string ReadAsStringInternal()
		{
			_readType = ReadType.ReadAsString;
			while (ReadInternal())
			{
				JsonToken tokenType = TokenType;
				switch (tokenType)
				{
				case JsonToken.Comment:
					continue;
				case JsonToken.String:
					return (string)Value;
				case JsonToken.Null:
					return null;
				}
				if (IsPrimitiveToken(tokenType) && Value != null)
				{
					string text = ((!(Value is IFormattable)) ? Value.ToString() : ((IFormattable)Value).ToString(null, Culture));
					SetToken(JsonToken.String, text);
					return text;
				}
				if (tokenType == JsonToken.EndArray)
				{
					return null;
				}
				throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, tokenType));
			}
			SetToken(JsonToken.None);
			return null;
		}

		internal DateTime? ReadAsDateTimeInternal()
		{
			_readType = ReadType.ReadAsDateTime;
			do
			{
				if (!ReadInternal())
				{
					SetToken(JsonToken.None);
					return null;
				}
			}
			while (TokenType == JsonToken.Comment);
			if (TokenType == JsonToken.Date)
			{
				return (DateTime)Value;
			}
			if (TokenType == JsonToken.Null)
			{
				return null;
			}
			if (TokenType == JsonToken.String)
			{
				string text = (string)Value;
				if (string.IsNullOrEmpty(text))
				{
					SetToken(JsonToken.Null);
					return null;
				}
				if (DateTime.TryParse(text, Culture, DateTimeStyles.RoundtripKind, out var result))
				{
					result = DateTimeUtils.EnsureDateTime(result, DateTimeZoneHandling);
					SetToken(JsonToken.Date, result);
					return result;
				}
				throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, Value));
			}
			if (TokenType == JsonToken.EndArray)
			{
				return null;
			}
			throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
		}

		private bool IsWrappedInTypeObject()
		{
			_readType = ReadType.Read;
			if (TokenType == JsonToken.StartObject)
			{
				if (!ReadInternal())
				{
					throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
				}
				if (Value.ToString() == "$type")
				{
					ReadInternal();
					if (Value != null && Value.ToString().StartsWith("System.Byte[]"))
					{
						ReadInternal();
						if (Value.ToString() == "$value")
						{
							return true;
						}
					}
				}
				throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject));
			}
			return false;
		}

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

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

		protected void SetToken(JsonToken newToken, object value)
		{
			_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:
				_currentState = ((Peek() != 0) ? State.PostValue : State.Finished);
				UpdateScopeWithFinishedValue();
				break;
			case JsonToken.Comment:
				break;
			}
		}

		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));
			}
			_currentState = ((Peek() != 0) ? State.PostValue : State.Finished);
		}

		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:
				_currentState = State.Finished;
				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));
			}
		}

		internal static bool IsPrimitiveToken(JsonToken token)
		{
			switch (token)
			{
			case JsonToken.Integer:
			case JsonToken.Float:
			case JsonToken.String:
			case JsonToken.Boolean:
			case JsonToken.Null:
			case JsonToken.Undefined:
			case JsonToken.Date:
			case JsonToken.Bytes:
				return true;
			default:
				return false;
			}
		}

		internal static bool IsStartToken(JsonToken token)
		{
			switch (token)
			{
			case JsonToken.StartObject:
			case JsonToken.StartArray:
			case JsonToken.StartConstructor:
				return true;
			default:
				return false;
			}
		}

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

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

		public virtual void Close()
		{
			_currentState = State.Closed;
			_tokenType = JsonToken.None;
			_value = null;
		}
	}
}
namespace Newtonsoft.Json.Bson
{
	public class BsonReader : JsonReader
	{
		private enum BsonReaderState
		{
			Normal,
			ReferenceStart,
			ReferenceRef,
			ReferenceId,
			CodeWScopeStart,
			CodeWScopeCode,
			CodeWScopeScope,
			CodeWScopeScopeObject,
			CodeWScopeScopeEnd
		}

		private class ContainerContext
		{
			public readonly BsonType Type;

			public int Length;

			public int Position;

			public ContainerContext(BsonType type)
			{
				Type = type;
			}
		}

		private const int MaxCharBytesSize = 128;

		private static readonly byte[] SeqRange1 = new byte[2] { 0, 127 };

		private static readonly byte[] SeqRange2 = new byte[2] { 194, 223 };

		private static readonly byte[] SeqRange3 = new byte[2] { 224, 239 };

		private static readonly byte[] SeqRange4 = new byte[2] { 240, 244 };

		private readonly BinaryReader _reader;

		private readonly List<ContainerContext> _stack;

		private byte[] _byteBuffer;

		private char[] _charBuffer;

		private BsonType _currentElementType;

		private BsonReaderState _bsonReaderState;

		private ContainerContext _currentContext;

		private bool _readRootValueAsArray;

		private bool _jsonNet35BinaryCompatibility;

		private DateTimeKind _dateTimeKindHandling;

		[Obsolete("JsonNet35BinaryCompatibility will be removed in a future version of Json.NET.")]
		public bool JsonNet35BinaryCompatibility
		{
			get
			{
				return _jsonNet35BinaryCompatibility;
			}
			set
			{
				_jsonNet35BinaryCompatibility = value;
			}
		}

		public bool ReadRootValueAsArray
		{
			get
			{
				return _readRootValueAsArray;
			}
			set
			{
				_readRootValueAsArray = value;
			}
		}

		public DateTimeKind DateTimeKindHandling
		{
			get
			{
				return _dateTimeKindHandling;
			}
			set
			{
				_dateTimeKindHandling = value;
			}
		}

		public BsonReader(Stream stream)
			: this(stream, readRootValueAsArray: false, DateTimeKind.Local)
		{
		}

		public BsonReader(BinaryReader reader)
			: this(reader, readRootValueAsArray: false, DateTimeKind.Local)
		{
		}

		public BsonReader(Stream stream, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling)
		{
			ValidationUtils.ArgumentNotNull(stream, "stream");
			_reader = new BinaryReader(stream);
			_stack = new List<ContainerContext>();
			_readRootValueAsArray = readRootValueAsArray;
			_dateTimeKindHandling = dateTimeKindHandling;
		}

		public BsonReader(BinaryReader reader, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			_reader = reader;
			_stack = new List<ContainerContext>();
			_readRootValueAsArray = readRootValueAsArray;
			_dateTimeKindHandling = dateTimeKindHandling;
		}

		private string ReadElement()
		{
			_currentElementType = ReadType();
			return ReadString();
		}

		public override byte[] ReadAsBytes()
		{
			return ReadAsBytesInternal();
		}

		public override decimal? ReadAsDecimal()
		{
			return ReadAsDecimalInternal();
		}

		public override int? ReadAsInt32()
		{
			return ReadAsInt32Internal();
		}

		public override string ReadAsString()
		{
			return ReadAsStringInternal();
		}

		public override DateTime? ReadAsDateTime()
		{
			return ReadAsDateTimeInternal();
		}

		public override DateTimeOffset? ReadAsDateTimeOffset()
		{
			return ReadAsDateTimeOffsetInternal();
		}

		public override bool Read()
		{
			_readType = Newtonsoft.Json.ReadType.Read;
			return ReadInternal();
		}

		internal override bool ReadInternal()
		{
			try
			{
				bool flag;
				switch (_bsonReaderState)
				{
				case BsonReaderState.Normal:
					flag = ReadNormal();
					break;
				case BsonReaderState.ReferenceStart:
				case BsonReaderState.ReferenceRef:
				case BsonReaderState.ReferenceId:
					flag = ReadReference();
					break;
				case BsonReaderState.CodeWScopeStart:
				case BsonReaderState.CodeWScopeCode:
				case BsonReaderState.CodeWScopeScope:
				case BsonReaderState.CodeWScopeScopeObject:
				case BsonReaderState.CodeWScopeScopeEnd:
					flag = ReadCodeWScope();
					break;
				default:
					throw JsonReaderException.Create(this, "Unexpected state: {0}".FormatWith(CultureInfo.InvariantCulture, _bsonReaderState));
				}
				if (!flag)
				{
					SetToken(JsonToken.None);
					return false;
				}
				return true;
			}
			catch (EndOfStreamException)
			{
				SetToken(JsonToken.None);
				return false;
			}
		}

		public override void Close()
		{
			base.Close();
			if (base.CloseInput && _reader != null)
			{
				_reader.Close();
			}
		}

		private bool ReadCodeWScope()
		{
			switch (_bsonReaderState)
			{
			case BsonReaderState.CodeWScopeStart:
				SetToken(JsonToken.PropertyName, "$code");
				_bsonReaderState = BsonReaderState.CodeWScopeCode;
				return true;
			case BsonReaderState.CodeWScopeCode:
				ReadInt32();
				SetToken(JsonToken.String, ReadLengthString());
				_bsonReaderState = BsonReaderState.CodeWScopeScope;
				return true;
			case BsonReaderState.CodeWScopeScope:
			{
				if (base.CurrentState == State.PostValue)
				{
					SetToken(JsonToken.PropertyName, "$scope");
					return true;
				}
				SetToken(JsonToken.StartObject);
				_bsonReaderState = BsonReaderState.CodeWScopeScopeObject;
				ContainerContext containerContext = new ContainerContext(BsonType.Object);
				PushContext(containerContext);
				containerContext.Length = ReadInt32();
				return true;
			}
			case BsonReaderState.CodeWScopeScopeObject:
			{
				bool flag = ReadNormal();
				if (flag && TokenType == JsonToken.EndObject)
				{
					_bsonReaderState = BsonReaderState.CodeWScopeScopeEnd;
				}
				return flag;
			}
			case BsonReaderState.CodeWScopeScopeEnd:
				SetToken(JsonToken.EndObject);
				_bsonReaderState = BsonReaderState.Normal;
				return true;
			default:
				throw new ArgumentOutOfRangeException();
			}
		}

		private bool ReadReference()
		{
			switch (base.CurrentState)
			{
			case State.ObjectStart:
				SetToken(JsonToken.PropertyName, "$ref");
				_bsonReaderState = BsonReaderState.ReferenceRef;
				return true;
			case State.Property:
				if (_bsonReaderState == BsonReaderState.ReferenceRef)
				{
					SetToken(JsonToken.String, ReadLengthString());
					return true;
				}
				if (_bsonReaderState == BsonReaderState.ReferenceId)
				{
					SetToken(JsonToken.Bytes, ReadBytes(12));
					return true;
				}
				throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + _bsonReaderState);
			case State.PostValue:
				if (_bsonReaderState == BsonReaderState.ReferenceRef)
				{
					SetToken(JsonToken.PropertyName, "$id");
					_bsonReaderState = BsonReaderState.ReferenceId;
					return true;
				}
				if (_bsonReaderState == BsonReaderState.ReferenceId)
				{
					SetToken(JsonToken.EndObject);
					_bsonReaderState = BsonReaderState.Normal;
					return true;
				}
				throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + _bsonReaderState);
			default:
				throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + base.CurrentState);
			}
		}

		private bool ReadNormal()
		{
			switch (base.CurrentState)
			{
			case State.Start:
			{
				JsonToken token2 = ((!_readRootValueAsArray) ? JsonToken.StartObject : JsonToken.StartArray);
				BsonType type = ((!_readRootValueAsArray) ? BsonType.Object : BsonType.Array);
				SetToken(token2);
				ContainerContext containerContext = new ContainerContext(type);
				PushContext(containerContext);
				containerContext.Length = ReadInt32();
				return true;
			}
			case State.Complete:
			case State.Closed:
				return false;
			case State.Property:
				ReadType(_currentElementType);
				return true;
			case State.ObjectStart:
			case State.ArrayStart:
			case State.PostValue:
			{
				ContainerContext currentContext = _currentContext;
				if (currentContext == null)
				{
					return false;
				}
				int num = currentContext.Length - 1;
				if (currentContext.Position < num)
				{
					if (currentContext.Type == BsonType.Array)
					{
						ReadElement();
						ReadType(_currentElementType);
						return true;
					}
					SetToken(JsonToken.PropertyName, ReadElement());
					return true;
				}
				if (currentContext.Position == num)
				{
					if (ReadByte() != 0)
					{
						throw JsonReaderException.Create(this, "Unexpected end of object byte value.");
					}
					PopContext();
					if (_currentContext != null)
					{
						MovePosition(currentContext.Length);
					}
					JsonToken token = ((currentContext.Type == BsonType.Object) ? JsonToken.EndObject : JsonToken.EndArray);
					SetToken(token);
					return true;
				}
				throw JsonReaderException.Create(this, "Read past end of current container context.");
			}
			default:
				throw new ArgumentOutOfRangeException();
			case State.ConstructorStart:
			case State.Constructor:
			case State.Error:
			case State.Finished:
				return false;
			}
		}

		private void PopContext()
		{
			_stack.RemoveAt(_stack.Count - 1);
			if (_stack.Count == 0)
			{
				_currentContext = null;
			}
			else
			{
				_currentContext = _stack[_stack.Count - 1];
			}
		}

		private void PushContext(ContainerContext newContext)
		{
			_stack.Add(newContext);
			_currentContext = newContext;
		}

		private byte ReadByte()
		{
			MovePosition(1);
			return _reader.ReadByte();
		}

		private void ReadType(BsonType type)
		{
			switch (type)
			{
			case BsonType.Number:
			{
				double num = ReadDouble();
				if (_floatParseHandling == FloatParseHandling.Decimal)
				{
					SetToken(JsonToken.Float, Convert.ToDecimal(num, CultureInfo.InvariantCulture));
				}
				else
				{
					SetToken(JsonToken.Float, num);
				}
				break;
			}
			case BsonType.String:
			case BsonType.Symbol:
				SetToken(JsonToken.String, ReadLengthString());
				break;
			case BsonType.Object:
			{
				SetToken(JsonToken.StartObject);
				ContainerContext containerContext2 = new ContainerContext(BsonType.Object);
				PushContext(containerContext2);
				containerContext2.Length = ReadInt32();
				break;
			}
			case BsonType.Array:
			{
				SetToken(JsonToken.StartArray);
				ContainerContext containerContext = new ContainerContext(BsonType.Array);
				PushContext(containerContext);
				containerContext.Length = ReadInt32();
				break;
			}
			case BsonType.Binary:
				SetToken(JsonToken.Bytes, ReadBinary());
				break;
			case BsonType.Undefined:
				SetToken(JsonToken.Undefined);
				break;
			case BsonType.Oid:
			{
				byte[] value2 = ReadBytes(12);
				SetToken(JsonToken.Bytes, value2);
				break;
			}
			case BsonType.Boolean:
			{
				bool flag = Convert.ToBoolean(ReadByte());
				SetToken(JsonToken.Boolean, flag);
				break;
			}
			case BsonType.Date:
			{
				long javaScriptTicks = ReadInt64();
				DateTime dateTime = DateTimeUtils.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
				SetToken(JsonToken.Date, DateTimeKindHandling switch
				{
					DateTimeKind.Unspecified => DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified), 
					DateTimeKind.Local => dateTime.ToLocalTime(), 
					_ => dateTime, 
				});
				break;
			}
			case BsonType.Null:
				SetToken(JsonToken.Null);
				break;
			case BsonType.Regex:
			{
				string text = ReadString();
				string text2 = ReadString();
				string value = "/" + text + "/" + text2;
				SetToken(JsonToken.String, value);
				break;
			}
			case BsonType.Reference:
				SetToken(JsonToken.StartObject);
				_bsonReaderState = BsonReaderState.ReferenceStart;
				break;
			case BsonType.Code:
				SetToken(JsonToken.String, ReadLengthString());
				break;
			case BsonType.CodeWScope:
				SetToken(JsonToken.StartObject);
				_bsonReaderState = BsonReaderState.CodeWScopeStart;
				break;
			case BsonType.Integer:
				SetToken(JsonToken.Integer, (long)ReadInt32());
				break;
			case BsonType.TimeStamp:
			case BsonType.Long:
				SetToken(JsonToken.Integer, ReadInt64());
				break;
			default:
				throw new ArgumentOutOfRangeException("type", "Unexpected BsonType value: " + type);
			}
		}

		private byte[] ReadBinary()
		{
			int count = ReadInt32();
			BsonBinaryType bsonBinaryType = (BsonBinaryType)ReadByte();
			if (bsonBinaryType == BsonBinaryType.BinaryOld && !_jsonNet35BinaryCompatibility)
			{
				count = ReadInt32();
			}
			return ReadBytes(count);
		}

		private string ReadString()
		{
			EnsureBuffers();
			StringBuilder stringBuilder = null;
			int num = 0;
			int num2 = 0;
			while (true)
			{
				int num3 = num2;
				byte b;
				while (num3 < 128 && (b = _reader.ReadByte()) > 0)
				{
					_byteBuffer[num3++] = b;
				}
				int num4 = num3 - num2;
				num += num4;
				if (num3 < 128 && stringBuilder == null)
				{
					int chars = Encoding.UTF8.GetChars(_byteBuffer, 0, num4, _charBuffer, 0);
					MovePosition(num + 1);
					return new string(_charBuffer, 0, chars);
				}
				int lastFullCharStop = GetLastFullCharStop(num3 - 1);
				int chars2 = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0);
				if (stringBuilder == null)
				{
					stringBuilder = new StringBuilder(256);
				}
				stringBuilder.Append(_charBuffer, 0, chars2);
				if (lastFullCharStop < num4 - 1)
				{
					num2 = num4 - lastFullCharStop - 1;
					Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, num2);
					continue;
				}
				if (num3 < 128)
				{
					break;
				}
				num2 = 0;
			}
			MovePosition(num + 1);
			return stringBuilder.ToString();
		}

		private string ReadLengthString()
		{
			int num = ReadInt32();
			MovePosition(num);
			string @string = GetString(num - 1);
			_reader.ReadByte();
			return @string;
		}

		private string GetString(int length)
		{
			if (length == 0)
			{
				return string.Empty;
			}
			EnsureBuffers();
			StringBuilder stringBuilder = null;
			int num = 0;
			int num2 = 0;
			do
			{
				int count = ((length - num > 128 - num2) ? (128 - num2) : (length - num));
				int num3 = _reader.Read(_byteBuffer, num2, count);
				if (num3 == 0)
				{
					throw new EndOfStreamException("Unable to read beyond the end of the stream.");
				}
				num += num3;
				num3 += num2;
				if (num3 == length)
				{
					int chars = Encoding.UTF8.GetChars(_byteBuffer, 0, num3, _charBuffer, 0);
					return new string(_charBuffer, 0, chars);
				}
				int lastFullCharStop = GetLastFullCharStop(num3 - 1);
				if (stringBuilder == null)
				{
					stringBuilder = new StringBuilder(length);
				}
				int chars2 = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0);
				stringBuilder.Append(_charBuffer, 0, chars2);
				if (lastFullCharStop < num3 - 1)
				{
					num2 = num3 - lastFullCharStop - 1;
					Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, num2);
				}
				else
				{
					num2 = 0;
				}
			}
			while (num < length);
			return stringBuilder.ToString();
		}

		private int GetLastFullCharStop(int start)
		{
			int num = start;
			int num2 = 0;
			for (; num >= 0; num--)
			{
				num2 = BytesInSequence(_byteBuffer[num]);
				switch (num2)
				{
				case 0:
					continue;
				default:
					num--;
					break;
				case 1:
					break;
				}
				break;
			}
			if (num2 == start - num)
			{
				return start;
			}
			return num;
		}

		private int BytesInSequence(byte b)
		{
			if (b <= SeqRange1[1])
			{
				return 1;
			}
			if (b >= SeqRange2[0] && b <= SeqRange2[1])
			{
				return 2;
			}
			if (b >= SeqRange3[0] && b <= SeqRange3[1])
			{
				return 3;
			}
			if (b >= SeqRange4[0] && b <= SeqRange4[1])
			{
				return 4;
			}
			return 0;
		}

		private void EnsureBuffers()
		{
			if (_byteBuffer == null)
			{
				_byteBuffer = new byte[128];
			}
			if (_charBuffer == null)
			{
				int maxCharCount = Encoding.UTF8.GetMaxCharCount(128);
				_charBuffer = new char[maxCharCount];
			}
		}

		private double ReadDouble()
		{
			MovePosition(8);
			return _reader.ReadDouble();
		}

		private int ReadInt32()
		{
			MovePosition(4);
			return _reader.ReadInt32();
		}

		private long ReadInt64()
		{
			MovePosition(8);
			return _reader.ReadInt64();
		}

		private BsonType ReadType()
		{
			MovePosition(1);
			return (BsonType)_reader.ReadSByte();
		}

		private void MovePosition(int count)
		{
			_currentContext.Position += count;
		}

		private byte[] ReadBytes(int count)
		{
			MovePosition(count);
			return _reader.ReadBytes(count);
		}
	}
	internal abstract class BsonToken
	{
		public abstract BsonType Type { get; }

		public BsonToken Parent { get; set; }

		public int CalculatedSize { get; set; }
	}
	internal class BsonObject : BsonToken, IEnumerable<BsonProperty>, IEnumerable
	{
		private readonly List<BsonProperty> _children = new List<BsonProperty>();

		public override BsonType Type => BsonType.Object;

		public void Add(string name, BsonToken token)
		{
			_children.Add(new BsonProperty
			{
				Name = new BsonString(name, includeLength: false),
				Value = token
			});
			token.Parent = this;
		}

		public IEnumerator<BsonProperty> GetEnumerator()
		{
			return _children.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	internal class BsonArray : BsonToken, IEnumerable<BsonToken>, IEnumerable
	{
		private readonly List<BsonToken> _children = new List<BsonToken>();

		public override BsonType Type => BsonType.Array;

		public void Add(BsonToken token)
		{
			_children.Add(token);
			token.Parent = this;
		}

		public IEnumerator<BsonToken> GetEnumerator()
		{
			return _children.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	internal class BsonValue : BsonToken
	{
		private readonly object _value;

		private readonly BsonType _type;

		public object Value => _value;

		public override BsonType Type => _type;

		public BsonValue(object value, BsonType type)
		{
			_value = value;
			_type = type;
		}
	}
	internal class BsonString : BsonValue
	{
		public int ByteCount { get; set; }

		public bool IncludeLength { get; set; }

		public BsonString(object value, bool includeLength)
			: base(value, BsonType.String)
		{
			IncludeLength = includeLength;
		}
	}
	internal class BsonBinary : BsonValue
	{
		public BsonBinaryType BinaryType { get; set; }

		public BsonBinary(byte[] value, BsonBinaryType binaryType)
			: base(value, BsonType.Binary)
		{
			BinaryType = binaryType;
		}
	}
	internal class BsonRegex : BsonToken
	{
		public BsonString Pattern { get; set; }

		public BsonString Options { get; set; }

		public override BsonType Type => BsonType.Regex;

		public BsonRegex(string pattern, string options)
		{
			Pattern = new BsonString(pattern, includeLength: false);
			Options = new BsonString(options, includeLength: false);
		}
	}
	internal class BsonProperty
	{
		public BsonString Name { get; set; }

		public BsonToken Value { get; set; }
	}
	internal enum BsonType : sbyte
	{
		Number = 1,
		String = 2,
		Object = 3,
		Array = 4,
		Binary = 5,
		Undefined = 6,
		Oid = 7,
		Boolean = 8,
		Date = 9,
		Null = 10,
		Regex = 11,
		Reference = 12,
		Code = 13,
		Symbol = 14,
		CodeWScope = 15,
		Integer = 16,
		TimeStamp = 17,
		Long = 18,
		MinKey = -1,
		MaxKey = sbyte.MaxValue
	}
}
namespace Newtonsoft.Json
{
	public abstract class JsonWriter : IDisposable
	{
		internal enum State
		{
			Start,
			Property,
			ObjectStart,
			Object,
			ArrayStart,
			Array,
			ConstructorStart,
			Constructor,
			Closed,
			Error
		}

		private static readonly State[][] StateArray;

		internal static readonly State[][] StateArrayTempate;

		private readonly List<JsonPosition> _stack;

		private JsonPosition _currentPosition;

		private State _currentState;

		private Formatting _formatting;

		private DateFormatHandling _dateFormatHandling;

		private DateTimeZoneHandling _dateTimeZoneHandling;

		private StringEscapeHandling _stringEscapeHandling;

		private FloatFormatHandling _floatFormatHandling;

		private string _dateFormatString;

		private CultureInfo _culture;

		public bool CloseOutput { get; set; }

		protected internal int Top
		{
			get
			{
				int num = _stack.Count;
				if (Peek() != 0)
				{
					num++;
				}
				return num;
			}
		}

		public WriteState WriteState
		{
			get
			{
				switch (_currentState)
				{
				case State.Error:
					return WriteState.Error;
				case State.Closed:
					return WriteState.Closed;
				case State.ObjectStart:
				case State.Object:
					return WriteState.Object;
				case State.ArrayStart:
				case State.Array:
					return WriteState.Array;
				case State.ConstructorStart:
				case State.Constructor:
					return WriteState.Constructor;
				case State.Property:
					return WriteState.Property;
				case State.Start:
					return WriteState.Start;
				default:
					throw JsonWriterException.Create(this, "Invalid state: " + _currentState, null);
				}
			}
		}

		internal string ContainerPath
		{
			get
			{
				if (_currentPosition.Type == JsonContainerType.None)
				{
					return string.Empty;
				}
				return JsonPosition.BuildPath(_stack);
			}
		}

		public string Path
		{
			get
			{
				if (_currentPosition.Type == JsonContainerType.None)
				{
					return string.Empty;
				}
				IEnumerable<JsonPosition> positions = ((_currentState == State.ArrayStart || _currentState == State.ConstructorStart || _currentState == State.ObjectStart) ? _stack : _stack.Concat(new JsonPosition[1] { _currentPosition }));
				return JsonPosition.BuildPath(positions);
			}
		}

		public Formatting Formatting
		{
			get
			{
				return _formatting;
			}
			set
			{
				_formatting = value;
			}
		}

		public DateFormatHandling DateFormatHandling
		{
			get
			{
				return _dateFormatHandling;
			}
			set
			{
				_dateFormatHandling = value;
			}
		}

		public DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling;
			}
			set
			{
				_dateTimeZoneHandling = value;
			}
		}

		public StringEscapeHandling StringEscapeHandling
		{
			get
			{
				return _stringEscapeHandling;
			}
			set
			{
				_stringEscapeHandling = value;
				OnStringEscapeHandlingChanged();
			}
		}

		public FloatFormatHandling FloatFormatHandling
		{
			get
			{
				return _floatFormatHandling;
			}
			set
			{
				_floatFormatHandling = value;
			}
		}

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

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

		internal static State[][] BuildStateArray()
		{
			List<State[]> list = StateArrayTempate.ToList();
			State[] item = StateArrayTempate[0];
			State[] item2 = StateArrayTempate[7];
			foreach (JsonToken value in EnumUtils.GetValues(typeof(JsonToken)))
			{
				if (list.Count <= (int)value)
				{
					switch (value)
					{
					case JsonToken.Integer:
					case JsonToken.Float:
					case JsonToken.String:
					case JsonToken.Boolean:
					case JsonToken.Null:
					case JsonToken.Undefined:
					case JsonToken.Date:
					case JsonToken.Bytes:
						list.Add(item2);
						break;
					default:
						list.Add(item);
						break;
					}
				}
			}
			return list.ToArray();
		}

		static JsonWriter()
		{
			StateArrayTempate = new State[8][]
			{
				new State[10]
				{
					State.Error,
					State.Error,
					State.Error,
					State.Error,
					State.Error,
					State.Error,
					State.Error,
					State.Error,
					State.Error,
					State.Error
				},
				new State[10]
				{
					State.ObjectStart,
					State.ObjectStart,
					State.Error,
					State.Error,
					State.ObjectStart,
					State.ObjectStart,
					State.ObjectStart,
					State.ObjectStart,
					State.Error,
					State.Error
				},
				new State[10]
				{
					State.ArrayStart,
					State.ArrayStart,
					State.Error,
					State.Error,
					State.ArrayStart,
					State.ArrayStart,
					State.ArrayStart,
					State.ArrayStart,
					State.Error,
					State.Error
				},
				new State[10]
				{
					State.ConstructorStart,
					State.ConstructorStart,
					State.Error,
					State.Error,
					State.ConstructorStart,
					State.ConstructorStart,
					State.ConstructorStart,
					State.ConstructorStart,
					State.Error,
					State.Error
				},
				new State[10]
				{
					State.Property,
					State.Error,
					State.Property,
					State.Property,
					State.Error,
					State.Error,
					State.Error,
					State.Error,
					State.Error,
					State.Error
				},
				new State[10]
				{
					State.Start,
					State.Property,
					State.ObjectStart,
					State.Object,
					State.ArrayStart,
					State.Array,
					State.Constructor,
					State.Constructor,
					State.Error,
					State.Error
				},
				new State[10]
				{
					State.Start,
					State.Property,
					State.ObjectStart,
					State.Object,
					State.ArrayStart,
					State.Array,
					State.Constructor,
					State.Constructor,
					State.Error,
					State.Error
				},
				new State[10]
				{
					State.Start,
					State.Object,
					State.Error,
					State.Error,
					State.Array,
					State.Array,
					State.Constructor,
					State.Constructor,
					State.Error,
					State.Error
				}
			};
			StateArray = BuildStateArray();
		}

		internal virtual void OnStringEscapeHandlingChanged()
		{
		}

		protected JsonWriter()
		{
			_stack = new List<JsonPosition>(4);
			_currentState = State.Start;
			_formatting = Formatting.None;
			_dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
			CloseOutput = true;
		}

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

		private void Push(JsonContainerType value)
		{
			if (_currentPosition.Type != 0)
			{
				_stack.Add(_currentPosition);
			}
			_currentPosition = new JsonPosition(value);
		}

		private JsonContainerType Pop()
		{
			JsonPosition currentPosition = _currentPosition;
			if (_stack.Count > 0)
			{
				_currentPosition = _stack[_stack.Count - 1];
				_stack.RemoveAt(_stack.Count - 1);
			}
			else
			{
				_currentPosition = default(JsonPosition);
			}
			return currentPosition.Type;
		}

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

		public abstract void Flush();

		public virtual void Close()
		{
			AutoCompleteAll();
		}

		public virtual void WriteStartObject()
		{
			InternalWriteStart(JsonToken.StartObject, JsonContainerType.Object);
		}

		public virtual void WriteEndObject()
		{
			InternalWriteEnd(JsonContainerType.Object);
		}

		public virtual void WriteStartArray()
		{
			InternalWriteStart(JsonToken.StartArray, JsonContainerType.Array);
		}

		public virtual void WriteEndArray()
		{
			InternalWriteEnd(JsonContainerType.Array);
		}

		public virtual void WriteStartConstructor(string name)
		{
			InternalWriteStart(JsonToken.StartConstructor, JsonContainerType.Constructor);
		}

		public virtual void WriteEndConstructor()
		{
			InternalWriteEnd(JsonContainerType.Constructor);
		}

		public virtual void WritePropertyName(string name)
		{
			InternalWritePropertyName(name);
		}

		public virtual void WritePropertyName(string name, bool escape)
		{
			WritePropertyName(name);
		}

		public virtual void WriteEnd()
		{
			WriteEnd(Peek());
		}

		public void WriteToken(JsonReader reader)
		{
			WriteToken(reader, writeChildren: true, writeDateConstructorAsDate: true);
		}

		public void WriteToken(JsonReader reader, bool writeChildren)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			WriteToken(reader, writeChildren, writeDateConstructorAsDate: true);
		}

		internal void WriteToken(JsonReader reader, bool writeChildren, bool writeDateConstructorAsDate)
		{
			int initialDepth = ((reader.TokenType == JsonToken.None) ? (-1) : (IsStartToken(reader.TokenType) ? reader.Depth : (reader.Depth + 1)));
			WriteToken(reader, initialDepth, writeChildren, writeDateConstructorAsDate);
		}

		internal void WriteToken(JsonReader reader, int initialDepth, bool writeChildren, bool writeDateConstructorAsDate)
		{
			do
			{
				switch (reader.TokenType)
				{
				case JsonToken.StartObject:
					WriteStartObject();
					break;
				case JsonToken.StartArray:
					WriteStartArray();
					break;
				case JsonToken.StartConstructor:
				{
					string a = reader.Value.ToString();
					if (writeDateConstructorAsDate && string.Equals(a, "Date", StringComparison.Ordinal))
					{
						WriteConstructorDate(reader);
					}
					else
					{
						WriteStartConstructor(reader.Value.ToString());
					}
					break;
				}
				case JsonToken.PropertyName:
					WritePropertyName(reader.Value.ToString());
					break;
				case JsonToken.Comment:
					WriteComment((reader.Value != null) ? reader.Value.ToString() : null);
					break;
				case JsonToken.Integer:
					if (reader.Value is BigInteger)
					{
						WriteValue((BigInteger)reader.Value);
					}
					else
					{
						WriteValue(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture));
					}
					break;
				case JsonToken.Float:
				{
					object value = reader.Value;
					if (value is decimal)
					{
						WriteValue((decimal)value);
					}
					else if (value is double)
					{
						WriteValue((double)value);
					}
					else if (value is float)
					{
						WriteValue((float)value);
					}
					else
					{
						WriteValue(Convert.ToDouble(value, CultureInfo.InvariantCulture));
					}
					break;
				}
				case JsonToken.String:
					WriteValue(reader.Value.ToString());
					break;
				case JsonToken.Boolean:
					WriteValue(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture));
					break;
				case JsonToken.Null:
					WriteNull();
					break;
				case JsonToken.Undefined:
					WriteUndefined();
					break;
				case JsonToken.EndObject:
					WriteEndObject();
					break;
				case JsonToken.EndArray:
					WriteEndArray();
					break;
				case JsonToken.EndConstructor:
					WriteEndConstructor();
					break;
				case JsonToken.Date:
					if (reader.Value is DateTimeOffset)
					{
						WriteValue((DateTimeOffset)reader.Value);
					}
					else
					{
						WriteValue(Convert.ToDateTime(reader.Value, CultureInfo.InvariantCulture));
					}
					break;
				case JsonToken.Raw:
					WriteRawValue((reader.Value != null) ? reader.Value.ToString() : null);
					break;
				case JsonToken.Bytes:
					WriteValue((byte[])reader.Value);
					break;
				default:
					throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", reader.TokenType, "Unexpected token type.");
				case JsonToken.None:
					break;
				}
			}
			while (initialDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0) && writeChildren && reader.Read());
		}

		private void WriteConstructorDate(JsonReader reader)
		{
			if (!reader.Read())
			{
				throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null);
			}
			if (reader.TokenType != JsonToken.Integer)
			{
				throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected Integer, got " + reader.TokenType, null);
			}
			long javaScriptTicks = (long)reader.Value;
			DateTime value = DateTimeUtils.ConvertJavaScriptTicksToDateTime(javaScriptTicks);
			if (!reader.Read())
			{
				throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null);
			}
			if (reader.TokenType != JsonToken.EndConstructor)
			{
				throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected EndConstructor, got " + reader.TokenType, null);
			}
			WriteValue(value);
		}

		internal static bool IsEndToken(JsonToken token)
		{
			switch (token)
			{
			case JsonToken.EndObject:
			case JsonToken.EndArray:
			case JsonToken.EndConstructor:
				return true;
			default:
				return false;
			}
		}

		internal static bool IsStartToken(JsonToken token)
		{
			switch (token)
			{
			case JsonToken.StartObject:
			case JsonToken.StartArray:
			case JsonToken.StartConstructor:
				return true;
			default:
				return false;
			}
		}

		private void WriteEnd(JsonContainerType type)
		{
			switch (type)
			{
			case JsonContainerType.Object:
				WriteEndObject();
				break;
			case JsonContainerType.Array:
				WriteEndArray();
				break;
			case JsonContainerType.Constructor:
				WriteEndConstructor();
				break;
			default:
				throw JsonWriterException.Create(this, "Unexpected type when writing end: " + type, null);
			}
		}

		private void AutoCompleteAll()
		{
			while (Top > 0)
			{
				WriteEnd();
			}
		}

		private JsonToken GetCloseTokenForType(JsonContainerType type)
		{
			return type switch
			{
				JsonContainerType.Object => JsonToken.EndObject, 
				JsonContainerType.Array => JsonToken.EndArray, 
				JsonContainerType.Constructor => JsonToken.EndConstructor, 
				_ => throw JsonWriterException.Create(this, "No close token for type: " + type, null), 
			};
		}

		private void AutoCompleteClose(JsonContainerType type)
		{
			int num = 0;
			if (_currentPosition.Type == type)
			{
				num = 1;
			}
			else
			{
				int num2 = Top - 2;
				for (int num3 = num2; num3 >= 0; num3--)
				{
					int index = num2 - num3;
					if (_stack[index].Type == type)
					{
						num = num3 + 2;
						break;
					}
				}
			}
			if (num == 0)
			{
				throw JsonWriterException.Create(this, "No token to close.", null);
			}
			for (int i = 0; i < num; i++)
			{
				JsonToken closeTokenForType = GetCloseTokenForType(Pop());
				if (_currentState == State.Property)
				{
					WriteNull();
				}
				if (_formatting == Formatting.Indented && _currentState != State.ObjectStart && _currentState != State.ArrayStart)
				{
					WriteIndent();
				}
				WriteEnd(closeTokenForType);
				JsonContainerType jsonContainerType = Peek();
				switch (jsonContainerType)
				{
				case JsonContainerType.Object:
					_currentState = State.Object;
					break;
				case JsonContainerType.Array:
					_currentState = State.Array;
					break;
				case JsonContainerType.Constructor:
					_currentState = State.Array;
					break;
				case JsonContainerType.None:
					_currentState = State.Start;
					break;
				default:
					throw JsonWriterException.Create(this, "Unknown JsonType: " + jsonContainerType, null);
				}
			}
		}

		protected virtual void WriteEnd(JsonToken token)
		{
		}

		protected virtual void WriteIndent()
		{
		}

		protected virtual void WriteValueDelimiter()
		{
		}

		protected virtual void WriteIndentSpace()
		{
		}

		internal void AutoComplete(JsonToken tokenBeingWritten)
		{
			State state = StateArray[(int)tokenBeingWritten][(int)_currentState];
			if (state == State.Error)
			{
				throw JsonWriterException.Create(this, "Token {0} in state {1} would result in an invalid JSON object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString()), null);
			}
			if ((_currentState == State.Object || _currentState == State.Array || _currentState == State.Constructor) && tokenBeingWritten != JsonToken.Comment)
			{
				WriteValueDelimiter();
			}
			if (_formatting == Formatting.Indented)
			{
				if (_currentState == State.Property)
				{
					WriteIndentSpace();
				}
				if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.Constructor || _currentState == State.ConstructorStart || (tokenBeingWritten == JsonToken.PropertyName && _currentState != 0))
				{
					WriteIndent();
				}
			}
			_currentState = state;
		}

		public virtual void WriteNull()
		{
			InternalWriteValue(JsonToken.Null);
		}

		public virtual void WriteUndefined()
		{
			InternalWriteValue(JsonToken.Undefined);
		}

		public virtual void WriteRaw(string json)
		{
			InternalWriteRaw();
		}

		public virtual void WriteRawValue(string json)
		{
			UpdateScopeWithFinishedValue();
			AutoComplete(JsonToken.Undefined);
			WriteRaw(json);
		}

		public virtual void WriteValue(string value)
		{
			InternalWriteValue(JsonToken.String);
		}

		public virtual void WriteValue(int value)
		{
			InternalWriteValue(JsonToken.Integer);
		}

		[CLSCompliant(false)]
		public virtual void WriteValue(uint value)
		{
			InternalWriteValue(JsonToken.Integer);
		}

		public virtual void WriteValue(long value)
		{
			InternalWriteValue(JsonToken.Integer);
		}

		[CLSCompliant(false)]
		public virtual void WriteValue(ulong value)
		{
			InternalWriteValue(JsonToken.Integer);
		}

		public virtual void WriteValue(float value)
		{
			InternalWriteValue(JsonToken.Float);
		}

		public virtual void WriteValue(double value)
		{
			InternalWriteValue(JsonToken.Float);
		}

		public virtual void WriteValue(bool value)
		{
			InternalWriteValue(JsonToken.Boolean);
		}

		public virtual void WriteValue(short value)
		{
			InternalWriteValue(JsonToken.Integer);
		}

		[CLSCompliant(false)]
		public virtual void WriteValue(ushort value)
		{
			InternalWriteValue(JsonToken.Integer);
		}

		public virtual void WriteValue(char value)
		{
			InternalWriteValue(JsonToken.String);
		}

		public virtual void WriteValue(byte value)
		{
			InternalWriteValue(JsonToken.Integer);
		}

		[CLSCompliant(false)]
		public virtual void WriteValue(sbyte value)
		{
			InternalWriteValue(JsonToken.Integer);
		}

		public virtual void WriteValue(decimal value)
		{
			InternalWriteValue(JsonToken.Float);
		}

		public virtual void WriteValue(DateTime value)
		{
			InternalWriteValue(JsonToken.Date);
		}

		public virtual void WriteValue(DateTimeOffset value)
		{
			InternalWriteValue(JsonToken.Date);
		}

		public virtual void WriteValue(Guid value)
		{
			InternalWriteValue(JsonToken.String);
		}

		public virtual void WriteValue(TimeSpan value)
		{
			InternalWriteValue(JsonToken.String);
		}

		public virtual void WriteValue(int? value)
		{
			if (!value.HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		[CLSCompliant(false)]
		public virtual void WriteValue(uint? value)
		{
			if (!value.HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(long? value)
		{
			if (!value.HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		[CLSCompliant(false)]
		public virtual void WriteValue(ulong? value)
		{
			if (!value.HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(float? value)
		{
			if (!value.HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(double? value)
		{
			if (!value.HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(bool? value)
		{
			if (!value.HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(short? value)
		{
			if (!((int?)value).HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		[CLSCompliant(false)]
		public virtual void WriteValue(ushort? value)
		{
			if (!((int?)value).HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(char? value)
		{
			if (!((int?)value).HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(byte? value)
		{
			if (!((int?)value).HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		[CLSCompliant(false)]
		public virtual void WriteValue(sbyte? value)
		{
			if (!((int?)value).HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(decimal? value)
		{
			if (!value.HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(DateTime? value)
		{
			if (!value.HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(DateTimeOffset? value)
		{
			if (!value.HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(Guid? value)
		{
			if (!value.HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(TimeSpan? value)
		{
			if (!value.HasValue)
			{
				WriteNull();
			}
			else
			{
				WriteValue(value.Value);
			}
		}

		public virtual void WriteValue(byte[] value)
		{
			if (value == null)
			{
				WriteNull();
			}
			else
			{
				InternalWriteValue(JsonToken.Bytes);
			}
		}

		public virtual void WriteValue(Uri value)
		{
			if (value == null)
			{
				WriteNull();
			}
			else
			{
				InternalWriteValue(JsonToken.String);
			}
		}

		public virtual void WriteValue(object value)
		{
			if (value == null)
			{
				WriteNull();
				return;
			}
			if (value is BigInteger)
			{
				throw CreateUnsupportedTypeException(this, value);
			}
			WriteValue(this, ConvertUtils.GetTypeCode(value), value);
		}

		public virtual void WriteComment(string text)
		{
			InternalWriteComment();
		}

		public virtual void WriteWhitespace(string ws)
		{
			InternalWriteWhitespace(ws);
		}

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

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

		internal static void WriteValue(JsonWriter writer, PrimitiveTypeCode typeCode, object value)
		{
			switch (typeCode)
			{
			case PrimitiveTypeCode.Char:
				writer.WriteValue((char)value);
				return;
			case PrimitiveTypeCode.CharNullable:
				writer.WriteValue((value == null) ? null : new char?((char)value));
				return;
			case PrimitiveTypeCode.Boolean:
				writer.WriteValue((bool)value);
				return;
			case PrimitiveTypeCode.BooleanNullable:
				writer.WriteValue((value == null) ? null : new bool?((bool)value));
				return;
			case PrimitiveTypeCode.SByte:
				writer.WriteValue((sbyte)value);
				return;
			case PrimitiveTypeCode.SByteNullable:
				writer.WriteValue((value == null) ? null : new sbyte?((sbyte)value));
				return;
			case PrimitiveTypeCode.Int16:
				writer.WriteValue((short)value);
				return;
			case PrimitiveTypeCode.Int16Nullable:
				writer.WriteValue((value == null) ? null : new short?((short)value));
				return;
			case PrimitiveTypeCode.UInt16:
				writer.WriteValue((ushort)value);
				return;
			case PrimitiveTypeCode.UInt16Nullable:
				writer.WriteValue((value == null) ? null : new ushort?((ushort)value));
				return;
			case PrimitiveTypeCode.Int32:
				writer.WriteValue((int)value);
				return;
			case PrimitiveTypeCode.Int32Nullable:
				writer.WriteValue((value == null) ? null : new int?((int)value));
				return;
			case PrimitiveTypeCode.Byte:
				writer.WriteValue((byte)value);
				return;
			case PrimitiveTypeCode.ByteNullable:
				writer.WriteValue((value == null) ? null : new byte?((byte)value));
				return;
			case PrimitiveTypeCode.UInt32:
				writer.WriteValue((uint)value);
				return;
			case PrimitiveTypeCode.UInt32Nullable:
				writer.WriteValue((value == null) ? null : new uint?((uint)value));
				return;
			case PrimitiveTypeCode.Int64:
				writer.WriteValue((long)value);
				return;
			case PrimitiveTypeCode.Int64Nullable:
				writer.WriteValue((value == null) ? null : new long?((long)value));
				return;
			case PrimitiveTypeCode.UInt64:
				writer.WriteValue((ulong)value);
				return;
			case PrimitiveTypeCode.UInt64Nullable:
				writer.WriteValue((value == null) ? null : new ulong?((ulong)value));
				return;
			case PrimitiveTypeCode.Single:
				writer.WriteValue((float)value);
				return;
			case PrimitiveTypeCode.SingleNullable:
				writer.WriteValue((value == null) ? null : new float?((float)value));
				return;
			case PrimitiveTypeCode.Double:
				writer.WriteValue((double)value);
				return;
			case PrimitiveTypeCode.DoubleNullable:
				writer.WriteValue((value == null) ? null : new double?((double)value));
				return;
			case PrimitiveTypeCode.DateTime:
				writer.WriteValue((DateTime)value);
				return;
			case PrimitiveTypeCode.DateTimeNullable:
				writer.WriteValue((value == null) ? null : new DateTime?((DateTime)value));
				return;
			case PrimitiveTypeCode.DateTimeOffset:
				writer.WriteValue((DateTimeOffset)value);
				return;
			case PrimitiveTypeCode.DateTimeOffsetNullable:
				writer.WriteValue((value == null) ? null : new DateTimeOffset?((DateTimeOffset)value));
				return;
			case PrimitiveTypeCode.Decimal:
				writer.WriteValue((decimal)value);
				return;
			case PrimitiveTypeCode.DecimalNullable:
				writer.WriteValue((value == null) ? null : new decimal?((decimal)value));
				return;
			case PrimitiveTypeCode.Guid:
				writer.WriteValue((Guid)value);
				return;
			case PrimitiveTypeCode.GuidNullable:
				writer.WriteValue((value == null) ? null : new Guid?((Guid)value));
				return;
			case PrimitiveTypeCode.TimeSpan:
				writer.WriteValue((TimeSpan)value);
				return;
			case PrimitiveTypeCode.TimeSpanNullable:
				writer.WriteValue((value == null) ? null : new TimeSpan?((TimeSpan)value));
				return;
			case PrimitiveTypeCode.BigInteger:
				writer.WriteValue((BigInteger)value);
				return;
			case PrimitiveTypeCode.BigIntegerNullable:
				writer.WriteValue((value == null) ? null : new BigInteger?((BigInteger)value));
				return;
			case PrimitiveTypeCode.Uri:
				writer.WriteValue((Uri)value);
				return;
			case PrimitiveTypeCode.String:
				writer.WriteValue((string)value);
				return;
			case PrimitiveTypeCode.Bytes:
				writer.WriteValue((byte[])value);
				return;
			case PrimitiveTypeCode.DBNull:
				writer.WriteNull();
				return;
			}
			if (value is IConvertible)
			{
				IConvertible convertible = (IConvertible)value;
				TypeInformation typeInformation = ConvertUtils.GetTypeInformation(convertible);
				PrimitiveTypeCode typeCode2 = ((typeInformation.TypeCode == PrimitiveTypeCode.Object) ? PrimitiveTypeCode.String : typeInformation.TypeCode);
				Type conversionType = ((typeInformation.TypeCode == PrimitiveTypeCode.Object) ? typeof(string) : typeInformation.Type);
				object value2 = convertible.ToType(conversionType, CultureInfo.InvariantCulture);
				WriteValue(writer, typeCode2, value2);
				return;
			}
			throw CreateUnsupportedTypeException(writer, value);
		}

		private static JsonWriterException CreateUnsupportedTypeException(JsonWriter writer, object value)
		{
			return JsonWriterException.Create(writer, "Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
		}

		protected void SetWriteState(JsonToken token, object value)
		{
			switch (token)
			{
			case JsonToken.StartObject:
				InternalWriteStart(token, JsonContainerType.Object);
				break;
			case JsonToken.StartArray:
				InternalWriteStart(token, JsonContainerType.Array);
				break;
			case JsonToken.StartConstructor:
				InternalWriteStart(token, JsonContainerType.Constructor);
				break;
			case JsonToken.PropertyName:
				if (!(value is string))
				{
					throw new ArgumentException("A name is required when setting property name state.", "value");
				}
				InternalWritePropertyName((string)value);
				break;
			case JsonToken.Comment:
				InternalWriteComment();
				break;
			case JsonToken.Raw:
				InternalWriteRaw();
				break;
			case JsonToken.Integer:
			case JsonToken.Float:
			case JsonToken.String:
			case JsonToken.Boolean:
			case JsonToken.Null:
			case JsonToken.Undefined:
			case JsonToken.Date:
			case JsonToken.Bytes:
				InternalWriteValue(token);
				break;
			case JsonToken.EndObject:
				InternalWriteEnd(JsonContainerType.Object);
				break;
			case JsonToken.EndArray:
				InternalWriteEnd(JsonContainerType.Array);
				break;
			case JsonToken.EndConstructor:
				InternalWriteEnd(JsonContainerType.Constructor);
				break;
			default:
				throw new ArgumentOutOfRangeException("token");
			}
		}

		internal void InternalWriteEnd(JsonContainerType container)
		{
			AutoCompleteClose(container);
		}

		internal void InternalWritePropertyName(string name)
		{
			_currentPosition.PropertyName = name;
			AutoComplete(JsonToken.PropertyName);
		}

		internal void InternalWriteRaw()
		{
		}

		internal void InternalWriteStart(JsonToken token, JsonContainerType container)
		{
			UpdateScopeWithFinishedValue();
			AutoComplete(token);
			Push(container);
		}

		internal void InternalWriteValue(JsonToken token)
		{
			UpdateScopeWithFinishedValue();
			AutoComplete(token);
		}

		internal void InternalWriteWhitespace(string ws)
		{
			if (ws != null && !StringUtils.IsWhiteSpace(ws))
			{
				throw JsonWriterException.Create(this, "Only white space characters should be used.", null);
			}
		}

		internal void InternalWriteComment()
		{
			AutoComplete(JsonToken.Comment);
		}
	}
}
namespace Newtonsoft.Json.Bson
{
	public class BsonWriter : JsonWriter
	{
		private readonly BsonBinaryWriter _writer;

		private BsonToken _root;

		private BsonToken _parent;

		private string _propertyName;

		public DateTimeKind DateTimeKindHandling
		{
			get
			{
				return _writer.DateTimeKindHandling;
			}
			set
			{
				_writer.DateTimeKindHandling = value;
			}
		}

		public BsonWriter(Stream stream)
		{
			ValidationUtils.ArgumentNotNull(stream, "stream");
			_writer = new BsonBinaryWriter(new BinaryWriter(stream));
		}

		public BsonWriter(BinaryWriter writer)
		{
			ValidationUtils.ArgumentNotNull(writer, "writer");
			_writer = new BsonBinaryWriter(writer);
		}

		public override void Flush()
		{
			_writer.Flush();
		}

		protected override void WriteEnd(JsonToken token)
		{
			base.WriteEnd(token);
			RemoveParent();
			if (base.Top == 0)
			{
				_writer.WriteToken(_root);
			}
		}

		public override void WriteComment(string text)
		{
			throw JsonWriterException.Create(this, "Cannot write JSON comment as BSON.", null);
		}

		public override void WriteStartConstructor(string name)
		{
			throw JsonWriterException.Create(this, "Cannot write JSON constructor as BSON.", null);
		}

		public override void WriteRaw(string json)
		{
			throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null);
		}

		public override void WriteRawValue(string json)
		{
			throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null);
		}

		public override void WriteStartArray()
		{
			base.WriteStartArray();
			AddParent(new BsonArray());
		}

		public override void WriteStartObject()
		{
			base.WriteStartObject();
			AddParent(new BsonObject());
		}

		public override void WritePropertyName(string name)
		{
			base.WritePropertyName(name);
			_propertyName = name;
		}

		public override void Close()
		{
			base.Close();
			if (base.CloseOutput && _writer != null)
			{
				_writer.Close();
			}
		}

		private void AddParent(BsonToken container)
		{
			AddToken(container);
			_parent = container;
		}

		private void RemoveParent()
		{
			_parent = _parent.Parent;
		}

		private void AddValue(object value, BsonType type)
		{
			AddToken(new BsonValue(value, type));
		}

		internal void AddToken(BsonToken token)
		{
			if (_parent != null)
			{
				if (_parent is BsonObject)
				{
					((BsonObject)_parent).Add(_propertyName, token);
					_propertyName = null;
				}
				else
				{
					((BsonArray)_parent).Add(token);
				}
				return;
			}
			if (token.Type != BsonType.Object && token.Type != BsonType.Array)
			{
				throw JsonWriterException.Create(this, "Error writing {0} value. BSON must start with an Object or Array.".FormatWith(CultureInfo.InvariantCulture, token.Type), null);
			}
			_parent = token;
			_root = token;
		}

		public override void WriteValue(object value)
		{
			if (value is BigInteger)
			{
				InternalWriteValue(JsonToken.Integer);
				AddToken(new BsonBinary(((BigInteger)value).ToByteArray(), BsonBinaryType.Binary));
			}
			else
			{
				base.WriteValue(value);
			}
		}

		public override void WriteNull()
		{
			base.WriteNull();
			AddValue(null, BsonType.Null);
		}

		public override void WriteUndefined()
		{
			base.WriteUndefined();
			AddValue(null, BsonType.Undefined);
		}

		public override void WriteValue(string value)
		{
			base.WriteValue(value);
			if (value == null)
			{
				AddValue(null, BsonType.Null);
			}
			else
			{
				AddToken(new BsonString(value, includeLength: true));
			}
		}

		public override void WriteValue(int value)
		{
			base.WriteValue(value);
			AddValue(value, BsonType.Integer);
		}

		[CLSCompliant(false)]
		public override void WriteValue(uint value)
		{
			if (value > int.MaxValue)
			{
				throw JsonWriterException.Create(this, "Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values.", null);
			}
			base.WriteValue(value);
			AddValue(value, BsonType.Integer);
		}

		public override void WriteValue(long value)
		{
			base.WriteValue(value);
			AddValue(value, BsonType.Long);
		}

		[CLSCompliant(false)]
		public override void WriteValue(ulong value)
		{
			if (value > long.MaxValue)
			{
				throw JsonWriterException.Create(this, "Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values.", null);
			}
			base.WriteValue(value);
			AddValue(value, BsonType.Long);
		}

		public override void WriteValue(float value)
		{
			base.WriteValue(value);
			AddValue(value, BsonType.Number);
		}

		public override void WriteValue(double value)
		{
			base.WriteValue(value);
			AddValue(value, BsonType.Number);
		}

		public override void WriteValue(bool value)
		{
			base.WriteValue(value);
			AddValue(value, BsonType.Boolean);
		}

		public override void WriteValue(short value)
		{
			base.WriteValue(value);
			AddValue(value, BsonType.Integer);
		}

		[CLSCompliant(false)]
		public override void WriteValue(ushort value)
		{
			base.WriteValue(value);
			AddValue(value, BsonType.Integer);
		}

		public override void WriteValue(char value)
		{
			base.WriteValue(value);
			string text = null;
			text = value.ToString(CultureInfo.InvariantCulture);
			AddToken(new BsonString(text, includeLength: true));
		}

		public override void WriteValue(byte value)
		{
			base.WriteValue(value);
			AddValue(value, BsonType.Integer);
		}

		[CLSCompliant(false)]
		public override void WriteValue(sbyte value)
		{
			base.WriteValue(value);
			AddValue(value, BsonType.Integer);
		}

		public override void WriteValue(decimal value)
		{
			base.WriteValue(value);
			AddValue(value, BsonType.Number);
		}

		public override void WriteValue(DateTime value)
		{
			base.WriteValue(value);
			value = DateTimeUtils.EnsureDateTime(value, base.DateTimeZoneHandling);
			AddValue(value, BsonType.Date);
		}

		public override void WriteValue(DateTimeOffset value)
		{
			base.WriteValue(value);
			AddValue(value, BsonType.Date);
		}

		public override void WriteValue(byte[] value)
		{
			base.WriteValue(value);
			AddToken(new BsonBinary(value, BsonBinaryType.Binary));
		}

		public override void WriteValue(Guid value)
		{
			base.WriteValue(value);
			AddToken(new BsonBinary(value.ToByteArray(), BsonBinaryType.Uuid));
		}

		public override void WriteValue(TimeSpan value)
		{
			base.WriteValue(value);
			AddToken(new BsonString(value.ToString(), includeLength: true));
		}

		public override void WriteValue(Uri value)
		{
			base.WriteValue(value);
			AddToken(new BsonString(value.ToString(), includeLength: true));
		}

		public void WriteObjectId(byte[] value)
		{
			ValidationUtils.ArgumentNotNull(value, "value");
			if (value.Length != 12)
			{
				throw JsonWriterException.Create(this, "An object id must be 12 bytes", null);
			}
			UpdateScopeWithFinishedValue();
			AutoComplete(JsonToken.Undefined);
			AddValue(value, BsonType.Oid);
		}

		public void WriteRegex(string pattern, string options)
		{
			ValidationUtils.ArgumentNotNull(pattern, "pattern");
			UpdateScopeWithFinishedValue();
			AutoComplete(JsonToken.Undefined);
			AddToken(new BsonRegex(pattern, options));
		}
	}
}
namespace Newtonsoft.Json
{
	public enum ConstructorHandling
	{
		Default,
		AllowNonPublicDefaultConstructor
	}
}
namespace Newtonsoft.Json.Converters
{
	internal interface IBinary
	{
		byte[] ToArray();
	}
}
namespace Newtonsoft.Json
{
	public abstract class JsonConverter
	{
		public virtual bool CanRead => true;

		public virtual bool CanWrite => true;

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

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

		public abstract bool CanConvert(Type objectType);

		public virtual JsonSchema GetSchema()
		{
			return null;
		}
	}
}
namespace Newtonsoft.Json.Converters
{
	public class BinaryConverter : JsonConverter
	{
		private const string BinaryTypeName = "System.Data.Linq.Binary";

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			if (value == null)
			{
				writer.WriteNull();
				return;
			}
			byte[] byteArray = GetByteArray(value);
			writer.WriteValue(byteArray);
		}

		private byte[] GetByteArray(object value)
		{
			if (value.GetType().AssignableToTypeName("System.Data.Linq.Binary"))
			{
				IBinary binary = DynamicWrapper.CreateWrapper<IBinary>(value);
				return binary.ToArray();
			}
			if (value is SqlBinary sqlBinary)
			{
				return sqlBinary.Value;
			}
			throw new JsonSerializationException("Unexpected value type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			Type type = (ReflectionUtils.IsNullableType(objectType) ? Nullable.GetUnderlyingType(objectType) : objectType);
			if (reader.TokenType == JsonToken.Null)
			{
				if (!ReflectionUtils.IsNullable(objectType))
				{
					throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
				}
				return null;
			}
			byte[] array;
			if (reader.TokenType == JsonToken.StartArray)
			{
				array = ReadByteArray(reader);
			}
			else
			{
				if (reader.TokenType != JsonToken.String)
				{
					throw JsonSerializationException.Create(reader, "Unexpected token parsing binary. Expected String or StartArray, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
				}
				string s = reader.Value.ToString();
				array = Convert.FromBase64String(s);
			}
			if (type.AssignableToTypeName("System.Data.Linq.Binary"))
			{
				return Activator.CreateInstance(type, array);
			}
			if (type == typeof(SqlBinary))
			{
				return new SqlBinary(array);
			}
			throw JsonSerializationException.Create(reader, "Unexpected object type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, objectType));
		}

		private byte[] ReadByteArray(JsonReader reader)
		{
			List<byte> list = new List<byte>();
			while (reader.Read())
			{
				switch (reader.TokenType)
				{
				case JsonToken.Integer:
					list.Add(Convert.ToByte(reader.Value, CultureInfo.InvariantCulture));
					break;
				case JsonToken.EndArray:
					return list.ToArray();
				default:
					throw JsonSerializationException.Create(reader, "Unexpected token when reading bytes: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
				case JsonToken.Comment:
					break;
				}
			}
			throw JsonSerializationException.Create(reader, "Unexpected end when reading bytes.");
		}

		public override bool CanConvert(Type objectType)
		{
			if (objectType.AssignableToTypeName("System.Data.Linq.Binary"))
			{
				return true;
			}
			if (objectType == typeof(SqlBinary) || objectType == typeof(SqlBinary?))
			{
				return true;
			}
			return false;
		}
	}
	public class BsonObjectIdConverter : JsonConverter
	{
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			BsonObjectId bsonObjectId = (BsonObjectId)value;
			if (writer is BsonWriter bsonWriter)
			{
				bsonWriter.WriteObjectId(bsonObjectId.Value);
			}
			else
			{
				writer.WriteValue(bsonObjectId.Value);
			}
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			if (reader.TokenType != JsonToken.Bytes)
			{
				throw new JsonSerializationException("Expected Bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
			}
			byte[] value = (byte[])reader.Value;
			return new BsonObjectId(value);
		}

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(BsonObjectId);
		}
	}
	public abstract class CustomCreationConverter<T> : JsonConverter
	{
		public override bool CanWrite => false;

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			throw new NotSupportedException("CustomCreationConverter should only be used while deserializing.");
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			if (reader.TokenType == JsonToken.Null)
			{
				return null;
			}
			T val = Create(objectType);
			if (val == null)
			{
				throw new JsonSerializationException("No object created.");
			}
			serializer.Populate(reader, val);
			return val;
		}

		public abstract T Create(Type objectType);

		public override bool CanConvert(Type objectType)
		{
			return typeof(T).IsAssignableFrom(objectType);
		}
	}
	public class DataSetConverter : JsonConverter
	{
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			DataSet dataSet = (DataSet)value;
			DefaultContractResolver defaultContractResolver = serializer.ContractResolver as DefaultContractResolver;
			DataTableConverter dataTableConverter = new DataTableConverter();
			writer.WriteStartObject();
			foreach (DataTable table in dataSet.Tables)
			{
				writer.WritePropertyName((defaultContractResolver != null) ? defaultContractResolver.GetResolvedPropertyName(table.TableName) : table.TableName);
				dataTableConverter.WriteJson(writer, table, serializer);
			}
			writer.WriteEndObject();
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			DataSet dataSet = ((objectType == typeof(DataSet)) ? new DataSet() : ((DataSet)Activator.CreateInstance(objectType)));
			DataTableConverter dataTableConverter = new DataTableConverter();
			reader.Read();
			while (reader.TokenType == JsonToken.PropertyName)
			{
				DataTable dataTable = dataSet.Tables[(string)reader.Value];
				bool flag = dataTable != null;
				dataTable = (DataTable)dataTableConverter.ReadJson(reader, typeof(DataTable), dataTable, serializer);
				if (!flag)
				{
					dataSet.Tables.Add(dataTable);
				}
				reader.Read();
			}
			return dataSet;
		}

		public override bool CanConvert(Type valueType)
		{
			return typeof(DataSet).IsAssignableFrom(valueType);
		}
	}
	public class DataTableConverter : JsonConverter
	{
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			DataTable dataTable = (DataTable)value;
			DefaultContractResolver defaultContractResolver = serializer.ContractResolver as DefaultContractResolver;
			writer.WriteStartArray();
			foreach (DataRow row in dataTable.Rows)
			{
				writer.WriteStartObject();
				foreach (DataColumn column in row.Table.Columns)
				{
					if (serializer.NullValueHandling != NullValueHandling.Ignore || (row[column] != null && row[column] != DBNull.Value))
					{
						writer.WritePropertyName((defaultContractResolver != null) ? defaultContractResolver.GetResolvedPropertyName(column.ColumnName) : column.ColumnName);
						serializer.Serialize(writer, row[column]);
					}
				}
				writer.WriteEndObject();
			}
			writer.WriteEndArray();
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			DataTable dataTable = existingValue as DataTable;
			if (dataTable == null)
			{
				dataTable = ((objectType == typeof(DataTable)) ? new DataTable() : ((DataTable)Activator.CreateInstance(objectType)));
			}
			if (reader.TokenType == JsonToken.PropertyName)
			{
				dataTable.TableName = (string)reader.Value;
				reader.Read();
			}
			reader.Read();
			while (reader.TokenType == JsonToken.StartObject)
			{
				DataRow dataRow = dataTable.NewRow();
				reader.Read();
				while (reader.TokenType == JsonToken.PropertyName)
				{
					string text = (string)reader.Value;
					reader.Read();
					if (!dataTable.Columns.Contains(text))
					{
						Type columnDataType = GetColumnDataType(reader.TokenType);
						dataTable.Columns.Add(new DataColumn(text, columnDataType));
					}
					dataRow[text] = reader.Value ?? DBNull.Value;
					reader.Read();
				}
				dataRow.EndEdit();
				dataTable.Rows.Add(dataRow);
				reader.Read();
			}
			return dataTable;
		}

		private static Type GetColumnDataType(JsonToken tokenType)
		{
			switch (tokenType)
			{
			case JsonToken.Integer:
				return typeof(long);
			case JsonToken.Float:
				return typeof(double);
			case JsonToken.String:
			case JsonToken.Null:
			case JsonToken.Undefined:
				return typeof(string);
			case JsonToken.Boolean:
				return typeof(bool);
			case JsonToken.Date:
				return typeof(DateTime);
			default:
				throw new ArgumentOutOfRangeException();
			}
		}

		public override bool CanConvert(Type valueType)
		{
			return typeof(DataTable).IsAssignableFrom(valueType);
		}
	}
	public abstract class DateTimeConverterBase : JsonConverter
	{
		public override bool CanConvert(Type objectType)
		{
			if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
			{
				return true;
			}
			if (objectType == typeof(DateTimeOffset) || objectType == typeof(DateTimeOffset?))
			{
				return true;
			}
			return false;
		}
	}
	internal interface IEntityKeyMember
	{
		string Key { get; set; }

		object Value { get; set; }
	}
	public class EntityKeyMemberConverter : JsonConverter
	{
		private const string EntityKeyMemberFullTypeName = "System.Data.EntityKeyMember";

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			IEntityKeyMember entityKeyMember = DynamicWrapper.CreateWrapper<IEntityKeyMember>(value);
			Type type = ((entityKeyMember.Value != null) ? entityKeyMember.Value.GetType() : null);
			writer.WriteStartObject();
			writer.WritePropertyName("Key");
			writer.WriteValue(entityKeyMember.Key);
			writer.WritePropertyName("Type");
			writer.WriteValue((type != null) ? type.FullName : null);
			writer.WritePropertyName("Value");
			if (type != null)
			{
				if (JsonSerializerInternalWriter.TryConvertToString(entityKeyMember.Value, type, out var s))
				{
					writer.WriteValue(s);
				}
				else
				{
					writer.WriteValue(entityKeyMember.Value);
				}
			}
			else
			{
				writer.WriteNull();
			}
			writer.WriteEndObject();
		}

		private static void ReadAndAssertProperty(JsonReader reader, string propertyName)
		{
			ReadAndAssert(reader);
			if (reader.TokenType != JsonToken.PropertyName || reader.Value.ToString() != propertyName)
			{
				throw new JsonSerializationException("Expected JSON property '{0}'.".FormatWith(CultureInfo.InvariantCulture, propertyName));
			}
		}

		private static void ReadAndAssert(JsonReader reader)
		{
			if (!reader.Read())
			{
				throw new JsonSerializationException("Unexpected end.");
			}
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			IEntityKeyMember entityKeyMember = DynamicWrapper.CreateWrapper<IEntityKeyMember>(Activator.CreateInstance(objectType));
			ReadAndAssertProperty(reader, "Key");
			ReadAndAssert(reader);
			entityKeyMember.Key = reader.Value.ToString();
			ReadAndAssertProperty(reader, "Type");
			ReadAndAssert(reader);
			string typeName = reader.Value.ToString();
			Type type = Type.GetType(typeName);
			ReadAndAssertProperty(reader, "Value");
			ReadAndAssert(reader);
			entityKeyMember.Value = serializer.Deserialize(reader, type);
			ReadAndAssert(reader);
			return DynamicWrapper.GetUnderlyingObject(entityKeyMember);
		}

		public override bool CanConvert(Type objectType)
		{
			return objectType.AssignableToTypeName("System.Data.EntityKeyMember");
		}
	}
	public class ExpandoObjectConverter : JsonConverter
	{
		public override bool CanWrite => false;

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			return ReadValue(reader);
		}

		private object ReadValue(JsonReader reader)
		{
			while (reader.TokenType == JsonToken.Comment)
			{
				if (!reader.Read())
				{
					throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject.");
				}
			}
			switch (reader.TokenType)
			{
			case JsonToken.StartObject:
				return ReadObject(reader);
			case JsonToken.StartArray:
				return ReadList(reader);
			default:
				if (JsonReader.IsPrimitiveToken(reader.TokenType))
				{
					return reader.Value;
				}
				throw JsonSerializationException.Create(reader, "Unexpected token when converting ExpandoObject: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
			}
		}

		private object ReadList(JsonReader reader)
		{
			IList<object> list = new List<object>();
			while (reader.Read())
			{
				switch (reader.TokenType)
				{
				case JsonToken.EndArray:
					return list;
				case JsonToken.Comment:
					continue;
				}
				object item = ReadValue(reader);
				list.Add(item);
			}
			throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject.");
		}

		private object ReadObject(JsonReader reader)
		{
			IDictionary<string, object> dictionary = new ExpandoObject();
			while (reader.Read())
			{
				switch (reader.TokenType)
				{
				case JsonToken.PropertyName:
				{
					string key = reader.Value.ToString();
					if (!reader.Read())
					{
						throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject.");
					}
					object value = ReadValue(reader);
					dictionary[key] = value;
					break;
				}
				case JsonToken.EndObject:
					return dictionary;
				}
			}
			throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject.");
		}

		public override bool CanConvert(Type objectType)
		{
			return objectType == typeof(ExpandoObject);
		}
	}
	public class IsoDateTimeConverter : DateTimeConverterBase
	{
		private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";

		private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;

		private string _dateTimeFormat;

		private CultureInfo _culture;

		public DateTimeStyles DateTimeStyles
		{
			get
			{
				return _dateTimeStyles;
			}
			set
			{
				_dateTimeStyles = value;
			}
		}

		public string DateTimeFormat
		{
			get
			{
				return _dateTimeFormat ?? string.Empty;
			}
			set
			{
				_dateTimeFormat = StringUtils.NullEmptyString(value);
			}
		}

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

		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			string value2;
			if (value is DateTime dateTime)
			{
				if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
				{
					dateTime = dateTime.ToUniversalTime();
				}
				value2 = dateTime.ToString(_dateTimeFormat ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK", Culture);
			}
			else
			{
				if (!(value is DateTimeOffset dateTimeOffset))
				{
					throw new JsonSerializationException("Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {0}.".FormatWith(CultureInfo.InvariantCulture, ReflectionUtils.GetObjectType(value)));
				}
				if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
				{
					dateTimeOffset = dateTimeOffset.ToUniversalTime();
				}
				value2 = dateTimeOffset.ToString(_dateTimeFormat ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK", Culture);
			}
			writer.WriteValue(value2);
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			bool flag = ReflectionUtils.IsNullableType(objectType);
			Type type = (flag ? Nullable.GetUnderlyingType(objectType) : objectType);
			if (reader.TokenType == JsonToken.Null)
			{
				if (!ReflectionUtils.IsNullableType(objectType))
				{
					throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
				}
				return null;
			}
			if (reader.TokenType == JsonToken.Date)
			{
				if (type == typeof(DateTimeOffset))
				{
					return new DateTimeOffset((DateTime)reader.Value);
				}
				return reader.Value;
			}
			if (reader.TokenType != JsonToken.String)
			{
				throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
			}
			string text = reader.Value.ToString();
			if (string.IsNullOrEmpty(text) && flag)
			{
				return null;
			}
			if (type == typeof(DateTimeOffset))
			{
				if (!string.IsNullOrEmpty(_dateTimeFormat))
				{
					return DateTimeOffset.ParseExact(text, _dateTimeFormat, Culture, _dateTimeStyles);
				}
				return DateTimeOffset.Parse(text, Culture, _dateTimeStyles);
			}
			if (!string.IsNullOrEmpty(_dateTimeFormat))
			{
				return DateTime.ParseExact(text, _dateTimeFormat, Culture, _dateTimeStyles);
			}
			return DateTime.Parse(text, Culture, _dateTimeStyles);
		}
	}
	public class JavaScriptDateTimeConverter : DateTimeConverterBase
	{
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			long value2;
			if (value is DateTime dateTime)
			{
				DateTime dateTime2 = dateTime.ToUniversalTime();
				value2 = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(dateTime2);
			}
			else
			{
				if (!(value is DateTimeOffset dateTimeOffset))
				{
					throw new JsonSerializationException("Expected date object value.");
				}
				value2 = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(dateTimeOffset.ToUniversalTime().UtcDateTime);
			}
			writer.WriteStartConstructor("Date");
			writer.WriteValue(value2);
			writer.WriteEndConstructor();
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			Type type = (ReflectionUtils.IsNullableType(objectType) ? Nullable.GetUnderlyingType(objectType) : objectType);
			if (reader.TokenType == JsonToken.Null)
			{
				if (!ReflectionUtils.IsNullable(objectType))
				{
					throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.I

Tavis.JsonPatch.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: CompilationRelaxations(8)]
[assembly: TargetFramework(".NETPortable,Version=v4.0,Profile=Profile88", FrameworkDisplayName = ".NET Portable Subset")]
[assembly: AssemblyTitle("JsonPatch")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTrademark("")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCopyright("Copyright ©  2014")]
[assembly: AssemblyProduct("JsonPatch")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Tavis;

public interface IPatchTarget
{
	void ApplyOperation(Operation operation);
}
public abstract class BaseTargetAdapter : IPatchTarget
{
	public void ApplyOperation(Operation operation)
	{
		if (operation is AddOperation)
		{
			Add((AddOperation)operation);
		}
		else if (operation is CopyOperation)
		{
			Copy((CopyOperation)operation);
		}
		else if (operation is MoveOperation)
		{
			Move((MoveOperation)operation);
		}
		else if (operation is RemoveOperation)
		{
			Remove((RemoveOperation)operation);
		}
		else if (operation is ReplaceOperation)
		{
			Replace((ReplaceOperation)operation);
		}
		else if (operation is TestOperation)
		{
			Test((TestOperation)operation);
		}
	}

	protected abstract void Add(AddOperation operation);

	protected abstract void Copy(CopyOperation operation);

	protected abstract void Move(MoveOperation operation);

	protected abstract void Remove(RemoveOperation operation);

	protected abstract void Replace(ReplaceOperation operation);

	protected abstract void Test(TestOperation operation);
}
public class JsonNetTargetAdapter : BaseTargetAdapter
{
	private readonly JToken _target;

	public JsonNetTargetAdapter(JToken target)
	{
		_target = target;
	}

	protected override void Replace(ReplaceOperation operation)
	{
		JToken val = operation.Path.Find(_target);
		val.Replace(operation.Value);
	}

	protected override void Add(AddOperation operation)
	{
		JToken val = null;
		JObject val2 = null;
		try
		{
			if (operation.Path.IsNewPointer())
			{
				JsonPointer parentPointer = operation.Path.ParentPointer;
				JToken obj = parentPointer.Find(_target);
				val = ((obj is JArray) ? obj : null);
			}
			else
			{
				val = operation.Path.Find(_target);
			}
		}
		catch (ArgumentException)
		{
			JsonPointer parentPointer2 = operation.Path.ParentPointer;
			JToken obj2 = parentPointer2.Find(_target);
			val2 = (JObject)(object)((obj2 is JObject) ? obj2 : null);
		}
		if (val == null && val2 != null)
		{
			val2.Add(((object)operation.Path).ToString().Split(new char[1] { '/' }).Last(), operation.Value);
		}
		else if (val is JArray)
		{
			JArray val3 = (JArray)(object)((val is JArray) ? val : null);
			val3.Add(operation.Value);
		}
		else if (val.Parent is JProperty)
		{
			JContainer parent = val.Parent;
			JProperty val4 = (JProperty)(object)((parent is JProperty) ? parent : null);
			val4.Value = operation.Value;
		}
	}

	protected override void Remove(RemoveOperation operation)
	{
		JToken val = operation.Path.Find(_target);
		if (val.Parent is JProperty)
		{
			((JToken)val.Parent).Remove();
		}
		else
		{
			val.Remove();
		}
	}

	protected override void Move(MoveOperation operation)
	{
		if (((object)operation.Path).ToString().StartsWith(((object)operation.FromPath).ToString()))
		{
			throw new ArgumentException("To path cannot be below from path");
		}
		JToken value = operation.FromPath.Find(_target);
		Remove(new RemoveOperation
		{
			Path = operation.FromPath
		});
		Add(new AddOperation
		{
			Path = operation.Path,
			Value = value
		});
	}

	protected override void Test(TestOperation operation)
	{
		JToken val = operation.Path.Find(_target);
		if (!((object)val).Equals((object?)_target))
		{
			throw new InvalidOperationException("Value at " + ((object)operation.Path).ToString() + " does not match.");
		}
	}

	protected override void Copy(CopyOperation operation)
	{
		JToken value = operation.FromPath.Find(_target);
		Add(new AddOperation
		{
			Path = operation.Path,
			Value = value
		});
	}
}
public abstract class Operation
{
	public JsonPointer Path { get; set; }

	public abstract void Write(JsonWriter writer);

	protected static void WriteOp(JsonWriter writer, string op)
	{
		writer.WritePropertyName("op");
		writer.WriteValue(op);
	}

	protected static void WritePath(JsonWriter writer, JsonPointer pointer)
	{
		writer.WritePropertyName("path");
		writer.WriteValue(((object)pointer).ToString());
	}

	protected static void WriteFromPath(JsonWriter writer, JsonPointer pointer)
	{
		writer.WritePropertyName("from");
		writer.WriteValue(((object)pointer).ToString());
	}

	protected static void WriteValue(JsonWriter writer, JToken value)
	{
		writer.WritePropertyName("value");
		value.WriteTo(writer, (JsonConverter[])(object)new JsonConverter[0]);
	}

	public abstract void Read(JObject jOperation);
}
public class AddOperation : Operation
{
	public JToken Value { get; set; }

	public override void Write(JsonWriter writer)
	{
		writer.WriteStartObject();
		Operation.WriteOp(writer, "add");
		Operation.WritePath(writer, base.Path);
		Operation.WriteValue(writer, Value);
		writer.WriteEndObject();
	}

	public override void Read(JObject jOperation)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		base.Path = new JsonPointer((string)jOperation.GetValue("path"));
		Value = jOperation.GetValue("value");
	}
}
public class CopyOperation : Operation
{
	public JsonPointer FromPath { get; set; }

	public override void Write(JsonWriter writer)
	{
		writer.WriteStartObject();
		Operation.WriteOp(writer, "copy");
		Operation.WritePath(writer, base.Path);
		Operation.WriteFromPath(writer, FromPath);
		writer.WriteEndObject();
	}

	public override void Read(JObject jOperation)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		base.Path = new JsonPointer((string)jOperation.GetValue("path"));
		FromPath = new JsonPointer((string)jOperation.GetValue("from"));
	}
}
public class MoveOperation : Operation
{
	public JsonPointer FromPath { get; set; }

	public override void Write(JsonWriter writer)
	{
		writer.WriteStartObject();
		Operation.WriteOp(writer, "move");
		Operation.WritePath(writer, base.Path);
		Operation.WriteFromPath(writer, FromPath);
		writer.WriteEndObject();
	}

	public override void Read(JObject jOperation)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		base.Path = new JsonPointer((string)jOperation.GetValue("path"));
		FromPath = new JsonPointer((string)jOperation.GetValue("from"));
	}
}
public class RemoveOperation : Operation
{
	public override void Write(JsonWriter writer)
	{
		writer.WriteStartObject();
		Operation.WriteOp(writer, "remove");
		Operation.WritePath(writer, base.Path);
		writer.WriteEndObject();
	}

	public override void Read(JObject jOperation)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		base.Path = new JsonPointer((string)jOperation.GetValue("path"));
	}
}
public class ReplaceOperation : Operation
{
	public JToken Value { get; set; }

	public override void Write(JsonWriter writer)
	{
		writer.WriteStartObject();
		Operation.WriteOp(writer, "replace");
		Operation.WritePath(writer, base.Path);
		Operation.WriteValue(writer, Value);
		writer.WriteEndObject();
	}

	public override void Read(JObject jOperation)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		base.Path = new JsonPointer((string)jOperation.GetValue("path"));
		Value = jOperation.GetValue("value");
	}
}
public class TestOperation : Operation
{
	public JToken Value { get; set; }

	public override void Write(JsonWriter writer)
	{
		writer.WriteStartObject();
		Operation.WriteOp(writer, "test");
		Operation.WritePath(writer, base.Path);
		Operation.WriteValue(writer, Value);
		writer.WriteEndObject();
	}

	public override void Read(JObject jOperation)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		base.Path = new JsonPointer((string)jOperation.GetValue("path"));
		Value = jOperation.GetValue("value");
	}
}
public class PatchDocument
{
	private readonly List<Operation> _Operations = new List<Operation>();

	public List<Operation> Operations => _Operations;

	public PatchDocument(params Operation[] operations)
	{
		foreach (Operation operation in operations)
		{
			AddOperation(operation);
		}
	}

	public void ApplyTo(JToken jToken)
	{
		ApplyTo((IPatchTarget)new JsonNetTargetAdapter(jToken));
	}

	public void ApplyTo(IPatchTarget target)
	{
		foreach (Operation operation in Operations)
		{
			target.ApplyOperation(operation);
		}
	}

	public void AddOperation(Operation operation)
	{
		Operations.Add(operation);
	}

	public static PatchDocument Load(Stream document)
	{
		StreamReader streamReader = new StreamReader(document);
		return Parse(streamReader.ReadToEnd());
	}

	public static PatchDocument Parse(string jsondocument)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		JToken obj = JToken.Parse(jsondocument);
		JArray val = (JArray)(object)((obj is JArray) ? obj : null);
		PatchDocument patchDocument = new PatchDocument();
		if (val != null)
		{
			foreach (JObject item in ((IEnumerable)(object)((JToken)val).Children()).Cast<JObject>())
			{
				Operation operation = CreateOperation((string)item["op"]);
				operation.Read(item);
				patchDocument.AddOperation(operation);
			}
		}
		return patchDocument;
	}

	private static Operation CreateOperation(string op)
	{
		return op switch
		{
			"add" => new AddOperation(), 
			"copy" => new CopyOperation(), 
			"move" => new MoveOperation(), 
			"remove" => new RemoveOperation(), 
			"replace" => new ReplaceOperation(), 
			"test" => new TestOperation(), 
			_ => null, 
		};
	}

	public MemoryStream ToStream()
	{
		MemoryStream memoryStream = new MemoryStream();
		CopyToStream(memoryStream);
		memoryStream.Flush();
		memoryStream.Position = 0L;
		return memoryStream;
	}

	public void CopyToStream(Stream stream)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		JsonTextWriter val = new JsonTextWriter((TextWriter)new StreamWriter(stream));
		((JsonWriter)val).Formatting = (Formatting)1;
		((JsonWriter)val).WriteStartArray();
		foreach (Operation operation in Operations)
		{
			operation.Write((JsonWriter)(object)val);
		}
		((JsonWriter)val).WriteEndArray();
		((JsonWriter)val).Flush();
	}
}

Tavis.JsonPointer.dll

Decompiled 4 months ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Newtonsoft.Json.Linq;

[assembly: TargetFramework(".NETPortable,Version=v4.0,Profile=Profile88", FrameworkDisplayName = ".NET Portable Subset")]
[assembly: AssemblyTitle("JsonPointer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("JsonPointer")]
[assembly: AssemblyCopyright("Copyright ©  2014")]
[assembly: AssemblyTrademark("")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Tavis;

public class JsonPointer
{
	private readonly string[] _Tokens;

	public JsonPointer ParentPointer
	{
		get
		{
			if (_Tokens.Length == 0)
			{
				return null;
			}
			return new JsonPointer(_Tokens.Take(_Tokens.Length - 1).ToArray());
		}
	}

	public JsonPointer(string pointer)
	{
		_Tokens = pointer.Split(new char[1] { '/' }).Skip(1).Select(Decode)
			.ToArray();
	}

	private JsonPointer(string[] tokens)
	{
		_Tokens = tokens;
	}

	private string Decode(string token)
	{
		return Uri.UnescapeDataString(token).Replace("~1", "/").Replace("~0", "~");
	}

	public bool IsNewPointer()
	{
		return _Tokens.Last() == "-";
	}

	public JToken Find(JToken sample)
	{
		if (_Tokens.Length == 0)
		{
			return sample;
		}
		try
		{
			JToken val = sample;
			string[] tokens = _Tokens;
			foreach (string text in tokens)
			{
				if (val is JArray)
				{
					val = val[(object)Convert.ToInt32(text)];
					continue;
				}
				val = val[(object)text];
				if (val == null)
				{
					throw new ArgumentException("Cannot find " + text);
				}
			}
			return val;
		}
		catch (Exception innerException)
		{
			throw new ArgumentException("Failed to dereference pointer", innerException);
		}
	}

	public override string ToString()
	{
		return "/" + string.Join("/", _Tokens);
	}
}