private void RegisterMobileControlTagPrefix()
        {
            // Try to load the Mobile assembly if not already done
            if (!_fTriedToLoadMobileAssembly)
            {
                _mobileAssembly = LoadAssembly(AssemblyRef.SystemWebMobile, false /*throwOnFail*/);

                if (_mobileAssembly != null)
                {
                    _mobilePageType = _mobileAssembly.GetType("System.Web.UI.MobileControls.MobilePage");
                    Debug.Assert(_mobilePageType != null);
                    _mobileUserControlType = _mobileAssembly.GetType("System.Web.UI.MobileControls.MobileUserControl");
                    Debug.Assert(_mobileUserControlType != null);
                }

                _fTriedToLoadMobileAssembly = true;
            }

            if (_mobileAssembly == null)
            {
                return;
            }

            RootBuilder.RegisterTagPrefix("Mobile", "System.Web.UI.MobileControls", _mobileAssembly);
        }
        internal override void ProcessDirective(string directiveName, IDictionary directive)
        {
            if (string.Compare(directiveName, "outputcache", true, CultureInfo.InvariantCulture) == 0)
            {
                // Make sure the outputcache directive was not already specified
                if (_outputCacheDirective != null)
                {
                    throw new HttpException(
                              HttpRuntime.FormatResourceString(SR.Only_one_directive_allowed, directiveName));
                }

                ProcessOutputCacheDirective(directiveName, directive);

                _outputCacheDirective = directive;
            }
            else if (string.Compare(directiveName, "register", true, CultureInfo.InvariantCulture) == 0)
            {
                // Register directive

                // Optionally, allow an assembly, which is used by the designer
                string   assemblyName = Util.GetAndRemoveNonEmptyAttribute(directive, "assembly");
                Assembly assembly     = null;
                if (assemblyName != null)
                {
                    assembly = AddAssemblyDependency(assemblyName);

                    if (assembly == null)
                    {
                        // It should never be null at runtime, since it throws
                        Debug.Assert(FInDesigner, "FInDesigner");

                        // Just ignore the directive (ASURT 100454)
                        return;
                    }
                }

                // Get the tagprefix, which is required
                string prefix = Util.GetAndRemoveNonEmptyIdentifierAttribute(directive, "tagprefix");
                if (prefix == null)
                {
                    throw new HttpException(HttpRuntime.FormatResourceString(
                                                SR.Missing_attr, "tagprefix"));
                }

                string tagName = Util.GetAndRemoveNonEmptyIdentifierAttribute(directive, "tagname");
                string src     = Util.GetAndRemoveNonEmptyAttribute(directive, "src");
                string ns      = Util.GetAndRemoveNonEmptyNoSpaceAttribute(directive, "namespace");

                if (tagName != null)
                {
                    // If tagname was specified, 'src' is required
                    if (src == null)
                    {
                        throw new HttpException(HttpRuntime.FormatResourceString(SR.Missing_attr, "src"));
                    }

                    EnsureNullAttribute("namespace", ns);
                }
                else
                {
                    // If tagname was NOT specified, 'namespace' is required
                    if (ns == null)
                    {
                        throw new HttpException(HttpRuntime.FormatResourceString(SR.Missing_attr, "namespace"));
                    }

                    // Assembly is also required (ASURT 61326)
                    if (assembly == null)
                    {
                        throw new HttpException(HttpRuntime.FormatResourceString(SR.Missing_attr, "assembly"));
                    }

                    EnsureNullAttribute("src", src);
                }

                // If there are some attributes left, fail
                Util.CheckUnknownDirectiveAttributes(directiveName, directive);

                // Is it a single tag to .aspx file mapping?
                if (tagName != null)
                {
                    // Compile it into a Type
                    Type type = GetUserControlType(src);

                    // Register the new tag, including its prefix
                    RootBuilder.RegisterTag(prefix + ":" + tagName, type);

                    return;
                }

                AddImportEntry(ns);

                // If there is a prefix, register the namespace to allow tags with
                // that prefix to be created.
                RootBuilder.RegisterTagPrefix(prefix, ns, assembly);
            }
            else if (string.Compare(directiveName, "reference", true, CultureInfo.InvariantCulture) == 0)
            {
                string page    = Util.GetAndRemoveNonEmptyNoSpaceAttribute(directive, "page");
                string control = Util.GetAndRemoveNonEmptyNoSpaceAttribute(directive, "control");

                // If neither or both are specified, fail
                if ((page == null) == (control == null))
                {
                    throw new HttpException(HttpRuntime.FormatResourceString(SR.Invalid_reference_directive));
                }

                if (page != null)
                {
                    GetReferencedPageType(page);
                }

                if (control != null)
                {
                    GetUserControlType(control);
                }

                // If there are some attributes left, fail
                Util.CheckUnknownDirectiveAttributes(directiveName, directive);
            }
            else
            {
                base.ProcessDirective(directiveName, directive);
            }
        }