public override SymbolKeyResolution Resolve(Compilation compilation, bool ignoreAssemblyKey, CancellationToken cancellationToken)
            {
                var elementInfo = elementKey.Resolve(compilation, ignoreAssemblyKey, cancellationToken);

                return(CreateSymbolInfo(GetAllSymbols <ITypeSymbol>(elementInfo).Select(s => compilation.CreateArrayTypeSymbol(s, rank))));
            }
            private static void ParseTypeSymbol(string id, ref int index, Compilation compilation, ISymbol typeParameterContext, List <ISymbol> results)
            {
                var ch = PeekNextChar(id, index);

                // context expression embedded in reference => <context-definition>:<type-parameter>
                // note: this is a deviation from the language spec
                if ((ch == 'M' || ch == 'T') && PeekNextChar(id, index + 1) == ':')
                {
                    var contexts = s_symbolListPool.Allocate();
                    try
                    {
                        ParseDeclaredId(id, ref index, compilation, contexts);
                        if (contexts.Count == 0)
                        {
                            // context cannot be bound, so abort
                            return;
                        }

                        if (PeekNextChar(id, index) == ':')
                        {
                            index++;

                            // try parsing following in all contexts
                            var startIndex = index;
                            foreach (var context in contexts)
                            {
                                index = startIndex;
                                ParseTypeSymbol(id, ref index, compilation, context, results);
                            }
                        }
                        else
                        {
                            // this was a definition where we expected a reference?
                            results.AddRange(contexts.OfType <ITypeSymbol>());
                        }
                    }
                    finally
                    {
                        s_symbolListPool.ClearAndFree(contexts);
                    }
                }
                else
                {
                    if (ch == '`')
                    {
                        ParseTypeParameterSymbol(id, ref index, typeParameterContext, results);
                    }
                    else
                    {
                        ParseNamedTypeSymbol(id, ref index, compilation, typeParameterContext, results);
                    }

                    // apply any array or pointer constructions to results
                    var startIndex = index;
                    var endIndex   = index;

                    for (int i = 0; i < results.Count; i++)
                    {
                        index = startIndex;
                        var typeSymbol = (ITypeSymbol)results[i];

                        while (true)
                        {
                            if (PeekNextChar(id, index) == '[')
                            {
                                var bounds = ParseArrayBounds(id, ref index);
                                typeSymbol = compilation.CreateArrayTypeSymbol(typeSymbol, bounds);
                                continue;
                            }

                            if (PeekNextChar(id, index) == '*')
                            {
                                index++;
                                typeSymbol = compilation.CreatePointerTypeSymbol(typeSymbol);
                                continue;
                            }

                            break;
                        }

                        results[i] = typeSymbol;
                        endIndex   = index;
                    }

                    index = endIndex;
                }
            }