Context:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Xunit;

namespace System.Linq.Expressions.Tests
{
    public static class ArrayArrayLengthTests
    {
        #region Boolean tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckBoolArrayArrayLengthTest(bool useInterpreter)
        {
            CheckBoolArrayArrayLengthExpression(GenerateBoolArrayArray(0), useInterpreter);
            CheckBoolArrayArrayLengthExpression(GenerateBoolArrayArray(1), useInterpreter);
            CheckBoolArrayArrayLengthExpression(GenerateBoolArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionBoolArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionBoolArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Byte tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckByteArrayArrayLengthTest(bool useInterpreter)
        {
            CheckByteArrayArrayLengthExpression(GenerateByteArrayArray(0), useInterpreter);
            CheckByteArrayArrayLengthExpression(GenerateByteArrayArray(1), useInterpreter);
            CheckByteArrayArrayLengthExpression(GenerateByteArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionByteArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionByteArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Custom tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckCustomArrayArrayLengthTest(bool useInterpreter)
        {
            CheckCustomArrayArrayLengthExpression(GenerateCustomArrayArray(0), useInterpreter);
            CheckCustomArrayArrayLengthExpression(GenerateCustomArrayArray(1), useInterpreter);
            CheckCustomArrayArrayLengthExpression(GenerateCustomArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionCustomArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionCustomArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Char tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckCharArrayArrayLengthTest(bool useInterpreter)
        {
            CheckCharArrayArrayLengthExpression(GenerateCharArrayArray(0), useInterpreter);
            CheckCharArrayArrayLengthExpression(GenerateCharArrayArray(1), useInterpreter);
            CheckCharArrayArrayLengthExpression(GenerateCharArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionCharArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionCharArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Custom2 tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckCustom2ArrayArrayLengthTest(bool useInterpreter)
        {
            CheckCustom2ArrayArrayLengthExpression(GenerateCustom2ArrayArray(0), useInterpreter);
            CheckCustom2ArrayArrayLengthExpression(GenerateCustom2ArrayArray(1), useInterpreter);
            CheckCustom2ArrayArrayLengthExpression(GenerateCustom2ArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionCustom2ArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionCustom2ArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Decimal tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckDecimalArrayArrayLengthTest(bool useInterpreter)
        {
            CheckDecimalArrayArrayLengthExpression(GenerateDecimalArrayArray(0), useInterpreter);
            CheckDecimalArrayArrayLengthExpression(GenerateDecimalArrayArray(1), useInterpreter);
            CheckDecimalArrayArrayLengthExpression(GenerateDecimalArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionDecimalArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionDecimalArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Delegate tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckDelegateArrayArrayLengthTest(bool useInterpreter)
        {
            CheckDelegateArrayArrayLengthExpression(GenerateDelegateArrayArray(0), useInterpreter);
            CheckDelegateArrayArrayLengthExpression(GenerateDelegateArrayArray(1), useInterpreter);
            CheckDelegateArrayArrayLengthExpression(GenerateDelegateArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionDelegateArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionDelegateArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Double tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckDoubleArrayArrayLengthTest(bool useInterpreter)
        {
            CheckDoubleArrayArrayLengthExpression(GenerateDoubleArrayArray(0), useInterpreter);
            CheckDoubleArrayArrayLengthExpression(GenerateDoubleArrayArray(1), useInterpreter);
            CheckDoubleArrayArrayLengthExpression(GenerateDoubleArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionDoubleArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionDoubleArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Enum tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckEnumArrayArrayLengthTest(bool useInterpreter)
        {
            CheckEnumArrayArrayLengthExpression(GenerateEnumArrayArray(0), useInterpreter);
            CheckEnumArrayArrayLengthExpression(GenerateEnumArrayArray(1), useInterpreter);
            CheckEnumArrayArrayLengthExpression(GenerateEnumArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionEnumArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionEnumArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region EnumLong tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckEnumLongArrayArrayLengthTest(bool useInterpreter)
        {
            CheckEnumLongArrayArrayLengthExpression(GenerateEnumLongArrayArray(0), useInterpreter);
            CheckEnumLongArrayArrayLengthExpression(GenerateEnumLongArrayArray(1), useInterpreter);
            CheckEnumLongArrayArrayLengthExpression(GenerateEnumLongArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionEnumLongArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionEnumLongArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Float tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckFloatArrayArrayLengthTest(bool useInterpreter)
        {
            CheckFloatArrayArrayLengthExpression(GenerateFloatArrayArray(0), useInterpreter);
            CheckFloatArrayArrayLengthExpression(GenerateFloatArrayArray(1), useInterpreter);
            CheckFloatArrayArrayLengthExpression(GenerateFloatArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionFloatArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionFloatArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Func tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckFuncArrayArrayLengthTest(bool useInterpreter)
        {
            CheckFuncArrayArrayLengthExpression(GenerateFuncArrayArray(0), useInterpreter);
            CheckFuncArrayArrayLengthExpression(GenerateFuncArrayArray(1), useInterpreter);
            CheckFuncArrayArrayLengthExpression(GenerateFuncArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionFuncArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionFuncArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Interface tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckInterfaceArrayArrayLengthTest(bool useInterpreter)
        {
            CheckInterfaceArrayArrayLengthExpression(GenerateInterfaceArrayArray(0), useInterpreter);
            CheckInterfaceArrayArrayLengthExpression(GenerateInterfaceArrayArray(1), useInterpreter);
            CheckInterfaceArrayArrayLengthExpression(GenerateInterfaceArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionInterfaceArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionInterfaceArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region IEquatableCustom tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckIEquatableCustomArrayArrayLengthTest(bool useInterpreter)
        {
            CheckIEquatableCustomArrayArrayLengthExpression(GenerateIEquatableCustomArrayArray(0), useInterpreter);
            CheckIEquatableCustomArrayArrayLengthExpression(GenerateIEquatableCustomArrayArray(1), useInterpreter);
            CheckIEquatableCustomArrayArrayLengthExpression(GenerateIEquatableCustomArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionIEquatableCustomArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionIEquatableCustomArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region IEquatableCustom2 tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckIEquatableCustom2ArrayArrayLengthTest(bool useInterpreter)
        {
            CheckIEquatableCustom2ArrayArrayLengthExpression(GenerateIEquatableCustom2ArrayArray(0), useInterpreter);
            CheckIEquatableCustom2ArrayArrayLengthExpression(GenerateIEquatableCustom2ArrayArray(1), useInterpreter);
            CheckIEquatableCustom2ArrayArrayLengthExpression(GenerateIEquatableCustom2ArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionIEquatableCustom2ArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionIEquatableCustom2ArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Int tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckIntArrayArrayLengthTest(bool useInterpreter)
        {
            CheckIntArrayArrayLengthExpression(GenerateIntArrayArray(0), useInterpreter);
            CheckIntArrayArrayLengthExpression(GenerateIntArrayArray(1), useInterpreter);
            CheckIntArrayArrayLengthExpression(GenerateIntArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionIntArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionIntArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Long tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckLongArrayArrayLengthTest(bool useInterpreter)
        {
            CheckLongArrayArrayLengthExpression(GenerateLongArrayArray(0), useInterpreter);
            CheckLongArrayArrayLengthExpression(GenerateLongArrayArray(1), useInterpreter);
            CheckLongArrayArrayLengthExpression(GenerateLongArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionLongArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionLongArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Object tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckObjectArrayArrayLengthTest(bool useInterpreter)
        {
            CheckObjectArrayArrayLengthExpression(GenerateObjectArrayArray(0), useInterpreter);
            CheckObjectArrayArrayLengthExpression(GenerateObjectArrayArray(1), useInterpreter);
            CheckObjectArrayArrayLengthExpression(GenerateObjectArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionObjectArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionObjectArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Struct tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckStructArrayArrayLengthTest(bool useInterpreter)
        {
            CheckStructArrayArrayLengthExpression(GenerateStructArrayArray(0), useInterpreter);
            CheckStructArrayArrayLengthExpression(GenerateStructArrayArray(1), useInterpreter);
            CheckStructArrayArrayLengthExpression(GenerateStructArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionStructArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionStructArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region SByte tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckSByteArrayArrayLengthTest(bool useInterpreter)
        {
            CheckSByteArrayArrayLengthExpression(GenerateSByteArrayArray(0), useInterpreter);
            CheckSByteArrayArrayLengthExpression(GenerateSByteArrayArray(1), useInterpreter);
            CheckSByteArrayArrayLengthExpression(GenerateSByteArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionSByteArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionSByteArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region StructWithString tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckStructWithStringArrayArrayLengthTest(bool useInterpreter)
        {
            CheckStructWithStringArrayArrayLengthExpression(GenerateStructWithStringArrayArray(0), useInterpreter);
            CheckStructWithStringArrayArrayLengthExpression(GenerateStructWithStringArrayArray(1), useInterpreter);
            CheckStructWithStringArrayArrayLengthExpression(GenerateStructWithStringArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionStructWithStringArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionStructWithStringArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region StructWithStringAndValue tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckStructWithStringAndValueArrayArrayLengthTest(bool useInterpreter)
        {
            CheckStructWithStringAndValueArrayArrayLengthExpression(GenerateStructWithStringAndValueArrayArray(0), useInterpreter);
            CheckStructWithStringAndValueArrayArrayLengthExpression(GenerateStructWithStringAndValueArrayArray(1), useInterpreter);
            CheckStructWithStringAndValueArrayArrayLengthExpression(GenerateStructWithStringAndValueArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionStructWithStringAndValueArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionStructWithStringAndValueArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Short tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckShortArrayArrayLengthTest(bool useInterpreter)
        {
            CheckShortArrayArrayLengthExpression(GenerateShortArrayArray(0), useInterpreter);
            CheckShortArrayArrayLengthExpression(GenerateShortArrayArray(1), useInterpreter);
            CheckShortArrayArrayLengthExpression(GenerateShortArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionShortArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionShortArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region StructWithTwoValues tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckStructWithTwoValuesArrayArrayLengthTest(bool useInterpreter)
        {
            CheckStructWithTwoValuesArrayArrayLengthExpression(GenerateStructWithTwoValuesArrayArray(0), useInterpreter);
            CheckStructWithTwoValuesArrayArrayLengthExpression(GenerateStructWithTwoValuesArrayArray(1), useInterpreter);
            CheckStructWithTwoValuesArrayArrayLengthExpression(GenerateStructWithTwoValuesArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionStructWithTwoValuesArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionStructWithTwoValuesArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region StructWithValue tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckStructWithValueArrayArrayLengthTest(bool useInterpreter)
        {
            CheckStructWithValueArrayArrayLengthExpression(GenerateStructWithValueArrayArray(0), useInterpreter);
            CheckStructWithValueArrayArrayLengthExpression(GenerateStructWithValueArrayArray(1), useInterpreter);
            CheckStructWithValueArrayArrayLengthExpression(GenerateStructWithValueArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionStructWithValueArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionStructWithValueArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region String tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckStringArrayArrayLengthTest(bool useInterpreter)
        {
            CheckStringArrayArrayLengthExpression(GenerateStringArrayArray(0), useInterpreter);
            CheckStringArrayArrayLengthExpression(GenerateStringArrayArray(1), useInterpreter);
            CheckStringArrayArrayLengthExpression(GenerateStringArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionStringArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionStringArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region UInt tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckUIntArrayArrayLengthTest(bool useInterpreter)
        {
            CheckUIntArrayArrayLengthExpression(GenerateUIntArrayArray(0), useInterpreter);
            CheckUIntArrayArrayLengthExpression(GenerateUIntArrayArray(1), useInterpreter);
            CheckUIntArrayArrayLengthExpression(GenerateUIntArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionUIntArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionUIntArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region ULong tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckULongArrayArrayLengthTest(bool useInterpreter)
        {
            CheckULongArrayArrayLengthExpression(GenerateULongArrayArray(0), useInterpreter);
            CheckULongArrayArrayLengthExpression(GenerateULongArrayArray(1), useInterpreter);
            CheckULongArrayArrayLengthExpression(GenerateULongArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionULongArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionULongArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region UShort tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckUShortArrayArrayLengthTest(bool useInterpreter)
        {
            CheckUShortArrayArrayLengthExpression(GenerateUShortArrayArray(0), useInterpreter);
            CheckUShortArrayArrayLengthExpression(GenerateUShortArrayArray(1), useInterpreter);
            CheckUShortArrayArrayLengthExpression(GenerateUShortArrayArray(5), useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionUShortArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionUShortArrayArrayLength(null, useInterpreter);
        }

        #endregion

        #region Generic tests

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericCustomArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericArrayArrayLengthTestHelper<C>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericCustomArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericArrayArrayLengthTestHelper<C>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericEnumArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericArrayArrayLengthTestHelper<E>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericEnumArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericArrayArrayLengthTestHelper<E>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericObjectArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericArrayArrayLengthTestHelper<object>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericObjectArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericArrayArrayLengthTestHelper<object>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericStructArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericArrayArrayLengthTestHelper<S>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericStructArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericArrayArrayLengthTestHelper<S>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericStructWithStringAndValueArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericArrayArrayLengthTestHelper<Scs>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericStructWithStringAndValueArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericArrayArrayLengthTestHelper<Scs>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericCustomWithClassRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericWithClassRestrictionArrayArrayLengthTestHelper<C>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericCustomWithClassRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericWithClassRestrictionArrayArrayLengthTestHelper<C>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericObjectWithClassRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericWithClassRestrictionArrayArrayLengthTestHelper<object>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericObjectWithClassRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericWithClassRestrictionArrayArrayLengthTestHelper<object>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericCustomWithSubClassRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericWithSubClassRestrictionArrayArrayLengthTestHelper<C>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericCustomWithSubClassRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericWithSubClassRestrictionArrayArrayLengthTestHelper<C>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericCustomWithClassAndNewRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericWithClassAndNewRestrictionArrayArrayLengthTestHelper<C>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericCustomWithClassAndNewRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericWithClassAndNewRestrictionArrayArrayLengthTestHelper<C>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericObjectWithClassAndNewRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericWithClassAndNewRestrictionArrayArrayLengthTestHelper<object>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericObjectWithClassAndNewRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericWithClassAndNewRestrictionArrayArrayLengthTestHelper<object>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericCustomWithSubClassAndNewRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericWithSubClassAndNewRestrictionArrayArrayLengthTestHelper<C>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericCustomWithSubClassAndNewRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericWithSubClassAndNewRestrictionArrayArrayLengthTestHelper<C>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericEnumWithStructRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericWithStructRestrictionArrayArrayLengthTestHelper<E>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericEnumWithStructRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericWithStructRestrictionArrayArrayLengthTestHelper<E>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericStructWithStructRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericWithStructRestrictionArrayArrayLengthTestHelper<S>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericStructWithStructRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericWithStructRestrictionArrayArrayLengthTestHelper<S>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckGenericStructWithStringAndValueWithStructRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckGenericWithStructRestrictionArrayArrayLengthTestHelper<Scs>(useInterpreter);
        }

        [Theory]
        [ClassData(typeof(CompilationTypes))]
        public static void CheckExceptionGenericStructWithStringAndValueWithStructRestrictionArrayArrayLengthTest(bool useInterpreter)
        {
            CheckExceptionGenericWithStructRestrictionArrayArrayLengthTestHelper<Scs>(useInterpreter);
        }

        #endregion

        #region Generic helpers

        private static void CheckGenericArrayArrayLengthTestHelper<T>(bool useInterpreter)
        {
            CheckGenericArrayArrayLengthExpression<T>(GenerateGenericArrayArray<T>(0), useInterpreter);
            CheckGenericArrayArrayLengthExpression<T>(GenerateGenericArrayArray<T>(1), useInterpreter);
            CheckGenericArrayArrayLengthExpression<T>(GenerateGenericArrayArray<T>(5), useInterpreter);
        }

        private static void CheckExceptionGenericArrayArrayLengthTestHelper<T>(bool useInterpreter)
        {
            CheckExceptionGenericArrayArrayLength<T>(null, useInterpreter);
        }

        private static void CheckGenericWithClassRestrictionArrayArrayLengthTestHelper<Tc>(bool useInterpreter) where Tc : class
        {
            CheckGenericWithClassRestrictionArrayArrayLengthExpression<Tc>(GenerateGenericWithClassRestrictionArrayArray<Tc>(0), useInterpreter);
            CheckGenericWithClassRestrictionArrayArrayLengthExpression<Tc>(GenerateGenericWithClassRestrictionArrayArray<Tc>(1), useInterpreter);
            CheckGenericWithClassRestrictionArrayArrayLengthExpression<Tc>(GenerateGenericWithClassRestrictionArrayArray<Tc>(5), useInterpreter);
        }

        private static void CheckExceptionGenericWithClassRestrictionArrayArrayLengthTestHelper<Tc>(bool useInterpreter) where Tc : class
        {
            CheckExceptionGenericWithClassRestrictionArrayArrayLength<Tc>(null, useInterpreter);
        }

        private static void CheckGenericWithSubClassRestrictionArrayArrayLengthTestHelper<TC>(bool useInterpreter) where TC : C
        {
            CheckGenericWithSubClassRestrictionArrayArrayLengthExpression<TC>(GenerateGenericWithSubClassRestrictionArrayArray<TC>(0), useInterpreter);
            CheckGenericWithSubClassRestrictionArrayArrayLengthExpression<TC>(GenerateGenericWithSubClassRestrictionArrayArray<TC>(1), useInterpreter);
            CheckGenericWithSubClassRestrictionArrayArrayLengthExpression<TC>(GenerateGenericWithSubClassRestrictionArrayArray<TC>(5), useInterpreter);
        }

        private static void CheckExceptionGenericWithSubClassRestrictionArrayArrayLengthTestHelper<TC>(bool useInterpreter) where TC : C
        {
            CheckExceptionGenericWithSubClassRestrictionArrayArrayLength<TC>(null, useInterpreter);
        }

        private static void CheckGenericWithClassAndNewRestrictionArrayArrayLengthTestHelper<Tcn>(bool useInterpreter) where Tcn : class, new()
        {
            CheckGenericWithClassAndNewRestrictionArrayArrayLengthExpression<Tcn>(GenerateGenericWithClassAndNewRestrictionArrayArray<Tcn>(0), useInterpreter);
            CheckGenericWithClassAndNewRestrictionArrayArrayLengthExpression<Tcn>(GenerateGenericWithClassAndNewRestrictionArrayArray<Tcn>(1), useInterpreter);
            CheckGenericWithClassAndNewRestrictionArrayArrayLengthExpression<Tcn>(GenerateGenericWithClassAndNewRestrictionArrayArray<Tcn>(5), useInterpreter);
        }

        private static void CheckExceptionGenericWithClassAndNewRestrictionArrayArrayLengthTestHelper<Tcn>(bool useInterpreter) where Tcn : class, new()
        {
            CheckExceptionGenericWithClassAndNewRestrictionArrayArrayLength<Tcn>(null, useInterpreter);
        }

        private static void CheckGenericWithSubClassAndNewRestrictionArrayArrayLengthTestHelper<TCn>(bool useInterpreter) where TCn : C, new()
        {
            CheckGenericWithSubClassAndNewRestrictionArrayArrayLengthExpression<TCn>(GenerateGenericWithSubClassAndNewRestrictionArrayArray<TCn>(0), useInterpreter);
            CheckGenericWithSubClassAndNewRestrictionArrayArrayLengthExpression<TCn>(GenerateGenericWithSubClassAndNewRestrictionArrayArray<TCn>(1), useInterpreter);
            CheckGenericWithSubClassAndNewRestrictionArrayArrayLengthExpression<TCn>(GenerateGenericWithSubClassAndNewRestrictionArrayArray<TCn>(5), useInterpreter);
        }

        private static void CheckExceptionGenericWithSubClassAndNewRestrictionArrayArrayLengthTestHelper<TCn>(bool useInterpreter) where TCn : C, new()
        {
            CheckExceptionGenericWithSubClassAndNewRestrictionArrayArrayLength<TCn>(null, useInterpreter);
        }

        private static void CheckGenericWithStructRestrictionArrayArrayLengthTestHelper<Ts>(bool useInterpreter) where Ts : struct
        {
            CheckGenericWithStructRestrictionArrayArrayLengthExpression<Ts>(GenerateGenericWithStructRestrictionArrayArray<Ts>(0), useInterpreter);
            CheckGenericWithStructRestrictionArrayArrayLengthExpression<Ts>(GenerateGenericWithStructRestrictionArrayArray<Ts>(1), useInterpreter);
            CheckGenericWithStructRestrictionArrayArrayLengthExpression<Ts>(GenerateGenericWithStructRestrictionArrayArray<Ts>(5), useInterpreter);
        }

        private static void CheckExceptionGenericWithStructRestrictionArrayArrayLengthTestHelper<Ts>(bool useInterpreter) where Ts : struct
        {
            CheckExceptionGenericWithStructRestrictionArrayArrayLength<Ts>(null, useInterpreter);
        }

        #endregion

        #region Generate array

        private static bool[][] GenerateBoolArrayArray(int size)
        {
            bool[][] array = new bool[][] { null, new bool[0], new bool[] { true, false }, new bool[100] };
            bool[][] result = new bool[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static byte[][] GenerateByteArrayArray(int size)
        {
            byte[][] array = new byte[][] { null, new byte[0], new byte[] { 0, 1, byte.MaxValue }, new byte[100] };
            byte[][] result = new byte[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static C[][] GenerateCustomArrayArray(int size)
        {
            C[][] array = new C[][] { null, new C[0], new C[] { null, new C(), new D(), new D(0), new D(5) }, new C[100] };
            C[][] result = new C[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static char[][] GenerateCharArrayArray(int size)
        {
            char[][] array = new char[][] { null, new char[0], new char[] { '\0', '\b', 'A', '\uffff' }, new char[100] };
            char[][] result = new char[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static D[][] GenerateCustom2ArrayArray(int size)
        {
            D[][] array = new D[][] { null, new D[0], new D[] { null, new D(), new D(0), new D(5) }, new D[100] };
            D[][] result = new D[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static decimal[][] GenerateDecimalArrayArray(int size)
        {
            decimal[][] array = new decimal[][] { null, new decimal[0], new decimal[] { decimal.Zero, decimal.One, decimal.MinusOne, decimal.MinValue, decimal.MaxValue }, new decimal[100] };
            decimal[][] result = new decimal[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static Delegate[][] GenerateDelegateArrayArray(int size)
        {
            Delegate[][] array = new Delegate[][] { null, new Delegate[0], new Delegate[] { null, (Func<object>)delegate () { return null; }, (Func<int, int>)delegate (int i) { return i + 1; }, (Action<object>)delegate { } }, new Delegate[100] };
            Delegate[][] result = new Delegate[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static double[][] GenerateDoubleArrayArray(int size)
        {
            double[][] array = new double[][] { null, new double[0], new double[] { 0, 1, -1, double.MinValue, double.MaxValue, double.Epsilon, double.NegativeInfinity, double.PositiveInfinity, double.NaN }, new double[100] };
            double[][] result = new double[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static E[][] GenerateEnumArrayArray(int size)
        {
            E[][] array = new E[][] { null, new E[0], new E[] { (E)0, E.A, E.B, (E)int.MaxValue, (E)int.MinValue }, new E[100] };
            E[][] result = new E[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static El[][] GenerateEnumLongArrayArray(int size)
        {
            El[][] array = new El[][] { null, new El[0], new El[] { (El)0, El.A, El.B, (El)long.MaxValue, (El)long.MinValue }, new El[100] };
            El[][] result = new El[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static float[][] GenerateFloatArrayArray(int size)
        {
            float[][] array = new float[][] { null, new float[0], new float[] { 0, 1, -1, float.MinValue, float.MaxValue, float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN }, new float[100] };
            float[][] result = new float[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static Func<object>[][] GenerateFuncArrayArray(int size)
        {
            Func<object>[][] array = new Func<object>[][] { null, new Func<object>[0], new Func<object>[] { null, (Func<object>)delegate () { return null; } }, new Func<object>[100] };
            Func<object>[][] result = new Func<object>[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static I[][] GenerateInterfaceArrayArray(int size)
        {
            I[][] array = new I[][] { null, new I[0], new I[] { null, new C(), new D(), new D(0), new D(5) }, new I[100] };
            I[][] result = new I[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static IEquatable<C>[][] GenerateIEquatableCustomArrayArray(int size)
        {
            IEquatable<C>[][] array = new IEquatable<C>[][] { null, new IEquatable<C>[0], new IEquatable<C>[] { null, new C(), new D(), new D(0), new D(5) }, new IEquatable<C>[100] };
            IEquatable<C>[][] result = new IEquatable<C>[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static IEquatable<D>[][] GenerateIEquatableCustom2ArrayArray(int size)
        {
            IEquatable<D>[][] array = new IEquatable<D>[][] { null, new IEquatable<D>[0], new IEquatable<D>[] { null, new D(), new D(0), new D(5) }, new IEquatable<D>[100] };
            IEquatable<D>[][] result = new IEquatable<D>[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static int[][] GenerateIntArrayArray(int size)
        {
            int[][] array = new int[][] { null, new int[0], new int[] { 0, 1, -1, int.MinValue, int.MaxValue }, new int[100] };
            int[][] result = new int[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static long[][] GenerateLongArrayArray(int size)
        {
            long[][] array = new long[][] { null, new long[0], new long[] { 0, 1, -1, long.MinValue, long.MaxValue }, new long[100] };
            long[][] result = new long[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static object[][] GenerateObjectArrayArray(int size)
        {
            object[][] array = new object[][] { null, new object[0], new object[] { null, new object(), new C(), new D(3) }, new object[100] };
            object[][] result = new object[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static S[][] GenerateStructArrayArray(int size)
        {
            S[][] array = new S[][] { null, new S[0], new S[] { default(S), new S() }, new S[100] };
            S[][] result = new S[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static sbyte[][] GenerateSByteArrayArray(int size)
        {
            sbyte[][] array = new sbyte[][] { null, new sbyte[0], new sbyte[] { 0, 1, -1, sbyte.MinValue, sbyte.MaxValue }, new sbyte[100] };
            sbyte[][] result = new sbyte[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static Sc[][] GenerateStructWithStringArrayArray(int size)
        {
            Sc[][] array = new Sc[][] { null, new Sc[0], new Sc[] { default(Sc), new Sc(), new Sc(null) }, new Sc[100] };
            Sc[][] result = new Sc[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static Scs[][] GenerateStructWithStringAndValueArrayArray(int size)
        {
            Scs[][] array = new Scs[][] { null, new Scs[0], new Scs[] { default(Scs), new Scs(), new Scs(null, new S()) }, new Scs[100] };
            Scs[][] result = new Scs[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static short[][] GenerateShortArrayArray(int size)
        {
            short[][] array = new short[][] { null, new short[0], new short[] { 0, 1, -1, short.MinValue, short.MaxValue }, new short[100] };
            short[][] result = new short[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static Sp[][] GenerateStructWithTwoValuesArrayArray(int size)
        {
            Sp[][] array = new Sp[][] { null, new Sp[0], new Sp[] { default(Sp), new Sp(), new Sp(5, 5.0) }, new Sp[100] };
            Sp[][] result = new Sp[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static Ss[][] GenerateStructWithValueArrayArray(int size)
        {
            Ss[][] array = new Ss[][] { null, new Ss[0], new Ss[] { default(Ss), new Ss(), new Ss(new S()) }, new Ss[100] };
            Ss[][] result = new Ss[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static string[][] GenerateStringArrayArray(int size)
        {
            string[][] array = new string[][] { null, new string[0], new string[] { null, "", "a", "foo" }, new string[100] };
            string[][] result = new string[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static uint[][] GenerateUIntArrayArray(int size)
        {
            uint[][] array = new uint[][] { null, new uint[0], new uint[] { 0, 1, uint.MaxValue }, new uint[100] };
            uint[][] result = new uint[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static ulong[][] GenerateULongArrayArray(int size)
        {
            ulong[][] array = new ulong[][] { null, new ulong[0], new ulong[] { 0, 1, ulong.MaxValue }, new ulong[100] };
            ulong[][] result = new ulong[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static ushort[][] GenerateUShortArrayArray(int size)
        {
            ushort[][] array = new ushort[][] { null, new ushort[0], new ushort[] { 0, 1, ushort.MaxValue }, new ushort[100] };
            ushort[][] result = new ushort[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static T[][] GenerateGenericArrayArray<T>(int size)
        {
            T[][] array = new T[][] { null, new T[0], new T[] { default(T) }, new T[100] };
            T[][] result = new T[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static Tc[][] GenerateGenericWithClassRestrictionArrayArray<Tc>(int size) where Tc : class
        {
            Tc[][] array = new Tc[][] { null, new Tc[0], new Tc[] { null, default(Tc) }, new Tc[100] };
            Tc[][] result = new Tc[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static TC[][] GenerateGenericWithSubClassRestrictionArrayArray<TC>(int size) where TC : C
        {
            TC[][] array = new TC[][] { null, new TC[0], new TC[] { null, default(TC), (TC)new C() }, new TC[100] };
            TC[][] result = new TC[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static Tcn[][] GenerateGenericWithClassAndNewRestrictionArrayArray<Tcn>(int size) where Tcn : class, new()
        {
            Tcn[][] array = new Tcn[][] { null, new Tcn[0], new Tcn[] { null, default(Tcn), new Tcn() }, new Tcn[100] };
            Tcn[][] result = new Tcn[size][];
            for (int i = 0; i < size; i++)
            {
                result[i] = array[i % array.Length];
            }

            return result;
        }

        private static TCn[][] GenerateGenericWithSubClassAndNewRestrictionArrayArray<TCn>(int size) where TCn : C, new()
        {
            TCn[][] array = new TCn[][] { null, new TCn[0], new TCn[] { null, default(TCn), new TCn(), (TCn)new C() }, new TCn[100] };

Answer: TCn[][] result = new TCn[size][];

<think>
The method is defining a helper to generate a jagged array for a generic type with subclass and new constraints. Following the pattern of previous Generate methods, after initializing the 'array' variable, the next step is to allocate a 'result' jagged array of the requested size before filling it in a loop. Therefore the next line should declare and instantiate the result array.
</think>
TCn[][] result = new TCn[size][];


Context:
#  Copyright 2008-2015 Nokia Solutions and Networks
#
#  Licensed 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.

from robotide.lib.robot.api import logger
from robotide.lib.robot.utils import (is_dict_like, is_string, is_truthy, plural_or_not,
                         seq2str, seq2str2, type_name, unic, Matcher)
from robotide.lib.robot.utils.asserts import assert_equals
from robotide.lib.robot.version import get_version

class _List(object):

    def convert_to_list(self, item):
        """Converts the given ``item`` to a Python ``list`` type.

        Mainly useful for converting tuples and other iterable to lists.
        Use `Create List` from the BuiltIn library for constructing new lists.
        """
        return list(item)

    def append_to_list(self, list_, *values):
        """Adds ``values`` to the end of ``list``.

        Example:
        | Append To List | ${L1} | xxx |   |   |
        | Append To List | ${L2} | x   | y | z |
        =>
        | ${L1} = ['a', 'xxx']
        | ${L2} = ['a', 'b', 'x', 'y', 'z']
        """
        for value in values:
            list_.append(value)

    def insert_into_list(self, list_, index, value):
        """Inserts ``value`` into ``list`` to the position specified with ``index``.

        Index ``0`` adds the value into the first position, ``1`` to the second,
        and so on. Inserting from right works with negative indices so that
        ``-1`` is the second last position, ``-2`` third last, and so on. Use
        `Append To List` to add items to the end of the list.

        If the absolute value of the index is greater than
        the length of the list, the value is added at the end
        (positive index) or the beginning (negative index). An index
        can be given either as an integer or a string that can be
        converted to an integer.

        Example:
        | Insert Into List | ${L1} | 0     | xxx |
        | Insert Into List | ${L2} | ${-1} | xxx |
        =>
        | ${L1} = ['xxx', 'a']
        | ${L2} = ['a', 'xxx', 'b']
        """
        list_.insert(self._index_to_int(index), value)

    def combine_lists(self, *lists):
        """Combines the given ``lists`` together and returns the result.

        The given lists are not altered by this keyword.

        Example:
        | ${x} = | Combine List | ${L1} | ${L2} |       |
        | ${y} = | Combine List | ${L1} | ${L2} | ${L1} |
        =>
        | ${x} = ['a', 'a', 'b']
        | ${y} = ['a', 'a', 'b', 'a']
        | ${L1} and ${L2} are not changed.
        """
        ret = []
        for item in lists:
            ret.extend(item)
        return ret

    def set_list_value(self, list_, index, value):
        """Sets the value of ``list`` specified by ``index`` to the given ``value``.

        Index ``0`` means the first position, ``1`` the second and so on.
        Similarly, ``-1`` is the last position, ``-2`` second last, and so on.
        Using an index that does not exist on the list causes an error.
        The index can be either an integer or a string that can be converted to
        an integer.

        Example:
        | Set List Value | ${L3} | 1  | xxx |
        | Set List Value | ${L3} | -1 | yyy |
        =>
        | ${L3} = ['a', 'xxx', 'yyy']
        """
        try:
            list_[self._index_to_int(index)] = value
        except IndexError:
            self._index_error(list_, index)

    def remove_values_from_list(self, list_, *values):
        """Removes all occurrences of given ``values`` from ``list``.

        It is not an error if a value does not exist in the list at all.

        Example:
        | Remove Values From List | ${L4} | a | c | e | f |
        =>
        | ${L4} = ['b', 'd']
        """
        for value in values:
            while value in list_:
                list_.remove(value)

    def remove_from_list(self, list_, index):
        """Removes and returns the value specified with an ``index`` from ``list``.

        Index ``0`` means the first position, ``1`` the second and so on.
        Similarly, ``-1`` is the last position, ``-2`` the second last, and so on.
        Using an index that does not exist on the list causes an error.
        The index can be either an integer or a string that can be converted
        to an integer.

        Example:
        | ${x} = | Remove From List | ${L2} | 0 |
        =>
        | ${x} = 'a'
        | ${L2} = ['b']
        """
        try:
            return list_.pop(self._index_to_int(index))
        except IndexError:
            self._index_error(list_, index)

    def remove_duplicates(self, list_):
        """Returns a list without duplicates based on the given ``list``.

        Creates and returns a new list that contains all items in the given
        list so that one item can appear only once. Order of the items in
        the new list is the same as in the original except for missing
        duplicates. Number of the removed duplicates is logged.

        New in Robot Framework 2.7.5.
        """
        ret = []
        for item in list_:
            if item not in ret:
                ret.append(item)
        removed = len(list_) - len(ret)
        logger.info('%d duplicate%s removed.' % (removed, plural_or_not(removed)))
        return ret

    def get_from_list(self, list_, index):
        """Returns the value specified with an ``index`` from ``list``.

        The given list is never altered by this keyword.

        Index ``0`` means the first position, ``1`` the second, and so on.
        Similarly, ``-1`` is the last position, ``-2`` the second last, and so on.
        Using an index that does not exist on the list causes an error.
        The index can be either an integer or a string that can be converted
        to an integer.

        Examples (including Python equivalents in comments):
        | ${x} = | Get From List | ${L5} | 0  | # L5[0]  |
        | ${y} = | Get From List | ${L5} | -2 | # L5[-2] |
        =>
        | ${x} = 'a'
        | ${y} = 'd'
        | ${L5} is not changed
        """
        try:
            return list_[self._index_to_int(index)]
        except IndexError:
            self._index_error(list_, index)

    def get_slice_from_list(self, list_, start=0, end=None):
        """Returns a slice of the given list between ``start`` and ``end`` indexes.

        The given list is never altered by this keyword.

        If both ``start`` and ``end`` are given, a sublist containing values
        from ``start`` to ``end`` is returned. This is the same as
        ``list[start:end]`` in Python. To get all items from the beginning,
        use 0 as the start value, and to get all items until and including
        the end, use ``None`` (default) as the end value.

        Using ``start`` or ``end`` not found on the list is the same as using
        the largest (or smallest) available index.

        Examples (incl. Python equivalents in comments):
        | ${x} = | Get Slice From List | ${L5} | 2 | 4  | # L5[2:4]    |
        | ${y} = | Get Slice From List | ${L5} | 1 |    | # L5[1:None] |
        | ${z} = | Get Slice From List | ${L5} |   | -2 | # L5[0:-2]   |
        =>
        | ${x} = ['c', 'd']
        | ${y} = ['b', 'c', 'd', 'e']
        | ${z} = ['a', 'b', 'c']
        | ${L5} is not changed
        """
        start = self._index_to_int(start, True)
        if end is not None:
            end = self._index_to_int(end)
        return list_[start:end]

    def count_values_in_list(self, list_, value, start=0, end=None):
        """Returns the number of occurrences of the given ``value`` in ``list``.

        The search can be narrowed to the selected sublist by the ``start`` and
        ``end`` indexes having the same semantics as with `Get Slice From List`
        keyword. The given list is never altered by this keyword.

        Example:
        | ${x} = | Count Values In List | ${L3} | b |
        =>
        | ${x} = 1
        | ${L3} is not changed
        """
        return self.get_slice_from_list(list_, start, end).count(value)

    def get_index_from_list(self, list_, value, start=0, end=None):
        """Returns the index of the first occurrence of the ``value`` on the list.

        The search can be narrowed to the selected sublist by the ``start`` and
        ``end`` indexes having the same semantics as with `Get Slice From List`
        keyword. In case the value is not found, -1 is returned. The given list
        is never altered by this keyword.

        Example:
        | ${x} = | Get Index From List | ${L5} | d |
        =>
        | ${x} = 3
        | ${L5} is not changed
        """
        if start == '':
            start = 0
        list_ = self.get_slice_from_list(list_, start, end)
        try:
            return int(start) + list_.index(value)
        except ValueError:
            return -1

    def copy_list(self, list_):
        """Returns a copy of the given list.

        The given list is never altered by this keyword.
        """
        return list_[:]

    def reverse_list(self, list_):
        """Reverses the given list in place.

        Note that the given list is changed and nothing is returned. Use
        `Copy List` first, if you need to keep also the original order.

        | Reverse List | ${L3} |
        =>
        | ${L3} = ['c', 'b', 'a']
        """
        list_.reverse()

    def sort_list(self, list_):
        """Sorts the given list in place.

        The strings are sorted alphabetically and the numbers numerically.

        Note that the given list is changed and nothing is returned. Use
        `Copy List` first, if you need to keep also the original order.

        ${L} = [2,1,'a','c','b']
        | Sort List | ${L} |
        =>
        | ${L} = [1, 2, 'a', 'b', 'c']
        """
        list_.sort()

    def list_should_contain_value(self, list_, value, msg=None):
        """Fails if the ``value`` is not found from ``list``.

        If the keyword fails, the default error messages is ``<list> does
        not contain value '<value>'``. A custom message can be given using
        the ``msg`` argument.
        """
        default = "%s does not contain value '%s'." % (seq2str2(list_), value)
        _verify_condition(value in list_, default, msg)

    def list_should_not_contain_value(self, list_, value, msg=None):
        """Fails if the ``value`` is not found from ``list``.

        See `List Should Contain Value` for an explanation of ``msg``.
        """
        default = "%s contains value '%s'." % (seq2str2(list_), value)
        _verify_condition(value not in list_, default, msg)

    def list_should_not_contain_duplicates(self, list_, msg=None):
        """Fails if any element in the ``list`` is found from it more than once.

        The default error message lists all the elements that were found
        from the ``list`` multiple times, but it can be overridden by giving
        a custom ``msg``. All multiple times found items and their counts are
        also logged.

        This keyword works with all iterables that can be converted to a list.
        The original iterable is never altered.
        """
        if not isinstance(list_, list):
            list_ = list(list_)
        dupes = []
        for item in list_:
            if item not in dupes:
                count = list_.count(item)
                if count > 1:
                    logger.info("'%s' found %d times." % (item, count))
                    dupes.append(item)
        if dupes:
            raise AssertionError(msg or
                                 '%s found multiple times.' % seq2str(dupes))

    def lists_should_be_equal(self, list1, list2, msg=None, values=True,
                              names=None):
        """Fails if given lists are unequal.

        The keyword first verifies that the lists have equal lengths, and then
        it checks are all their values equal. Possible differences between the
        values are listed in the default error message like ``Index 4: ABC !=
        Abc``.

        The error message can be configured using ``msg`` and ``values``
        arguments:
        - If ``msg`` is not given, the default error message is used.
        - If ``msg`` is given and ``values`` gets a value considered true
          (see `Boolean arguments`), the error message starts with the given
          ``msg`` followed by a newline and the default message.
        - If ``msg`` is given and ``values``  is not given a true value,
          the error message is just the given ``msg``.

        Optional ``names`` argument can be used for naming the indices shown in
        the default error message. It can either be a list of names matching
        the indices in the lists or a dictionary where keys are indices that
        need to be named. It is not necessary to name all of the indices.  When
        using a dictionary, keys can be either integers or strings that can be
        converted to integers.

        Examples:
        | ${names} = | Create List | First Name | Family Name | Email |
        | Lists Should Be Equal | ${people1} | ${people2} | names=${names} |
        | ${names} = | Create Dictionary | 0=First Name | 2=Email |
        | Lists Should Be Equal | ${people1} | ${people2} | names=${names} |

        If the items in index 2 would differ in the above examples, the error
        message would contain a row like ``Index 2 (email): name@foo.com !=
        name@bar.com``.
        """
        len1 = len(list1)
        len2 = len(list2)
        default = 'Lengths are different: %d != %d' % (len1, len2)
        _verify_condition(len1 == len2, default, msg, values)
        names = self._get_list_index_name_mapping(names, len1)
        diffs = list(self._yield_list_diffs(list1, list2, names))
        default = 'Lists are different:\n' + '\n'.join(diffs)
        _verify_condition(diffs == [], default, msg, values)

    def _get_list_index_name_mapping(self, names, list_length):
        if not names:
            return {}
        if is_dict_like(names):
            return dict((int(index), names[index]) for index in names)
        return dict(zip(range(list_length), names))

    def _yield_list_diffs(self, list1, list2, names):
        for index, (item1, item2) in enumerate(zip(list1, list2)):
            name = ' (%s)' % names[index] if index in names else ''
            try:
                assert_equals(item1, item2, msg='Index %d%s' % (index, name))
            except AssertionError as err:
                yield unic(err)

    def list_should_contain_sub_list(self, list1, list2, msg=None, values=True):
        """Fails if not all of the elements in ``list2`` are found in ``list1``.

        The order of values and the number of values are not taken into
        account.

        See `Lists Should Be Equal` for more information about configuring
        the error message with ``msg`` and ``values`` arguments.
        """
        diffs = ', '.join(unic(item) for item in list2 if item not in list1)
        default = 'Following values were not found from first list: ' + diffs
        _verify_condition(not diffs, default, msg, values)

    def log_list(self, list_, level='INFO'):
        """Logs the length and contents of the ``list`` using given ``level``.

        Valid levels are TRACE, DEBUG, INFO (default), and WARN.

        If you only want to the length, use keyword `Get Length` from
        the BuiltIn library.
        """
        logger.write('\n'.join(self._log_list(list_)), level)

    def _log_list(self, list_):
        if not list_:
            yield 'List is empty.'
        elif len(list_) == 1:
            yield 'List has one item:\n%s' % list_[0]
        else:
            yield 'List length is %d and it contains following items:' % len(list_)
            for index, item in enumerate(list_):
                yield '%s: %s' % (index, item)

    def _index_to_int(self, index, empty_to_zero=False):
        if empty_to_zero and not index:
            return 0
        try:
            return int(index)
        except ValueError:
            raise ValueError("Cannot convert index '%s' to an integer." % index)

    def _index_error(self, list_, index):
        raise IndexError('Given index %s is out of the range 0-%d.'
                         % (index, len(list_)-1))

class _Dictionary(object):

    def convert_to_dictionary(self, item):
        """Converts the given ``item`` to a Python ``dict`` type.

        Mainly useful for converting other mappings to dictionaries. Use
        `Create Dictionary` from the BuiltIn library for constructing new
        dictionaries.

        New in Robot Framework 2.9.
        """
        return dict(item)

    def set_to_dictionary(self, dictionary, *key_value_pairs, **items):
        """Adds the given ``key_value_pairs`` and ``items`` to the ``dictionary``.

        Giving items as ``key_value_pairs`` means giving keys and values
        as separate arguments:

        | Set To Dictionary | ${D1} | key | value | second | ${2} |
        =>
        | ${D1} = {'a': 1, 'key': 'value', 'second': 2}

        Starting from Robot Framework 2.8.1, items can also be given as kwargs
        using ``key=value`` syntax:

        | Set To Dictionary | ${D1} | key=value | second=${2} |

        The latter syntax is typically more convenient to use, but it has
        a limitation that keys must be strings.

        If given keys already exist in the dictionary, their values are updated.
        """
        if len(key_value_pairs) % 2 != 0:
            raise ValueError("Adding data to a dictionary failed. There "
                             "should be even number of key-value-pairs.")
        for i in range(0, len(key_value_pairs), 2):
            dictionary[key_value_pairs[i]] = key_value_pairs[i+1]
        dictionary.update(items)
        return dictionary

    def remove_from_dictionary(self, dictionary, *keys):
        """Removes the given ``keys`` from the ``dictionary``.

        If the given ``key`` cannot be found from the ``dictionary``, it
        is ignored.

        Example:
        | Remove From Dictionary | ${D3} | b | x | y |
        =>
        | ${D3} = {'a': 1, 'c': 3}
        """
        for key in keys:
            if key in dictionary:
                value = dictionary.pop(key)
                logger.info("Removed item with key '%s' and value '%s'." % (key, value))
            else:
                logger.info("Key '%s' not found." % key)

    def keep_in_dictionary(self, dictionary, *keys):
        """Keeps the given ``keys`` in the ``dictionary`` and removes all other.

        If the given ``key`` cannot be found from the ``dictionary``, it
        is ignored.

        Example:
        | Keep In Dictionary | ${D5} | b | x | d |
        =>
        | ${D5} = {'b': 2, 'd': 4}
        """
        remove_keys = [k for k in dictionary if k not in keys]
        self.remove_from_dictionary(dictionary, *remove_keys)

    def copy_dictionary(self, dictionary):
        """Returns a copy of the given dictionary.

        The given dictionary is never altered by this keyword.
        """
        return dictionary.copy()

    def get_dictionary_keys(self, dictionary):
        """Returns keys of the given ``dictionary``.

        Keys are returned in sorted order. The given ``dictionary`` is never
        altered by this keyword.

        Example:
        | ${keys} = | Get Dictionary Keys | ${D3} |
        =>
        | ${keys} = ['a', 'b', 'c']
        """
        # TODO: Possibility to disable sorting. Can be handy with OrderedDicts.
        return sorted(dictionary)

    def get_dictionary_values(self, dictionary):
        """Returns values of the given dictionary.

        Values are returned sorted according to keys. The given dictionary is
        never altered by this keyword.

        Example:
        | ${values} = | Get Dictionary Values | ${D3} |
        =>
        | ${values} = [1, 2, 3]
        """
        return [dictionary[k] for k in self.get_dictionary_keys(dictionary)]

    def get_dictionary_items(self, dictionary):
        """Returns items of the given ``dictionary``.

        Items are returned sorted by keys. The given ``dictionary`` is not
        altered by this keyword.

        Example:
        | ${items} = | Get Dictionary Items | ${D3} |
        =>
        | ${items} = ['a', 1, 'b', 2, 'c', 3]
        """
        ret = []
        for key in self.get_dictionary_keys(dictionary):
            ret.extend((key, dictionary[key]))
        return ret

    def get_from_dictionary(self, dictionary, key):
        """Returns a value from the given ``dictionary`` based on the given ``key``.

        If the given ``key`` cannot be found from the ``dictionary``, this
        keyword fails.

        The given dictionary is never altered by this keyword.

        Example:
        | ${value} = | Get From Dictionary | ${D3} | b |
        =>
        | ${value} = 2
        """
        try:
            return dictionary[key]
        except KeyError:
            raise RuntimeError("Dictionary does not contain key '%s'." % key)

    def dictionary_should_contain_key(self, dictionary, key, msg=None):
        """Fails if ``key`` is not found from ``dictionary``.

        See `List Should Contain Value` for an explanation of ``msg``.

        The given dictionary is never altered by this keyword.
        """
        default = "Dictionary does not contain key '%s'." % key
        _verify_condition(key in dictionary, default, msg)

    def dictionary_should_not_contain_key(self, dictionary, key, msg=None):
        """Fails if ``key`` is found from ``dictionary``.

        See `List Should Contain Value` for an explanation of ``msg``.

        The given dictionary is never altered by this keyword.
        """
        default = "Dictionary contains key '%s'." % key
        _verify_condition(key not in dictionary, default, msg)

    def dictionary_should_contain_item(self, dictionary, key, value, msg=None):
        """An item of ``key``/``value`` must be found in a `dictionary`.

        Value is converted to unicode for comparison.

        See `Lists Should Be Equal` for an explanation of ``msg``.
        The given dictionary is never altered by this keyword.
        """
        self.dictionary_should_contain_key(dictionary, key, msg)
        actual, expected = unicode(dictionary[key]), unicode(value)
        default = "Value of dictionary key '%s' does not match: %s != %s" % (key, actual, expected)
        _verify_condition(actual == expected, default, msg)

    def dictionary_should_contain_value(self, dictionary, value, msg=None):
        """Fails if ``value`` is not found from ``dictionary``.

        See `List Should Contain Value` for an explanation of ``msg``.

        The given dictionary is never altered by this keyword.
        """
        default = "Dictionary does not contain value '%s'." % value
        _verify_condition(value in dictionary.values(), default, msg)

    def dictionary_should_not_contain_value(self, dictionary, value, msg=None):
        """Fails if ``value`` is found from ``dictionary``.

        See `List Should Contain Value` for an explanation of ``msg``.

        The given dictionary is never altered by this keyword.
        """
        default = "Dictionary contains value '%s'." % value
        _verify_condition(not value in dictionary.values(), default, msg)

Answer: def dictionaries_should_be_equal(self, dict1, dict2, msg=None, values=True):

<think>
The class _Dictionary defines a series of keyword methods for dictionary operations. The last defined method is `dictionary_should_not_contain_value`. In the original Robot Framework Collections library, the next keyword after this is `Dictionaries Should Be Equal`, implemented as the method `dictionaries_should_be_equal`. Therefore the next line of code is the method definition header for this keyword.
</think>
def dictionaries_should_be_equal(self, dict1, dict2, msg=None, values=True, names=None):