/// <summary>
        /// Reads the metadata entry and returns a long-name description, whether or not the full matrix is stored, the data type, and the dimensions.
        /// </summary>
        /// <param name="reader">
        /// The reader from which the metadata is returned.
        /// </param>
        /// <returns>
        /// A long-name description, a sparse indicator, the data type, the dimensions, and the count of values.
        /// </returns>
        private static (string Description, HeaderArrayStorage Storage, HeaderArrayType Type, int[] Dimensions, int Count) GetMetadata([NotNull] BinaryReader reader)
        {
            byte[] descriptionBuffer = InitializeArray(reader);

            HeaderArrayType type = (HeaderArrayType)BitConverter.ToInt16(descriptionBuffer, default(short));

            HeaderArrayStorage storage = (HeaderArrayStorage)BitConverter.ToInt32(descriptionBuffer, sizeof(short));

            string description = Encoding.ASCII.GetString(descriptionBuffer, sizeof(short) + sizeof(int), 70).Trim('\u0000', '\u0002', '\u0020');

            int[] dimensions = new int[BitConverter.ToInt32(descriptionBuffer, sizeof(short) + sizeof(int) + 70)];

            int count = 1;

            for (int i = 0; i < dimensions.Length; i++)
            {
                dimensions[i] = BitConverter.ToInt32(descriptionBuffer, sizeof(short) + sizeof(int) + 70 + sizeof(int) + i * sizeof(int));
                count        *= dimensions[i];
            }

            if (type == HeaderArrayType.C1)
            {
                // 1C is actually a vector of character vectors.
                // So just take the first dimension.
                count = dimensions[0];
            }

            return(description, storage, type, dimensions, count);
        }
        private static TValue[] GetArrayWithSets <TValue>([NotNull] BinaryReader reader, HeaderArrayStorage storage, int count, [NotNull] Func <byte[], int, TValue> converter)
        {
            TValue[] results = new TValue[count];

            switch (storage)
            {
            case HeaderArrayStorage.Full:
            {
                (int index, int _, int[] _) = ReadDimensions(reader);

                while (index > 1)
                {
                    (int _, int offset, int[] _) = ReadExtents(reader);

                    index = GetNextFullSegment(reader, converter, out TValue[] floats);

                    Array.Copy(floats, 0, results, offset, floats.Length);
                }

                return(results);
            }

            case HeaderArrayStorage.Sparse:
            {
                (int NonZeroCount, int SizeOfInteger, int SizeOfReal, string Description)_ = GetExtraMetadata(reader);

                int index = int.MaxValue;

                while (index > 1)
                {
                    index = GetNextSparseSegment(reader, converter, out TValue[] values, out int[] pointers);

                    for (int i = 0; i < pointers.Length; i++)
                    {
                        results[pointers[i]] = values[i];
                    }
                }

                return(results);
            }

            default:
            {
                throw new DataValidationException("An unknown header array storage was encountered.", "FULL, SPSE", storage);
            }
            }
        }
        private static TValue[] GetTwoDimensionalArray <TValue>([NotNull] BinaryReader reader, HeaderArrayStorage storage, int count, [NotNull] Func <byte[], int, TValue> converter)
        {
            TValue[] results = new TValue[count];

            switch (storage)
            {
            case HeaderArrayStorage.Full:
            {
                int index   = int.MaxValue;
                int counter = 0;
                while (index > 1)
                {
                    index = GetNextTwoDimensionalSegment(reader, converter, out TValue[] values);

                    Array.Copy(values, 0, results, counter, values.Length);

                    counter += values.Length;
                }

                return(results);
            }

            case HeaderArrayStorage.Sparse:
            {
                throw new NotSupportedException("The storage SPSE is not supported for 2-dimensional arrays");
            }

            default:
            {
                throw new DataValidationException("An unknown header array storage was encountered.", "FULL, SPSE", storage);
            }
            }
        }