private static MetadataTypeReference ReadGenericArgument(ref StringSpan remaining)
        {
            var isBracketed = TryRead(ref remaining, '[');

            var(typeName, genericArguments, nestedArrayRanks) = ReadTypeParts(ref remaining);

            var assemblyName = default(StringSpan);

            if (isBracketed)
            {
                var endingBracket = remaining.IndexOf(']');
                if (endingBracket == -1)
                {
                    throw new FormatException("Expected ']'");
                }
                assemblyName = TryReadAssemblyName(remaining.Slice(0, endingBracket));
                remaining    = remaining.Slice(endingBracket + 1);
            }

            return(CreateType(typeName, assemblyName, genericArguments, nestedArrayRanks));
        }
        ReadTypeParts(ref StringSpan remaining)
        {
            var firstComma   = remaining.IndexOf(',');
            var beforeComma  = firstComma != -1 ? remaining.Slice(0, firstComma) : remaining;
            var firstBracket = beforeComma.IndexOf('[');

            if (firstBracket == -1)
            {
                var outerEndingBracket = beforeComma.IndexOf(']');
                if (outerEndingBracket != -1)
                {
                    remaining = remaining.Slice(outerEndingBracket);
                    return(beforeComma.Slice(0, outerEndingBracket), null, null);
                }

                remaining = firstComma != -1 ? remaining.Slice(firstComma) : default;
                return(beforeComma, null, null);
            }

            var typeName = remaining.Slice(0, firstBracket);

            remaining = remaining.Slice(firstBracket + 1);

            var nestedArrayRanks = (List <int>)null;

            IReadOnlyList <MetadataTypeReference> genericArguments;
            var hasGenericAritySeparator = typeName.LastIndexOf('`') != -1;

            if (!hasGenericAritySeparator)
            {
                genericArguments = null;
                nestedArrayRanks = new List <int> {
                    ReadArrayRank(ref remaining)
                };
            }
            else
            {
                genericArguments = ReadGenericArgumentList(ref remaining);
                if (genericArguments.Count == 0)
                {
                    throw new FormatException("Expected: generic argument");
                }
            }

            for (;;)
            {
                while (TryRead(ref remaining, ' '))
                {
                }
                if (!TryRead(ref remaining, '['))
                {
                    break;
                }
                if (nestedArrayRanks == null)
                {
                    nestedArrayRanks = new List <int>();
                }
                nestedArrayRanks.Add(ReadArrayRank(ref remaining));
            }

            return(typeName, genericArguments, nestedArrayRanks);
        }