public static int[] ReadArrayRankLength(CachedSnapshot data, CachedSnapshot.ManagedMemorySectionEntriesCache heap, UInt64 address, int iTypeDescriptionArrayType, VirtualMachineInformation virtualMachineInformation)
        {
            if (iTypeDescriptionArrayType < 0)
            {
                return(null);
            }

            var bo     = heap.Find(address, virtualMachineInformation);
            var bounds = bo.Add(virtualMachineInformation.arrayBoundsOffsetInHeader).ReadPointer();

            if (bounds == 0)
            {
                return(new int[1] {
                    bo.Add(virtualMachineInformation.arraySizeOffsetInHeader).ReadInt32()
                });
            }

            var cursor = heap.Find(bounds, virtualMachineInformation);
            int rank   = data.typeDescriptions.GetRank(iTypeDescriptionArrayType);

            int[] l = new int[rank];
            for (int i = 0; i != rank; i++)
            {
                l[i]   = cursor.ReadInt32();
                cursor = cursor.Add(8);
            }
            return(l);
        }
        static int SizeOfObjectInBytes(CachedSnapshot snapshot, int iTypeDescription, BytesAndOffset byteOffset, CachedSnapshot.ManagedMemorySectionEntriesCache heap)
        {
            if (iTypeDescription < 0)
            {
                return(0);
            }

            if (snapshot.typeDescriptions.HasFlag(iTypeDescription, TypeFlags.kArray))
            {
                return(ArrayTools.ReadArrayObjectSizeInBytes(snapshot, byteOffset, iTypeDescription));
            }

            if (snapshot.typeDescriptions.typeDescriptionName[iTypeDescription] == "System.String")
            {
                return(StringTools.ReadStringObjectSizeInBytes(byteOffset, snapshot.virtualMachineInformation));
            }

            //array and string are the only types that are special, all other types just have one size, which is stored in the type description
            return(snapshot.typeDescriptions.size[iTypeDescription]);
        }