diff --git a/nanoFramework.CoreLibrary/CoreLibrary.nfproj b/nanoFramework.CoreLibrary/CoreLibrary.nfproj
index cf5e473..e150172 100644
--- a/nanoFramework.CoreLibrary/CoreLibrary.nfproj
+++ b/nanoFramework.CoreLibrary/CoreLibrary.nfproj
@@ -38,7 +38,7 @@
$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdbtruetrue
- default
+ 13.0true
@@ -66,10 +66,12 @@
+
-
+
+
@@ -260,4 +262,4 @@
-
\ No newline at end of file
+
diff --git a/nanoFramework.CoreLibrary/System/Array.Enumerators.cs b/nanoFramework.CoreLibrary/System/Array.Enumerators.cs
new file mode 100644
index 0000000..532e448
--- /dev/null
+++ b/nanoFramework.CoreLibrary/System/Array.Enumerators.cs
@@ -0,0 +1,101 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+#nullable enable
+
+namespace System
+{
+ internal abstract class SZGenericArrayEnumeratorBase : IDisposable
+ {
+ protected int _index;
+ protected readonly int _endIndex;
+
+ protected SZGenericArrayEnumeratorBase(int endIndex)
+ {
+ _index = -1;
+ _endIndex = endIndex;
+ }
+
+ public bool MoveNext()
+ {
+ int index = _index + 1;
+
+ if ((uint)index < (uint)_endIndex)
+ {
+ _index = index;
+
+ return true;
+ }
+
+ _index = _endIndex;
+
+ return false;
+ }
+
+ public void Reset() => _index = -1;
+
+ public void Dispose()
+ {
+ }
+ }
+
+ internal sealed class SZGenericArrayEnumerator : SZGenericArrayEnumeratorBase, IEnumerator
+ {
+ private readonly T[]? _array;
+
+ /// Provides an empty enumerator singleton.
+ ///
+ /// If the consumer is using SZGenericArrayEnumerator elsewhere or is otherwise likely
+ /// to be using T[] elsewhere, this singleton should be used. Otherwise, GenericEmptyEnumerator's
+ /// singleton should be used instead, as it doesn't reference T[] in order to reduce footprint.
+ ///
+ internal static readonly SZGenericArrayEnumerator Empty = new SZGenericArrayEnumerator(null, 0);
+
+ internal SZGenericArrayEnumerator(T[]? array, int endIndex)
+ : base(endIndex)
+ {
+ Debug.Assert(array == null || endIndex == array.Length);
+ _array = array;
+ }
+
+ public T Current
+ {
+ get
+ {
+ if ((uint)_index >= (uint)_endIndex)
+ {
+ throw new InvalidOperationException();
+ }
+
+ return _array![_index];
+ }
+ }
+
+ object? IEnumerator.Current => Current;
+ }
+
+ internal abstract class GenericEmptyEnumeratorBase : IDisposable, IEnumerator
+ {
+#pragma warning disable CA1822 // https://github.com/dotnet/roslyn-analyzers/issues/5911
+ public bool MoveNext() => false;
+
+ public object Current
+ {
+ get
+ {
+ return default;
+ }
+ }
+
+ public void Reset() { }
+
+ public void Dispose() { }
+#pragma warning restore CA1822
+ }
+}
diff --git a/nanoFramework.CoreLibrary/System/Collections/Generic/Comparer.cs b/nanoFramework.CoreLibrary/System/Collections/Generic/Comparer.cs
index ff05153..309edfb 100644
--- a/nanoFramework.CoreLibrary/System/Collections/Generic/Comparer.cs
+++ b/nanoFramework.CoreLibrary/System/Collections/Generic/Comparer.cs
@@ -1,129 +1,183 @@
-//// Licensed to the .NET Foundation under one or more agreements.
-//// The .NET Foundation licenses this file to you under the MIT license.
-
-//using System.Diagnostics.CodeAnalysis;
-//using System.Runtime.CompilerServices;
-
-//namespace System.Collections.Generic
-//{
-// [Serializable]
-// public abstract partial class Comparer : IComparer, IComparer
-// {
-// // public static Comparer Default is runtime-specific
-
-// //public static Comparer Create(Comparison comparison)
-// //{
-// // ArgumentNullException.ThrowIfNull(comparison);
-
-// // return new ComparisonComparer(comparison);
-// //}
-
-// public abstract int Compare(T? x, T? y);
-
-// int IComparer.Compare(object? x, object? y)
-// {
-// if (x == null) return y == null ? 0 : -1;
-// if (y == null) return 1;
-// if (x is T && y is T) return Compare((T)x, (T)y);
-
-// throw new ArgumentException();
-// }
-// }
-
-// internal sealed class ComparisonComparer : Comparer
-// {
-// //private readonly Comparison _comparison;
-
-// //public ComparisonComparer(Comparison comparison)
-// //{
-// // _comparison = comparison;
-// //}
-
-// public override int Compare(T? x, T? y) => _comparison(x!, y!);
-// }
-
-// // Note: although there is a lot of shared code in the following
-// // comparers, we do not incorporate it into a base class for perf
-// // reasons. Adding another base class (even one with no fields)
-// // means another generic instantiation, which can be costly esp.
-// // for value types.
-// [Serializable]
-// // Needs to be public to support binary serialization compatibility
-// public sealed partial class GenericComparer : Comparer where T : IComparable?
-// {
-// public override int Compare(T? x, T? y)
-// {
-// if (x != null)
-// {
-// if (y != null) return x.CompareTo(y);
-// return 1;
-// }
-// if (y != null) return -1;
-// return 0;
-// }
-
-// // Equals method for the comparer itself.
-// public override bool Equals([NotNullWhen(true)] object? obj) =>
-// obj != null && GetType() == obj.GetType();
-
-// public override int GetHashCode() =>
-// GetType().GetHashCode();
-// }
-
-// [Serializable]
-// // Needs to be public to support binary serialization compatibility
-// public sealed class NullableComparer : Comparer
-// {
-// public NullableComparer() { }
-
-// public override int Compare(T? x, T? y)
-// {
-// if (x.HasValue)
-// {
-// if (y.HasValue) return Comparer.Default.Compare(x.value, y.value);
-// return 1;
-// }
-// if (y.HasValue) return -1;
-// return 0;
-// }
-
-// // Equals method for the comparer itself.
-// public override bool Equals([NotNullWhen(true)] object? obj) =>
-// obj != null && GetType() == obj.GetType();
-
-// public override int GetHashCode() =>
-// GetType().GetHashCode();
-// }
-
-// [Serializable]
-// // Needs to be public to support binary serialization compatibility
-// public sealed partial class ObjectComparer : Comparer
-// {
-// public override int Compare(T? x, T? y)
-// {
-// return Comparer.Default.Compare(x, y);
-// }
-
-// // Equals method for the comparer itself.
-// public override bool Equals([NotNullWhen(true)] object? obj) =>
-// obj != null && GetType() == obj.GetType();
-
-// public override int GetHashCode() =>
-// GetType().GetHashCode();
-// }
-
-// [Serializable]
-// internal sealed partial class EnumComparer : Comparer
-// {
-// public EnumComparer() { }
-
-// // public override int Compare(T x, T y) is runtime-specific
-
-// // Equals method for the comparer itself.
-// public override bool Equals([NotNullWhen(true)] object? obj) =>
-// obj != null && GetType() == obj.GetType();
-
-// public override int GetHashCode() =>
-// GetType().GetHashCode();
-// }
-//}
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+
+#nullable enable
+
+namespace System.Collections.Generic
+{
+ /////
+ ///// Provides a base class for implementations of the IComparer{T} generic interface.
+ /////
+ ///// The type of objects to compare.
+ //[Serializable]
+ //public abstract partial class Comparer : IComparer, IComparer
+ //{
+ // protected Comparer()
+ // {
+
+ // }
+ // //public static Comparer Create(Comparison comparison)
+ // //{
+ // // ArgumentNullException.ThrowIfNull(comparison);
+
+ // // return new ComparisonComparer(comparison);
+ // //}
+
+ // ///
+ // /// Returns a default sort-order comparer for the type specified by the generic argument.
+ // ///
+ // ///
+ // /// An object that inherits {T} and serves as a sort-order comparer for type {T}.
+ // ///
+ // public static extern Comparer Default
+ // {
+ // [MethodImpl(MethodImplOptions.InternalCall)]
+ // get;
+ // }
+
+ // public abstract int Compare(T? x, T? y);
+
+ // int IComparer.Compare(object? x, object? y)
+ // {
+ // if (x == null)
+ // {
+ // return y == null ? 0 : -1;
+ // }
+
+ // if (y == null)
+ // {
+ // return 1;
+ // }
+
+ // if (x is T && y is T)
+ // {
+ // return Compare((T)x, (T)y);
+ // }
+
+ // throw new ArgumentException();
+ // }
+ //}
+
+ //internal sealed class ComparisonComparer : Comparer
+ //{
+ // private readonly Comparison _comparison;
+
+ // public ComparisonComparer(Comparison comparison)
+ // {
+ // _comparison = comparison;
+ // }
+
+ // public override int Compare(T? x, T? y) => _comparison(x!, y!);
+ //}
+
+ // Note: although there is a lot of shared code in the following
+ // comparers, we do not incorporate it into a base class for perf
+ // reasons. Adding another base class (even one with no fields)
+ // means another generic instantiation, which can be costly esp.
+ // for value types.
+ //[Serializable]
+ // Needs to be public to support binary serialization compatibility
+ //public sealed partial class GenericComparer : Comparer where T : IComparable?
+ //{
+ // public override int Compare(T? x, T? y)
+ // {
+ // if (x != null)
+ // {
+ // if (y != null)
+ // {
+ // return x.CompareTo(y);
+ // }
+
+ // return 1;
+ // }
+ // if (y != null)
+ // {
+ // return -1;
+ // }
+
+ // return 0;
+ // }
+
+ // // Equals method for the comparer itself.
+ // public override bool Equals([NotNullWhen(true)] object? obj) =>
+ // obj != null && GetType() == obj.GetType();
+
+ // public override int GetHashCode() =>
+ // GetType().GetHashCode();
+ //}
+
+ /////
+ /////
+ /////
+ /////
+ //[Serializable]
+ //public sealed class NullableComparer : Comparer where T : struct
+ //{
+ // public NullableComparer() { }
+
+ // public override int Compare(T? x, T? y)
+ // {
+ // if (x.HasValue)
+ // {
+ // if (y.HasValue)
+ // {
+ // return Comparer.Default.Compare(x.value, y.value);
+ // }
+
+ // return 1;
+ // }
+
+ // if (y.HasValue)
+ // {
+ // return -1;
+ // }
+
+ // return 0;
+ // }
+
+ // // Equals method for the comparer itself.
+ // public override bool Equals([NotNullWhen(true)] object? obj) =>
+ // obj != null && GetType() == obj.GetType();
+
+ // public override int GetHashCode() =>
+ // GetType().GetHashCode();
+ //}
+
+ //[Serializable]
+ //public sealed partial class ObjectComparer : Comparer
+ //{
+ // public override int Compare(T? x, T? y)
+ // {
+ // return Default.Compare(x, y);
+ // }
+
+ // // Equals method for the comparer itself.
+ // public override bool Equals([NotNullWhen(true)] object? obj) =>
+ // obj != null && GetType() == obj.GetType();
+
+ // public override int GetHashCode() =>
+ // GetType().GetHashCode();
+ //}
+
+ //[Serializable]
+ //internal sealed partial class EnumComparer : Comparer where T : struct, Enum
+ //{
+ // public EnumComparer() { }
+
+ // public override int Compare(T x, T y)
+ // {
+ // // TODO: native?
+ // throw new NotImplementedException();
+ // }
+
+ // // Equals method for the comparer itself.
+ // public override bool Equals([NotNullWhen(true)] object? obj) =>
+ // obj != null && GetType() == obj.GetType();
+
+ // public override int GetHashCode() =>
+ // GetType().GetHashCode();
+ //}
+}
diff --git a/nanoFramework.CoreLibrary/System/Collections/Generic/ComparerHelpers.cs b/nanoFramework.CoreLibrary/System/Collections/Generic/ComparerHelpers.cs
deleted file mode 100644
index a4fcece..0000000
--- a/nanoFramework.CoreLibrary/System/Collections/Generic/ComparerHelpers.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-//// Licensed to the .NET Foundation under one or more agreements.
-//// The .NET Foundation licenses this file to you under the MIT license.
-
-//using System.Diagnostics;
-//using static System.RuntimeTypeHandle;
-
-//namespace System.Collections.Generic
-//{
-// ///
-// /// Helper class for creating the default and .
-// ///
-// ///
-// /// This class is intentionally type-unsafe and non-generic to minimize the generic instantiation overhead of creating
-// /// the default comparer/equality comparer for a new type parameter. Efficiency of the methods in here does not matter too
-// /// much since they will only be run once per type parameter, but generic code involved in creating the comparers needs to be
-// /// kept to a minimum.
-// ///
-// internal static class ComparerHelpers
-// {
-// ///
-// /// Creates the default .
-// ///
-// /// The type to create the default comparer for.
-// ///
-// /// The logic in this method is replicated in vm/compile.cpp to ensure that NGen saves the right instantiations,
-// /// and in vm/jitinterface.cpp so the jit can model the behavior of this method.
-// ///
-// internal static object CreateDefaultComparer(Type type)
-// {
-// Debug.Assert(type != null && type is RuntimeType);
-
-// object? result = null;
-// var runtimeType = (RuntimeType)type;
-
-// // If T implements IComparable return a GenericComparer
-// if (typeof(IComparable<>).MakeGenericType(type).IsAssignableFrom(type))
-// {
-// result = CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer), runtimeType);
-// }
-// else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
-// {
-// // Nullable does not implement IComparable directly because that would add an extra interface call per comparison.
-// var embeddedType = (RuntimeType)type.GetGenericArguments()[0];
-// result = CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer), embeddedType);
-// }
-// // The comparer for enums is specialized to avoid boxing.
-// else if (type.IsEnum)
-// {
-// result = CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumComparer<>), runtimeType);
-// }
-
-// return result ?? CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ObjectComparer