Decompiled source of TestFilter System Collections Immutable dll AEFAA2EA v0.0.0

System.Collections.Immutable.dll

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

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("System.Collections.Immutable.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b86c4cb78549b34bab61a3b1800e23bfeb5b3ec390074041536a7e3cbd97f5f04cf0f857155a8928eaa29ebfd11cfbbad3ba70efea7bda3226c6a8d370a4cd303f714486b6ebc225985a638471e6ef571cc92a4613c00b8fa65d61ccee0cbe5f36330c9a01f4183559f1bef24cc2917c6d913e3a541333a1d05d9bed22b38cb")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: AssemblyDefaultAlias("System.Collections.Immutable")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata("IsTrimmable", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyDescription("This package provides collections that are thread safe and guaranteed to never change their contents, also known as immutable collections. Like strings, any methods that perform modifications will not change the existing instance but instead return a new instance. For efficiency reasons, the implementation uses a sharing mechanism to ensure that newly created instances share as much data as possible with the previous instance while ensuring that operations have a predictable time complexity.\r\n\r\nThe System.Collections.Immutable library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks.")]
[assembly: AssemblyFileVersion("7.0.22.51805")]
[assembly: AssemblyInformationalVersion("7.0.0+d099f075e45d2aa6007a22b71b45a08758559f80")]
[assembly: AssemblyProduct("Microsoft® .NET")]
[assembly: AssemblyTitle("System.Collections.Immutable")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/dotnet/runtime")]
[assembly: AssemblyVersion("7.0.0.0")]
[module: RefSafetyRules(11)]
[module: System.Runtime.CompilerServices.NullablePublicOnly(true)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class NullablePublicOnlyAttribute : Attribute
	{
		public readonly bool IncludesInternals;

		public NullablePublicOnlyAttribute(bool P_0)
		{
			IncludesInternals = P_0;
		}
	}
	[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 FxResources.System.Collections.Immutable
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static readonly bool s_usingResourceKeys = AppContext.TryGetSwitch("System.Resources.UseSystemResourceKeys", out var isEnabled) && isEnabled;

		private static ResourceManager s_resourceManager;

		internal static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(typeof(SR)));

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

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

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

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

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

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

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

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

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

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

		private static bool UsingResourceKeys()
		{
			return s_usingResourceKeys;
		}

		internal static string GetResourceString(string resourceKey)
		{
			if (UsingResourceKeys())
			{
				return resourceKey;
			}
			string result = null;
			try
			{
				result = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			return result;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string resourceString = GetResourceString(resourceKey);
			if (!(resourceKey == resourceString) && resourceString != null)
			{
				return resourceString;
			}
			return defaultString;
		}

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

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

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

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

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

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

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

		internal static string Format(IFormatProvider? provider, string resourceFormat, params object?[]? args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + ", " + string.Join(", ", args);
				}
				return string.Format(provider, resourceFormat, args);
			}
			return resourceFormat;
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class AllowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
	internal sealed class DisallowNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class MaybeNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
	internal sealed class NotNullAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class MaybeNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public MaybeNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class NotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public NotNullWhenAttribute(bool returnValue)
		{
			ReturnValue = returnValue;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
	internal sealed class NotNullIfNotNullAttribute : Attribute
	{
		public string ParameterName { get; }

		public NotNullIfNotNullAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	internal sealed class DoesNotReturnAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	internal sealed class DoesNotReturnIfAttribute : Attribute
	{
		public bool ParameterValue { get; }

		public DoesNotReturnIfAttribute(bool parameterValue)
		{
			ParameterValue = parameterValue;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
}
namespace System.Runtime.InteropServices
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class LibraryImportAttribute : Attribute
	{
		public string LibraryName { get; }

		public string? EntryPoint { get; set; }

		public StringMarshalling StringMarshalling { get; set; }

		public Type? StringMarshallingCustomType { get; set; }

		public bool SetLastError { get; set; }

		public LibraryImportAttribute(string libraryName)
		{
			LibraryName = libraryName;
		}
	}
	internal enum StringMarshalling
	{
		Custom,
		Utf8,
		Utf16
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class NonVersionableAttribute : Attribute
	{
	}
}
namespace System.Linq
{
	public static class ImmutableArrayExtensions
	{
		public static IEnumerable<TResult> Select<T, TResult>(this ImmutableArray<T> immutableArray, Func<T, TResult> selector)
		{
			immutableArray.ThrowNullRefIfNotInitialized();
			return immutableArray.array.Select(selector);
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		private static readonly Type s_typeOfT = typeof(T);

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

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

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

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

		public object Key => _inner.Current.Key;

		public object? Value => _inner.Current.Value;

		public object Current => Entry;

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

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

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

		private TEnumerator _enumeratorStruct;

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

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

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

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

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

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

		bool IsEmpty { get; }

		int Count { get; }

		IBinaryTree? Left { get; }

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

		new IBinaryTree<T>? Left { get; }

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

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

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

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

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

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

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

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

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

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

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

		IImmutableList<T> Add(T value);

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

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

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

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

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

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

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

		IImmutableList<T> RemoveAt(int index);

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

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

		void ForEach(Action<T> action);

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

		void CopyTo(T[] array);

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

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

		bool Exists(Predicate<T> match);

		T? Find(Predicate<T> match);

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

		int FindIndex(Predicate<T> match);

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

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

		T? FindLast(Predicate<T> match);

		int FindLastIndex(Predicate<T> match);

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

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

		bool TrueForAll(Predicate<T> match);

		int BinarySearch(T item);

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

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

		IImmutableQueue<T> Clear();

		T Peek();

		IImmutableQueue<T> Enqueue(T value);

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

		bool Contains(T value);

		IImmutableSet<T> Add(T value);

		IImmutableSet<T> Remove(T value);

		bool TryGetValue(T equalValue, out T actualValue);

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

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

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

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

		bool SetEquals(IEnumerable<T> other);

		bool IsProperSubsetOf(IEnumerable<T> other);

		bool IsProperSupersetOf(IEnumerable<T> other);

		bool IsSubsetOf(IEnumerable<T> other);

		bool IsSupersetOf(IEnumerable<T> other);

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

		IImmutableStack<T> Clear();

		IImmutableStack<T> Push(T value);

		IImmutableStack<T> Pop();

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

			private readonly IEqualityComparer<T> _valueComparer;

			internal static IEqualityComparer<HashBucket> DefaultInstance => s_defaultInstance;

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

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

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

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

			internal static IEqualityComparer<HashBucket> DefaultInstance => s_defaultInstance;

			private HashBucketByRefEqualityComparer()
			{
			}

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

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

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

			private IEqualityComparer<T> _equalityComparer;

			private readonly IEqualityComparer<HashBucket> _hashBucketEqualityComparer;

			private int _count;

			private ImmutableHashSet<T> _immutable;

			private int _version;

			public int Count => _count;

			bool ICollection<T>.IsReadOnly => false;

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

			internal int Version => _version;

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

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

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

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

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

			public bool TryGetValue(T equalValue, out T actualValue)
			{
				int key = ((equalValue != null) ? _equalityComparer.GetHashCode(equalValue) : 0);
				if (_root.TryGetValue(key, out var value))
				{
					return value.TryExchange(equalValue, _equalityComparer, out actualValue);
				}
				actualValue = equalValue;
				return false;
			}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			private SortedInt32KeyNode<HashBucket>.Enumerator _mapEnumerator;

			private HashBucket.Enumerator _bucketEnumerator;

			private int _enumeratingBuilderVersion;

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

			object? IEnumerator.Current => Current;

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

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

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

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

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

		internal enum OperationResult
		{
			SizeChanged,
			NoChangeRequired
		}

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

				private readonly HashBucket _bucket;

				private bool _disposed;

				private Position _currentPosition;

				private ImmutableList<T>.Enumerator _additionalEnumerator;

				object? IEnumerator.Current => Current;

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

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

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

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

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

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

			private readonly T _firstValue;

			private readonly ImmutableList<T>.Node _additionalElements;

			internal bool IsEmpty => _additionalElements == null;

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

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

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

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

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

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

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

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

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

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

			internal void Freeze()
			{
				_additionalElements?.Freeze();
			}
		}

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

			private readonly IEqualityComparer<T> _equalityComparer;

			private readonly int _count;

			private readonly IEqualityComparer<HashBucket> _hashBucketEqualityComparer;

			internal SortedInt32KeyNode<HashBucket> Root => _root;

			internal IEqualityComparer<T> EqualityComparer => _equalityComparer;

			internal int Count => _count;

			internal IEqualityComparer<HashBucket> HashBucketEqualityComparer => _hashBucketEqualityComparer;

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

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

		private enum CountType
		{
			Adjustment,
			FinalValue
		}

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

			private readonly int _count;

			private readonly CountType _countType;

			internal SortedInt32KeyNode<HashBucket> Root => _root;

			internal int Count => _count;

			internal CountType CountType => _countType;

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

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

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

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

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

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

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

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

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

		private readonly IEqualityComparer<T> _equalityComparer;

		private readonly int _count;

		private readonly SortedInt32KeyNode<HashBucket> _root;

		private readonly IEqualityComparer<HashBucket> _hashBucketEqualityComparer;

		public int Count => _count;

		public bool IsEmpty => Count == 0;

		public IEqualityComparer<T> KeyComparer => _equalityComparer;

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

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

		internal IBinaryTree Root => _root;

		private MutationInput Origin => new MutationInput(this);

		bool ICollection<T>.IsReadOnly => true;

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

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

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

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

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

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

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

		public bool TryGetValue(T equalValue, out T actualValue)
		{
			int key = ((equalValue != null) ? _equalityComparer.GetHashCode(equalValue) : 0);
			if (_root.TryGetValue(key, out var value))
			{
				return value.TryExchange(equalValue, _equalityComparer, out actualValue);
			}
			actualValue = equalValue;
			return false;
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		private static bool Contains(T item, MutationInput origin)
		{
			int key = ((item != null) ? origin.EqualityComparer.GetHashCode(item) : 0);
			if (origin.Root.TryGetValue(key, out var value))
			{
				return value.Contains(item, origin.EqualityComparer);
			}
			return false;
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public static ImmutableArray<T> Create<T>(ReadOnlySpan<T> items)
		{
			if (items.IsEmpty)
			{
				return ImmutableArray<T>.Empty;
			}
			T[] items2 = items.ToArray();
			return new ImmutableArray<T>(items2);
		}

		public static ImmutableArray<T> Create<T>(Span<T> items)
		{
			return Create((ReadOnlySpan<T>)items);
		}

		public static ImmutableArray<T> ToImmutableArray<T>(this ReadOnlySpan<T> items)
		{
			return Create(items);
		}

		public static ImmutableArray<T> ToImmutableArray<T>(this Span<T> items)
		{
			return Create((ReadOnlySpan<T>)items);
		}

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

		public static ImmutableArray<T> Create<T>(params T[]? items)
		{
			if (items == null || items.Length == 0)
			{
				return ImmutableArray<T>.Empty;
			}
			T[] array = new T[items.Length];
			Array.Copy(items, array, items.Length);
			return new ImmutableArray<T>(array);
		}

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

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

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

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

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

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

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

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

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

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

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

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

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

		public static int BinarySearch<T>(this ImmutableArray<T> array, int index, int length, T value, IComparer<T>? comparer)
		{
			return Array.BinarySearch(array.array, index, length, value, comparer);
		}
	}
	[DebuggerDisplay("{DebuggerDisplay,nq}")]
	[System.Runtime.Versioning.NonVersionable]
	public readonly struct ImmutableArray<T> : IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable, IList<T>, ICollection<T>, IEquatable<ImmutableArray<T>>, IList, ICollection, IImmutableArray, IStructuralComparable, IStructuralEquatable, IImmutableList<T>
	{
		[DebuggerDisplay("Count = {Count}")]
		[DebuggerTypeProxy(typeof(ImmutableArrayBuilderDebuggerProxy<>))]
		public sealed class Builder : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyList<T>, IReadOnlyCollection<T>
		{
			private T[] _elements;

			private int _count;

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

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

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

			bool ICollection<T>.IsReadOnly => false;

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

			internal Builder()
				: this(8)
			{
			}

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

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

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

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

			public void Clear()
			{
				Count = 0;
			}

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

			public void InsertRange(int index, IEnumerable<T> items)
			{
				Requires.Range(index >= 0 && index <= Count, "index");
				Requires.NotNull(items, "items");
				int count = ImmutableExtensions.GetCount(ref items);
				EnsureCapacity(Count + count);
				if (index != Count)
				{
					Array.Copy(_elements, index, _elements, index + count, _count - index);
				}
				if (!items.TryCopyTo(_elements, index))
				{
					foreach (T item in items)
					{
						_elements[index++] = item;
					}
				}
				_count += count;
			}

			public void InsertRange(int index, ImmutableArray<T> items)
			{
				Requires.Range(index >= 0 && index <= Count, "index");
				if (!items.IsEmpty)
				{
					EnsureCapacity(Count + items.Length);
					if (index != Count)
					{
						Array.Copy(_elements, index, _elements, index + items.Length, _count - index);
					}
					Array.Copy(items.array, 0, _elements, index, items.Length);
					_count += items.Length;
				}
			}

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

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

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

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

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

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

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

			public void AddRange(ReadOnlySpan<T> items)
			{
				int count = Count;
				Count += items.Length;
				items.CopyTo(new Span<T>(_elements, count, items.Length));
			}

			public void AddRange<TDerived>(ReadOnlySpan<TDerived> items) where TDerived : T
			{
				int count = Count;
				Count += items.Length;
				Span<T> span = new Span<T>(_elements, count, items.Length);
				for (int i = 0; i < items.Length; i++)
				{
					span[i] = (T)(object)items[i];
				}
			}

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

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

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

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

			public bool Remove(T element, IEqualityComparer<T>? equalityComparer)
			{
				int num = IndexOf(element, 0, _count, equalityComparer);
				if (num >= 0)
				{
					RemoveAt(num);
					return true;
				}
				return false;
			}

			public void RemoveAll(Predicate<T> match)
			{
				List<int> list = null;
				for (int i = 0; i < _count; i++)
				{
					if (match(_elements[i]))
					{
						if (list == null)
						{
							list = new List<int>();
						}
						list.Add(i);
					}
				}
				if (list != null)
				{
					RemoveAtRange(list);
				}
			}

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

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

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

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

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

			public void Replace(T oldValue, T newValue, IEqualityComparer<T>? equalityComparer)
			{
				int num = IndexOf(oldValue, 0, _count, equalityComparer);
				if (num >= 0)
				{
					_elements[num] = newValue;
				}
			}

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

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

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

			public void CopyTo(T[] destination)
			{
				Requires.NotNull(destination, "destination");
				Array.Copy(_elements, 0, destination, 0, Count);
			}

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

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

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

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

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

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

			public int IndexOf(T item, int startIndex, IEqualityComparer<T>? equalityComparer)
			{
				return IndexOf(item, startIndex, Count - startIndex, equalityComparer);
			}

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

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

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

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

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

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

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

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

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

			public void CopyTo(Span<T> destination)
			{
				Requires.Range(Count <= destination.Length, "destination");
				new ReadOnlySpan<T>(_elements, 0, Count).CopyTo(destination);
			}

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

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

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

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

			private void RemoveAtRange(ICollection<int> indicesToRemove)
			{
				Requires.NotNull(indicesToRemove, "indicesToRemove");
				if (indicesToRemove.Count == 0)
				{
					return;
				}
				int num = 0;
				int num2 = 0;
				int num3 = -1;
				foreach (int item in indicesToRemove)
				{
					int num4 = ((num3 == -1) ? item : (item - num3 - 1));
					Array.Copy(_elements, num + num2, _elements, num, num4);
					num2++;
					num += num4;
					num3 = item;
				}
				Array.Copy(_elements, num + num2, _elements, num, _elements.Length - (num + num2));
				_count -= indicesToRemove.Count;
			}
		}

		public struct Enumerator
		{
			private readonly T[] _array;

			private int _index;

			public T Current => _array[_index];

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

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

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

			private readonly T[] _array;

			private int _index;

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

			object IEnumerator.Current => Current;

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

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

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

			public void Dispose()
			{
			}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

		public ImmutableArray<T> InsertRange(int index, ImmutableArray<T> items)
		{
			ImmutableArray<T> result = this;
			result.ThrowNullRefIfNotInitialized();
			items.ThrowNullRefIfNotInitialized();
			Requires.Range(index >= 0 && index <= result.Length, "index");
			if (result.IsEmpty)
			{
				return items;
			}
			if (items.IsEmpty)
			{
				return result;
			}
			return result.InsertSpanRangeInternal(index, items.AsSpan());
		}

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

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

		public ImmutableArray<T> AddRange(T[] items, int length)
		{
			ImmutableArray<T> result = this;
			result.ThrowNullRefIfNotInitialized();
			Requires.NotNull(items, "items");
			Requires.Range(length >= 0 && length <= items.Length, "length");
			if (items.Length == 0 || length == 0)
			{
				return result;
			}
			if (result.IsEmpty)
			{
				return ImmutableArray.Create(items, 0, length);
			}
			T[] array = new T[result.Length + length];
			Array.Copy(result.array, array, result.Length);
			Array.Copy(items, 0, array, result.Length, length);
			return new ImmutableArray<T>(array);
		}

		public ImmutableArray<T> AddRange<TDerived>(TDerived[] items) where TDerived : T
		{
			ImmutableArray<T> result = this;
			result.ThrowNullRefIfNotInitialized();
			Requires.NotNull(items, "items");
			if (items.Length == 0)
			{
				return result;
			}
			T[] array = new T[result.Length + items.Length];
			Array.Copy(result.array, array, result.Length);
			Array.Copy(items, 0, array, result.Length, items.Length);
			return new ImmutableArray<T>(array);
		}

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

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

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

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

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

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

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

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

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

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

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

		public ImmutableArray<T> RemoveRange(IEnumerable<T> items, IEqualityComparer<T>? equalityComparer)
		{
			ImmutableArray<T> immutableArray = this;
			immutableArray.ThrowNullRefIfNotInitialized();
			Requires.NotNull(items, "items");
			SortedSet<int> sortedSet = new SortedSet<int>();
			foreach (T item in items)
			{
				int num = -1;
				do
				{
					num = immutableArray.IndexOf(item, num + 1, equalityComparer);
				}
				while (nu