internal static T[,] Clone2DimArrayInternal <T>(T[,] objFrom, T[,] objTo, DeepCloneState state, bool isDeep)
        {
            if (objFrom == null || objTo == null)
            {
                return(null);
            }
            int l3 = Math.Min(objFrom.GetLength(0), objTo.GetLength(0));
            int l2 = Math.Min(objFrom.GetLength(1), objTo.GetLength(1));

            state.AddKnownRef(objFrom, objTo);
            if ((!isDeep || DeepClonerSafeTypes.CanReturnSameObject(typeof(T))) && objFrom.GetLength(0) == objTo.GetLength(0) && objFrom.GetLength(1) == objTo.GetLength(1))
            {
                Array.Copy(objFrom, objTo, objFrom.Length);
                return(objTo);
            }
            if (!isDeep)
            {
                for (int n = 0; n < l3; n++)
                {
                    for (int m = 0; m < l2; m++)
                    {
                        objTo[n, m] = objFrom[n, m];
                    }
                }
                return(objTo);
            }
            if (typeof(T).IsValueType())
            {
                Func <T, DeepCloneState, T> cloner = DeepClonerGenerator.GetClonerForValueType <T>();
                for (int l = 0; l < l3; l++)
                {
                    for (int k = 0; k < l2; k++)
                    {
                        objTo[l, k] = cloner(objFrom[l, k], state);
                    }
                }
            }
            else
            {
                for (int j = 0; j < l3; j++)
                {
                    for (int i = 0; i < l2; i++)
                    {
                        objTo[j, i] = (T)DeepClonerGenerator.CloneClassInternal(objFrom[j, i], state);
                    }
                }
            }
            return(objTo);
        }
        internal static T[] Clone1DimArrayClassInternal <T>(T[] objFrom, T[] objTo, DeepCloneState state)
        {
            if (objFrom == null || objTo == null)
            {
                return(null);
            }
            int j = Math.Min(objFrom.Length, objTo.Length);

            state.AddKnownRef(objFrom, objTo);
            for (int i = 0; i < j; i++)
            {
                objTo[i] = (T)DeepClonerGenerator.CloneClassInternal(objFrom[i], state);
            }
            return(objTo);
        }
        internal static Array CloneAbstractArrayInternal(Array objFrom, Array objTo, DeepCloneState state, bool isDeep)
        {
            if (objFrom == null || objTo == null)
            {
                return(null);
            }
            int rank = objFrom.Rank;

            if (objTo.Rank != rank)
            {
                throw new InvalidOperationException("Invalid rank of target array");
            }
            int[] lowerBoundsFrom = Enumerable.Range(0, rank).Select(objFrom.GetLowerBound).ToArray();
            int[] lowerBoundsTo   = Enumerable.Range(0, rank).Select(objTo.GetLowerBound).ToArray();
            int[] lengths         = (from x in Enumerable.Range(0, rank)
                                     select Math.Min(objFrom.GetLength(x), objTo.GetLength(x))).ToArray();
            int[] idxesFrom = Enumerable.Range(0, rank).Select(objFrom.GetLowerBound).ToArray();
            int[] idxesTo   = Enumerable.Range(0, rank).Select(objTo.GetLowerBound).ToArray();
            state.AddKnownRef(objFrom, objTo);
            while (true)
            {
                if (isDeep)
                {
                    objTo.SetValue(DeepClonerGenerator.CloneClassInternal(objFrom.GetValue(idxesFrom), state), idxesTo);
                }
                else
                {
                    objTo.SetValue(objFrom.GetValue(idxesFrom), idxesTo);
                }
                int ofs = rank - 1;
                while (true)
                {
                    idxesFrom[ofs]++;
                    idxesTo[ofs]++;
                    if (idxesFrom[ofs] < lowerBoundsFrom[ofs] + lengths[ofs])
                    {
                        break;
                    }
                    idxesFrom[ofs] = lowerBoundsFrom[ofs];
                    idxesTo[ofs]   = lowerBoundsTo[ofs];
                    ofs--;
                    if (ofs < 0)
                    {
                        return(objTo);
                    }
                }
            }
        }
        internal static T[] Clone1DimArrayStructInternal <T>(T[] objFrom, T[] objTo, DeepCloneState state)
        {
            if (objFrom == null || objTo == null)
            {
                return(null);
            }
            int j = Math.Min(objFrom.Length, objTo.Length);

            state.AddKnownRef(objFrom, objTo);
            Func <T, DeepCloneState, T> cloner = DeepClonerGenerator.GetClonerForValueType <T>();

            for (int i = 0; i < j; i++)
            {
                objTo[i] = cloner(objTo[i], state);
            }
            return(objTo);
        }