/// <summary>
        /// Get a symbol representing a type in the assembly.
        /// </summary>
        /// <param name="unit">Module calling the type.</param>
        /// <param name="type">Name of the type.</param>
        /// <param name="assembly">Assembly containing the type.</param>
        /// <returns>Symbol representing the type.</returns>
        private static Phx.Symbols.MsilTypeSymbol GetTypeSymbol(Phx.ModuleUnit unit, string type, Phx.Symbols.AssemblySymbol assembly)
        {
            Phx.Symbols.MsilTypeSymbol typeSymbol = null;

            // Look for any existing symbol
            foreach (Phx.Symbols.Symbol symbol in unit.SymbolTable.AllSymbols)
            {
                Phx.Symbols.MsilTypeSymbol s = symbol as Phx.Symbols.MsilTypeSymbol;
                if (s != null && s.NameString.Equals(type))
                {
                    typeSymbol = s;
                    break;
                }
            }

            if (typeSymbol == null)
            {
                // Create the symbol if not found
                Phx.Name classTypeName = Phx.Name.New(unit.Lifetime, type);
                typeSymbol = Phx.Symbols.MsilTypeSymbol.New(unit.SymbolTable, classTypeName, 0);

                // Add the type to the assembly's scope
                assembly.InsertInLexicalScope(typeSymbol, classTypeName);
            }

            return(typeSymbol);
        }
        /// <summary>
        /// Get a symbol representing a function that takes an unsigned integer
        /// parameter.
        /// </summary>
        /// <param name="unit">Module calling the function.</param>
        /// <param name="assembly">Name of the assembly.</param>
        /// <param name="type">Name of the class.</param>
        /// <param name="method">Name of the function.</param>
        /// <returns>FunctionSymbol representing the function.</returns>
        private static Phx.Symbols.FunctionSymbol GetFunctionSymbol(Phx.PEModuleUnit unit, string assembly, string type, string method)
        {
            // Look the function up in the cache
            Phx.Symbols.FunctionSymbol functionSymbol = null;
            if (FunctionSymbols.TryGetValue(unit, out functionSymbol) && functionSymbol != null)
            {
                return(functionSymbol);
            }

            // Create symbols for the assemblies and types
            Phx.Symbols.AssemblySymbol assemblySymbol = GetAssemblySymbol(unit, assembly);
            Phx.Symbols.MsilTypeSymbol typeSymbol     = GetTypeSymbol(unit, type, assemblySymbol);

            // Build a symbol reference
            Phx.Types.FunctionTypeBuilder builder = Phx.Types.FunctionTypeBuilder.New(unit.TypeTable);
            builder.Begin();
            builder.CallingConventionKind = Phx.Types.CallingConventionKind.ClrCall;
            builder.AppendReturnParameter(unit.TypeTable.VoidType);
            builder.AppendParameter(unit.TypeTable.UInt32Type);

            // Create the function symbol
            Phx.Name name = Phx.Name.New(unit.Lifetime, method);
            functionSymbol = Phx.Symbols.FunctionSymbol.New(unit.SymbolTable, 0, name, builder.GetFunctionType(), Phx.Symbols.Visibility.GlobalReference);
            typeSymbol.InsertInLexicalScope(functionSymbol, name);

            // Create a type
            Phx.Types.AggregateType aggregate = Phx.Types.AggregateType.NewDynamicSize(unit.TypeTable, typeSymbol);
            aggregate.IsDefinition = false;
            aggregate.AppendMethodSymbol(functionSymbol);

            // Cache the function
            FunctionSymbols[unit] = functionSymbol;

            return(functionSymbol);
        }
        /// <summary>
        /// Get a symbol representing the assembly.
        /// </summary>
        /// <param name="unit">Module calling the assembly.</param>
        /// <param name="assembly">Name of the assembly.</param>
        /// <returns>Symbol representing the assembly.</returns>
        private static Phx.Symbols.AssemblySymbol GetAssemblySymbol(Phx.ModuleUnit unit, string assembly)
        {
            Phx.Symbols.AssemblySymbol assemblySymbol = null;

            // Look for any existing symbol
            foreach (Phx.Symbols.Symbol symbol in unit.SymbolTable.AllSymbols)
            {
                Phx.Symbols.AssemblySymbol s = symbol as Phx.Symbols.AssemblySymbol;
                if (s != null && s.NameString.Equals(assembly))
                {
                    assemblySymbol = s;
                    break;
                }
            }

            if (assemblySymbol == null)
            {
                // Create the assembly manifest
                Phx.Name    name    = Phx.Name.New(unit.Lifetime, assembly);
                Phx.Version version = Phx.Version.New(unit.Lifetime);

                // A bug in Phx.Version ToString renders this field incorrect in
                // the debugger, FYI.
                version.MajorVersion   = (ushort)CoverageVisitAssemblyVersion.Major;
                version.MinorVersion   = (ushort)CoverageVisitAssemblyVersion.Minor;
                version.BuildNumber    = (ushort)CoverageVisitAssemblyVersion.Build;
                version.RevisionNumber = (ushort)CoverageVisitAssemblyVersion.Revision;

                Phx.Manifest manifest = Phx.Manifest.New(unit.Lifetime);
                manifest.Name          = name;
                manifest.HashAlgorithm = 0x00008004;
                manifest.Version       = version;

                if (!string.IsNullOrEmpty(CoverageVisitAssemblyPublicKey))
                {
                    byte[] key = PublicKeyTokenToBytes(CoverageVisitAssemblyPublicKey);
                    if (key != null)
                    {
                        Phx.PublicKey pk = Phx.PublicKey.New(unit.Lifetime);
                        pk.IsPublicKeyToken = true;
                        pk.KeyLength        = (uint)key.Length;
                        pk.Key             = key;
                        manifest.PublicKey = pk;
                    }
                }

                // Create the assembly symbol if not found
                assemblySymbol = Phx.Symbols.AssemblySymbol.New(null, manifest, name, unit.SymbolTable);
            }

            return(assemblySymbol);
        }