using Lucene.Net.Diagnostics;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace Lucene.Net.Util
{
    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements.  See the NOTICE file distributed with
     * this work for additional information regarding copyright ownership.
     * The ASF licenses this file to You under the Apache License, Version 2.0
     * (the "License"); you may not use this file except in compliance with
     * the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */

    /// <summary>
    /// Methods for manipulating arrays.
    /// <para/>
    /// @lucene.internal
    /// </summary>
    public static class ArrayUtil // LUCENENET specific - made static
    {
        /// <summary>
        /// Maximum length for an array; we set this to "a
        /// bit" below <see cref="int.MaxValue"/> because the exact max
        /// allowed byte[] is JVM dependent, so we want to avoid
        /// a case where a large value worked during indexing on
        /// one JVM but failed later at search time with a
        /// different JVM.
        /// </summary>
        public static readonly int MAX_ARRAY_LENGTH = int.MaxValue - 256;

        /*
           Begin Apache Harmony code

           Revision taken on Friday, June 12. https://svn.apache.org/repos/asf/harmony/enhanced/classlib/archive/java6/modules/luni/src/main/java/java/lang/Integer.java

         */

        /// <summary>
        /// Parses the string argument as if it was an <see cref="int"/> value and returns the
        /// result. Throws <see cref="FormatException"/> if the string does not represent an
        /// int quantity.
        /// <para/>
        /// NOTE: This was parseInt() in Lucene
        /// </summary>
        /// <param name="chars"> A string representation of an int quantity. </param>
        /// <returns> The value represented by the argument </returns>
        /// <exception cref="FormatException"> If the argument could not be parsed as an int quantity. </exception>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static int ParseInt32(char[] chars)
        {
            return ParseInt32(chars, 0, chars.Length, 10);
        }

        /// <summary>
        /// Parses a char array into an <see cref="int"/>. 
        /// <para/>
        /// NOTE: This was parseInt() in Lucene
        /// </summary>
        /// <param name="chars"> The character array </param>
        /// <param name="offset"> The offset into the array </param>
        /// <param name="len"> The length </param>
        /// <returns> the <see cref="int"/> </returns>
        /// <exception cref="FormatException"> If it can't parse </exception>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static int ParseInt32(char[] chars, int offset, int len)
        {
            return ParseInt32(chars, offset, len, 10);
        }

        /// <summary>
        /// Parses the string argument as if it was an <see cref="int"/> value and returns the
        /// result. Throws <see cref="FormatException"/> if the string does not represent an
        /// <see cref="int"/> quantity. The second argument specifies the radix to use when parsing
        /// the value.
        /// <para/>
        /// NOTE: This was parseInt() in Lucene
        /// </summary>
        /// <param name="chars"> A string representation of an int quantity. </param>
        /// <param name="radix"> The base to use for conversion. </param>
        /// <returns> The value represented by the argument </returns>
        /// <exception cref="FormatException"> If the argument could not be parsed as an int quantity. </exception>
        public static int ParseInt32(char[] chars, int offset, int len, int radix)
        {
            int minRadix = 2, maxRadix = 36;
            if (chars == null || radix < minRadix || radix > maxRadix)
            {
                throw new FormatException();
            }
            int i = 0;
            if (len == 0)
            {
                throw new FormatException("chars length is 0");
            }
            bool negative = chars[offset + i] == '-';
            if (negative && ++i == len)
            {
                throw new FormatException("can't convert to an int");
            }
            if (negative == true)
            {
                offset++;
                len--;
            }
            return Parse(chars, offset, len, radix, negative);
        }

        private static int Parse(char[] chars, int offset, int len, int radix, bool negative)
        {
            int max = int.MinValue / radix;
            int result = 0;
            for (int i = 0; i < len; i++)
            {
                int digit = (int)char.GetNumericValue(chars[i + offset]);
                if (digit == -1)
                {
                    throw new FormatException("Unable to parse");
                }
                if (max > result)
                {
                    throw new FormatException("Unable to parse");
                }
                int next = result * radix - digit;
                if (next > result)
                {
                    throw new FormatException("Unable to parse");
                }
                result = next;
            }
            /*while (offset < len) {
            }*/
            if (!negative)
            {
                result = -result;
                if (result < 0)
                {
                    throw new FormatException("Unable to parse");
                }
            }
            return result;
        }

        /*

       END APACHE HARMONY CODE
        */

        /// <summary>
        /// Returns an array size &gt;= <paramref name="minTargetSize"/>, generally
        /// over-allocating exponentially to achieve amortized
        /// linear-time cost as the array grows.
        /// <para/>
        /// NOTE: this was originally borrowed from Python 2.4.2
        /// listobject.c sources (attribution in LICENSE.txt), but
        /// has now been substantially changed based on
        /// discussions from java-dev thread with subject "Dynamic
        /// array reallocation algorithms", started on Jan 12
        /// 2010.
        /// <para/>
        /// @lucene.internal
        /// </summary>
        /// <param name="minTargetSize"> Minimum required value to be returned. </param>
        /// <param name="bytesPerElement"> Bytes used by each element of
        /// the array.  See constants in <see cref="RamUsageEstimator"/>. </param>
        public static int Oversize(int minTargetSize, int bytesPerElement)
        {
            if (minTargetSize < 0)
            {
                // catch usage that accidentally overflows int
                throw new ArgumentException("invalid array size " + minTargetSize);
            }

            if (minTargetSize == 0)
            {
                // wait until at least one element is requested
                return 0;
            }

            // asymptotic exponential growth by 1/8th, favors
            // spending a bit more CPU to not tie up too much wasted
            // RAM:
            int extra = minTargetSize >> 3;

            if (extra < 3)
            {
                // for very small arrays, where constant overhead of
                // realloc is presumably relatively high, we grow
                // faster
                extra = 3;
            }

            int newSize = minTargetSize + extra;

            // add 7 to allow for worst case byte alignment addition below:
            if (newSize + 7 < 0)
            {
                // int overflowed -- return max allowed array size
                return int.MaxValue;
            }

            if (Constants.RUNTIME_IS_64BIT)
            {
                // round up to 8 byte alignment in 64bit env
                switch (bytesPerElement)
                {
                    case 4:
                        // round up to multiple of 2
                        return (newSize + 1) & 0x7ffffffe;

                    case 2:
                        // round up to multiple of 4
                        return (newSize + 3) & 0x7ffffffc;

                    case 1:
                        // round up to multiple of 8
                        return (newSize + 7) & 0x7ffffff8;

                    case 8:
                    // no rounding
                    default:
                        // odd (invalid?) size
                        return newSize;
                }
            }
            else
            {
                // round up to 4 byte alignment in 64bit env
                switch (bytesPerElement)
                {
                    case 2:
                        // round up to multiple of 2
                        return (newSize + 1) & 0x7ffffffe;

                    case 1:
                        // round up to multiple of 4
                        return (newSize + 3) & 0x7ffffffc;

                    case 4:
                    case 8:
                    // no rounding
                    default:
                        // odd (invalid?) size
                        return newSize;
                }
            }
        }

        public static int GetShrinkSize(int currentSize, int targetSize, int bytesPerElement)
        {
            int newSize = Oversize(targetSize, bytesPerElement);
            // Only reallocate if we are "substantially" smaller.
            // this saves us from "running hot" (constantly making a
            // bit bigger then a bit smaller, over and over):
            if (newSize < currentSize / 2)
            {
                return newSize;
            }
            else
            {
                return currentSize;
            }
        }

        public static short[] Grow(short[] array, int minSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(minSize >= 0, "size must be positive (got {0}): likely integer overflow?", minSize);
            if (array.Length < minSize)
            {
                short[] newArray = new short[Oversize(minSize, RamUsageEstimator.NUM_BYTES_INT16)];
                Array.Copy(array, 0, newArray, 0, array.Length);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static short[] Grow(short[] array)
        {
            return Grow(array, 1 + array.Length);
        }

        public static float[] Grow(float[] array, int minSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(minSize >= 0, "size must be positive (got " + minSize + "): likely integer overflow?");
            if (array.Length < minSize)
            {
                float[] newArray = new float[Oversize(minSize, RamUsageEstimator.NUM_BYTES_SINGLE)];
                Array.Copy(array, 0, newArray, 0, array.Length);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static float[] Grow(float[] array)
        {
            return Grow(array, 1 + array.Length);
        }

        public static double[] Grow(double[] array, int minSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(minSize >= 0, "size must be positive (got {0}): likely integer overflow?", minSize);
            if (array.Length < minSize)
            {
                double[] newArray = new double[Oversize(minSize, RamUsageEstimator.NUM_BYTES_DOUBLE)];
                Array.Copy(array, 0, newArray, 0, array.Length);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static double[] Grow(double[] array)
        {
            return Grow(array, 1 + array.Length);
        }

        public static short[] Shrink(short[] array, int targetSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(targetSize >= 0, "size must be positive (got {0}): likely integer overflow?", targetSize);
            int newSize = GetShrinkSize(array.Length, targetSize, RamUsageEstimator.NUM_BYTES_INT16);
            if (newSize != array.Length)
            {
                short[] newArray = new short[newSize];
                Array.Copy(array, 0, newArray, 0, newSize);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        public static int[] Grow(int[] array, int minSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(minSize >= 0, "size must be positive (got {0}): likely integer overflow?" , minSize);
            if (array.Length < minSize)
            {
                int[] newArray = new int[Oversize(minSize, RamUsageEstimator.NUM_BYTES_INT32)];
                Array.Copy(array, 0, newArray, 0, array.Length);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static int[] Grow(int[] array)
        {
            return Grow(array, 1 + array.Length);
        }

        public static int[] Shrink(int[] array, int targetSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(targetSize >= 0, "size must be positive (got {0}): likely integer overflow?", targetSize);
            int newSize = GetShrinkSize(array.Length, targetSize, RamUsageEstimator.NUM_BYTES_INT32);
            if (newSize != array.Length)
            {
                int[] newArray = new int[newSize];
                Array.Copy(array, 0, newArray, 0, newSize);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        public static long[] Grow(long[] array, int minSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(minSize >= 0, "size must be positive (got {0}): likely integer overflow?", minSize);
            if (array.Length < minSize)
            {
                long[] newArray = new long[Oversize(minSize, RamUsageEstimator.NUM_BYTES_INT64)];
                Array.Copy(array, 0, newArray, 0, array.Length);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static long[] Grow(long[] array)
        {
            return Grow(array, 1 + array.Length);
        }

        public static long[] Shrink(long[] array, int targetSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(targetSize >= 0, "size must be positive (got {0}): likely integer overflow?", targetSize);
            int newSize = GetShrinkSize(array.Length, targetSize, RamUsageEstimator.NUM_BYTES_INT64);
            if (newSize != array.Length)
            {
                long[] newArray = new long[newSize];
                Array.Copy(array, 0, newArray, 0, newSize);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [CLSCompliant(false)]
        public static sbyte[] Grow(sbyte[] array, int minSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(minSize >= 0, "size must be positive (got {0}): likely integer overflow?", minSize);
            if (array.Length < minSize)
            {
                var newArray = new sbyte[Oversize(minSize, 1)];
                Array.Copy(array, 0, newArray, 0, array.Length);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        public static byte[] Grow(byte[] array, int minSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(minSize >= 0, "size must be positive (got {0}): likely integer overflow?", minSize);
            if (array.Length < minSize)
            {
                byte[] newArray = new byte[Oversize(minSize, 1)];
                Array.Copy(array, 0, newArray, 0, array.Length);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static byte[] Grow(byte[] array)
        {
            return Grow(array, 1 + array.Length);
        }

        public static byte[] Shrink(byte[] array, int targetSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(targetSize >= 0, "size must be positive (got {0}): likely integer overflow?", targetSize);
            int newSize = GetShrinkSize(array.Length, targetSize, 1);
            if (newSize != array.Length)
            {
                var newArray = new byte[newSize];
                Array.Copy(array, 0, newArray, 0, newSize);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        public static bool[] Grow(bool[] array, int minSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(minSize >= 0, "size must be positive (got {0}): likely integer overflow?", minSize);
            if (array.Length < minSize)
            {
                bool[] newArray = new bool[Oversize(minSize, 1)];
                Array.Copy(array, 0, newArray, 0, array.Length);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool[] Grow(bool[] array)
        {
            return Grow(array, 1 + array.Length);
        }

        public static bool[] Shrink(bool[] array, int targetSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(targetSize >= 0, "size must be positive (got {0}): likely integer overflow?", targetSize);
            int newSize = GetShrinkSize(array.Length, targetSize, 1);
            if (newSize != array.Length)
            {
                bool[] newArray = new bool[newSize];
                Array.Copy(array, 0, newArray, 0, newSize);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        public static char[] Grow(char[] array, int minSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(minSize >= 0, "size must be positive (got {0}): likely integer overflow?", minSize);
            if (array.Length < minSize)
            {
                char[] newArray = new char[Oversize(minSize, RamUsageEstimator.NUM_BYTES_CHAR)];
                Array.Copy(array, 0, newArray, 0, array.Length);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static char[] Grow(char[] array)
        {
            return Grow(array, 1 + array.Length);
        }

        public static char[] Shrink(char[] array, int targetSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(targetSize >= 0, "size must be positive (got {0}): likely integer overflow?", targetSize);
            int newSize = GetShrinkSize(array.Length, targetSize, RamUsageEstimator.NUM_BYTES_CHAR);
            if (newSize != array.Length)
            {
                char[] newArray = new char[newSize];
                Array.Copy(array, 0, newArray, 0, newSize);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [CLSCompliant(false)]
        public static int[][] Grow(int[][] array, int minSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(minSize >= 0, "size must be positive (got {0}): likely integer overflow?", minSize);
            if (array.Length < minSize)
            {
                var newArray = new int[Oversize(minSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF)][];
                Array.Copy(array, 0, newArray, 0, array.Length);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [CLSCompliant(false)]
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static int[][] Grow(int[][] array)
        {
            return Grow(array, 1 + array.Length);
        }

        [CLSCompliant(false)]
        public static int[][] Shrink(int[][] array, int targetSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(targetSize >= 0, "size must be positive (got {0}): likely integer overflow?", targetSize);
            int newSize = GetShrinkSize(array.Length, targetSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF);
            if (newSize != array.Length)
            {
                int[][] newArray = new int[newSize][];
                Array.Copy(array, 0, newArray, 0, newSize);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [CLSCompliant(false)]
        public static float[][] Grow(float[][] array, int minSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(minSize >= 0, "size must be positive (got {0}): likely integer overflow?", minSize);
            if (array.Length < minSize)
            {
                float[][] newArray = new float[Oversize(minSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF)][];
                Array.Copy(array, 0, newArray, 0, array.Length);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        [CLSCompliant(false)]
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static float[][] Grow(float[][] array)
        {
            return Grow(array, 1 + array.Length);
        }

        [CLSCompliant(false)]
        public static float[][] Shrink(float[][] array, int targetSize)
        {
            if (Debugging.AssertsEnabled) Debugging.Assert(targetSize >= 0, "size must be positive (got {0}): likely integer overflow?", targetSize);
            int newSize = GetShrinkSize(array.Length, targetSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF);
            if (newSize != array.Length)
            {
                float[][] newArray = new float[newSize][];
                Array.Copy(array, 0, newArray, 0, newSize);
                return newArray;
            }
            else
            {
                return array;
            }
        }

        /// <summary>
        /// Returns hash of chars in range start (inclusive) to
        /// end (inclusive)
        /// </summary>
        public static int GetHashCode(char[] array, int start, int end)
        {
            int code = 0;
            for (int i = end - 1; i >= start; i--)
            {
                code = code * 31 + array[i];
            }
            return code;
        }

        /// <summary>
        /// Returns hash of bytes in range start (inclusive) to
        /// end (inclusive)
        /// </summary>
        public static int GetHashCode(byte[] array, int start, int end)
        {
            int code = 0;
            for (int i = end - 1; i >= start; i--)
            {
                code = code * 31 + array[i];
            }
            return code;
        }

        // Since Arrays.equals doesn't implement offsets for equals
        /// <summary>
        /// See if two array slices are the same.
        /// </summary>
        /// <param name="left">        The left array to compare </param>
        /// <param name="offsetLeft">  The offset into the array.  Must be positive </param>
        /// <param name="right">       The right array to compare </param>
        /// <param name="offsetRight"> the offset into the right array.  Must be positive </param>
        /// <param name="length">      The length of the section of the array to compare </param>
        /// <returns> <c>true</c> if the two arrays, starting at their respective offsets, are equal
        /// </returns>
        /// <seealso cref="Support.Arrays.Equals{T}(T[], T[])"/>
        public static bool Equals(char[] left, int offsetLeft, char[] right, int offsetRight, int length)
        {
            if ((offsetLeft + length <= left.Length) && (offsetRight + length <= right.Length))
            {
                for (int i = 0; i < length; i++)
                {
                    if (left[offsetLeft + i] != right[offsetRight + i])
                    {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }

        // Since Arrays.equals doesn't implement offsets for equals
        /// <summary>
        /// See if two array slices are the same.
        /// </summary>
        /// <param name="left">        The left array to compare </param>
        /// <param name="offsetLeft">  The offset into the array.  Must be positive </param>
        /// <param name="right">       The right array to compare </param>
        /// <param name="offsetRight"> the offset into the right array.  Must be positive </param>
        /// <param name="length">      The length of the section of the array to compare </param>
        /// <returns> <c>true</c> if the two arrays, starting at their respective offsets, are equal
        /// </returns>
        /// <seealso cref="Support.Arrays.Equals{T}(T[], T[])"/>
        public static bool Equals(byte[] left, int offsetLeft, byte[] right, int offsetRight, int length)
        {
            if ((offsetLeft + length <= left.Length) && (offsetRight + length <= right.Length))
            {
                for (int i = 0; i < length; i++)
                {
                    if (left[offsetLeft + i] != right[offsetRight + i])
                    {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }

        /* DISABLE this FOR NOW: this has performance problems until Java creates intrinsics for Class#getComponentType() and Array.newInstance()
        public static <T> T[] grow(T[] array, int minSize) {
          assert minSize >= 0: "size must be positive (got " + minSize + "): likely integer overflow?";
          if (array.length < minSize) {
            @SuppressWarnings("unchecked") final T[] newArray =
              (T[]) Array.newInstance(array.getClass().getComponentType(), oversize(minSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF));
            System.arraycopy(array, 0, newArray, 0, array.length);
            return newArray;
          } else
            return array;
        }

        public static <T> T[] grow(T[] array) {
          return grow(array, 1 + array.length);
        }

        public static <T> T[] shrink(T[] array, int targetSize) {
          assert targetSize >= 0: "size must be positive (got " + targetSize + "): likely integer overflow?";
          final int newSize = getShrinkSize(array.length, targetSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF);
          if (newSize != array.length) {
            @SuppressWarnings("unchecked") final T[] newArray =
              (T[]) Array.newInstance(array.getClass().getComponentType(), newSize);
            System.arraycopy(array, 0, newArray, 0, newSize);
            return newArray;
          } else
            return array;
        }
        */

        // Since Arrays.equals doesn't implement offsets for equals
        /// <summary>
        /// See if two array slices are the same.
        /// </summary>
        /// <param name="left">        The left array to compare </param>
        /// <param name="offsetLeft">  The offset into the array.  Must be positive </param>
        /// <param name="right">       The right array to compare </param>
        /// <param name="offsetRight"> the offset into the right array.  Must be positive </param>
        /// <param name="length">      The length of the section of the array to compare </param>
        /// <returns> <c>true</c> if the two arrays, starting at their respective offsets, are equal
        /// </returns>
        /// <seealso cref="Support.Arrays.Equals{T}(T[], T[])"/>
        public static bool Equals(int[] left, int offsetLeft, int[] right, int offsetRight, int length)
        {
            if ((offsetLeft + length <= left.Length) && (offsetRight + length <= right.Length))
            {
                for (int i = 0; i < length; i++)
                {
                    if (left[offsetLeft + i] != right[offsetRight + i])
                    {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }

        /// <summary>
        /// NOTE: This was toIntArray() in Lucene
        /// </summary>
        public static int[] ToInt32Array(ICollection<int?> ints)
        {
            int[] result = new int[ints.Count];
            int upto = 0;
            foreach (int? v in ints)
            {
                if (v.HasValue)
                {
                    result[upto++] = v.Value;
                }
                else
                {
                    throw new NullReferenceException(); // LUCENENET NOTE: This is the same behavior you get in Java when setting int = Integer and the integer is null.
                }
            }

            // paranoia:
            if (Debugging.AssertsEnabled) Debugging.Assert(upto == result.Length);

            return result;
        }

        // LUCENENET specific - we don't have an IComparable<T> constraint -
        // the logic of GetNaturalComparer<T> handles that so we just
        // do a cast here.
#if FEATURE_SERIALIZABLE
        [Serializable]
#endif
        private class NaturalComparer<T> : IComparer<T> //where T : IComparable<T>
        {
            private NaturalComparer()
            {
            }

            public static NaturalComparer<T> Default { get; } = new NaturalComparer<T>();

            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            public virtual int Compare(T o1, T o2)
            {
                return ((IComparable<T>)o1).CompareTo(o2);
            }
        }

        /// <summary>
        /// Get the natural <see cref="IComparer{T}"/> for the provided object class.
        /// <para/>
        /// The comparer returned depends on the <typeparam name="T"/> argument:
        /// <list type="number">
        ///     <item><description>If the type is <see cref="string"/>, the comparer returned uses
        ///         the <see cref="string.CompareOrdinal(string, string)"/> to make the comparison
        ///         to ensure that the current culture doesn't affect the results. This is the
        ///         default string comparison used in Java, and what Lucene's design depends on.</description></item>
        ///     <item><description>If the type implements <see cref="IComparable{T}"/>, the comparer uses
        ///         <see cref="IComparable{T}.CompareTo(T)"/> for the comparison. This allows
        ///         the use of types with custom comparison schemes.</description></item>
        ///     <item><description>If neither of the above conditions are true, will default to <see cref="Comparer{T}.Default"/>.</description></item>
        /// </list>
        /// <para/>
        /// NOTE: This was naturalComparer() in Lucene
        /// </summary>
        public static IComparer<T> GetNaturalComparer<T>()
            //where T : IComparable<T> // LUCENENET specific: removing constraint because in .NET, it is not needed
        {
            Type genericClosingType = typeof(T);

            // LUCENENET specific - we need to ensure that strings are compared
            // in a culture-insenitive manner.
            if (genericClosingType.Equals(typeof(string)))
            {
                return (IComparer<T>)StringComparer.Ordinal;
            }
            // LUCENENET specific - Only return the NaturalComparer if the type
            // implements IComparable<T>, otherwise use Comparer<T>.Default.
            // This allows the comparison to be customized, but it is not mandatory
            // to implement IComparable<T>.
            else if (typeof(IComparable<T>).IsAssignableFrom(genericClosingType))
            {
                return NaturalComparer<T>.Default;
            }

            return Comparer<T>.Default;
        }

        /// <summary>
        /// Swap values stored in slots <paramref name="i"/> and <paramref name="j"/> </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Swap<T>(T[] arr, int i, int j)
        {
            T tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }

        // intro-sorts

        /// <summary>
        /// Sorts the given array slice using the <see cref="IComparer{T}"/>. This method uses the intro sort
        /// algorithm, but falls back to insertion sort for small arrays. </summary>
        /// <param name="fromIndex"> Start index (inclusive) </param>
        /// <param name="toIndex"> End index (exclusive) </param>
        public static void IntroSort<T>(T[] a, int fromIndex, int toIndex, IComparer<T> comp)
        {
            if (toIndex - fromIndex <= 1)
            {
                return;
            }
            (new ArrayIntroSorter<T>(a, comp)).Sort(fromIndex, toIndex);
        }

        /// <summary>
        /// Sorts the given array using the <see cref="IComparer{T}"/>. This method uses the intro sort
        /// algorithm, but falls back to insertion sort for small arrays.
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void IntroSort<T>(T[] a, IComparer<T> comp)
        {
            IntroSort(a, 0, a.Length, comp);
        }

        /// <summary>
        /// Sorts the given array slice in natural order. This method uses the intro sort
        /// algorithm, but falls back to insertion sort for small arrays. </summary>
        /// <param name="fromIndex"> Start index (inclusive) </param>
        /// <param name="toIndex"> End index (exclusive) </param>
        public static void IntroSort<T>(T[] a, int fromIndex, int toIndex) //where T : IComparable<T> // LUCENENET specific: removing constraint because in .NET, it is not needed
        {
            if (toIndex - fromIndex <= 1)
            {
                return;
            }
            IntroSort(a, fromIndex, toIndex, ArrayUtil.GetNaturalComparer<T>());
        }

        /// <summary>
        /// Sorts the given array in natural order. This method uses the intro sort
        /// algorithm, but falls back to insertion sort for small arrays.
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void IntroSort<T>(T[] a) //where T : IComparable<T> // LUCENENET specific: removing constraint because in .NET, it is not needed
        {
            IntroSort(a, 0, a.Length);
        }

        // tim sorts:

        /// <summary>
        /// Sorts the given array slice using the <see cref="IComparer{T}"/>. This method uses the Tim sort
        /// algorithm, but falls back to binary sort for small arrays. </summary>
        /// <param name="fromIndex"> Start index (inclusive) </param>
        /// <param name="toIndex"> End index (exclusive) </param>
        public static void TimSort<T>(T[] a, int fromIndex, int toIndex, IComparer<T> comp)
        {
            if (toIndex - fromIndex <= 1)
            {
                return;
            }
            (new ArrayTimSorter<T>(a, comp, a.Length / 64)).Sort(fromIndex, toIndex);
        }

        /// <summary>
        /// Sorts the given array using the <see cref="IComparer{T}"/>. this method uses the Tim sort
        /// algorithm, but falls back to binary sort for small arrays.
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void TimSort<T>(T[] a, IComparer<T> comp)
        {
            TimSort(a, 0, a.Length, comp);
        }

        /// <summary>
        /// Sorts the given array slice in natural order. this method uses the Tim sort
        /// algorithm, but falls back to binary sort for small arrays. </summary>
        /// <param name="fromIndex"> Start index (inclusive) </param>
        /// <param name="toIndex"> End index (exclusive) </param>
        public static void TimSort<T>(T[] a, int fromIndex, int toIndex) //where T : IComparable<T> // LUCENENET specific: removing constraint because in .NET, it is not needed
        {
            if (toIndex - fromIndex <= 1)
            {
                return;
            }
            TimSort(a, fromIndex, toIndex, ArrayUtil.GetNaturalComparer<T>());
        }

        /// <summary>
        /// Sorts the given array in natural order. this method uses the Tim sort
        /// algorithm, but falls back to binary sort for small arrays.
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void TimSort<T>(T[] a) //where T : IComparable<T>  // LUCENENET specific: removing constraint because in .NET, it is not needed
        {
            TimSort(a, 0, a.Length);
        }
    }
}