private void LazyLoadDtd(Uri baseUri)
		{
			if (this.m_dtd == null && !this.m_ignoreDtd)
			{
				if (string.IsNullOrEmpty(this.m_syslit))
				{
					if (this.m_docType != null && StringUtilities.EqualsIgnoreCase(this.m_docType, "html"))
					{
						var type = this.GetType();
						var name = type.Namespace + ".Html.dtd";
#if NETFX_CORE
						using (var stm = type.GetTypeInfo().Assembly.GetManifestResourceStream(name))
#else
						using (var stm = type.Assembly.GetManifestResourceStream(name))
#endif
						{
							var sr = new StreamReader(stm, Encoding.UTF8, true);
							this.m_dtd = SgmlDtd.Parse(baseUri, "HTML", sr, null, this.m_streamOpener, null);
						}
					}
				}
				else
				{
					if (baseUri != null)
					{
						baseUri = new Uri(baseUri, this.m_syslit);
					}
					else if (this.m_baseUri != null)
					{
						baseUri = new Uri(this.m_baseUri, this.m_syslit);
					}
					else
					{
						baseUri = new Uri(this.m_syslit);
					}
					this.m_dtd = SgmlDtd.Parse(baseUri, this.m_docType, this.m_pubid, baseUri.AbsoluteUri, this.m_subset, this.m_streamOpener, null);
				}
			}

			if (this.m_dtd != null && this.m_dtd.Name != null)
			{
				switch (this.CaseFolding)
				{
					case CaseFolding.ToUpper:
						this.m_rootElementName = this.m_dtd.Name.ToUpperInvariant();
						break;
					case CaseFolding.ToLower:
						this.m_rootElementName = this.m_dtd.Name.ToLowerInvariant();
						break;
					default:
						this.m_rootElementName = this.m_dtd.Name;
						break;
				}

				this.m_isHtml = StringUtilities.EqualsIgnoreCase(this.m_dtd.Name, "html");
			}
		}
		public static SgmlDtd Parse(Uri baseUri, string name, TextReader input, string subset, Func<Uri, StreamInformation> streamOpener, XmlNameTable nt)
		{
			SgmlDtd dtd = new SgmlDtd(name, nt);
			dtd.PushEntity(baseUri, new Entity(dtd.Name, baseUri, input, streamOpener));
			if (!string.IsNullOrEmpty(subset))
			{
				dtd.PushEntity(baseUri, new Entity(name, subset));
			}

			try
			{
				dtd.Parse();
			}
			catch (Exception e)
			{
				throw new SgmlParseException(e.Message + dtd.m_current.Context());
			}

			return dtd;
		}
		/// <summary>
		/// Checks whether an element using this group can contain a specified element.
		/// </summary>
		/// <param name="name">The name of the element to look for.</param>
		/// <param name="dtd">The DTD to use during the checking.</param>
		/// <returns>true if an element using this group can contain the element, otherwise false.</returns>
		public bool CanContain(string name, SgmlDtd dtd)
		{
			if (m_declaredContent != DeclaredContent.Default)
				return false; // empty or text only node.

			return m_model.CanContain(name, dtd);
		}
		/// <summary>
		/// Checks whether an element using this group can contain a specified element.
		/// </summary>
		/// <param name="name">The name of the element to look for.</param>
		/// <param name="dtd">The DTD to use during the checking.</param>
		/// <returns>true if an element using this group can contain the element, otherwise false.</returns>
		/// <remarks>
		/// Rough approximation - this is really assuming an "Or" group
		/// </remarks>
		public bool CanContain(string name, SgmlDtd dtd)
		{
			if (dtd == null)
				throw new ArgumentNullException("dtd");

			// Do a simple search of members.
			foreach (object obj in Members)
			{
				if (obj is string)
				{
					if (string.Equals((string)obj, name, StringComparison.OrdinalIgnoreCase))
						return true;
				}
			}
			// didn't find it, so do a more expensive search over child elements
			// that have optional start tags and over child groups.
			foreach (object obj in Members)
			{
				string s = obj as string;
				if (s != null)
				{
					ElementDecl e = dtd.FindElement(s);
					if (e != null)
					{
						if (e.StartTagOptional)
						{
							// tricky case, the start tag is optional so element may be
							// allowed inside this guy!
							if (e.CanContain(name, dtd))
								return true;
						}
					}
				}
				else
				{
					Group m = (Group)obj;
					if (m.CanContain(name, dtd))
						return true;
				}
			}

			return false;
		}
		/// <summary>
		/// Tests whether this element can contain another specified element.
		/// </summary>
		/// <param name="name">The name of the element to check for.</param>
		/// <param name="dtd">The DTD to use to do the check.</param>
		/// <returns>True if the specified element can be contained by this element.</returns>
		public bool CanContain(string name, SgmlDtd dtd)
		{
			// return true if this element is allowed to contain the given element.
			if (m_exclusions != null)
			{
				foreach (string s in m_exclusions)
				{
					if (string.Equals(s, name, StringComparison.OrdinalIgnoreCase))
						return false;
				}
			}

			if (m_inclusions != null)
			{
				foreach (string s in m_inclusions)
				{
					if (string.Equals(s, name, StringComparison.OrdinalIgnoreCase))
						return true;
				}
			}
			return m_contentModel.CanContain(name, dtd);
		}