* Mono.Documentation/monodocer.cs: Only provide a Main() method and
authorJonathan Pryor <jpryor@novell.com>
Fri, 17 Oct 2008 04:11:03 +0000 (04:11 -0000)
committerJonathan Pryor <jpryor@novell.com>
Fri, 17 Oct 2008 04:11:03 +0000 (04:11 -0000)
  use Mono.GetOptions when targeting .NET 1.0 (i.e. monodocer1.exe).

svn path=/trunk/mcs/; revision=116151

1  2 
mcs/tools/mdoc/ChangeLog
mcs/tools/mdoc/Mono.Documentation/monodocer.cs
mcs/tools/mdoc/Resources/monodoc-ecma.xsd
mcs/tools/mdoc/monodoc-ecma.xsd

index d7c2366d696292fac4817a644a40c41b65e15034,d7c2366d696292fac4817a644a40c41b65e15034..3018f48fee6577cd0ca414a38f3d738d6f313b5a
@@@ -1,3 -1,3 +1,8 @@@
++2008-10-17  Jonathan Pryor <jpryor@novell.com>
++
++      * Mono.Documentation/monodocer.cs: Only provide a Main() method and
++        use Mono.GetOptions when targeting .NET 1.0 (i.e. monodocer1.exe).
++
  2008-10-16  Jonathan Pryor <jpryor@novell.com>
  
  Migration from monodoc/tools to mcs/tools/mdoc...
index 428c152c8bf7c875d99bfdf0cb8cbd2d8520b624,0000000000000000000000000000000000000000..12b7d06c37338e11c3dbbfd0a2f2734bfb5ce74d
mode 100644,000000..100644
--- /dev/null
@@@ -1,4041 -1,0 +1,4080 @@@
- #if NET_1_0
 +// Updater program for syncing Mono's ECMA-style documentation files
 +// with an assembly.
 +// By Joshua Tauberer <tauberer@for.net>
 +
 +using System;
 +using System.Collections;
 +#if !NET_1_0
 +using System.Collections.Generic;
 +#endif
 +using System.Globalization;
 +using System.IO;
 +using System.Text;
 +using System.Reflection;
 +using System.Xml;
 +using System.Xml.XPath;
 +
++#if NET_1_0
 +using Mono.GetOptions;
 +
- [assembly: AssemblyTitle("Monodocer - The Mono Documentation Tool")]
- [assembly: AssemblyCopyright("Copyright (c) 2004 Joshua Tauberer <tauberer@for.net>\nreleased under the GPL.")]
- [assembly: AssemblyDescription("A tool for creating and updating Mono XML documentation files for assemblies.")]
 +using MemberInfoEnumerable = System.Collections.IEnumerable;
 +using MyXmlNodeList        = System.Collections.ArrayList;
 +using StringList           = System.Collections.ArrayList;
 +using StringToStringMap    = System.Collections.Hashtable;
 +using StringToXmlNodeMap   = System.Collections.Hashtable;
 +#else
 +using MemberInfoEnumerable = System.Collections.Generic.IEnumerable<System.Reflection.MemberInfo>;
 +using MyXmlNodeList        = System.Collections.Generic.List<System.Xml.XmlNode>;
 +using StringList           = System.Collections.Generic.List<string>;
 +using StringToStringMap    = System.Collections.Generic.Dictionary<string, string>;
 +using StringToXmlNodeMap   = System.Collections.Generic.Dictionary<string, System.Xml.XmlNode>;
 +#endif
 +
- [assembly: Mono.UsageComplement("")]
++namespace Mono.Documentation {
 +
- namespace Mono.Documentation {
- public class Updater {
++class MDocUpdaterOptions 
++#if NET_1_0
++      : Options
++#endif
++{
++#if NET_1_0
++      [Option("The root {directory} of an assembly's documentation files.")]
++#endif
++      public string path = null;
 +
-       private class Opts : Options {
-               [Option("The root {directory} of an assembly's documentation files.")]
-               public string path = null;
-               [Option("When updating documentation, write the updated files to this {path}.")]
-               public string updateto = null;
-               [Option(-1, "The assembly to document.  Specify a {file} path or the name of a GAC'd assembly.")]
-               public string[] assembly = null;
-               [Option(-1, "Document only the {type name}d by this argument.")]
-               public string[] type = null;
-               [Option("Update only the types in this {namespace}.")]
-               public string @namespace = null;
-               [Option("Allow monodocer to delete members from files.")]
-               public bool delete = false;
-               [Option("Include overridden methods in documentation.")]
-               public bool overrides = false;
-               [Option("Don't update members.")]
-               public bool ignoremembers = false;
-               [Option("Don't rename documentation XML files for missing types.  IGNORED.")]
-               public bool ignore_extra_docs = false;
-               [Option("The {name} of the project this documentation is for.")]
-               public string name;
-               [Option("An XML documentation {file} made by the /doc option of mcs/csc the contents of which will be imported.")]
-               public string importslashdoc;
-               
-               [Option("An ECMA or monodoc-generated XML documemntation {file} to import.")]
-               public string importecmadoc;
-               [Option("Import either a /doc or ECMA documentation file.")]
-               public string import;
-               [Option("Indent the XML files nicely.")]
-               public bool pretty = false;
-               
-               [Option("Create a <since/> element for added types/members with the value {since}.")]
-               public string since;
-               [Option("Show full stack trace on error.")]
-               public bool show_exceptions;
-       }
-       
-       public static void Main(string[] args) {
-               Opts opts = new Opts();
++#if NET_1_0
++      [Option("When updating documentation, write the updated files to this {path}.")]
++#endif
++      public string updateto = null;
++
++#if NET_1_0
++      [Option(-1, "The assembly to document.  Specify a {file} path or the name of a GAC'd assembly.")]
++#endif
++      public string[] assembly = null;
++
++#if NET_1_0
++      [Option(-1, "Document only the {type name}d by this argument.")]
++#endif
++      public string[] type = null;
++
++#if NET_1_0
++      [Option("Update only the types in this {namespace}.")]
++#endif
++      public string @namespace = null;
++
++#if NET_1_0
++      [Option("Allow monodocer to delete members from files.")]
++#endif
++      public bool delete = false;
++
++#if NET_1_0
++      [Option("Include overridden methods in documentation.")]
++#endif
++      public bool overrides = false;
++
++#if NET_1_0
++      [Option("Don't update members.")]
++#endif
++      public bool ignoremembers = false;
++
++#if NET_1_0
++      [Option("Don't rename documentation XML files for missing types.  IGNORED.")]
++#endif
++      public bool ignore_extra_docs = false;
++
++#if NET_1_0
++      [Option("The {name} of the project this documentation is for.")]
++#endif
++      public string name;
++
++#if NET_1_0
++      [Option("An XML documentation {file} made by the /doc option of mcs/csc the contents of which will be imported.")]
++#endif
++      public string importslashdoc;
++      
++#if NET_1_0
++      [Option("An ECMA or monodoc-generated XML documemntation {file} to import.")]
++#endif
++      public string importecmadoc;
++
++#if NET_1_0
++      [Option("Import either a /doc or ECMA documentation file.")]
++#endif
++      public string import;
++
++#if NET_1_0
++      [Option("Indent the XML files nicely.")]
++#endif
++      public bool pretty = false;
++      
++#if NET_1_0
++      [Option("Create a <since/> element for added types/members with the value {since}.")]
++#endif
++      public string since;
++
++#if NET_1_0
++      [Option("Show full stack trace on error.")]
++#endif
++      public bool show_exceptions;
++}
++
++class MDocUpdater {
 +      
 +      static string srcPath;
 +      static Assembly[] assemblies;
 +      
 +      static bool nooverrides = true, delete = false, ignoremembers = false;
 +      static bool pretty = false;
 +      static bool show_exceptions = false;
 +      
 +      static int additions = 0, deletions = 0;
 +
 +      static string name;
 +      static XmlDocument slashdocs;
 +      static XmlReader ecmadocs;
 +
 +      static string since;
 +
 +      static MemberFormatter csharpFullFormatter  = new CSharpFullMemberFormatter ();
 +      static MemberFormatter csharpFormatter      = new CSharpMemberFormatter ();
 +      static MemberFormatter docTypeFormatter     = new DocTypeMemberFormatter ();
 +      static MemberFormatter slashdocFormatter    = new SlashDocMemberFormatter ();
 +      static MemberFormatter filenameFormatter    = new FileNameMemberFormatter ();
 +
 +      static MyXmlNodeList extensionMethods = new MyXmlNodeList ();
 +
 +      const BindingFlags DefaultBindingFlags = 
 +              BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
 +      
-               IEnumerable<Mono.Documentation.Updater.DocsTypeInfo>
++#if NET_1_0
++      public static void Main(string[] args)
++      {
++              MDocUpdaterOptions opts = new MDocUpdaterOptions ();
 +              opts.ProcessArgs(args);
 +
 +              if (args.Length == 0) {
 +                      opts.DoHelp();
 +                      return;
 +              }
++              Run (opts);
++      }
++#endif
 +              
++      public static void Run (MDocUpdaterOptions opts)
++      {
 +              nooverrides = !opts.overrides;
 +              delete = opts.delete;
 +              ignoremembers = opts.ignoremembers;
 +              name = opts.name;
 +              pretty = opts.pretty;
 +              since = opts.since;
 +              show_exceptions = opts.show_exceptions;
 +
 +              try {
 +                      // PARSE BASIC OPTIONS AND LOAD THE ASSEMBLY TO DOCUMENT
 +                      
 +                      if (opts.path == null)
 +                              throw new InvalidOperationException("The path option is required.");
 +                      
 +                      srcPath = opts.path;
 +
 +                      if (opts.type != null && opts.type.Length > 0 && opts.@namespace != null)
 +                              throw new InvalidOperationException("You cannot specify both 'type' and 'namespace'.");
 +                      
 +                      if (opts.assembly == null)
 +                              throw new InvalidOperationException("The assembly option is required.");
 +                              
 +                      assemblies = new Assembly [opts.assembly.Length];
 +                      for (int i = 0; i < opts.assembly.Length; i++)
 +                              assemblies [i] = LoadAssembly (opts.assembly [i]);
 +                              
 +                      // IMPORT FROM /DOC?
 +                      
 +                      if (opts.importslashdoc != null) {
 +                              try {
 +                                      slashdocs = new XmlDocument();
 +                                      slashdocs.Load(opts.importslashdoc);
 +                              } catch (Exception e) {
 +                                      Error ("Could not load /doc file: {0}", e.Message);
 +                                      Environment.ExitCode = 1;
 +                                      return;
 +                              }
 +                      }
 +                      
 +                      if (opts.importecmadoc != null) {
 +                              try {
 +                                      ecmadocs = new XmlTextReader (opts.importecmadoc);
 +                              } catch (Exception e) {
 +                                      Error ("Could not load ECMA XML file: {0}", e.Message);
 +                                      Environment.ExitCode = 1;
 +                                      return;
 +                              }
 +                      }
 +
 +                      if (opts.import != null && ecmadocs == null && slashdocs == null) {
 +                              try {
 +                                      XmlReader r = new XmlTextReader (opts.import);
 +                                      if (r.Read ()) {
 +                                              while (r.NodeType != XmlNodeType.Element) {
 +                                                      if (!r.Read ())
 +                                                              throw new Exception ("Unable to read XML file: " + 
 +                                                                              opts.import);
 +                                              }
 +                                              if (r.LocalName == "doc") {
 +                                                      slashdocs = new XmlDocument();
 +                                                      slashdocs.Load (opts.import);
 +                                              }
 +                                              else if (r.LocalName == "Libraries") {
 +                                                      ecmadocs = new XmlTextReader (opts.import);
 +                                              }
 +                                              else
 +                                                      throw new Exception ("Unsupported XML format within " + opts.import);
 +                                      }
 +                                      r.Close ();
 +                              } catch (Exception e) {
 +                                      Error ("Could not load XML file: {0}", e.Message);
 +                                      Environment.ExitCode = 1;
 +                                      return;
 +                              }
 +                      }
 +                      
 +                      // PERFORM THE UPDATES
 +                      
 +                      string dest_dir = opts.updateto != null ? opts.updateto : opts.path;
 +                      if (opts.type != null && opts.type.Length > 0)
 +                              DoUpdateTypes(opts.path, opts.type, dest_dir);
 +                      else if (opts.@namespace != null)
 +                              DoUpdateNS (opts.@namespace, Path.Combine (opts.path, opts.@namespace),
 +                                              Path.Combine (dest_dir, opts.@namespace));
 +                      else
 +                              DoUpdateAssemblies(opts.path, dest_dir);
 +              
 +              } catch (InvalidOperationException error) {
 +                      Error (opts.show_exceptions ? error.ToString () : error.Message);
 +                      Environment.ExitCode = 1;
 +                      return;
 +                      
 +              } catch (System.IO.IOException error) {
 +                      Error (opts.show_exceptions ? error.ToString () : error.Message);
 +                      Environment.ExitCode = 1;
 +                      return;
 +
 +              } catch (Exception error) {
 +                      Error (opts.show_exceptions ? error.ToString () : error.Message);
 +                      Environment.ExitCode = 1;
 +              }
 +
 +              Console.WriteLine("Members Added: {0}, Members Deleted: {1}", additions, deletions);
 +      }
 +
 +      private static void Error (object message)
 +      {
 +              Console.Error.Write ("monodocer: ");
 +              Console.Error.WriteLine (message);
 +      }
 +      
 +      private static void Error (string format, params object[] args)
 +      {
 +              Console.Error.Write ("monodocer: ");
 +              Console.Error.WriteLine (format, args);
 +      }
 +      
 +      private static Assembly LoadAssembly (string name)
 +      {
 +              Assembly assembly = null;
 +              try {
 +                      assembly = Assembly.LoadFile (name);
 +              } catch (System.IO.FileNotFoundException) { }
 +
 +              if (assembly == null) {
 +                      try {
 +                              assembly = Assembly.LoadWithPartialName (name);
 +                      } catch (Exception) { }
 +              }
 +                      
 +              if (assembly == null)
 +                      throw new InvalidOperationException("Assembly " + name + " not found.");
 +
 +              return assembly;
 +      }
 +
 +      private static void WriteXml(XmlElement element, System.IO.TextWriter output) {
 +              OrderTypeAttributes (element);
 +              XmlTextWriter writer = new XmlTextWriter(output);
 +              writer.Formatting = Formatting.Indented;
 +              writer.Indentation = 2;
 +              writer.IndentChar = ' ';
 +              element.WriteTo(writer);
 +              output.WriteLine();     
 +      }
 +
 +      private static void OrderTypeAttributes (XmlElement e)
 +      {
 +              foreach (XmlElement type in e.SelectNodes ("//Type")) {
 +                      OrderTypeAttributes (type.Attributes);
 +              }
 +      }
 +
 +      static readonly string[] TypeAttributeOrder = {
 +              "Name", "FullName", "FullNameSP", "Maintainer"
 +      };
 +
 +      private static void OrderTypeAttributes (XmlAttributeCollection c)
 +      {
 +              XmlAttribute[] attrs = new XmlAttribute [TypeAttributeOrder.Length];
 +              for (int i = 0; i < c.Count; ++i) {
 +                      XmlAttribute a = c [i];
 +                      for (int j = 0; j < TypeAttributeOrder.Length; ++j) {
 +                              if (a.Name == TypeAttributeOrder [j]) {
 +                                      attrs [j] = a;
 +                                      break;
 +                              }
 +                      }
 +              }
 +              for (int i = attrs.Length-1; i >= 0; --i) {
 +                      XmlAttribute n = attrs [i];
 +                      if (n == null)
 +                              continue;
 +                      XmlAttribute r = null;
 +                      for (int j = i+1; j < attrs.Length; ++j) {
 +                              if (attrs [j] != null) {
 +                                      r = attrs [j];
 +                                      break;
 +                              }
 +                      }
 +                      if (r == null)
 +                              continue;
 +                      c.Remove (n);
 +                      c.InsertBefore (n, r);
 +              }
 +      }
 +      
 +      private static XmlDocument CreateIndexStub() {
 +              XmlDocument index = new XmlDocument();
 +
 +              XmlElement index_root = index.CreateElement("Overview");
 +              index.AppendChild(index_root);
 +
 +              if (assemblies.Length == 0)
 +                      throw new Exception ("No assembly");
 +
 +              XmlElement index_assemblies = index.CreateElement("Assemblies");
 +              index_root.AppendChild(index_assemblies);
 +
 +              XmlElement index_remarks = index.CreateElement("Remarks");
 +              index_remarks.InnerText = "To be added.";
 +              index_root.AppendChild(index_remarks);
 +
 +              XmlElement index_copyright = index.CreateElement("Copyright");
 +              index_copyright.InnerText = "To be added.";
 +              index_root.AppendChild(index_copyright);
 +
 +              XmlElement index_types = index.CreateElement("Types");
 +              index_root.AppendChild(index_types);
 +              
 +              return index;
 +      }
 +      
 +      private static void WriteNamespaceStub(string ns, string outdir) {
 +              XmlDocument index = new XmlDocument();
 +
 +              XmlElement index_root = index.CreateElement("Namespace");
 +              index.AppendChild(index_root);
 +              
 +              index_root.SetAttribute("Name", ns);
 +
 +              XmlElement index_docs = index.CreateElement("Docs");
 +              index_root.AppendChild(index_docs);
 +
 +              XmlElement index_summary = index.CreateElement("summary");
 +              index_summary.InnerText = "To be added.";
 +              index_docs.AppendChild(index_summary);
 +
 +              XmlElement index_remarks = index.CreateElement("remarks");
 +              index_remarks.InnerText = "To be added.";
 +              index_docs.AppendChild(index_remarks);
 +
 +              using (TextWriter writer = OpenWrite (outdir + "/ns-" + ns + ".xml",  FileMode.CreateNew)) {
 +                      WriteXml(index.DocumentElement, writer);
 +              }
 +      }
 +
 +      public static void DoUpdateTypes(string basepath, string[] typenames, string dest) {
 +              ArrayList found = new ArrayList ();
 +              foreach (Assembly assembly in assemblies) {
 +                      foreach (DocsTypeInfo docsTypeInfo in GetTypes (assembly, typenames)) {
 +                              string relpath = DoUpdateType (docsTypeInfo.Type, basepath, dest, docsTypeInfo.EcmaDocs);
 +                              if (relpath != null)
 +                                      found.Add (docsTypeInfo.Type.FullName);
 +                      }
 +              }
 +              StringList notFound = new StringList (typenames.Length);
 +              foreach (string typename in typenames)
 +                      if (!found.Contains (typename))
 +                              notFound.Add (typename);
 +              if (notFound.Count > 0)
 +                      throw new InvalidOperationException("Type(s) not found: " + string.Join (", ", DocUtils.ToStringArray (notFound)));
 +      }
 +
 +      public static string DoUpdateType(Type type, string basepath, string dest, XmlReader ecmaDocsType)
 +      {
 +              if (type.Namespace == null)
 +                      Error ("warning: The type `{0}' is in the root namespace.  This may cause problems with display within monodoc.",
 +                                      type.FullName);
 +              if (!IsPublic (type))
 +                      return null;
 +              
 +              // Must get the A+B form of the type name.
 +              string typename = GetTypeFileName(type);
 +              
 +              string reltypefile = DocUtils.PathCombine (type.Namespace, typename + ".xml");
 +              string typefile = Path.Combine (basepath, reltypefile);
 +              System.IO.FileInfo file = new System.IO.FileInfo(typefile);
 +
 +              string output = null;
 +              if (dest == null) {
 +                      output = typefile;
 +              } else if (dest == "-") {
 +                      output = null;
 +              } else {
 +                      output = Path.Combine (dest, reltypefile);
 +              }       
 +
 +              if (file.Exists) {
 +                      // Update
 +                      XmlDocument basefile = new XmlDocument();
 +                      if (!pretty) basefile.PreserveWhitespace = true;
 +                      try {
 +                              basefile.Load(typefile);
 +                      } catch (Exception e) {
 +                              throw new InvalidOperationException("Error loading " + typefile + ": " + e.Message, e);
 +                      }
 +                      
 +                      DoUpdateType2("Updating", basefile, type, output, false, ecmaDocsType);
 +              } else {
 +                      // Stub
 +                      XmlElement td = StubType(type, output, ecmaDocsType);
 +                      if (td == null)
 +                              return null;
 +                      
 +                      System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo (DocUtils.PathCombine (dest, type.Namespace));
 +                      if (!dir.Exists) {
 +                              dir.Create();
 +                              Console.WriteLine("Namespace Directory Created: " + type.Namespace);
 +                      }
 +              }
 +              return reltypefile;
 +      }
 +
 +      private static XPathNavigator SelectSingleNode (XPathNavigator n, string xpath)
 +      {
 +#if !NET_1_0
 +              return n.SelectSingleNode (xpath);
 +#else
 +              XPathNodeIterator i = n.Select (xpath);
 +              XPathNavigator r = null;
 +              while (i.MoveNext ()) {
 +                      r = i.Current;
 +              }
 +              return r;
 +#endif
 +      }
 +
 +      public static void DoUpdateNS(string ns, string nspath, string outpath) {
 +              Hashtable seenTypes = new Hashtable();
 +              Assembly assembly = assemblies [0];
 +              
 +              foreach (System.IO.FileInfo file in new System.IO.DirectoryInfo(nspath).GetFiles("*.xml")) {
 +                      XmlDocument basefile = new XmlDocument();
 +                      if (!pretty) basefile.PreserveWhitespace = true;
 +                      string typefile = Path.Combine(nspath, file.Name);
 +                      try {
 +                              basefile.Load(typefile);
 +                      } catch (Exception e) {
 +                              throw new InvalidOperationException("Error loading " + typefile + ": " + e.Message, e);
 +                      }
 +
 +                      string typename = 
 +                              GetTypeFileName (basefile.SelectSingleNode("Type/@FullName").InnerText);
 +                      Type type = assembly.GetType(typename, false);
 +                      if (type == null) {
 +                              Error ("Type no longer in assembly: " + typename);
 +                              continue;
 +                      }                       
 +
 +                      seenTypes[type] = seenTypes;
 +                      DoUpdateType2("Updating", basefile, type, Path.Combine(outpath, file.Name), false, null);
 +              }
 +              
 +              // Stub types not in the directory
 +              foreach (DocsTypeInfo docsTypeInfo in GetTypes (assembly, null)) {
 +                      Type type = docsTypeInfo.Type;
 +                      if (type.Namespace != ns || seenTypes.ContainsKey(type))
 +                              continue;
 +
 +                      XmlElement td = StubType(type, Path.Combine(outpath, GetTypeFileName(type) + ".xml"), docsTypeInfo.EcmaDocs);
 +                      if (td == null) continue;
 +              }
 +      }
 +      
 +      private static string GetTypeFileName(Type type) {
 +              return filenameFormatter.GetName (type);
 +      }
 +
 +      public static string GetTypeFileName (string typename)
 +      {
 +              StringBuilder filename = new StringBuilder (typename.Length);
 +              int numArgs = 0;
 +              int numLt = 0;
 +              bool copy = true;
 +              for (int i = 0; i < typename.Length; ++i) {
 +                      char c = typename [i];
 +                      switch (c) {
 +                              case '<':
 +                                      copy = false;
 +                                      ++numLt;
 +                                      break;
 +                              case '>':
 +                                      --numLt;
 +                                      if (numLt == 0) {
 +                                              filename.Append ('`').Append ((numArgs+1).ToString());
 +                                              numArgs = 0;
 +                                              copy = true;
 +                                      }
 +                                      break;
 +                              case ',':
 +                                      if (numLt == 1)
 +                                              ++numArgs;
 +                                      break;
 +                              default:
 +                                      if (copy)
 +                                              filename.Append (c);
 +                                      break;
 +                      }
 +              }
 +              return filename.ToString ();
 +      }
 +
 +      
 +      private static void AddIndexAssembly (Assembly assembly, XmlElement parent)
 +      {
 +              XmlElement index_assembly = parent.OwnerDocument.CreateElement("Assembly");
 +              index_assembly.SetAttribute("Name", assembly.GetName().Name);
 +              index_assembly.SetAttribute("Version", assembly.GetName().Version.ToString());
 +              MakeAttributes(index_assembly, assembly, true);
 +              parent.AppendChild(index_assembly);
 +      }
 +
 +      private static void DoUpdateAssemblies (string source, string dest) 
 +      {
 +              string indexfile = dest + "/index.xml";
 +              XmlDocument index;
 +              if (System.IO.File.Exists(indexfile)) {
 +                      index = new XmlDocument();
 +                      index.Load(indexfile);
 +
 +                      // Format change
 +                      ClearElement(index.DocumentElement, "Assembly");
 +                      ClearElement(index.DocumentElement, "Attributes");
 +              } else {
 +                      index = CreateIndexStub();
 +              }
 +              
 +              if (name == null) {
 +                      string defaultTitle = "Untitled";
 +                      if (assemblies.Length == 1)
 +                              defaultTitle = assemblies[0].GetName().Name;
 +                      WriteElementInitialText(index.DocumentElement, "Title", defaultTitle);
 +              } else {
 +                      WriteElementText(index.DocumentElement, "Title", name);
 +              }
 +              
 +              XmlElement index_types = WriteElement(index.DocumentElement, "Types");
 +              XmlElement index_assemblies = WriteElement(index.DocumentElement, "Assemblies");
 +              index_assemblies.RemoveAll ();
 +              
 +              Hashtable goodfiles = new Hashtable();
 +
 +              foreach (Assembly assm in assemblies) {
 +                      AddIndexAssembly (assm, index_assemblies);
 +                      DoUpdateAssembly (assm, index_types, source, dest, goodfiles);
 +              }
 +
 +              SortIndexEntries (index_types);
 +              
 +              CleanupFiles (dest, goodfiles);
 +              CleanupIndexTypes (index_types, goodfiles);
 +              CleanupExtensions (index_types);
 +
 +              using (TextWriter writer = OpenWrite (indexfile, FileMode.Create))
 +                      WriteXml(index.DocumentElement, writer);
 +      }
 +              
 +      private static char[] InvalidFilenameChars = {'\\', '/', ':', '*', '?', '"', '<', '>', '|'};
 +
 +      private static void DoUpdateAssembly (Assembly assembly, XmlElement index_types, string source, string dest, Hashtable goodfiles) 
 +      {
 +              foreach (DocsTypeInfo docTypeInfo in GetTypes (assembly, null)) {
 +                      Type type = docTypeInfo.Type;
 +                      if (!IsPublic (type) || type.FullName.IndexOfAny (InvalidFilenameChars) >= 0)
 +                              continue;
 +
 +                      string reltypepath = DoUpdateType (type, source, dest, docTypeInfo.EcmaDocs);
 +                      if (reltypepath == null)
 +                              continue;
 +                      
 +                      // Add namespace and type nodes into the index file as needed
 +                      XmlElement nsnode = (XmlElement)index_types.SelectSingleNode("Namespace[@Name='" + type.Namespace + "']");
 +                      if (nsnode == null) {
 +                              nsnode = index_types.OwnerDocument.CreateElement("Namespace");
 +                              nsnode.SetAttribute("Name", type.Namespace);
 +                              index_types.AppendChild(nsnode);
 +                      }
 +                      string typename = GetTypeFileName(type);
 +                      string doc_typename = GetDocTypeName (type);
 +                      XmlElement typenode = (XmlElement)nsnode.SelectSingleNode("Type[@Name='" + typename + "']");
 +                      if (typenode == null) {
 +                              typenode = index_types.OwnerDocument.CreateElement("Type");
 +                              typenode.SetAttribute("Name", typename);
 +                              nsnode.AppendChild(typenode);
 +                      }
 +                      if (typename != doc_typename)
 +                              typenode.SetAttribute("DisplayName", doc_typename);
 +                      else
 +                              typenode.RemoveAttribute("DisplayName");
 +                      typenode.SetAttribute ("Kind", GetTypeKind (type));
 +                              
 +                      // Ensure the namespace index file exists
 +                      string onsdoc = DocUtils.PathCombine (dest, type.Namespace + ".xml");
 +                      string nsdoc  = DocUtils.PathCombine (dest, "ns-" + type.Namespace + ".xml");
 +                      if (File.Exists (onsdoc)) {
 +                              File.Move (onsdoc, nsdoc);
 +                      }
 +
 +                      if (!File.Exists (nsdoc)) {
 +                              Console.WriteLine("New Namespace File: " + type.Namespace);
 +                              WriteNamespaceStub(type.Namespace, dest);
 +                      }
 +
 +                      // mark the file as corresponding to a type
 +                      goodfiles[reltypepath] = goodfiles;
 +              }
 +      }
 +
 +      class DocsTypeInfo {
 +              public Type Type;
 +              public XmlReader EcmaDocs;
 +
 +              public DocsTypeInfo (Type type, XmlReader docs)
 +              {
 +                      this.Type = type;
 +                      this.EcmaDocs = docs;
 +              }
 +      }
 +
 +      static 
 +#if NET_1_0
 +              IEnumerable
 +#else
-                                       if (object.ReferenceEquals (oldmember, seenmembers [sig]))
-                                               ; // ignore, already seen
++              IEnumerable<Mono.Documentation.MDocUpdater.DocsTypeInfo>
 +#endif
 +              GetTypes (Assembly assembly, string[] forTypes)
 +      {
 +              Hashtable seen = null;
 +              if (forTypes != null)
 +                      Array.Sort (forTypes);
 +              if (ecmadocs != null) {
 +                      seen = new Hashtable ();
 +                      int typeDepth = -1;
 +                      while (ecmadocs.Read ()) {
 +                              switch (ecmadocs.Name) {
 +                                      case "Type": {
 +                                              if (typeDepth == -1)
 +                                                      typeDepth = ecmadocs.Depth;
 +                                              if (ecmadocs.NodeType != XmlNodeType.Element)
 +                                                      continue;
 +                                              if (typeDepth != ecmadocs.Depth) // nested <Type/> element?
 +                                                      continue;
 +                                              string typename = ecmadocs.GetAttribute ("FullName");
 +                                              string typename2 = GetTypeFileName (typename);
 +                                              if (forTypes != null && 
 +                                                              Array.BinarySearch (forTypes, typename) < 0 &&
 +                                                              typename != typename2 &&
 +                                                              Array.BinarySearch (forTypes, typename2) < 0)
 +                                                      continue;
 +                                              Type t;
 +                                              if ((t = assembly.GetType (typename, false)) == null &&
 +                                                              (t = assembly.GetType (typename2, false)) == null)
 +                                                      continue;
 +                                              seen.Add (typename, "");
 +                                              if (typename != typename2)
 +                                                      seen.Add (typename2, "");
 +                                              Console.WriteLine ("  Import: {0}", t.FullName);
 +                                              yield return new DocsTypeInfo (t, ecmadocs);
 +                                              break;
 +                                      }
 +                                      default:
 +                                              break;
 +                              }
 +                      }
 +              }
 +              foreach (Type type in assembly.GetTypes()) {
 +                      if (forTypes != null && Array.BinarySearch (forTypes, type.FullName) < 0)
 +                              continue;
 +                      if (seen != null && seen.ContainsKey (type.FullName))
 +                              continue;
 +                      yield return new DocsTypeInfo (type, null);
 +              }
 +      }
 +
 +      private static void SortIndexEntries (XmlElement indexTypes)
 +      {
 +              XmlNodeList namespaces = indexTypes.SelectNodes ("Namespace");
 +              XmlNodeComparer c = new AttributeNameComparer ();
 +              SortXmlNodes (indexTypes, namespaces, c);
 +
 +              for (int i = 0; i < namespaces.Count; ++i)
 +                      SortXmlNodes (namespaces [i], namespaces [i].SelectNodes ("Type"), c);
 +      }
 +
 +      private static void SortXmlNodes (XmlNode parent, XmlNodeList children, XmlNodeComparer comparer)
 +      {
 +              MyXmlNodeList l = new MyXmlNodeList (children.Count);
 +              for (int i = 0; i < children.Count; ++i)
 +                      l.Add (children [i]);
 +              l.Sort (comparer);
 +              for (int i = l.Count - 1; i > 0; --i) {
 +                      parent.InsertBefore (parent.RemoveChild ((XmlNode) l [i-1]), (XmlNode) l [i]);
 +              }
 +      }
 +
 +      abstract class XmlNodeComparer : IComparer 
 +#if !NET_1_0
 +              , IComparer<XmlNode>
 +#endif
 +      {
 +              public abstract int Compare (XmlNode x, XmlNode y);
 +
 +              public int Compare (object x, object y)
 +              {
 +                      return Compare ((XmlNode) x, (XmlNode) y);
 +              }
 +      }
 +
 +      class AttributeNameComparer : XmlNodeComparer {
 +              public override int Compare (XmlNode x, XmlNode y)
 +              {
 +                      return x.Attributes ["Name"].Value.CompareTo (y.Attributes ["Name"].Value);
 +              }
 +      }
 +      
 +      class VersionComparer : XmlNodeComparer {
 +              public override int Compare (XmlNode x, XmlNode y)
 +              {
 +                      // Some of the existing docs use e.g. 1.0.x.x, which Version doesn't like.
 +                      string a = GetVersion (x.InnerText);
 +                      string b = GetVersion (y.InnerText);
 +                      return new Version (a).CompareTo (new Version (b));
 +              }
 +
 +              static string GetVersion (string v)
 +              {
 +                      int n = v.IndexOf ("x");
 +                      if (n < 0)
 +                              return v;
 +                      return v.Substring (0, n-1);
 +              }
 +      }
 +
 +      private static string GetTypeKind (Type type)
 +      {
 +              if (type.IsEnum)
 +                      return "Enumeration";
 +              if (type.IsValueType)
 +                      return "Structure";
 +              if (type.IsInterface)
 +                      return "Interface";
 +              if (IsDelegate (type))
 +                      return "Delegate";
 +              if (type.IsClass || type == typeof(System.Enum))
 +                      return "Class";
 +              throw new ArgumentException ("Unknown kind for type: " + type.FullName);
 +      }
 +
 +      private static bool IsPublic (Type type)
 +      {
 +              Type decl = type;
 +              while (decl != null) {
 +                      if (!(decl.IsPublic || decl.IsNestedPublic)) {
 +                              return false;
 +                      }
 +                      decl = decl.DeclaringType;
 +              }
 +              return true;
 +      }
 +
 +      private static void CleanupFiles (string dest, Hashtable goodfiles)
 +      {
 +              // Look for files that no longer correspond to types
 +              foreach (System.IO.DirectoryInfo nsdir in new System.IO.DirectoryInfo(dest).GetDirectories("*")) {
 +                      foreach (System.IO.FileInfo typefile in nsdir.GetFiles("*.xml")) {
 +                              string relTypeFile = Path.Combine(nsdir.Name, typefile.Name);
 +                              if (!goodfiles.ContainsKey(relTypeFile)) {
 +                                      XmlDocument doc = new XmlDocument ();
 +                                      doc.Load (typefile.FullName);
 +                                      XmlElement e = doc.SelectSingleNode("/Type") as XmlElement;
 +                                      if (UpdateAssemblyVersions(e, GetAssemblyVersions(), false)) {
 +                                              using (TextWriter writer = OpenWrite (typefile.FullName, FileMode.Truncate))
 +                                                      WriteXml(doc.DocumentElement, writer);
 +                                              goodfiles [relTypeFile] = goodfiles;
 +                                              continue;
 +                                      }
 +                                      string newname = typefile.FullName + ".remove";
 +                                      try { System.IO.File.Delete(newname); } catch (Exception) { }
 +                                      try { typefile.MoveTo(newname); } catch (Exception) { }                                 
 +                                      Console.WriteLine("Class no longer present; file renamed: " + Path.Combine(nsdir.Name, typefile.Name));
 +                              }
 +                      }
 +              }
 +      }
 +
 +      private static TextWriter OpenWrite (string path, FileMode mode)
 +      {
 +              return new StreamWriter (
 +                      new FileStream (path, mode),
 +                      new UTF8Encoding (false)
 +              );
 +      }
 +
 +      private static string[] GetAssemblyVersions ()
 +      {
 +              StringList versions = new StringList (assemblies.Length);
 +              for (int i = 0; i < assemblies.Length; ++i)
 +                      versions.Add (GetAssemblyVersion (assemblies [i]));
 +              return DocUtils.ToStringArray (versions);
 +      }
 +              
 +      private static void CleanupIndexTypes (XmlElement index_types, Hashtable goodfiles)
 +      {
 +              // Look for type nodes that no longer correspond to types
 +              MyXmlNodeList remove = new MyXmlNodeList ();
 +              foreach (XmlElement typenode in index_types.SelectNodes("Namespace/Type")) {
 +                      string fulltypename = Path.Combine (((XmlElement)typenode.ParentNode).GetAttribute("Name"), typenode.GetAttribute("Name") + ".xml");
 +                      if (!goodfiles.ContainsKey(fulltypename)) {
 +                              remove.Add (typenode);
 +                      }
 +              }
 +              foreach (XmlNode n in remove)
 +                      n.ParentNode.RemoveChild (n);
 +      }
 +
 +      private static void CleanupExtensions (XmlElement index_types)
 +      {
 +              XmlNode e = index_types.SelectSingleNode ("/Overview/ExtensionMethods");
 +              if (extensionMethods.Count == 0) {
 +                      if (e == null)
 +                              return;
 +                      index_types.RemoveChild (e);
 +                      return;
 +              }
 +              if (e == null) {
 +                      e = index_types.OwnerDocument.CreateElement ("ExtensionMethods");
 +                      index_types.SelectSingleNode ("/Overview").AppendChild (e);
 +              }
 +              else
 +                      e.RemoveAll ();
 +              extensionMethods.Sort (DefaultExtensionMethodComparer);
 +              foreach (XmlNode m in extensionMethods) {
 +                      e.AppendChild (index_types.OwnerDocument.ImportNode (m, true));
 +              }
 +      }
 +
 +      class ExtensionMethodComparer : XmlNodeComparer {
 +              public override int Compare (XmlNode x, XmlNode y)
 +              {
 +                      XmlNode xLink = x.SelectSingleNode ("Member/Link");
 +                      XmlNode yLink = y.SelectSingleNode ("Member/Link");
 +
 +                      int n = xLink.Attributes ["Type"].Value.CompareTo (
 +                                      yLink.Attributes ["Type"].Value);
 +                      if (n != 0)
 +                              return n;
 +                      n = xLink.Attributes ["Member"].Value.CompareTo (
 +                                      yLink.Attributes ["Member"].Value);
 +                      if (n == 0 && !object.ReferenceEquals (x, y))
 +                              throw new InvalidOperationException ("Duplicate extension method found!");
 +                      return n;
 +              }
 +      }
 +
 +      static readonly XmlNodeComparer DefaultExtensionMethodComparer = new ExtensionMethodComparer ();
 +              
 +      public static void DoUpdateType2(string message, XmlDocument basefile, Type type, string output, bool insertSince, XmlReader ecmaDocsType) {
 +              Console.WriteLine(message + ": " + type.FullName);
 +              
 +              StringToXmlNodeMap seenmembers = new StringToXmlNodeMap ();
 +
 +              // Update type metadata
 +              UpdateType(basefile.DocumentElement, type, ecmaDocsType);
 +
 +              if (ecmaDocsType != null) {
 +                      while (ecmaDocsType.Name != "Members" && ecmaDocsType.Read ()) {
 +                              // do nothing
 +                      }
 +                      if (ecmaDocsType.IsEmptyElement)
 +                              ecmaDocsType = null;
 +              }
 +
 +              // Update existing members.  Delete member nodes that no longer should be there,
 +              // and remember what members are already documented so we don't add them again.
 +              if (!ignoremembers) {
 +                      MyXmlNodeList todelete = new MyXmlNodeList ();
 +                      foreach (DocsNodeInfo info in GetDocumentationMembers (basefile, type, ecmaDocsType)) {
 +                              XmlElement oldmember  = info.Node;
 +                              MemberInfo oldmember2 = info.Member;
 +                              string sig = oldmember2 != null ? MakeMemberSignature(oldmember2) : null;
 +
 +                              // Interface implementations and overrides are deleted from the docs
 +                              // unless the overrides option is given.
 +                              if (oldmember2 != null && (!IsNew(oldmember2) || sig == null))
 +                                      oldmember2 = null;
 +                              
 +                              // Deleted (or signature changed)
 +                              if (oldmember2 == null) {
 +                                      if (UpdateAssemblyVersions (oldmember, new string[]{GetAssemblyVersion (type.Assembly)}, false))
 +                                              continue;
 +                                      DeleteMember ("Member Removed", output, oldmember, todelete);
 +                                      continue;
 +                              }
 +                              
 +                              // Duplicated
 +                              if (seenmembers.ContainsKey (sig)) {
++                                      if (object.ReferenceEquals (oldmember, seenmembers [sig])) {
++                                              // ignore, already seen
++                                      }
 +                                      else if (DefaultMemberComparer.Compare (oldmember, seenmembers [sig]) == 0)
 +                                              DeleteMember ("Duplicate Member Found", output, oldmember, todelete);
 +                                      else
 +                                              Error ("TODO: found a duplicate member '{0}', but it's not identical to the prior member found!", sig);
 +                                      continue;
 +                              }
 +                              
 +                              // Update signature information
 +                              UpdateMember(info);
 +                              
 +                              seenmembers.Add (sig, oldmember);
 +                      }
 +                      foreach (XmlElement oldmember in todelete)
 +                              oldmember.ParentNode.RemoveChild (oldmember);
 +              }
 +              
 +              if (!IsDelegate(type) && !ignoremembers) {
 +                      XmlNode members = WriteElement (basefile.DocumentElement, "Members");
 +                      foreach (MemberInfo m in Sort (type.GetMembers(DefaultBindingFlags))) {
 +                              if (m is Type) continue;
 +                              
 +                              string sig = MakeMemberSignature(m);
 +                              if (sig == null) continue;
 +                              if (seenmembers.ContainsKey(sig)) continue;
 +                              
 +                              // To be nice on diffs, members/properties/events that are overrides or are interface implementations
 +                              // are not added in.
 +                              if (!IsNew(m)) continue;
 +                              
 +                              XmlElement mm = MakeMember(basefile, new DocsNodeInfo (null, m));
 +                              if (mm == null) continue;
 +                              members.AppendChild( mm );
 +      
 +                              Console.WriteLine("Member Added: " + mm.SelectSingleNode("MemberSignature/@Value").InnerText);
 +                              additions++;
 +                      }
 +              }
 +              
 +              // Import code snippets from files
 +              foreach (XmlNode code in basefile.GetElementsByTagName("code")) {
 +                      if (!(code is XmlElement)) continue;
 +                      string file = ((XmlElement)code).GetAttribute("src");
 +                      string lang = ((XmlElement)code).GetAttribute("lang");
 +                      if (file != "") {
 +                              string src = GetCodeSource (lang, Path.Combine (srcPath, file));
 +                              if (src != null)
 +                                      code.InnerText = src;
 +                      }
 +              }
 +
 +              if (insertSince && since != null) {
 +                      XmlNode docs = basefile.DocumentElement.SelectSingleNode("Docs");
 +                      docs.AppendChild (CreateSinceNode (basefile));
 +              }
 +
 +              do {
 +                      XmlElement d = basefile.DocumentElement ["Docs"];
 +                      XmlElement m = basefile.DocumentElement ["Members"];
 +                      if (d != null && m != null)
 +                              basefile.DocumentElement.InsertBefore (
 +                                              basefile.DocumentElement.RemoveChild (d), m);
 +                      SortTypeMembers (m);
 +              } while (false);
 +
 +              System.IO.TextWriter writer;
 +              if (output == null)
 +                      writer = Console.Out;
 +              else {
 +                      FileInfo file = new FileInfo (output);
 +                      if (!file.Directory.Exists) {
 +                              Console.WriteLine("Namespace Directory Created: " + type.Namespace);
 +                              file.Directory.Create ();
 +                      }
 +                      writer = OpenWrite (output, FileMode.Create);
 +              }
 +
 +              using (writer)
 +                      WriteXml(basefile.DocumentElement, writer);
 +      }
 +
 +      private static string GetCodeSource (string lang, string file)
 +      {
 +              int anchorStart;
 +              if (lang == "C#" && (anchorStart = file.IndexOf (".cs#")) >= 0) {
 +                      // Grab the specified region
 +                      string region = "#region " + file.Substring (anchorStart + 4);
 +                      file          = file.Substring (0, anchorStart + 3);
 +                      try {
 +                              using (StreamReader reader = new StreamReader (file)) {
 +                                      string line;
 +                                      StringBuilder src = new StringBuilder ();
 +                                      int indent = -1;
 +                                      while ((line = reader.ReadLine ()) != null) {
 +                                              if (line.Trim() == region) {
 +                                                      indent = line.IndexOf (region);
 +                                                      continue;
 +                                              }
 +                                              if (indent >= 0 && line.Trim().StartsWith ("#endregion")) {
 +                                                      break;
 +                                              }
 +                                              if (indent >= 0)
 +                                                      src.Append (
 +                                                                      (line.Length > 0 ? line.Substring (indent) : string.Empty) +
 +                                                                      "\n");
 +                                      }
 +                                      return src.ToString ();
 +                              }
 +                      } catch (Exception e) {
 +                              Error ("Could not load <code/> file '{0}' region '{1}': {2}",
 +                                              file, region, show_exceptions ? e.ToString () : e.Message);
 +                              return null;
 +                      }
 +              }
 +              try {
 +                      using (StreamReader reader = new StreamReader (file))
 +                              return reader.ReadToEnd ();
 +              } catch (Exception e) {
 +                      Error ("Could not load <code/> file '" + file + "': " + e.Message);
 +              }
 +              return null;
 +      }
 +
 +      private static 
 +#if NET_1_0
 +              IEnumerable
 +#else
 +              IEnumerable<DocsNodeInfo>
 +#endif
 +              GetDocumentationMembers (XmlDocument basefile, Type type, XmlReader ecmaDocsMembers)
 +      {
 +              if (ecmaDocsMembers != null) {
 +                      int membersDepth = ecmaDocsMembers.Depth;
 +                      bool go = true;
 +                      while (go && ecmaDocsMembers.Read ()) {
 +                              switch (ecmaDocsMembers.Name) {
 +                                      case "Member": {
 +                                              if (membersDepth != ecmaDocsMembers.Depth - 1 || ecmaDocsMembers.NodeType != XmlNodeType.Element)
 +                                                      continue;
 +                                              DocumentationMember dm = new DocumentationMember (ecmaDocsMembers);
 +                                              string xp = GetXPathForMember (dm);
 +                                              XmlElement oldmember = (XmlElement) basefile.SelectSingleNode (xp);
 +                                              MemberInfo m;
 +                                              if (oldmember == null) {
 +                                                      m = GetMember (type, dm);
 +                                                      if (m == null) {
 +                                                              Error ("Could not import ECMA docs for `{0}'s `{1}': MemberInfo not found.",
 +                                                                              type.FullName, dm.MemberSignatures ["C#"]);
 +                                                                              // SelectSingleNode (ecmaDocsMember, "MemberSignature[@Language=\"C#\"]/@Value").Value);
 +                                                              continue;
 +                                                      }
 +                                                      // oldmember lookup may have failed due to type parameter renames.
 +                                                      // Try again.
 +                                                      oldmember = (XmlElement) basefile.SelectSingleNode (GetXPathForMember (m));
 +                                                      if (oldmember == null) {
 +                                                              XmlElement members = WriteElement(basefile.DocumentElement, "Members");
 +                                                              oldmember = basefile.CreateElement ("Member");
 +                                                              oldmember.SetAttribute ("MemberName", dm.MemberName);
 +                                                              members.AppendChild (oldmember);
 +                                                              foreach (string key in Sort (dm.MemberSignatures.Keys)) {
 +                                                                      XmlElement ms = basefile.CreateElement ("MemberSignature");
 +                                                                      ms.SetAttribute ("Language", key);
 +                                                                      ms.SetAttribute ("Value", (string) dm.MemberSignatures [key]);
 +                                                                      oldmember.AppendChild (ms);
 +                                                              }
 +                                                              oldmember.SetAttribute ("__monodocer-seen__", "true");
 +                                                              Console.WriteLine ("Member Added: {0}", MakeMemberSignature (m));
 +                                                              additions++;
 +                                                      }
 +                                              }
 +                                              else {
 +                                                      m = GetMember (type, new DocumentationMember (oldmember));
 +                                                      if (m == null) {
 +                                                              Error ("Could not import ECMA docs for `{0}'s `{1}': MemberInfo not found.",
 +                                                                              type.FullName, dm.MemberSignatures ["C#"]);
 +                                                              continue;
 +                                                      }
 +                                                      oldmember.SetAttribute ("__monodocer-seen__", "true");
 +                                              }
 +                                              DocsNodeInfo node = new DocsNodeInfo (oldmember, m);
 +                                              if (ecmaDocsMembers.Name != "Docs")
 +                                                      throw new InvalidOperationException ("Found " + ecmaDocsMembers.Name + "; expected <Docs/>!");
 +                                              node.EcmaDocs = ecmaDocsMembers;
 +                                              yield return node;
 +                                              break;
 +                                      }
 +                                      case "Members":
 +                                              if (membersDepth == ecmaDocsMembers.Depth && ecmaDocsMembers.NodeType == XmlNodeType.EndElement) {
 +                                                      go = false;
 +                                              }
 +                                              break;
 +                              }
 +                      }
 +              }
 +              foreach (XmlElement oldmember in basefile.SelectNodes("Type/Members/Member")) {
 +                      if (oldmember.GetAttribute ("__monodocer-seen__") == "true") {
 +                              oldmember.RemoveAttribute ("__monodocer-seen__");
 +                              continue;
 +                      }
 +                      MemberInfo m = GetMember (type, new DocumentationMember (oldmember));
 +                      if (m == null) {
 +                              yield return new DocsNodeInfo (oldmember);
 +                      }
 +                      else {
 +                              yield return new DocsNodeInfo (oldmember, m);
 +                      }
 +              }
 +      }
 +
 +      static void DeleteMember (string reason, string output, XmlNode member, MyXmlNodeList todelete)
 +      {
 +              string format = output != null
 +                      ? "{0}: File='{1}'; Signature='{4}'"
 +                      : "{0}: XPath='/Type[@FullName=\"{2}\"]/Members/Member[@MemberName=\"{3}\"]'; Signature='{4}'";
 +              Error (format,
 +                              reason, 
 +                              output,
 +                              member.OwnerDocument.DocumentElement.GetAttribute ("FullName"),
 +                              member.Attributes ["MemberName"].Value, 
 +                              member.SelectSingleNode ("MemberSignature[@Language='C#']/@Value").Value);
 +              if (!delete && MemberDocsHaveUserContent (member)) {
 +                      Error ("Member deletions must be enabled with the --delete option.");
 +              } else {
 +                      todelete.Add (member);
 +                      deletions++;
 +              }
 +      }
 +
 +      class MemberComparer : XmlNodeComparer {
 +              public override int Compare (XmlNode x, XmlNode y)
 +              {
 +                      int r;
 +                      string xMemberName = x.Attributes ["MemberName"].Value;
 +                      string yMemberName = y.Attributes ["MemberName"].Value;
 +
 +                      // generic methods *end* with '>'
 +                      // it's possible for explicitly implemented generic interfaces to
 +                      // contain <...> without being a generic method
 +                      if ((!xMemberName.EndsWith (">") || !yMemberName.EndsWith (">")) &&
 +                                      (r = xMemberName.CompareTo (yMemberName)) != 0)
 +                              return r;
 +
 +                      int lt;
 +                      if ((lt = xMemberName.IndexOf ("<")) >= 0)
 +                              xMemberName = xMemberName.Substring (0, lt);
 +                      if ((lt = yMemberName.IndexOf ("<")) >= 0)
 +                              yMemberName = yMemberName.Substring (0, lt);
 +                      if ((r = xMemberName.CompareTo (yMemberName)) != 0)
 +                              return r;
 +
 +                      // if @MemberName matches, then it's either two different types of
 +                      // members sharing the same name, e.g. field & property, or it's an
 +                      // overloaded method.
 +                      // for different type, sort based on MemberType value.
 +                      r = x.SelectSingleNode ("MemberType").InnerText.CompareTo (
 +                                      y.SelectSingleNode ("MemberType").InnerText);
 +                      if (r != 0)
 +                              return r;
 +
 +                      // same type -- must be an overloaded method.  Sort based on type 
 +                      // parameter count, then parameter count, then by the parameter 
 +                      // type names.
 +                      XmlNodeList xTypeParams = x.SelectNodes ("TypeParameters/TypeParameter");
 +                      XmlNodeList yTypeParams = y.SelectNodes ("TypeParameters/TypeParameter");
 +                      if (xTypeParams.Count != yTypeParams.Count)
 +                              return xTypeParams.Count <= yTypeParams.Count ? -1 : 1;
 +                      for (int i = 0; i < xTypeParams.Count; ++i) {
 +                              r = xTypeParams [i].Attributes ["Name"].Value.CompareTo (
 +                                              yTypeParams [i].Attributes ["Name"].Value);
 +                              if (r != 0)
 +                                      return r;
 +                      }
 +
 +                      XmlNodeList xParams = x.SelectNodes ("Parameters/Parameter");
 +                      XmlNodeList yParams = y.SelectNodes ("Parameters/Parameter");
 +                      if (xParams.Count != yParams.Count)
 +                              return xParams.Count <= yParams.Count ? -1 : 1;
 +                      for (int i = 0; i < xParams.Count; ++i) {
 +                              r = xParams [i].Attributes ["Type"].Value.CompareTo (
 +                                              yParams [i].Attributes ["Type"].Value);
 +                              if (r != 0)
 +                                      return r;
 +                      }
 +                      // all parameters match, but return value might not match if it was
 +                      // changed between one version and another.
 +                      XmlNode xReturn = x.SelectSingleNode ("ReturnValue/ReturnType");
 +                      XmlNode yReturn = y.SelectSingleNode ("ReturnValue/ReturnType");
 +                      if (xReturn != null && yReturn != null) {
 +                              r = xReturn.InnerText.CompareTo (yReturn.InnerText);
 +                              if (r != 0)
 +                                      return r;
 +                      }
 +
 +                      return 0;
 +              }
 +      }
 +
 +      static readonly MemberComparer DefaultMemberComparer = new MemberComparer ();
 +
 +      private static void SortTypeMembers (XmlNode members)
 +      {
 +              if (members == null)
 +                      return;
 +              SortXmlNodes (members, members.SelectNodes ("Member"), DefaultMemberComparer);
 +      }
 +      
 +      private static bool MemberDocsHaveUserContent (XmlNode e)
 +      {
 +              e = (XmlElement)e.SelectSingleNode("Docs");
 +              if (e == null) return false;
 +              foreach (XmlElement d in e.SelectNodes("*"))
 +                      if (d.InnerText != "" && !d.InnerText.StartsWith("To be added"))
 +                              return true;
 +              return false;
 +      }
 +      
 +      private static bool IsNew(MemberInfo m) {
 +              if (!nooverrides) return true;
 +              if (m is MethodInfo && !IsNew((MethodInfo)m)) return false;
 +              if (m is PropertyInfo && !IsNew(((PropertyInfo)m).GetGetMethod())) return false;
 +              if (m is PropertyInfo && !IsNew(((PropertyInfo)m).GetSetMethod())) return false;
 +              if (m is EventInfo && !IsNew(((EventInfo)m).GetAddMethod(true))) return false;
 +              if (m is EventInfo && !IsNew(((EventInfo)m).GetRaiseMethod())) return false;
 +              if (m is EventInfo && !IsNew(((EventInfo)m).GetRemoveMethod())) return false;
 +              return true;
 +      }
 +      
 +      private static bool IsNew(MethodInfo m) {
 +              if (m == null) return true;
 +              MethodInfo b = m.GetBaseDefinition();
 +              if (b == null || b == m) return true;
 +              return false;
 +      }
 +      
 +      // UPDATE HELPER FUNCTIONS      
 +      
 +#if false
 +      private static XmlElement FindMatchingMember(Type type, XmlElement newfile, XmlElement oldmember) {
 +              MemberInfo oldmember2 = GetMember(type, oldmember.CreateNavigator ());
 +              if (oldmember2 == null) return null;
 +              
 +              string membername = oldmember.GetAttribute("MemberName");
 +              foreach (XmlElement newmember in newfile.SelectNodes("Members/Member[@MemberName='" + membername + "']")) {
 +                      if (GetMember(type, newmember.CreateNavigator ()) == oldmember2) return newmember;
 +              }
 +              
 +              return null;
 +      }
 +#endif
 +      
 +      private static MemberInfo GetMember(Type type, DocumentationMember member) {
 +              string membertype = member.MemberType;
 +              
 +              string returntype = member.ReturnType;
 +              
 +              string docName = member.MemberName;
 +              string[] docTypeParams = GetTypeParameters (docName);
 +
 +              // Loop through all members in this type with the same name
 +              foreach (MemberInfo mi in GetReflectionMembers (type, docName)) {
 +                      if (mi is Type) continue;
 +                      if (GetMemberType(mi) != membertype) continue;
 +
 +                      string sig = MakeMemberSignature(mi);
 +                      if (sig == null) continue; // not publicly visible
 +
 +                      ParameterInfo[] pis = null;
 +                      string[] typeParams = null;
 +                      if (mi is MethodInfo || mi is ConstructorInfo) {
 +                              MethodBase mb = (MethodBase) mi;
 +                              pis = mb.GetParameters();
 +                              if (docTypeParams != null && DocUtils.GetContainsGenericParameters (mb)) {
 +                                      Type[] args = DocUtils.GetGenericArguments (mb);
 +                                      if (args.Length == docTypeParams.Length) {
 +                                              typeParams = new string [args.Length];
 +                                              for (int i = 0; i < args.Length; ++i)
 +                                                      typeParams [i] = args [i].Name;
 +                                      }
 +                              }
 +                      }
 +                      else if (mi is PropertyInfo)
 +                              pis = ((PropertyInfo)mi).GetIndexParameters();
 +                      
 +                      int mcount = member.Parameters == null ? 0 : member.Parameters.Count;
 +                      int pcount = pis == null ? 0 : pis.Length;
 +                      if (mcount != pcount)
 +                              continue;
 +                      
 +                      if (mi is MethodInfo) {
 +                              // Casting operators can overload based on return type.
 +                              if (returntype != GetReplacedString (
 +                                                      GetDocTypeFullName (((MethodInfo)mi).ReturnType), 
 +                                                      typeParams, docTypeParams)) {
 +                                      continue;
 +                              }
 +                      }
 +
 +                      if (pcount == 0)
 +                              return mi;
 +                      bool good = true;
 +                      for (int i = 0; i < pis.Length; i++) {
 +                              string paramType = GetReplacedString (
 +                                      GetDocParameterType (pis [i].ParameterType),
 +                                      typeParams, docTypeParams);
 +                              if (paramType != (string) member.Parameters [i]) {
 +                                      good = false;
 +                                      break;
 +                              }
 +                      }
 +                      if (!good) continue;
 +
 +                      return mi;
 +              }
 +              
 +              return null;
 +      }
 +
 +      private static MemberInfoEnumerable GetReflectionMembers (Type type, string docName)
 +      {
 +              // need to worry about 4 forms of //@MemberName values:
 +              //  1. "Normal" (non-generic) member names: GetEnumerator
 +              //    - Lookup as-is.
 +              //  2. Explicitly-implemented interface member names: System.Collections.IEnumerable.Current
 +              //    - try as-is, and try type.member (due to "kludge" for property
 +              //      support.
 +              //  3. "Normal" Generic member names: Sort<T> (CSC)
 +              //    - need to remove generic parameters --> "Sort"
 +              //  4. Explicitly-implemented interface members for generic interfaces: 
 +              //    -- System.Collections.Generic.IEnumerable<T>.Current
 +              //    - Try as-is, and try type.member, *keeping* the generic parameters.
 +              //     --> System.Collections.Generic.IEnumerable<T>.Current, IEnumerable<T>.Current
 +              //  5. As of 2008-01-02, gmcs will do e.g. 'IFoo`1[A].Method' instead of
 +              //    'IFoo<A>.Method' for explicitly implemented methods; don't interpret
 +              //    this as (1) or (2).
 +              if (docName.IndexOf ('<') == -1 && docName.IndexOf ('[') == -1) {
 +                      // Cases 1 & 2
 +                      foreach (MemberInfo mi in type.GetMember (docName, DefaultBindingFlags))
 +                              yield return mi;
 +                      if (CountChars (docName, '.') > 0)
 +                              // might be a property; try only type.member instead of
 +                              // namespace.type.member.
 +                              foreach (MemberInfo mi in 
 +                                              type.GetMember (DocUtils.GetTypeDotMember (docName), DefaultBindingFlags))
 +                                      yield return mi;
 +                      yield break;
 +              }
 +              // cases 3 & 4
 +              int numLt = 0;
 +              int numDot = 0;
 +              int startLt, startType, startMethod;
 +              startLt = startType = startMethod = -1;
 +              for (int i = 0; i < docName.Length; ++i) {
 +                      switch (docName [i]) {
 +                              case '<':
 +                                      if (numLt == 0) {
 +                                              startLt = i;
 +                                      }
 +                                      ++numLt;
 +                                      break;
 +                              case '>':
 +                                      --numLt;
 +                                      if (numLt == 0 && (i + 1) < docName.Length)
 +                                              // there's another character in docName, so this <...> sequence is
 +                                              // probably part of a generic type -- case 4.
 +                                              startLt = -1;
 +                                      break;
 +                              case '.':
 +                                      startType = startMethod;
 +                                      startMethod = i;
 +                                      ++numDot;
 +                                      break;
 +                      }
 +              }
 +              string refName = startLt == -1 ? docName : docName.Substring (0, startLt);
 +              // case 3
 +              foreach (MemberInfo mi in type.GetMember (refName, DefaultBindingFlags))
 +                      yield return mi;
 +
 +              // case 4
 +              foreach (MemberInfo mi in type.GetMember (refName.Substring (startType + 1), DefaultBindingFlags))
 +                      yield return mi;
 +
 +              // If we _still_ haven't found it, we've hit another generic naming issue:
 +              // post Mono 1.1.18, gmcs generates [[FQTN]] instead of <TypeName> for
 +              // explicitly-implemented METHOD names (not properties), e.g. 
 +              // "System.Collections.Generic.IEnumerable`1[[Foo, test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]].GetEnumerator"
 +              // instead of "System.Collections.Generic.IEnumerable<Foo>.GetEnumerator",
 +              // which the XML docs will contain.
 +              //
 +              // Alas, we can't derive the Mono name from docName, so we need to iterate
 +              // over all member names, convert them into CSC format, and compare... :-(
 +              if (numDot == 0)
 +                      yield break;
 +              foreach (MemberInfo mi in type.GetMembers (DefaultBindingFlags)) {
 +                      if (GetMemberName (mi) == docName)
 +                              yield return mi;
 +              }
 +      }
 +
 +      static string[] GetTypeParameters (string docName)
 +      {
 +              if (docName [docName.Length-1] != '>')
 +                      return null;
 +              StringList types = new StringList ();
 +              int endToken = docName.Length-2;
 +              int i = docName.Length-2;
 +              do {
 +                      if (docName [i] == ',' || docName [i] == '<') {
 +                              types.Add (docName.Substring (i + 1, endToken - i));
 +                              endToken = i-1;
 +                      }
 +                      if (docName [i] == '<')
 +                              break;
 +              } while (--i >= 0);
 +
 +              types.Reverse ();
 +              return DocUtils.ToStringArray (types);
 +      }
 +
 +      static string GetReplacedString (string typeName, string[] from, string[] to)
 +      {
 +              if (from == null)
 +                      return typeName;
 +              for (int i = 0; i < from.Length; ++i)
 +                      typeName = typeName.Replace (from [i], to [i]);
 +              return typeName;
 +      }
 +      
 +      // CREATE A STUB DOCUMENTATION FILE     
 +
 +      public static XmlElement StubType(Type type, string output, XmlReader ecmaDocsType) {
 +              string typesig = MakeTypeSignature(type);
 +              if (typesig == null) return null; // not publicly visible
 +              
 +              XmlDocument doc = new XmlDocument();
 +              XmlElement root = doc.CreateElement("Type");
 +              doc.AppendChild (root);
 +
 +              DoUpdateType2 ("New Type", doc, type, output, true, ecmaDocsType);
 +              
 +              return root;
 +      }
 +
 +      private static XmlElement CreateSinceNode (XmlDocument doc)
 +      {
 +              XmlElement s = doc.CreateElement ("since");
 +              s.SetAttribute ("version", since);
 +              return s;
 +      }
 +      
 +      // STUBBING/UPDATING FUNCTIONS
 +      
 +      public static void UpdateType(XmlElement root, Type type, XmlReader ecmaDocsType) {
 +              root.SetAttribute("Name", GetDocTypeName (type));
 +              root.SetAttribute("FullName", GetDocTypeFullName (type));
 +
 +              WriteElementAttribute(root, "TypeSignature[@Language='C#']", "Language", "C#");
 +              WriteElementAttribute(root, "TypeSignature[@Language='C#']", "Value", MakeTypeSignature(type));
 +              
 +              XmlElement ass = WriteElement(root, "AssemblyInfo");
 +              WriteElementText(ass, "AssemblyName", type.Assembly.GetName().Name);
 +              UpdateAssemblyVersions(root, type, true);
 +              if (type.Assembly.GetName().CultureInfo.Name != "")
 +                      WriteElementText(ass, "AssemblyCulture", type.Assembly.GetName().CultureInfo.Name);
 +              else
 +                      ClearElement(ass, "AssemblyCulture");
 +              
 +              // Why-oh-why do we put assembly attributes in each type file?
 +              // Neither monodoc nor monodocs2html use them, so I'm deleting them
 +              // since they're outdated in current docs, and a waste of space.
 +              //MakeAttributes(ass, type.Assembly, true);
 +              XmlNode assattrs = ass.SelectSingleNode("Attributes");
 +              if (assattrs != null)
 +                      ass.RemoveChild(assattrs);
 +              
 +              NormalizeWhitespace(ass);
 +              
 +              if (DocUtils.IsGenericType (type)) {
 +                      MakeTypeParameters (root, DocUtils.GetGenericArguments (type));
 +              } else {
 +                      ClearElement(root, "TypeParameters");
 +              }
 +              
 +              if (type.BaseType != null) {
 +                      XmlElement basenode = WriteElement(root, "Base");
 +                      
 +                      string basetypename = GetDocTypeFullName (type.BaseType);
 +                      if (basetypename == "System.MulticastDelegate") basetypename = "System.Delegate";
 +                      WriteElementText(root, "Base/BaseTypeName", basetypename);
 +                      
 +                      // Document how this type instantiates the generic parameters of its base type
 +                      if (DocUtils.IsGenericType (type.BaseType)) {
 +                              ClearElement(basenode, "BaseTypeArguments");
 +                              Type[] baseGenArgs     = DocUtils.GetGenericArguments (type.BaseType);
 +                              Type genericDefinition = DocUtils.GetGenericTypeDefinition (type.BaseType);
 +                              Type[] genTypeDefArgs  = DocUtils.GetGenericArguments (genericDefinition);
 +                              for (int i = 0; i < baseGenArgs.Length; i++) {
 +                                      Type typearg   = baseGenArgs [i];
 +                                      Type typeparam = genTypeDefArgs [i];
 +                                      
 +                                      XmlElement bta = WriteElement(basenode, "BaseTypeArguments");
 +                                      XmlElement arg = bta.OwnerDocument.CreateElement("BaseTypeArgument");
 +                                      bta.AppendChild(arg);
 +                                      arg.SetAttribute("TypeParamName", typeparam.Name);
 +                                      arg.InnerText = GetDocTypeFullName (typearg);
 +                              }
 +                      }
 +              } else {
 +                      ClearElement(root, "Base");
 +              }
 +
 +              if (!IsDelegate(type) && !type.IsEnum) {
 +                      // Get a sorted list of interface implementations.  Don't include
 +                      // interfaces that are implemented by a base type or another interface
 +                      // because they go on the base type or base interface's signature.
 +                      ArrayList interface_names = new ArrayList();
 +                      foreach (Type i in type.GetInterfaces())
 +                              if ((type.BaseType == null || Array.IndexOf(type.BaseType.GetInterfaces(), i) == -1) && InterfaceNotFromAnother(i, type.GetInterfaces()))
 +                                      interface_names.Add(GetDocTypeFullName (i));
 +                      interface_names.Sort();
 +
 +                      XmlElement interfaces = WriteElement(root, "Interfaces");
 +                      interfaces.RemoveAll();
 +                      foreach (string iname in interface_names) {
 +                              XmlElement iface = root.OwnerDocument.CreateElement("Interface");
 +                              interfaces.AppendChild(iface);
 +                              WriteElementText(iface, "InterfaceName", iname);
 +                      }
 +              } else {
 +                      ClearElement(root, "Interfaces");
 +              }
 +
 +              MakeAttributes(root, type, false);
 +              
 +              if (IsDelegate(type)) {
 +                      MakeTypeParameters (root, DocUtils.GetGenericArguments (type));
 +                      MakeParameters(root, type.GetMethod("Invoke").GetParameters());
 +                      MakeReturnValue(root, type.GetMethod("Invoke"));
 +              }
 +              
 +              DocsNodeInfo typeInfo = new DocsNodeInfo (WriteElement(root, "Docs"), type);
 +              if (ecmaDocsType != null) {
 +                      if (ecmaDocsType.Name != "Docs") {
 +                              int depth = ecmaDocsType.Depth;
 +                              while (ecmaDocsType.Read ()) {
 +                                      if (ecmaDocsType.Name == "Docs" && ecmaDocsType.Depth == depth + 1)
 +                                              break;
 +                              }
 +                      }
 +                      if (!ecmaDocsType.IsStartElement ("Docs"))
 +                              throw new InvalidOperationException ("Found " + ecmaDocsType.Name + "; expecting <Docs/>!");
 +                      typeInfo.EcmaDocs = ecmaDocsType;
 +              }
 +              MakeDocNode (typeInfo);
 +              
 +              if (!IsDelegate (type))
 +                      WriteElement (root, "Members");
 +
 +              NormalizeWhitespace(root);
 +      }
 +
 +      class MemberInfoComparer : IComparer
 +#if !NET_1_0
 +                                                                                                               , IComparer<MemberInfo>
 +#endif
 +      {
 +              public int Compare (MemberInfo x, MemberInfo y)
 +              {
 +                      string xs = slashdocFormatter.GetName (x);
 +                      string ys = slashdocFormatter.GetName (y);
 +                      // return String.Compare (xs, ys, StringComparison.OrdinalIgnoreCase);
 +                      return string.Compare (xs, ys, true, CultureInfo.InvariantCulture);
 +              }
 +
 +              public int Compare (object x, object y)
 +              {
 +                      return Compare ((MemberInfo) x, (MemberInfo) y);
 +              }
 +      }
 +
 +      static MemberInfoComparer memberInfoComparer = new MemberInfoComparer ();
 +
 +      private static MemberInfo[] Sort (MemberInfo[] members)
 +      {
 +#if NET_1_0
 +              ArrayList l = new ArrayList ();
 +              l.AddRange (members);
 +              l.Sort (memberInfoComparer);
 +              return (MemberInfo[]) l.ToArray (typeof(MemberInfo));
 +#else
 +              Array.Sort (members, memberInfoComparer);
 +              return members;
 +#endif
 +      }
 +
 +      static IEnumerable Sort (IEnumerable list)
 +      {
 +              ArrayList l = new ArrayList (list as ICollection);
 +              l.Sort ();
 +              return l;
 +      }
 +
 +#if !NET_1_0
 +      static IEnumerable<T> Sort<T> (IEnumerable<T> list)
 +      {
 +              List<T> l = new List<T> (list);
 +              l.Sort ();
 +              return l;
 +      }
 +#endif
 +      
 +      private static void UpdateMember(DocsNodeInfo info) {   
 +              XmlElement me = (XmlElement) info.Node;
 +              MemberInfo mi = info.Member;
 +              WriteElementAttribute(me, "MemberSignature[@Language='C#']", "Language", "C#");
 +              WriteElementAttribute(me, "MemberSignature[@Language='C#']", "Value", MakeMemberSignature(mi));
 +
 +              WriteElementText(me, "MemberType", GetMemberType(mi));
 +              
 +              UpdateAssemblyVersions(me, mi, true);
 +              MakeAttributes(me, mi, false);
 +              MakeReturnValue(me, mi);
 +              if (mi is MethodBase) {
 +                      MethodBase mb = (MethodBase) mi;
 +                      if (DocUtils.GetContainsGenericParameters (mb))
 +                              MakeTypeParameters (me, DocUtils.GetGenericArguments (mb));
 +              }
 +              MakeParameters(me, mi);
 +              
 +              string fieldValue;
 +              if (mi is FieldInfo && GetFieldConstValue((FieldInfo)mi, out fieldValue))
 +                      WriteElementText(me, "MemberValue", fieldValue);
 +              
 +              info.Node = WriteElement (me, "Docs");
 +              MakeDocNode (info);
 +              UpdateExtensionMethods (me, info);
 +      }
 +
 +      static readonly string[] ValidExtensionMembers = {
 +              "Docs",
 +              "MemberSignature",
 +              "MemberType",
 +              "Parameters",
 +              "ReturnValue",
 +              "TypeParameters",
 +      };
 +
 +      static readonly string[] ValidExtensionDocMembers = {
 +              "param",
 +              "summary",
 +              "typeparam",
 +      };
 +
 +      private static void UpdateExtensionMethods (XmlElement e, DocsNodeInfo info)
 +      {
 +              MethodInfo me = info.Member as MethodInfo;
 +              if (me == null)
 +                      return;
 +              if (info.Parameters.Length < 1)
 +                      return;
 +              if (!DocUtils.IsExtensionMethod (me))
 +                      return;
 +
 +              XmlNode em = e.OwnerDocument.CreateElement ("ExtensionMethod");
 +              XmlNode member = e.CloneNode (true);
 +              em.AppendChild (member);
 +              RemoveExcept (member, ValidExtensionMembers);
 +              RemoveExcept (member.SelectSingleNode ("Docs"), ValidExtensionDocMembers);
 +              WriteElementText (member, "MemberType", "ExtensionMethod");
 +              XmlElement link = member.OwnerDocument.CreateElement ("Link");
 +              link.SetAttribute ("Type", slashdocFormatter.GetName (me.DeclaringType));
 +              link.SetAttribute ("Member", slashdocFormatter.GetDeclaration (me));
 +              member.AppendChild (link);
 +              AddTargets (em, info);
 +
 +              extensionMethods.Add (em);
 +      }
 +
 +      private static void RemoveExcept (XmlNode node, string[] except)
 +      {
 +              if (node == null)
 +                      return;
 +              MyXmlNodeList remove = null;
 +              foreach (XmlNode n in node.ChildNodes) {
 +                      if (Array.BinarySearch (except, n.Name) < 0) {
 +                              if (remove == null)
 +                                      remove = new MyXmlNodeList ();
 +                              remove.Add (n);
 +                      }
 +              }
 +              if (remove != null)
 +                      foreach (XmlNode n in remove)
 +                              node.RemoveChild (n);
 +      }
 +
 +      private static void AddTargets (XmlNode member, DocsNodeInfo info)
 +      {
 +              XmlElement targets = member.OwnerDocument.CreateElement ("Targets");
 +              member.PrependChild (targets);
 +              if (!DocUtils.IsGenericParameter (info.Parameters [0].ParameterType))
 +                      AppendElementAttributeText (targets, "Target", "Type",
 +                              slashdocFormatter.GetDeclaration (info.Parameters [0].ParameterType));
 +              else {
 +                      Type[] constraints = DocUtils.GetGenericParameterConstraints (
 +                              info.Parameters [0].ParameterType);
 +                      if (constraints.Length == 0)
 +                              AppendElementAttributeText (targets, "Target", "Type", "System.Object");
 +                      else
 +                              foreach (Type c in constraints)
 +                                      AppendElementAttributeText(targets, "Target", "Type",
 +                                              slashdocFormatter.GetDeclaration (c));
 +              }
 +      }
 +      
 +      private static bool GetFieldConstValue(FieldInfo field, out string value) {
 +              value = null;
 +              if (field.DeclaringType.IsEnum) return false;
 +              if (DocUtils.IsGenericType (field.DeclaringType)) return false;
 +              if (field.IsLiteral || (field.IsStatic && field.IsInitOnly)) {
 +                      object val;
 +                      try {
 +                              val = field.GetValue(null);
 +                      } catch {
 +                              return false;
 +                      }
 +                      if (val == null) value = "null";
 +                      else if (val is Enum) value = val.ToString();
 +                      else if (val is IFormattable) {
 +                              value = ((IFormattable)val).ToString();
 +                              if (val is string)
 +                                      value = "\"" + value + "\"";
 +                      }
 +                      if (value != null && value != "")
 +                              return true;
 +              }
 +              return false;
 +      }
 +      
 +      // XML HELPER FUNCTIONS
 +      
 +      private static XmlElement WriteElement(XmlNode parent, string element) {
 +              XmlElement ret = (XmlElement)parent.SelectSingleNode(element);
 +              if (ret == null) {
 +                      string[] path = element.Split('/');
 +                      foreach (string p in path) {
 +                              ret = (XmlElement)parent.SelectSingleNode(p);
 +                              if (ret == null) {
 +                                      string ename = p;
 +                                      if (ename.IndexOf('[') >= 0) // strip off XPath predicate
 +                                              ename = ename.Substring(0, ename.IndexOf('['));
 +                                      ret = parent.OwnerDocument.CreateElement(ename);
 +                                      parent.AppendChild(ret);
 +                                      parent = ret;
 +                              } else {
 +                                      parent = ret;
 +                              }
 +                      }
 +              }
 +              return ret;
 +      }
 +      private static void WriteElementText(XmlNode parent, string element, string value) {
 +              XmlElement node = WriteElement(parent, element);
 +              node.InnerText = value;
 +      }
 +
 +      static XmlElement AppendElementText (XmlNode parent, string element, string value)
 +      {
 +              XmlElement n = parent.OwnerDocument.CreateElement (element);
 +              parent.AppendChild (n);
 +              n.InnerText = value;
 +              return n;
 +      }
 +
 +      static XmlElement AppendElementAttributeText (XmlNode parent, string element, string attribute, string value)
 +      {
 +              XmlElement n = parent.OwnerDocument.CreateElement (element);
 +              parent.AppendChild (n);
 +              n.SetAttribute (attribute, value);
 +              return n;
 +      }
 +
 +      private static XmlNode CopyNode (XmlNode source, XmlNode dest)
 +      {
 +              XmlNode copy = dest.OwnerDocument.ImportNode (source, true);
 +              dest.AppendChild (copy);
 +              return copy;
 +      }
 +
 +      private static void WriteElementInitialText(XmlElement parent, string element, string value) {
 +              XmlElement node = (XmlElement)parent.SelectSingleNode(element);
 +              if (node != null)
 +                      return;
 +              node = WriteElement(parent, element);
 +              node.InnerText = value;
 +      }
 +      private static void WriteElementAttribute(XmlElement parent, string element, string attribute, string value) {
 +              XmlElement node = WriteElement(parent, element);
 +              if (node.GetAttribute(attribute) == value) return;
 +              node.SetAttribute(attribute, value);
 +      }
 +      private static void ClearElement(XmlElement parent, string name) {
 +              XmlElement node = (XmlElement)parent.SelectSingleNode(name);
 +              if (node != null)
 +                      parent.RemoveChild(node);
 +      }
 +      private static void ClearElementChildren(XmlElement parent) {
 +              parent.RemoveAll();
 +      }
 +      
 +      // DOCUMENTATION HELPER FUNCTIONS
 +      
 +      private static void MakeDocNode (DocsNodeInfo info)
 +      {
 +              Type[] genericParams        = info.GenericParameters;
 +              ParameterInfo[] parameters  = info.Parameters;
 +              Type returntype             = info.ReturnType;
 +              bool returnisreturn         = info.ReturnIsReturn;
 +              XmlElement e                = info.Node;
 +              bool addremarks             = info.AddRemarks;
 +
 +              WriteElementInitialText(e, "summary", "To be added.");
 +              
 +              if (parameters != null) {
 +                      string[] values = new string [parameters.Length];
 +                      for (int i = 0; i < values.Length; ++i)
 +                              values [i] = parameters [i].Name;
 +                      UpdateParameters (e, "param", values);
 +              }
 +
 +              if (genericParams != null) {
 +                      string[] values = new string [genericParams.Length];
 +                      for (int i = 0; i < values.Length; ++i)
 +                              values [i] = genericParams [i].Name;
 +                      UpdateParameters (e, "typeparam", values);
 +              }
 +
 +              string retnodename = null;
 +              if (returntype != null && returntype != typeof(void)) {
 +                      retnodename = returnisreturn ? "returns" : "value";
 +                      string retnodename_other = !returnisreturn ? "returns" : "value";
 +                      
 +                      // If it has a returns node instead of a value node, change its name.
 +                      XmlElement retother = (XmlElement)e.SelectSingleNode(retnodename_other);
 +                      if (retother != null) {
 +                              XmlElement retnode = e.OwnerDocument.CreateElement(retnodename);
 +                              foreach (XmlNode node in retother)
 +                                      retnode.AppendChild(node.CloneNode(true));
 +                              e.ReplaceChild(retnode, retother);
 +                      } else {
 +                              WriteElementInitialText(e, retnodename, "To be added.");
 +                      }
 +              } else {
 +                      ClearElement(e, "returns");
 +                      ClearElement(e, "value");
 +              }
 +
 +              if (addremarks)
 +                      WriteElementInitialText(e, "remarks", "To be added.");
 +
 +              if (info.EcmaDocs != null) {
 +                      XmlReader r = info.EcmaDocs;
 +                      int depth = r.Depth;
 +                      r.ReadStartElement ("Docs");
 +                      while (r.Read ()) {
 +                              if (r.Name == "Docs") {
 +                                      if (r.Depth == depth && r.NodeType == XmlNodeType.EndElement)
 +                                              break;
 +                                      else
 +                                              throw new InvalidOperationException ("Skipped past current <Docs/> element!");
 +                              }
 +                              if (!r.IsStartElement ())
 +                                      continue;
 +                              switch (r.Name) {
 +                                      case "param":
 +                                      case "typeparam": {
 +                                              XmlNode doc = e.SelectSingleNode (
 +                                                              r.Name + "[@name='" + r.GetAttribute ("name") + "']");
 +                                              string value = r.ReadInnerXml ();
 +                                              if (doc != null)
 +                                                      doc.InnerXml = value.Replace ("\r", "");
 +                                              break;
 +                                      }
 +                                      case "altmember":
 +                                      case "exception":
 +                                      case "permission":
 +                                      case "seealso": {
 +                                              string name = r.Name;
 +                                              string cref = r.GetAttribute ("cref");
 +                                              XmlNode doc = e.SelectSingleNode (
 +                                                              r.Name + "[@cref='" + cref + "']");
 +                                              string value = r.ReadInnerXml ().Replace ("\r", "");
 +                                              if (doc != null)
 +                                                      doc.InnerXml = value;
 +                                              else {
 +                                                      XmlElement n = e.OwnerDocument.CreateElement (name);
 +                                                      n.SetAttribute ("cref", cref);
 +                                                      n.InnerXml = value;
 +                                                      e.AppendChild (n);
 +                                              }
 +                                              break;
 +                                      }
 +                                      default: {
 +                                              string name = r.Name;
 +                                              string xpath = r.Name;
 +                                              StringList attributes = new StringList (r.AttributeCount);
 +                                              if (r.MoveToFirstAttribute ()) {
 +                                                      do {
 +                                                              attributes.Add ("@" + r.Name + "=\"" + r.Value + "\"");
 +                                                      } while (r.MoveToNextAttribute ());
 +                                                      r.MoveToContent ();
 +                                              }
 +                                              if (attributes.Count > 0) {
 +                                                      xpath += "[" + string.Join (" and ", DocUtils.ToStringArray (attributes)) + "]";
 +                                              }
 +                                              XmlNode doc = e.SelectSingleNode (xpath);
 +                                              string value = r.ReadInnerXml ().Replace ("\r", "");
 +                                              if (doc != null) {
 +                                                      doc.InnerXml = value;
 +                                              }
 +                                              else {
 +                                                      XmlElement n = e.OwnerDocument.CreateElement (name);
 +                                                      n.InnerXml = value;
 +                                                      foreach (string a in attributes) {
 +                                                              int eq = a.IndexOf ('=');
 +                                                              n.SetAttribute (a.Substring (1, eq-1), a.Substring (eq+2, a.Length-eq-3));
 +                                                      }
 +                                                      e.AppendChild (n);
 +                                              }
 +                                              break;
 +                                      }
 +                              }
 +                      }
 +              }
 +              if (info.SlashDocs != null) {
 +                      XmlNode elem = info.SlashDocs;
 +                      if (elem != null) {
 +                              if (elem.SelectSingleNode("summary") != null)
 +                                      ClearElement(e, "summary");
 +                              if (elem.SelectSingleNode("remarks") != null)
 +                                      ClearElement(e, "remarks");
 +                              if (elem.SelectSingleNode("value") != null)
 +                                      ClearElement(e, "value");
 +                              if (retnodename != null && elem.SelectSingleNode(retnodename) != null)
 +                                      ClearElement(e, retnodename);
 +
 +                              foreach (XmlNode child in elem.ChildNodes) {
 +                                      switch (child.Name) {
 +                                              case "param":
 +                                              case "typeparam": {
 +                                                      XmlElement p2 = (XmlElement) e.SelectSingleNode (child.Name + "[@name='" + child.Attributes ["name"].Value + "']");
 +                                                      if (p2 != null)
 +                                                              p2.InnerXml = child.InnerXml;
 +                                                      break;
 +                                              }
 +                                              case "altmember":
 +                                              case "exception":
 +                                              case "permission": {
 +                                                      XmlElement a = (XmlElement) e.SelectSingleNode (child.Name + "[@cref='" + child.Attributes ["cref"].Value + "']");
 +                                                      if (a == null) {
 +                                                              a = e.OwnerDocument.CreateElement (child.Name);
 +                                                              a.SetAttribute ("cref", child.Attributes ["cref"].Value);
 +                                                              e.AppendChild (a);
 +                                                      }
 +                                                      a.InnerXml = child.InnerXml;
 +                                                      break;
 +                                              }
 +                                              case "seealso": {
 +                                                      XmlElement a = (XmlElement) e.SelectSingleNode ("altmember[@cref='" + child.Attributes ["cref"].Value + "']");
 +                                                      if (a == null) {
 +                                                              a = e.OwnerDocument.CreateElement ("altmember");
 +                                                              a.SetAttribute ("cref", child.Attributes ["cref"].Value);
 +                                                              e.AppendChild (a);
 +                                                      }
 +                                                      break;
 +                                              }
 +                                              default:
 +                                                      CopyNode (child, e);
 +                                                      break;
 +                                      }
 +                              }
 +                      }
 +              }
 +              
 +              OrderDocsNodes (e, e.ChildNodes);
 +              NormalizeWhitespace(e);
 +      }
 +
 +      static readonly string[] DocsNodeOrder = {
 +              "typeparam", "param", "summary", "returns", "value", "remarks",
 +      };
 +
 +      private static void OrderDocsNodes (XmlNode docs, XmlNodeList children)
 +      {
 +              MyXmlNodeList newChildren = new MyXmlNodeList (children.Count);
 +              for (int i = 0; i < DocsNodeOrder.Length; ++i) {
 +                      for (int j = 0; j < children.Count; ++j) {
 +                              XmlNode c = children [j];
 +                              if (c.Name == DocsNodeOrder [i]) {
 +                                      newChildren.Add (c);
 +                              }
 +                      }
 +              }
 +              if (newChildren.Count >= 0)
 +                      docs.PrependChild ((XmlNode) newChildren [0]);
 +              for (int i = 1; i < newChildren.Count; ++i) {
 +                      XmlNode prev = (XmlNode) newChildren [i-1];
 +                      XmlNode cur  = (XmlNode) newChildren [i];
 +                      docs.RemoveChild (cur);
 +                      docs.InsertAfter (cur, prev);
 +              }
 +      }
 +      
 +
 +      private static void UpdateParameters (XmlElement e, string element, string[] values)
 +      {       
 +              if (values != null) {
 +                      XmlNode[] paramnodes = new XmlNode[values.Length];
 +                      
 +                      // Some documentation had param nodes with leading spaces.
 +                      foreach (XmlElement paramnode in e.SelectNodes(element)){
 +                              paramnode.SetAttribute("name", paramnode.GetAttribute("name").Trim());
 +                      }
 +                      
 +                      // If a member has only one parameter, we can track changes to
 +                      // the name of the parameter easily.
 +                      if (values.Length == 1 && e.SelectNodes(element).Count == 1) {
 +                              UpdateParameterName (e, (XmlElement) e.SelectSingleNode(element), values [0]);
 +                      }
 +
 +                      bool reinsert = false;
 +
 +                      // Pick out existing and still-valid param nodes, and
 +                      // create nodes for parameters not in the file.
 +                      Hashtable seenParams = new Hashtable();
 +                      for (int pi = 0; pi < values.Length; pi++) {
 +                              string p = values [pi];
 +                              seenParams[p] = pi;
 +                              
 +                              paramnodes[pi] = e.SelectSingleNode(element + "[@name='" + p + "']");
 +                              if (paramnodes[pi] != null) continue;
 +                              
 +                              XmlElement pe = e.OwnerDocument.CreateElement(element);
 +                              pe.SetAttribute("name", p);
 +                              pe.InnerText = "To be added.";
 +                              paramnodes[pi] = pe;
 +                              reinsert = true;
 +                      }
 +
 +                      // Remove parameters that no longer exist and check all params are in the right order.
 +                      int idx = 0;
 +                      MyXmlNodeList todelete = new MyXmlNodeList ();
 +                      foreach (XmlElement paramnode in e.SelectNodes(element)) {
 +                              string name = paramnode.GetAttribute("name");
 +                              if (!seenParams.ContainsKey(name)) {
 +                                      if (!delete && !paramnode.InnerText.StartsWith("To be added")) {
 +                                              Error ("The following param node can only be deleted if the --delete option is given: ");
 +                                              if (e.ParentNode == e.OwnerDocument.DocumentElement) {
 +                                                      // delegate type
 +                                                      Error ("\tXPath=/Type[@FullName=\"{0}\"]/Docs/param[@name=\"{1}\"]",
 +                                                                      e.OwnerDocument.DocumentElement.GetAttribute ("FullName"),
 +                                                                      name);
 +                                              }
 +                                              else {
 +                                                      Error ("\tXPath=/Type[@FullName=\"{0}\"]//Member[@MemberName=\"{1}\"]/Docs/param[@name=\"{2}\"]",
 +                                                                      e.OwnerDocument.DocumentElement.GetAttribute ("FullName"),
 +                                                                      e.ParentNode.Attributes ["MemberName"].Value, 
 +                                                                      name);
 +                                              }
 +                                              Error ("\tValue={0}", paramnode.OuterXml);
 +                                      } else {
 +                                              todelete.Add (paramnode);
 +                                      }
 +                                      continue;
 +                              }
 +
 +                              if ((int)seenParams[name] != idx)
 +                                      reinsert = true;
 +                              
 +                              idx++;
 +                      }
 +
 +                      foreach (XmlNode n in todelete) {
 +                              n.ParentNode.RemoveChild (n);
 +                      }
 +                      
 +                      // Re-insert the parameter nodes at the top of the doc section.
 +                      if (reinsert)
 +                              for (int pi = values.Length-1; pi >= 0; pi--)
 +                                      e.PrependChild(paramnodes[pi]);
 +              } else {
 +                      // Clear all existing param nodes
 +                      foreach (XmlNode paramnode in e.SelectNodes(element)) {
 +                              if (!delete && !paramnode.InnerText.StartsWith("To be added")) {
 +                                      Console.WriteLine("The following param node can only be deleted if the --delete option is given:");
 +                                      Console.WriteLine(paramnode.OuterXml);
 +                              } else {
 +                                      paramnode.ParentNode.RemoveChild(paramnode);
 +                              }
 +                      }
 +              }
 +      }
 +
 +      private static void UpdateParameterName (XmlElement docs, XmlElement pe, string newName)
 +      {
 +              string existingName = pe.GetAttribute ("name");
 +              pe.SetAttribute ("name", newName);
 +              if (existingName == newName)
 +                      return;
 +              foreach (XmlElement paramref in docs.SelectNodes (".//paramref"))
 +                      if (paramref.GetAttribute ("name").Trim () == existingName)
 +                              paramref.SetAttribute ("name", newName);
 +      }
 +
 +      private static void NormalizeWhitespace(XmlElement e) {
 +              // Remove all text and whitespace nodes from the element so it
 +              // is outputted with nice indentation and no blank lines.
 +              ArrayList deleteNodes = new ArrayList();
 +              foreach (XmlNode n in e)
 +                      if (n is XmlText || n is XmlWhitespace || n is XmlSignificantWhitespace)
 +                              deleteNodes.Add(n);
 +              foreach (XmlNode n in deleteNodes)
 +                              n.ParentNode.RemoveChild(n);
 +      }
 +      
 +      private static bool UpdateAssemblyVersions(XmlElement root, MemberInfo member, bool add)
 +      {
 +              Type type = member as Type;
 +              if (type == null)
 +                      type = member.DeclaringType;
 +              return UpdateAssemblyVersions(root, new string[]{ GetAssemblyVersion(type.Assembly) }, add);
 +      }
 +      
 +      private static string GetAssemblyVersion(Assembly assembly)
 +      {
 +              return assembly.GetName().Version.ToString();
 +      }
 +      
 +      private static bool UpdateAssemblyVersions(XmlElement root, string[] assemblyVersions, bool add)
 +      {
 +              XmlElement e = (XmlElement) root.SelectSingleNode ("AssemblyInfo");
 +              if (e == null) {
 +                      e = root.OwnerDocument.CreateElement("AssemblyInfo");
 +                      root.AppendChild(e);
 +              }
 +              MyXmlNodeList matches = new MyXmlNodeList (assemblyVersions.Length);
 +              foreach (XmlElement v in e.SelectNodes ("AssemblyVersion")) {
 +                      foreach (string sv in assemblyVersions)
 +                              if (v.InnerText == sv)
 +                                      matches.Add (v);
 +              }
 +              // matches.Count > 0 && add: ignore -- already present
 +              if (matches.Count > 0 && !add) {
 +                      foreach (XmlNode c in matches)
 +                              e.RemoveChild (c);
 +              }
 +              else if (matches.Count == 0 && add) {
 +                      foreach (string sv in assemblyVersions) {
 +                              XmlElement c = root.OwnerDocument.CreateElement("AssemblyVersion");
 +                              c.InnerText = sv;
 +                              e.AppendChild(c);
 +                      }
 +              }
 +              // matches.Count == 0 && !add: ignore -- already not present
 +
 +              XmlNodeList avs = e.SelectNodes ("AssemblyVersion");
 +              SortXmlNodes (e, avs, new VersionComparer ());
 +
 +              return avs.Count != 0;
 +      }
 +
 +#if !NET_1_0
 +      private static Type[] IgnorableAttributes = {
 +              // Security related attributes
 +              typeof (System.Reflection.AssemblyKeyFileAttribute),
 +              typeof (System.Reflection.AssemblyDelaySignAttribute),
 +              // Present in @RefType
 +              typeof (System.Runtime.InteropServices.OutAttribute),
 +              // For naming the indexer to use when not using indexers
 +              typeof (System.Reflection.DefaultMemberAttribute),
 +              // for decimal constants
 +              typeof (System.Runtime.CompilerServices.DecimalConstantAttribute),
 +              // compiler generated code
 +              typeof (System.Runtime.CompilerServices.CompilerGeneratedAttribute),
 +              // more compiler generated code, e.g. iterator methods
 +              typeof (System.Diagnostics.DebuggerHiddenAttribute),
 +              typeof (System.Runtime.CompilerServices.FixedBufferAttribute),
 +              typeof (System.Runtime.CompilerServices.UnsafeValueTypeAttribute),
 +              // extension methods
 +              typeof (System.Runtime.CompilerServices.ExtensionAttribute),
 +      };
 +#endif
 +
 +      private static void MakeAttributes(XmlElement root, object attributes, bool assemblyAttributes) {
 +              int len;
 +#if NET_1_0
 +              object[] at = ((ICustomAttributeProvider) attributes).GetCustomAttributes (false);
 +              len = at.Length;
 +#else
 +              System.Collections.Generic.IList<CustomAttributeData> at;
 +              if (attributes is Assembly)
 +                      at = CustomAttributeData.GetCustomAttributes((Assembly)attributes);
 +              else if (attributes is MemberInfo)
 +                      at = CustomAttributeData.GetCustomAttributes((MemberInfo)attributes);
 +              else if (attributes is Module)
 +                      at = CustomAttributeData.GetCustomAttributes((Module)attributes);
 +              else if (attributes is ParameterInfo)
 +                      at = CustomAttributeData.GetCustomAttributes((ParameterInfo)attributes);
 +              else
 +                      throw new ArgumentException("unsupported type: " + attributes.GetType().ToString());
 +              len = at.Count;
 +#endif
 +      
 +              if (len == 0) {
 +                      ClearElement(root, "Attributes");
 +                      return;
 +              }
 +
 +              bool b = false;
 +              XmlElement e = (XmlElement)root.SelectSingleNode("Attributes");
 +              if (e != null)
 +                      e.RemoveAll();
 +              else
 +                      e = root.OwnerDocument.CreateElement("Attributes");
 +              
 +#if !NET_1_0
 +              foreach (CustomAttributeData a in at) {
 +                      if (!IsPublic (a.Constructor.DeclaringType))
 +                              continue;
 +                      if (slashdocFormatter.GetName (a.Constructor.DeclaringType) == null)
 +                              continue;
 +                      
 +                      if (Array.IndexOf (IgnorableAttributes, a.Constructor.DeclaringType) >= 0)
 +                              continue;
 +                      
 +                      b = true;
 +                      
 +                      StringList fields = new StringList ();
 +
 +                      foreach (CustomAttributeTypedArgument f in a.ConstructorArguments) {
 +                              fields.Add(MakeAttributesValueString(f.Value));
 +                      }
 +                      foreach (CustomAttributeNamedArgument f in a.NamedArguments) {
 +                              fields.Add(f.MemberInfo.Name + "=" + MakeAttributesValueString(f.TypedValue.Value));
 +                      }
 +
 +                      string a2 = String.Join(", ", DocUtils.ToStringArray (fields));
 +                      if (a2 != "") a2 = "(" + a2 + ")";
 +                      
 +                      XmlElement ae = root.OwnerDocument.CreateElement("Attribute");
 +                      e.AppendChild(ae);
 +                      
 +                      string name = a.Constructor.DeclaringType.FullName;
 +                      if (name.EndsWith("Attribute")) name = name.Substring(0, name.Length-"Attribute".Length);
 +                      WriteElementText(ae, "AttributeName", name + a2);
 +              }
 +#else
 +              foreach (Attribute a in at) {
 +                      if (!IsPublic (a.GetType ()))
 +                              continue;
 +                      if (slashdocFormatter.GetName (a.GetType ()) == null) continue; // hide non-visible attributes
 +                      //if (assemblyAttributes && a.GetType().FullName.StartsWith("System.Reflection.")) continue;
 +                      if (a.GetType().FullName == "System.Reflection.AssemblyKeyFileAttribute" || a.GetType().FullName == "System.Reflection.AssemblyDelaySignAttribute") continue; // hide security-related attributes
 +
 +                      b = true;
 +                      
 +                      // There's no way to reconstruct how the attribute's constructor was called,
 +                      // so as a substitute, just list the value of all of the attribute's public fields.
 +                      
 +                      StringList fields = new StringList ();
 +                      foreach (PropertyInfo f in a.GetType().GetProperties(BindingFlags.Public|BindingFlags.Instance)) {
 +                              if (f.Name == "TypeId") continue;
 +                              
 +                              object v;
 +                              try {
 +                                      v = f.GetValue(a, null);
 +                                      if (v == null) v = "null";
 +                                      else if (v is string) v = "\"" + v + "\"";
 +                                      else if (v is Type) v = "typeof(" + GetCSharpFullName ((Type)v) + ")";
 +                                      else if (v is Enum) v = v.GetType().FullName + "." + v.ToString().Replace(", ", "|");
 +                              }
 +                              catch (Exception ex) {
 +                                      v = "/* error getting property value: " + ex.Message + " */";
 +                              }
 +                                      
 +                              fields.Add(f.Name + "=" + v);
 +                      }
 +                      string a2 = String.Join(", ", DocUtils.ToStringArray (fields));
 +                      if (a2 != "") a2 = "(" + a2 + ")";
 +                      
 +                      XmlElement ae = root.OwnerDocument.CreateElement("Attribute");
 +                      e.AppendChild(ae);
 +                      
 +                      string name = a.GetType().FullName;
 +                      if (name.EndsWith("Attribute")) name = name.Substring(0, name.Length-"Attribute".Length);
 +                      WriteElementText(ae, "AttributeName", name + a2);
 +              }
 +#endif
 +              
 +              if (b && e.ParentNode == null)
 +                      root.AppendChild(e);
 +              else if (!b)
 +                      ClearElement(root, "Attributes");
 +              
 +              NormalizeWhitespace(e);
 +      }
 +      
 +#if !NET_1_0
 +      private static string MakeAttributesValueString(object v) {
 +              if (v == null) return "null";
 +              else if (v is string) return "\"" + v + "\"";
 +              else if (v is bool) return (bool)v ? "true" : "false";
 +              else if (v is Type) return "typeof(" + GetCSharpFullName ((Type)v) + ")";
 +              else if (v is Enum) {
 +                      string typename = v.GetType ().FullName;
 +                      return typename + "." + v.ToString().Replace(", ", " | " + typename + ".");
 +              }
 +              else return v.ToString();
 +      }
 +#endif
 +      
 +      private static void MakeParameters(XmlElement root, ParameterInfo[] parameters) {
 +              XmlElement e = WriteElement(root, "Parameters");
 +              e.RemoveAll();
 +              foreach (ParameterInfo p in parameters) {
 +                      XmlElement pe = root.OwnerDocument.CreateElement("Parameter");
 +                      e.AppendChild(pe);
 +                      pe.SetAttribute("Name", p.Name);
 +                      pe.SetAttribute("Type", GetDocParameterType (p.ParameterType));
 +                      if (p.ParameterType.IsByRef) {
 +                              if (p.IsOut) pe.SetAttribute("RefType", "out");
 +                              else pe.SetAttribute("RefType", "ref");
 +                      }
 +                      MakeAttributes(pe, p, false);
 +              }
 +      }
 +      
 +      private static void MakeTypeParameters(XmlElement root, Type[] typeParams)
 +      {
 +              if (typeParams == null || typeParams.Length == 0) {
 +                      XmlElement f = (XmlElement) root.SelectSingleNode ("TypeParameters");
 +                      if (f != null)
 +                              root.RemoveChild (f);
 +                      return;
 +              }
 +              XmlElement e = WriteElement(root, "TypeParameters");
 +              e.RemoveAll();
 +              foreach (Type t in typeParams) {
 +                      XmlElement pe = root.OwnerDocument.CreateElement("TypeParameter");
 +                      e.AppendChild(pe);
 +                      pe.SetAttribute("Name", t.Name);
 +                      MakeAttributes(pe, t, false);
 +#if !NET_1_0
 +                      XmlElement ce = (XmlElement) e.SelectSingleNode ("Constraints");
 +                      GenericParameterAttributes attrs = t.GenericParameterAttributes;
 +                      Type[] constraints = t.GetGenericParameterConstraints ();
 +                      if (attrs == GenericParameterAttributes.None && constraints.Length == 0) {
 +                              if (ce != null)
 +                                      e.RemoveChild (ce);
 +                              continue;
 +                      }
 +                      if (ce != null)
 +                              ce.RemoveAll();
 +                      else {
 +                              ce = root.OwnerDocument.CreateElement ("Constraints");
 +                      }
 +                      pe.AppendChild (ce);
 +                      if ((attrs & GenericParameterAttributes.Contravariant) != 0)
 +                              AppendElementText (ce, "ParameterAttribute", "Contravariant");
 +                      if ((attrs & GenericParameterAttributes.Covariant) != 0)
 +                              AppendElementText (ce, "ParameterAttribute", "Covariant");
 +                      if ((attrs & GenericParameterAttributes.DefaultConstructorConstraint) != 0)
 +                              AppendElementText (ce, "ParameterAttribute", "DefaultConstructorConstraint");
 +                      if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
 +                              AppendElementText (ce, "ParameterAttribute", "NotNullableValueTypeConstraint");
 +                      if ((attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0)
 +                              AppendElementText (ce, "ParameterAttribute", "ReferenceTypeConstraint");
 +                      foreach (Type c in constraints) {
 +                              AppendElementText (ce, 
 +                                              c.IsInterface ? "InterfaceName" : "BaseTypeName", GetDocTypeFullName (c));
 +                      }
 +#endif
 +              }
 +      }
 +
 +      private static void MakeParameters(XmlElement root, MemberInfo mi) {
 +              if (mi is ConstructorInfo) MakeParameters(root, ((ConstructorInfo)mi).GetParameters());
 +              else if (mi is MethodInfo) {
 +                      MethodBase mb = (MethodBase) mi;
 +                      ParameterInfo[] parameters = mb.GetParameters();
 +                      MakeParameters(root, parameters);
 +                      if (parameters.Length > 0 && DocUtils.IsExtensionMethod (mb)) {
 +                              XmlElement p = (XmlElement) root.SelectSingleNode ("Parameters/Parameter[position()=1]");
 +                              p.SetAttribute ("RefType", "this");
 +                      }
 +              }
 +              else if (mi is PropertyInfo) {
 +                      ParameterInfo[] parameters = ((PropertyInfo)mi).GetIndexParameters();
 +                      if (parameters.Length > 0)
 +                              MakeParameters(root, parameters);
 +                      else
 +                              return;
 +              }
 +              else if (mi is FieldInfo) return;
 +              else if (mi is EventInfo) return;
 +              else throw new ArgumentException();
 +      }
 +
 +      private static string GetDocParameterType (Type type)
 +      {
 +              return GetDocTypeFullName (type).Replace ("@", "&");
 +      }
 +
 +      private static void MakeReturnValue(XmlElement root, Type type, ICustomAttributeProvider attributes) {
 +              XmlElement e = WriteElement(root, "ReturnValue");
 +              e.RemoveAll();
 +              WriteElementText(e, "ReturnType", GetDocTypeFullName (type));
 +              if (attributes != null)
 +                      MakeAttributes(e, attributes, false);
 +      }
 +      
 +      private static void MakeReturnValue(XmlElement root, MemberInfo mi) {
 +              if (mi is ConstructorInfo) return;
 +              else if (mi is MethodInfo) MakeReturnValue(root, ((MethodInfo)mi).ReturnType, ((MethodInfo)mi).ReturnTypeCustomAttributes);
 +              else if (mi is PropertyInfo) MakeReturnValue(root, ((PropertyInfo)mi).PropertyType, null);
 +              else if (mi is FieldInfo) MakeReturnValue(root, ((FieldInfo)mi).FieldType, null);
 +              else if (mi is EventInfo) MakeReturnValue(root, ((EventInfo)mi).EventHandlerType, null);
 +              else throw new ArgumentException(mi + " is a " + mi.GetType().FullName);
 +      }
 +      
 +      private static XmlElement MakeMember(XmlDocument doc, DocsNodeInfo info) {
 +              MemberInfo mi = info.Member;
 +              if (mi is Type) return null;
 +
 +              string sigs = MakeMemberSignature(mi);
 +              if (sigs == null) return null; // not publicly visible
 +              
 +              // no documentation for property/event accessors.  Is there a better way of doing this?
 +              if (mi.Name.StartsWith("get_")) return null;
 +              if (mi.Name.StartsWith("set_")) return null;
 +              if (mi.Name.StartsWith("add_")) return null;
 +              if (mi.Name.StartsWith("remove_")) return null;
 +              if (mi.Name.StartsWith("raise_")) return null;
 +              
 +              XmlElement me = doc.CreateElement("Member");
 +              me.SetAttribute("MemberName", GetMemberName (mi));
 +              
 +              info.Node = me;
 +              UpdateMember(info);
 +
 +              if (since != null) {
 +                      XmlNode docs = me.SelectSingleNode("Docs");
 +                      docs.AppendChild (CreateSinceNode (doc));
 +              }
 +              
 +              return me;
 +      }
 +
 +      private static string GetMemberName (MemberInfo mi)
 +      {
 +              MethodBase mb = mi as MethodBase;
 +              if (mb == null) {
 +                      PropertyInfo pi = mi as PropertyInfo;
 +                      if (pi == null)
 +                              return mi.Name;
 +                      return DocUtils.GetPropertyName (pi);
 +              }
 +              StringBuilder sb = new StringBuilder (mi.Name.Length);
 +              if (!DocUtils.IsExplicitlyImplemented (mb))
 +                      sb.Append (mi.Name);
 +              else {
 +                      Type iface;
 +                      MethodInfo ifaceMethod;
 +                      DocUtils.GetInfoForExplicitlyImplementedMethod (mb, out iface, out ifaceMethod);
 +                      sb.Append (GetDocTypeFullName (iface));
 +                      sb.Append ('.');
 +                      sb.Append (ifaceMethod.Name);
 +              }
 +              if (DocUtils.GetContainsGenericParameters (mb)) {
 +                      Type[] typeParams = DocUtils.GetGenericArguments (mb);
 +                      if (typeParams.Length > 0) {
 +                              sb.Append ("<");
 +                              sb.Append (typeParams [0].Name);
 +                              for (int i = 1; i < typeParams.Length; ++i)
 +                                      sb.Append (",").Append (typeParams [i].Name);
 +                              sb.Append (">");
 +                      }
 +              }
 +              return sb.ToString ();
 +      }
 +
 +      private static int CountChars (string s, char c)
 +      {
 +              int count = 0;
 +              for (int i = 0; i < s.Length; ++i) {
 +                      if (s [i] == c)
 +                              ++count;
 +              }
 +              return count;
 +      }
 +      
 +      static bool IsDelegate(Type type) {
 +              return typeof(System.Delegate).IsAssignableFrom (type) && !type.IsAbstract;
 +      }
 +      
 +      /// SIGNATURE GENERATION FUNCTIONS
 +      
 +      private static bool InterfaceNotFromAnother(Type i, Type[] i2) {
 +              foreach (Type t in i2)
 +                      if (i != t && Array.IndexOf(t.GetInterfaces(), i) != -1)
 +                              return false;
 +              return true;
 +      }
 +      
 +      static string MakeTypeSignature (Type type) {
 +              return csharpFormatter.GetDeclaration (type);
 +      }
 +
 +      static string MakeMemberSignature(MemberInfo mi) {
 +              return csharpFullFormatter.GetDeclaration (mi);
 +      }
 +
 +      static string GetMemberType(MemberInfo mi) {
 +              if (mi is ConstructorInfo) return "Constructor";
 +              if (mi is MethodInfo) return "Method";
 +              if (mi is PropertyInfo) return "Property";
 +              if (mi is FieldInfo) return "Field";
 +              if (mi is EventInfo) return "Event";
 +              throw new ArgumentException();
 +      }
 +
 +      private static string GetDocTypeName (Type type)
 +      {
 +              return docTypeFormatter.GetName (type);
 +      }
 +
 +      private static string GetDocTypeFullName (Type type)
 +      {
 +              return DocTypeFullMemberFormatter.Default.GetName (type);
 +      }
 +
 +      private static string GetCSharpFullName (Type type)
 +      {
 +              return DocTypeFullMemberFormatter.Default.GetName (type);
 +      }
 +
 +      class DocsNodeInfo {
 +              public DocsNodeInfo (XmlElement node)
 +              {
 +                      this.Node = node;
 +              }
 +
 +              public DocsNodeInfo (XmlElement node, Type type)
 +                      : this (node)
 +              {
 +                      SetType (type);
 +              }
 +
 +              public DocsNodeInfo (XmlElement node, MemberInfo member)
 +                      : this (node)
 +              {
 +                      SetMemberInfo (member);
 +              }
 +
 +              public void SetType (Type type)
 +              {
 +                      if (type == null)
 +                              throw new ArgumentNullException ("type");
 +                      GenericParameters = DocUtils.GetGenericArguments (type);
 +                      if (type.DeclaringType != null) {
 +                              Type[] declGenParams = DocUtils.GetGenericArguments (type.DeclaringType);
 +                              if (declGenParams != null && GenericParameters.Length == declGenParams.Length) {
 +                                      GenericParameters = null;
 +                              }
 +                              else if (declGenParams != null) {
 +                                      Type[] nestedParams = new Type [GenericParameters.Length - declGenParams.Length];
 +                                      for (int i = 0; i < nestedParams.Length; ++i) {
 +                                              nestedParams [i] = GenericParameters [i+declGenParams.Length];
 +                                      }
 +                                      GenericParameters = nestedParams;
 +                              }
 +                      }
 +                      if (IsDelegate(type)) {
 +                              Parameters = type.GetMethod("Invoke").GetParameters();
 +                              ReturnType = type.GetMethod("Invoke").ReturnType;
 +                      }
 +                      SetSlashDocs (type);
 +              }
 +
 +              public void SetMemberInfo (MemberInfo member)
 +              {
 +                      if (member == null)
 +                              throw new ArgumentNullException ("member");
 +                      ReturnIsReturn = true;
 +                      AddRemarks = true;
 +                      Member = member;
 +                      
 +                      if (member is MethodInfo || member is ConstructorInfo) {
 +                              Parameters = ((MethodBase) member).GetParameters ();
 +                              if (DocUtils.GetContainsGenericParameters ((MethodBase) member)) {
 +                                      GenericParameters = DocUtils.GetGenericArguments ((MethodBase) member);
 +                              }
 +                      }
 +                      else if (member is PropertyInfo) {
 +                              Parameters = ((PropertyInfo) member).GetIndexParameters ();
 +                      }
 +                              
 +                      if (member is MethodInfo) {
 +                              ReturnType = ((MethodInfo) member).ReturnType;
 +                      } else if (member is PropertyInfo) {
 +                              ReturnType = ((PropertyInfo) member).PropertyType;
 +                              ReturnIsReturn = false;
 +                      }
 +
 +                      // no remarks section for enum members
 +                      if (member.DeclaringType != null && member.DeclaringType.IsEnum)
 +                              AddRemarks = false;
 +                      SetSlashDocs (member);
 +              }
 +
 +              private void SetSlashDocs (MemberInfo member)
 +              {
 +                      if (slashdocs == null)
 +                              return;
 +
 +                      string slashdocsig = slashdocFormatter.GetDeclaration (member);
 +                      if (slashdocsig != null)
 +                              SlashDocs = slashdocs.SelectSingleNode ("doc/members/member[@name='" + slashdocsig + "']");
 +              }
 +
 +              public Type ReturnType;
 +              public Type[] GenericParameters;
 +              public ParameterInfo[] Parameters;
 +              public bool ReturnIsReturn;
 +              public XmlElement Node;
 +              public bool AddRemarks = true;
 +              public XmlNode SlashDocs;
 +              public XmlReader EcmaDocs;
 +              public MemberInfo Member;
 +      }
 +
 +      static string GetXPathForMember (DocumentationMember member)
 +      {
 +              StringBuilder xpath = new StringBuilder ();
 +              xpath.Append ("//Members/Member[@MemberName=\"")
 +                      .Append (member.MemberName)
 +                      .Append ("\"]");
 +              if (member.Parameters != null && member.Parameters.Count > 0) {
 +                      xpath.Append ("/Parameters[count(Parameter) = ")
 +                              .Append (member.Parameters.Count);
 +                      for (int i = 0; i < member.Parameters.Count; ++i) {
 +                              xpath.Append (" and Parameter [").Append (i+1).Append ("]/@Type=\"");
 +                              xpath.Append (member.Parameters [i]);
 +                              xpath.Append ("\"");
 +                      }
 +                      xpath.Append ("]/..");
 +              }
 +              return xpath.ToString ();
 +      }
 +
 +      public static string GetXPathForMember (XPathNavigator member)
 +      {
 +              StringBuilder xpath = new StringBuilder ();
 +              xpath.Append ("//Type[@FullName=\"")
 +                      .Append (SelectSingleNode (member, "../../@FullName").Value)
 +                      .Append ("\"]/");
 +              xpath.Append ("Members/Member[@MemberName=\"")
 +                      .Append (SelectSingleNode (member, "@MemberName").Value)
 +                      .Append ("\"]");
 +              XPathNodeIterator parameters = member.Select ("Parameters/Parameter");
 +              if (parameters.Count > 0) {
 +                      xpath.Append ("/Parameters[count(Parameter) = ")
 +                              .Append (parameters.Count);
 +                      int i = 0;
 +                      while (parameters.MoveNext ()) {
 +                              ++i;
 +                              xpath.Append (" and Parameter [").Append (i).Append ("]/@Type=\"");
 +                              xpath.Append (parameters.Current.Value);
 +                              xpath.Append ("\"");
 +                      }
 +                      xpath.Append ("]/..");
 +              }
 +              return xpath.ToString ();
 +      }
 +
 +      public static string GetXPathForMember (MemberInfo member)
 +      {
 +              StringBuilder xpath = new StringBuilder ();
 +              xpath.Append ("//Type[@FullName=\"")
 +                      .Append (member.DeclaringType.FullName)
 +                      .Append ("\"]/");
 +              xpath.Append ("Members/Member[@MemberName=\"")
 +                      .Append (GetMemberName (member))
 +                      .Append ("\"]");
 +
 +              ParameterInfo[] parameters = null;
 +              if (member is MethodBase)
 +                      parameters = ((MethodBase) member).GetParameters ();
 +              else if (member is PropertyInfo) {
 +                      parameters = ((PropertyInfo) member).GetIndexParameters ();
 +              }
 +              if (parameters != null && parameters.Length > 0) {
 +                      xpath.Append ("/Parameters[count(Parameter) = ")
 +                              .Append (parameters.Length);
 +                      for (int i = 0; i < parameters.Length; ++i) {
 +                              xpath.Append (" and Parameter [").Append (i+1).Append ("]/@Type=\"");
 +                              xpath.Append (GetDocParameterType (parameters [i].ParameterType));
 +                              xpath.Append ("\"");
 +                      }
 +                      xpath.Append ("]/..");
 +              }
 +              return xpath.ToString ();
 +      }
 +}
 +
 +static class DocUtils {
 +      public static bool GetContainsGenericParameters (Type type)
 +      {
 +#if NET_1_0
 +              return false;
 +#else
 +              return type.ContainsGenericParameters;
 +#endif
 +      }
 +
 +      public static bool GetContainsGenericParameters (MethodBase mb)
 +      {
 +#if NET_1_0
 +              return false;
 +#else
 +              return mb.ContainsGenericParameters;
 +#endif
 +      }
 +
 +      public static Type[] GetGenericArguments (Type type)
 +      {
 +#if NET_1_0
 +              return new Type [0];
 +#else
 +              return type.GetGenericArguments ();
 +#endif
 +      }
 +
 +      public static Type[] GetGenericArguments (MethodBase mb)
 +      {
 +#if NET_1_0
 +              return new Type [0];
 +#else
 +              return mb.GetGenericArguments ();
 +#endif
 +      }
 +
 +      public static Type GetGenericTypeDefinition (Type type)
 +      {
 +#if NET_1_0
 +              return null;
 +#else
 +              return type.GetGenericTypeDefinition ();
 +#endif
 +      }
 +
 +      public static Type[] GetGenericParameterConstraints (Type type)
 +      {
 +#if NET_1_0
 +              return null;
 +#else
 +              return type.GetGenericParameterConstraints ();
 +#endif
 +      }
 +
 +      public static bool IsGenericType (Type type)
 +      {
 +#if NET_1_0
 +              return false;
 +#else
 +              return type.IsGenericType;
 +#endif
 +      }
 +
 +      public static bool IsGenericParameter (Type type)
 +      {
 +#if NET_1_0
 +              return false;
 +#else
 +              return type.IsGenericParameter;
 +#endif
 +      }
 +
 +      public static bool IsExplicitlyImplemented (MethodBase method)
 +      {
 +              return method.IsPrivate && method.IsFinal && method.IsVirtual;
 +      }
 +
 +      public static string GetTypeDotMember (string name)
 +      {
 +              int startType, startMethod;
 +              startType = startMethod = -1;
 +              for (int i = 0; i < name.Length; ++i) {
 +                      if (name [i] == '.') {
 +                              startType = startMethod;
 +                              startMethod = i;
 +                      }
 +              }
 +              return name.Substring (startType+1);
 +      }
 +
 +      public static string GetMember (string name)
 +      {
 +              int i = name.LastIndexOf ('.');
 +              if (i == -1)
 +                      return name;
 +              return name.Substring (i+1);
 +      }
 +
 +      public static void GetInfoForExplicitlyImplementedMethod (
 +                      MethodBase method, out Type iface, out MethodInfo ifaceMethod)
 +      {
 +              Type declType = method.DeclaringType;
 +              foreach (Type declIface in declType.GetInterfaces ()) {
 +                      InterfaceMapping map = declType.GetInterfaceMap (declIface);
 +                      for (int i = 0; i < map.TargetMethods.Length; ++i)
 +                              if (method == map.TargetMethods [i]) {
 +                                      iface       = map.InterfaceType;
 +                                      ifaceMethod = map.InterfaceMethods [i];
 +                                      return;
 +                              }
 +              }
 +              throw new InvalidOperationException ("Could not determine interface type for explicitly-implemented interface member " + method.Name);
 +      }
 +
 +      public static string[] ToStringArray (StringList list)
 +      {
 +#if NET_1_0
 +              return (string[]) list.ToArray (typeof(string));
 +#else
 +              return list.ToArray ();
 +#endif
 +      }
 +
 +      public static string GetPropertyName (PropertyInfo pi)
 +      {
 +              // Issue: (g)mcs-generated assemblies that explicitly implement
 +              // properties don't specify the full namespace, just the 
 +              // TypeName.Property; .NET uses Full.Namespace.TypeName.Property.
 +              MethodInfo method = pi.GetGetMethod (true);
 +              if (method == null)
 +                      method = pi.GetSetMethod (true);
 +              if (!IsExplicitlyImplemented (method))
 +                      return pi.Name;
 +
 +              // Need to determine appropriate namespace for this member.
 +              Type iface;
 +              MethodInfo ifaceMethod;
 +              GetInfoForExplicitlyImplementedMethod (method, out iface, out ifaceMethod);
 +              return string.Join (".", new string[]{
 +                              DocTypeFullMemberFormatter.Default.GetName (iface),
 +                              GetMember (pi.Name)});
 +      }
 +
 +      public static string PathCombine (string dir, string path)
 +      {
 +              if (dir == null)
 +                      dir = "";
 +              if (path == null)
 +                      path = "";
 +              return Path.Combine (dir, path);
 +      }
 +
 +      public static bool IsExtensionMethod (MethodBase method)
 +      {
 +#if NET_1_0
 +              return false;
 +#else
 +              return 
 +                      method.GetCustomAttributes (
 +                                      typeof(System.Runtime.CompilerServices.ExtensionAttribute), 
 +                                      false).Length != 0 &&
 +                      method.DeclaringType.GetCustomAttributes (
 +                                      typeof(System.Runtime.CompilerServices.ExtensionAttribute), 
 +                                      false).Length != 0;
 +#endif
 +      }
 +}
 +
 +class DocumentationMember {
 +      public StringToStringMap MemberSignatures = new StringToStringMap ();
 +      public string ReturnType;
 +      public StringList Parameters;
 +      public string MemberName;
 +      public string MemberType;
 +
 +      public DocumentationMember (XmlReader reader)
 +      {
 +              MemberName = reader.GetAttribute ("MemberName");
 +              int depth = reader.Depth;
 +              bool go = true;
 +              StringList p = new StringList ();
 +              do {
 +                      if (reader.NodeType != XmlNodeType.Element)
 +                              continue;
 +                      switch (reader.Name) {
 +                              case "MemberSignature":
 +                                      MemberSignatures [reader.GetAttribute ("Language")] = reader.GetAttribute ("Value");
 +                                      break;
 +                              case "MemberType":
 +                                      MemberType = reader.ReadElementString ();
 +                                      break;
 +                              case "ReturnType":
 +                                      if (reader.Depth == depth + 2)
 +                                              ReturnType = reader.ReadElementString ();
 +                                      break;
 +                              case "Parameter":
 +                                      if (reader.Depth == depth + 2)
 +                                              p.Add (reader.GetAttribute ("Type"));
 +                                      break;
 +                              case "Docs":
 +                                      if (reader.Depth == depth + 1)
 +                                              go = false;
 +                                      break;
 +                      }
 +              } while (go && reader.Read () && reader.Depth >= depth);
 +              if (p.Count > 0) {
 +                      Parameters = p;
 +              }
 +      }
 +
 +      public DocumentationMember (XmlNode node)
 +      {
 +              MemberName = node.Attributes ["MemberName"].Value;
 +              foreach (XmlNode n in node.SelectNodes ("MemberSignature")) {
 +                      XmlAttribute l = n.Attributes ["Language"];
 +                      XmlAttribute v = n.Attributes ["Value"];
 +                      if (l != null && v != null)
 +                              MemberSignatures [l.Value] = v.Value;
 +              }
 +              MemberType = node.SelectSingleNode ("MemberType").InnerText;
 +              XmlNode rt = node.SelectSingleNode ("ReturnValue/ReturnType");
 +              if (rt != null)
 +                      ReturnType = rt.InnerText;
 +              XmlNodeList p = node.SelectNodes ("Parameters/Parameter");
 +              if (p.Count > 0) {
 +                      Parameters = new StringList (p.Count);
 +                      for (int i = 0; i < p.Count; ++i)
 +                              Parameters.Add (p [i].Attributes ["Type"].Value);
 +              }
 +      }
 +}
 +
 +public abstract class MemberFormatter {
 +      public string GetName (MemberInfo member)
 +      {
 +              Type type = member as Type;
 +              if (type != null)
 +                      return GetTypeName (type);
 +              ConstructorInfo ctor = member as ConstructorInfo;
 +              if (ctor != null)
 +                      return GetConstructorName (ctor);
 +              MethodInfo method = member as MethodInfo;
 +              if (method != null)
 +                      return GetMethodName (method);
 +              PropertyInfo prop = member as PropertyInfo;
 +              if (prop != null)
 +                      return GetPropertyName (prop);
 +              FieldInfo field = member as FieldInfo;
 +              if (field != null)
 +                      return GetFieldName (field);
 +              EventInfo e = member as EventInfo;
 +              if (e != null)
 +                      return GetEventName (e);
 +              throw new NotSupportedException ("Can't handle: " + member.GetType().ToString());
 +      }
 +
 +      protected virtual string GetTypeName (Type type)
 +      {
 +              if (type == null)
 +                      throw new ArgumentNullException ("type");
 +              return _AppendTypeName (new StringBuilder (type.Name.Length), type).ToString ();
 +      }
 +
 +      protected virtual char[] ArrayDelimeters {
 +              get {return new char[]{'[', ']'};}
 +      }
 +
 +      protected StringBuilder _AppendTypeName (StringBuilder buf, Type type)
 +      {
 +              if (type.IsArray) {
 +                      _AppendTypeName (buf, type.GetElementType ()).Append (ArrayDelimeters [0]);
 +                      int rank = type.GetArrayRank ();
 +                      if (rank > 1)
 +                              buf.Append (new string (',', rank-1));
 +                      return buf.Append (ArrayDelimeters [1]);
 +              }
 +              if (type.IsByRef) {
 +                      return AppendRefTypeName (buf, type);
 +              }
 +              if (type.IsPointer) {
 +                      return AppendPointerTypeName (buf, type);
 +              }
 +              AppendNamespace (buf, type);
 +              if (DocUtils.IsGenericParameter (type)) {
 +                      return AppendTypeName (buf, type);
 +              }
 +              if (!DocUtils.IsGenericType (type)) {
 +                      if (type.DeclaringType != null)
 +                              AppendTypeName (buf, type.DeclaringType).Append (NestedTypeSeparator);
 +                      return AppendTypeName (buf, type);
 +              }
 +              return AppendGenericType (buf, type);
 +      }
 +
 +      protected virtual StringBuilder AppendNamespace (StringBuilder buf, Type type)
 +      {
 +              if (type.Namespace != null && type.Namespace.Length > 0)
 +                      buf.Append (type.Namespace).Append ('.');
 +              return buf;
 +      }
 +
 +      protected virtual StringBuilder AppendTypeName (StringBuilder buf, Type type)
 +      {
 +              return AppendTypeName (buf, type.Name);
 +      }
 +
 +      protected virtual StringBuilder AppendTypeName (StringBuilder buf, string typename)
 +      {
 +              int n = typename.IndexOf ("`");
 +              if (n >= 0)
 +                      return buf.Append (typename.Substring (0, n));
 +              return buf.Append (typename);
 +      }
 +
 +      protected virtual string RefTypeModifier {
 +              get {return "@";}
 +      }
 +
 +      protected virtual StringBuilder AppendRefTypeName (StringBuilder buf, Type type)
 +      {
 +              return _AppendTypeName (buf, type.GetElementType ()).Append (RefTypeModifier);
 +      }
 +
 +      protected virtual string PointerModifier {
 +              get {return "*";}
 +      }
 +
 +      protected virtual StringBuilder AppendPointerTypeName (StringBuilder buf, Type type)
 +      {
 +              return _AppendTypeName (buf, type.GetElementType ()).Append (PointerModifier);
 +      }
 +
 +      protected virtual char[] GenericTypeContainer {
 +              get {return new char[]{'<', '>'};}
 +      }
 +
 +      protected virtual char NestedTypeSeparator {
 +              get {return '.';}
 +      }
 +
 +      protected virtual StringBuilder AppendGenericType (StringBuilder buf, Type type)
 +      {
 +              Type[] genArgs = DocUtils.GetGenericArguments (type);
 +              int genArg = 0;
 +              if (type.DeclaringType != null) {
 +                      AppendTypeName (buf, type.DeclaringType);
 +                      if (DocUtils.IsGenericType (type.DeclaringType)) {
 +                              buf.Append (GenericTypeContainer [0]);
 +                              int max = DocUtils.GetGenericArguments (type.DeclaringType).Length;
 +                              _AppendTypeName (buf, genArgs [genArg++]);
 +                              while (genArg < max) {
 +                                      buf.Append (",");
 +                                      _AppendTypeName (buf, genArgs [genArg++]);
 +                              }
 +                              buf.Append (GenericTypeContainer [1]);
 +                      }
 +                      buf.Append (NestedTypeSeparator);
 +              }
 +              AppendTypeName (buf, type);
 +              if (genArg < genArgs.Length) {
 +                      buf.Append (GenericTypeContainer [0]);
 +                      _AppendTypeName (buf, genArgs [genArg++]);
 +                      while (genArg < genArgs.Length) {
 +                              buf.Append (",");
 +                              _AppendTypeName (buf, genArgs [genArg++]);
 +                      }
 +                      buf.Append (GenericTypeContainer [1]);
 +              }
 +              return buf;
 +      }
 +
 +      protected virtual StringBuilder AppendGenericTypeConstraints (StringBuilder buf, Type type)
 +      {
 +              return buf;
 +      }
 +
 +      protected virtual string GetConstructorName (ConstructorInfo constructor)
 +      {
 +              return constructor.Name;
 +      }
 +
 +      protected virtual string GetMethodName (MethodInfo method)
 +      {
 +              return method.Name;
 +      }
 +
 +      protected virtual string GetPropertyName (PropertyInfo property)
 +      {
 +              return property.Name;
 +      }
 +
 +      protected virtual string GetFieldName (FieldInfo field)
 +      {
 +              return field.Name;
 +      }
 +
 +      protected virtual string GetEventName (EventInfo e)
 +      {
 +              return e.Name;
 +      }
 +
 +      public string GetDeclaration (MemberInfo member)
 +      {
 +              Type type = member as Type;
 +              if (type != null)
 +                      return GetTypeDeclaration (type);
 +              ConstructorInfo ctor = member as ConstructorInfo;
 +              if (ctor != null)
 +                      return GetConstructorDeclaration (ctor);
 +              MethodInfo method = member as MethodInfo;
 +              if (method != null)
 +                      return GetMethodDeclaration (method);
 +              PropertyInfo prop = member as PropertyInfo;
 +              if (prop != null)
 +                      return GetPropertyDeclaration (prop);
 +              FieldInfo field = member as FieldInfo;
 +              if (field != null)
 +                      return GetFieldDeclaration (field);
 +              EventInfo e = member as EventInfo;
 +              if (e != null)
 +                      return GetEventDeclaration (e);
 +              throw new NotSupportedException ("Can't handle: " + member.GetType().ToString());
 +      }
 +
 +      protected virtual string GetTypeDeclaration (Type type)
 +      {
 +              if (type == null)
 +                      throw new ArgumentNullException ("type");
 +              StringBuilder buf = new StringBuilder (type.Name.Length);
 +              _AppendTypeName (buf, type);
 +              AppendGenericTypeConstraints (buf, type);
 +              return buf.ToString ();
 +      }
 +
 +      protected virtual string GetConstructorDeclaration (ConstructorInfo constructor)
 +      {
 +              return GetConstructorName (constructor);
 +      }
 +
 +      protected virtual string GetMethodDeclaration (MethodInfo method)
 +      {
 +              // Special signature for destructors.
 +              if (method.Name == "Finalize" && method.GetParameters().Length == 0)
 +                      return GetFinalizerName (method);
 +
 +              StringBuilder buf = new StringBuilder ();
 +
 +              AppendVisibility (buf, method);
 +              if (buf.Length == 0 && 
 +                              !(DocUtils.IsExplicitlyImplemented (method) && !method.IsSpecialName))
 +                      return null;
 +
 +              AppendModifiers (buf, method);
 +
 +              if (buf.Length != 0)
 +                      buf.Append (" ");
 +              buf.Append (GetName (method.ReturnType)).Append (" ");
 +
 +              AppendMethodName (buf, method);
 +              AppendGenericMethod (buf, method).Append (" ");
 +              AppendParameters (buf, method, method.GetParameters ());
 +              AppendGenericMethodConstraints (buf, method);
 +              return buf.ToString ();
 +      }
 +
 +      protected virtual StringBuilder AppendMethodName (StringBuilder buf, MethodBase method)
 +      {
 +              return buf.Append (method.Name);
 +      }
 +
 +      protected virtual string GetFinalizerName (MethodInfo method)
 +      {
 +              return "Finalize";
 +      }
 +
 +      protected virtual StringBuilder AppendVisibility (StringBuilder buf, MethodBase method)
 +      {
 +              return buf;
 +      }
 +
 +      protected virtual StringBuilder AppendModifiers (StringBuilder buf, MethodInfo method)
 +      {
 +              return buf;
 +      }
 +
 +      protected virtual StringBuilder AppendGenericMethod (StringBuilder buf, MethodInfo method)
 +      {
 +              return buf;
 +      }
 +
 +      protected virtual StringBuilder AppendParameters (StringBuilder buf, MethodBase method, ParameterInfo[] parameters)
 +      {
 +              return buf;
 +      }
 +
 +      protected virtual StringBuilder AppendGenericMethodConstraints (StringBuilder buf, MethodInfo method)
 +      {
 +              return buf;
 +      }
 +
 +      protected virtual string GetPropertyDeclaration (PropertyInfo property)
 +      {
 +              return GetPropertyName (property);
 +      }
 +
 +      protected virtual string GetFieldDeclaration (FieldInfo field)
 +      {
 +              return GetFieldName (field);
 +      }
 +
 +      protected virtual string GetEventDeclaration (EventInfo e)
 +      {
 +              return GetEventName (e);
 +      }
 +}
 +
 +class CSharpFullMemberFormatter : MemberFormatter {
 +
 +      protected override StringBuilder AppendNamespace (StringBuilder buf, Type type)
 +      {
 +              if (GetCSharpType (type.FullName) == null && type.Namespace != null && type.Namespace.Length > 0 && type.Namespace != "System")
 +                      buf.Append (type.Namespace).Append ('.');
 +              return buf;
 +      }
 +
 +      private string GetCSharpType (string t)
 +      {
 +              switch (t) {
 +              case "System.Byte":    return "byte";
 +              case "System.SByte":   return "sbyte";
 +              case "System.Int16":   return "short";
 +              case "System.Int32":   return "int";
 +              case "System.Int64":   return "long";
 +
 +              case "System.UInt16":  return "ushort";
 +              case "System.UInt32":  return "uint";
 +              case "System.UInt64":  return "ulong";
 +
 +              case "System.Single":  return "float";
 +              case "System.Double":  return "double";
 +              case "System.Decimal": return "decimal";
 +              case "System.Boolean": return "bool";
 +              case "System.Char":    return "char";
 +              case "System.Void":    return "void";
 +              case "System.String":  return "string";
 +              case "System.Object":  return "object";
 +              }
 +              return null;
 +      }
 +
 +      protected override StringBuilder AppendTypeName (StringBuilder buf, Type type)
 +      {
 +              if (DocUtils.IsGenericParameter (type))
 +                      return buf.Append (type.Name);
 +              string t = type.FullName;
 +              if (!t.StartsWith ("System.")) {
 +                      return base.AppendTypeName (buf, type);
 +              }
 +
 +              string s = GetCSharpType (t);
 +              if (s != null)
 +                      return buf.Append (s);
 +              
 +              return base.AppendTypeName (buf, type);
 +      }
 +
 +      protected override string GetTypeDeclaration (Type type)
 +      {
 +              string visibility = GetTypeVisibility (type.Attributes);
 +              if (visibility == null)
 +                      return null;
 +
 +              StringBuilder buf = new StringBuilder ();
 +              
 +              buf.Append (visibility);
 +              buf.Append (" ");
 +
 +              MemberFormatter full = new CSharpFullMemberFormatter ();
 +
 +              if (IsDelegate(type)) {
 +                      buf.Append("delegate ");
 +                      MethodInfo invoke = type.GetMethod ("Invoke");
 +                      buf.Append (full.GetName (invoke.ReturnType)).Append (" ");
 +                      buf.Append (GetName (type));
 +                      AppendParameters (buf, invoke, invoke.GetParameters ());
 +                      AppendGenericTypeConstraints (buf, type);
 +                      buf.Append (";");
 +
 +                      return buf.ToString();
 +              }
 +              
 +              if (type.IsAbstract && !type.IsInterface)
 +                      buf.Append("abstract ");
 +              if (type.IsSealed && !IsDelegate(type) && !type.IsValueType)
 +                      buf.Append("sealed ");
 +              buf.Replace ("abstract sealed", "static");
 +
 +              buf.Append (GetTypeKind (type));
 +              buf.Append (" ");
 +              buf.Append (GetCSharpType (type.FullName) == null 
 +                              ? GetName (type) 
 +                              : type.Name);
 +
 +              if (!type.IsEnum) {
 +                      Type basetype = type.BaseType;
 +                      if (basetype == typeof(object) || type.IsValueType) // don't show this in signatures
 +                              basetype = null;
 +                      
 +                      ArrayList interface_names = new ArrayList ();
 +                      foreach (Type i in type.GetInterfaces ())
 +                              if ((type.BaseType == null || Array.IndexOf (type.BaseType.GetInterfaces (), i) == -1) && 
 +                                              InterfaceNotFromAnother (i, type.GetInterfaces ()))
 +                                      interface_names.Add (full.GetName (i));
 +                      interface_names.Sort ();
 +                      
 +                      if (basetype != null || interface_names.Count > 0)
 +                              buf.Append (" : ");
 +                      
 +                      if (basetype != null) {
 +                              buf.Append (full.GetName (basetype));
 +                              if (interface_names.Count > 0)
 +                                      buf.Append (", ");
 +                      }
 +                      
 +                      for (int i = 0; i < interface_names.Count; i++){
 +                              if (i != 0)
 +                                      buf.Append (", ");
 +                              buf.Append (interface_names [i]);
 +                      }
 +                      AppendGenericTypeConstraints (buf, type);
 +              }
 +
 +              return buf.ToString ();
 +      }
 +
 +      static string GetTypeKind (Type t)
 +      {
 +              if (t.IsEnum)
 +                      return "enum";
 +              if (t.IsClass || t == typeof(System.Enum))
 +                      return "class";
 +              if (t.IsInterface)
 +                      return "interface";
 +              if (t.IsValueType)
 +                      return "struct";
 +              throw new ArgumentException(t.FullName);
 +      }
 +
 +      static string GetTypeVisibility (TypeAttributes ta)
 +      {
 +              switch (ta & TypeAttributes.VisibilityMask) {
 +              case TypeAttributes.Public:
 +              case TypeAttributes.NestedPublic:
 +                      return "public";
 +
 +              case TypeAttributes.NestedFamily:
 +              case TypeAttributes.NestedFamORAssem:
 +                      return "protected";
 +
 +              default:
 +                      return null;
 +              }
 +      }
 +
 +      static bool IsDelegate(Type type)
 +      {
 +              return typeof (System.Delegate).IsAssignableFrom (type) && !type.IsAbstract;
 +      }
 +      
 +      private static bool InterfaceNotFromAnother(Type i, Type[] i2)
 +      {
 +              foreach (Type t in i2)
 +                      if (i != t && Array.IndexOf (t.GetInterfaces(), i) != -1)
 +                              return false;
 +              return true;
 +      }
 +
 +      protected override StringBuilder AppendGenericTypeConstraints (StringBuilder buf, Type type)
 +      {
 +              if (!DocUtils.GetContainsGenericParameters (type))
 +                      return buf;
 +              return AppendConstraints (buf, DocUtils.GetGenericArguments (type));
 +      }
 +
 +      private StringBuilder AppendConstraints (StringBuilder buf, Type[] genArgs)
 +      {
 +#if !NET_1_0
 +              foreach (Type genArg in genArgs) {
 +                      GenericParameterAttributes attrs = genArg.GenericParameterAttributes;
 +                      Type[] constraints = genArg.GetGenericParameterConstraints ();
 +                      if (attrs == GenericParameterAttributes.None && constraints.Length == 0)
 +                              continue;
 +                      buf.Append (" where ").Append (genArg.Name).Append (" : ");
 +                      bool isref = (attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0;
 +                      bool isvt  = (attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0;
 +                      bool isnew = (attrs & GenericParameterAttributes.DefaultConstructorConstraint) != 0;
 +                      bool comma = false;
 +                      if (isref) {
 +                              buf.Append ("class");
 +                              comma = true;
 +                      }
 +                      else if (isvt) {
 +                              buf.Append ("struct");
 +                              comma = true;
 +                      }
 +                      if (constraints.Length > 0 && !isvt) {
 +                              if (comma)
 +                                      buf.Append (", ");
 +                              buf.Append (GetTypeName (constraints [0]));
 +                              for (int i = 1; i < constraints.Length; ++i)
 +                                      buf.Append (", ").Append (GetTypeName (constraints [i]));
 +                      }
 +                      if (isnew && !isvt) {
 +                              if (comma)
 +                                      buf.Append (", ");
 +                              buf.Append ("new()");
 +                      }
 +              }
 +#endif
 +              return buf;
 +      }
 +
 +      protected override string GetConstructorDeclaration (ConstructorInfo constructor)
 +      {
 +              StringBuilder buf = new StringBuilder ();
 +              AppendVisibility (buf, constructor);
 +              if (buf.Length == 0)
 +                      return null;
 +
 +              buf.Append (' ');
 +              base.AppendTypeName (buf, constructor.DeclaringType.Name).Append (' ');
 +              AppendParameters (buf, constructor, constructor.GetParameters ());
 +              buf.Append (';');
 +
 +              return buf.ToString ();
 +      }
 +      
 +      protected override string GetMethodDeclaration (MethodInfo method)
 +      {
 +              string decl = base.GetMethodDeclaration (method);
 +              if (decl != null)
 +                      return decl + ";";
 +              return null;
 +      }
 +
 +      protected override StringBuilder AppendMethodName (StringBuilder buf, MethodBase method)
 +      {
 +              if (DocUtils.IsExplicitlyImplemented (method)) {
 +                      Type iface;
 +                      MethodInfo ifaceMethod;
 +                      DocUtils.GetInfoForExplicitlyImplementedMethod (method, out iface, out ifaceMethod);
 +                      return buf.Append (new CSharpMemberFormatter ().GetName (iface))
 +                              .Append ('.')
 +                              .Append (ifaceMethod.Name);
 +              }
 +              return base.AppendMethodName (buf, method);
 +      }
 +
 +      protected override StringBuilder AppendGenericMethodConstraints (StringBuilder buf, MethodInfo method)
 +      {
 +              if (!DocUtils.GetContainsGenericParameters (method))
 +                      return buf;
 +              return AppendConstraints (buf, DocUtils.GetGenericArguments (method));
 +      }
 +
 +      protected override string RefTypeModifier {
 +              get {return "";}
 +      }
 +
 +      protected override string GetFinalizerName (MethodInfo method)
 +      {
 +              return "~" + method.DeclaringType.Name + " ()"; 
 +      }
 +
 +      protected override StringBuilder AppendVisibility (StringBuilder buf, MethodBase method)
 +      {
 +              if (method == null)
 +                      return buf;
 +              if (method.IsPublic)
 +                      return buf.Append ("public");
 +              if (method.IsFamily || method.IsFamilyOrAssembly)
 +                      return buf.Append ("protected");
 +              return buf;
 +      }
 +
 +      protected override StringBuilder AppendModifiers (StringBuilder buf, MethodInfo method)
 +      {
 +              string modifiers = String.Empty;
 +              if (method.IsStatic) modifiers += " static";
 +              if (method.IsVirtual && !method.IsAbstract) {
 +                      if ((method.Attributes & MethodAttributes.NewSlot) != 0) modifiers += " virtual";
 +                      else modifiers += " override";
 +              }
 +              if (method.IsAbstract && !method.DeclaringType.IsInterface) modifiers += " abstract";
 +              if (method.IsFinal) modifiers += " sealed";
 +              if (modifiers == " virtual sealed") modifiers = "";
 +
 +              return buf.Append (modifiers);
 +      }
 +
 +      protected override StringBuilder AppendGenericMethod (StringBuilder buf, MethodInfo method)
 +      {
 +              if (DocUtils.GetContainsGenericParameters (method)) {
 +                      Type[] args = DocUtils.GetGenericArguments (method);
 +                      if (args.Length > 0) {
 +                              buf.Append ("<");
 +                              buf.Append (args [0].Name);
 +                              for (int i = 1; i < args.Length; ++i)
 +                                      buf.Append (",").Append (args [i].Name);
 +                              buf.Append (">");
 +                      }
 +              }
 +              return buf;
 +      }
 +
 +      protected override StringBuilder AppendParameters (StringBuilder buf, MethodBase method, ParameterInfo[] parameters)
 +      {
 +              return AppendParameters (buf, method, parameters, '(', ')');
 +      }
 +
 +      private StringBuilder AppendParameters (StringBuilder buf, MethodBase method, ParameterInfo[] parameters, char begin, char end)
 +      {
 +              buf.Append (begin);
 +
 +              if (parameters.Length > 0) {
 +                      if (DocUtils.IsExtensionMethod (method))
 +                              buf.Append ("this ");
 +                      AppendParameter (buf, parameters [0]);
 +                      for (int i = 1; i < parameters.Length; ++i) {
 +                              buf.Append (", ");
 +                              AppendParameter (buf, parameters [i]);
 +                      }
 +              }
 +
 +              return buf.Append (end);
 +      }
 +
 +      private StringBuilder AppendParameter (StringBuilder buf, ParameterInfo parameter)
 +      {
 +              if (parameter.ParameterType.IsByRef) {
 +                      if (parameter.IsOut)
 +                              buf.Append ("out ");
 +                      else
 +                              buf.Append ("ref ");
 +              }
 +              buf.Append (GetName (parameter.ParameterType)).Append (" ");
 +              return buf.Append (parameter.Name);
 +      }
 +
 +      protected override string GetPropertyDeclaration (PropertyInfo property)
 +      {
 +              MethodInfo method;
 +
 +              string get_visible = null;
 +              if ((method = property.GetGetMethod (true)) != null && 
 +                              (DocUtils.IsExplicitlyImplemented (method) || 
 +                               (!method.IsPrivate && !method.IsAssembly && !method.IsFamilyAndAssembly)))
 +                      get_visible = AppendVisibility (new StringBuilder (), method).ToString ();
 +              string set_visible = null;
 +              if ((method = property.GetSetMethod (true)) != null &&
 +                              (DocUtils.IsExplicitlyImplemented (method) || 
 +                               (!method.IsPrivate && !method.IsAssembly && !method.IsFamilyAndAssembly)))
 +                      set_visible = AppendVisibility (new StringBuilder (), method).ToString ();
 +
 +              if ((set_visible == null) && (get_visible == null))
 +                      return null;
 +
 +              string visibility;
 +              StringBuilder buf = new StringBuilder ();
 +              if (get_visible != null && (set_visible == null || (set_visible != null && get_visible == set_visible)))
 +                      buf.Append (visibility = get_visible);
 +              else if (set_visible != null && get_visible == null)
 +                      buf.Append (visibility = set_visible);
 +              else
 +                      buf.Append (visibility = "public");
 +
 +              // Pick an accessor to use for static/virtual/override/etc. checks.
 +              method = property.GetSetMethod (true);
 +              if (method == null)
 +                      method = property.GetGetMethod (true);
 +      
 +              string modifiers = String.Empty;
 +              if (method.IsStatic) modifiers += " static";
 +              if (method.IsVirtual && !method.IsAbstract) {
 +                              if ((method.Attributes & MethodAttributes.NewSlot) != 0)
 +                                      modifiers += " virtual";
 +                              else
 +                                      modifiers += " override";
 +              }
 +              if (method.IsAbstract && !method.DeclaringType.IsInterface)
 +                      modifiers += " abstract";
 +              if (method.IsFinal)
 +                      modifiers += " sealed";
 +              if (modifiers == " virtual sealed")
 +                      modifiers = "";
 +              buf.Append (modifiers).Append (' ');
 +
 +              buf.Append (GetName (property.PropertyType)).Append (' ');
 +      
 +              MemberInfo[] defs = property.DeclaringType.GetDefaultMembers ();
 +              string name = property.Name;
 +              foreach (MemberInfo mi in defs) {
 +                      if (mi == property) {
 +                              name = "this";
 +                              break;
 +                      }
 +              }
 +              buf.Append (name == "this" ? name : DocUtils.GetPropertyName (property));
 +      
 +              if (property.GetIndexParameters ().Length != 0) {
 +                      AppendParameters (buf, method, property.GetIndexParameters (), '[', ']');
 +              }
 +
 +              buf.Append (" {");
 +              if (set_visible != null) {
 +                      if (set_visible != visibility)
 +                              buf.Append (' ').Append (set_visible);
 +                      buf.Append (" set;");
 +              }
 +              if (get_visible != null) {
 +                      if (get_visible != visibility)
 +                              buf.Append (' ').Append (get_visible);
 +                      buf.Append (" get;");
 +              }
 +              buf.Append (" }");
 +      
 +              return buf [0] != ' ' ? buf.ToString () : buf.ToString (1, buf.Length-1);
 +      }
 +
 +      protected override string GetFieldDeclaration (FieldInfo field)
 +      {
 +              if (field.DeclaringType.IsEnum && field.Name == "value__")
 +                      return null; // This member of enums aren't documented.
 +
 +              StringBuilder buf = new StringBuilder ();
 +              AppendFieldVisibility (buf, field);
 +              if (buf.Length == 0)
 +                      return null;
 +
 +              if (field.DeclaringType.IsEnum)
 +                      return field.Name;
 +
 +              if (field.IsStatic && !field.IsLiteral)
 +                      buf.Append (" static");
 +              if (field.IsInitOnly)
 +                      buf.Append (" readonly");
 +              if (field.IsLiteral)
 +                      buf.Append (" const");
 +
 +              buf.Append (' ').Append (GetName (field.FieldType)).Append (' ');
 +              buf.Append (field.Name);
 +              AppendFieldValue (buf, field);
 +              buf.Append (';');
 +
 +              return buf.ToString ();
 +      }
 +
 +      static StringBuilder AppendFieldVisibility (StringBuilder buf, FieldInfo field)
 +      {
 +              if (field.IsPublic)
 +                      return buf.Append ("public");
 +              if (field.IsFamily || field.IsFamilyOrAssembly)
 +                      return buf.Append ("protected");
 +              return buf;
 +      }
 +
 +      static StringBuilder AppendFieldValue (StringBuilder buf, FieldInfo field)
 +      {
 +              // enums have a value__ field, which we ignore, and FieldInfo.GetValue()
 +              // on a GenericType results in InvalidOperationException
 +              if (field.DeclaringType.IsEnum || 
 +                              DocUtils.IsGenericType (field.DeclaringType))
 +                      return buf;
 +              if (field.IsLiteral || (field.IsStatic && field.IsInitOnly)) {
 +                      object val = null;
 +                      try {
 +                              val   = field.GetValue (null);
 +                      } catch {
 +                              return buf;
 +                      }
 +                      if (val == null)
 +                              buf.Append (" = ").Append ("null");
 +                      else if (val is Enum)
 +                              buf.Append (" = ").Append (val.ToString ());
 +                      else if (val is IFormattable) {
 +                              string value = ((IFormattable)val).ToString();
 +                              if (val is string)
 +                                      value = "\"" + value + "\"";
 +                              buf.Append (" = ").Append (value);
 +                      }
 +              }
 +              return buf;
 +      }
 +
 +      protected override string GetEventDeclaration (EventInfo e)
 +      {
 +              StringBuilder buf = new StringBuilder ();
 +              if (AppendVisibility (buf, e.GetAddMethod (true)).Length == 0) {
 +                      return null;
 +              }
 +
 +              AppendModifiers (buf, e.GetAddMethod (true));
 +
 +              buf.Append (" event ");
 +              buf.Append (GetName (e.EventHandlerType)).Append (' ');
 +              buf.Append (e.Name).Append (';');
 +
 +              return buf.ToString ();
 +      }
 +}
 +
 +class CSharpMemberFormatter : CSharpFullMemberFormatter {
 +      protected override StringBuilder AppendNamespace (StringBuilder buf, Type type)
 +      {
 +              return buf;
 +      }
 +}
 +
 +class DocTypeFullMemberFormatter : MemberFormatter {
 +      public static readonly MemberFormatter Default = new DocTypeFullMemberFormatter ();
 +
 +      protected override char NestedTypeSeparator {
 +              get {return '+';}
 +      }
 +}
 +
 +class DocTypeMemberFormatter : DocTypeFullMemberFormatter {
 +      protected override StringBuilder AppendNamespace (StringBuilder buf, Type type)
 +      {
 +              return buf;
 +      }
 +}
 +
 +class SlashDocMemberFormatter : MemberFormatter {
 +
 +      protected override char[] GenericTypeContainer {
 +              get {return new char[]{'{', '}'};}
 +      }
 +
 +      private bool AddTypeCount = true;
 +
 +      protected override string GetTypeName (Type type)
 +      {
 +              return base.GetTypeName (type);
 +      }
 +
 +      private Type genDeclType;
 +      private MethodBase genDeclMethod;
 +
 +      protected override StringBuilder AppendTypeName (StringBuilder buf, Type type)
 +      {
 +              if (DocUtils.IsGenericParameter (type)) {
 +                      int l = buf.Length;
 +                      if (genDeclType != null) {
 +                              Type[] genArgs = DocUtils.GetGenericArguments (genDeclType);
 +                              for (int i = 0; i < genArgs.Length; ++i) {
 +                                      if (genArgs [i].Name == type.Name) {
 +                                              buf.Append ('`').Append (i);
 +                                              break;
 +                                      }
 +                              }
 +                      }
 +                      if (genDeclMethod != null) {
 +                              Type[] genArgs = null;
 +                              if (DocUtils.GetContainsGenericParameters (genDeclMethod)) {
 +                                      genArgs = DocUtils.GetGenericArguments (genDeclMethod);
 +                              }
 +                              else
 +                                      genArgs = new Type[0];
 +                              for (int i = 0; i < genArgs.Length; ++i) {
 +                                      if (genArgs [i].Name == type.Name) {
 +                                              buf.Append ("``").Append (i);
 +                                              break;
 +                                      }
 +                              }
 +                      }
 +                      if (genDeclType == null && genDeclMethod == null) {
 +                              // Probably from within an explicitly implemented interface member,
 +                              // where CSC uses parameter names instead of indices (why?), e.g.
 +                              // MyList`2.Mono#DocTest#Generic#IFoo{A}#Method``1(`0,``0) instead of
 +                              // MyList`2.Mono#DocTest#Generic#IFoo{`0}#Method``1(`0,``0).
 +                              buf.Append (type.Name);
 +                      }
 +                      if (buf.Length == l) {
 +                              throw new Exception (string.Format (
 +                                              "Unable to translate generic parameter {0}; genDeclType={1}, genDeclMethod={2}", 
 +                                              type.Name, genDeclType, genDeclMethod));
 +                      }
 +              }
 +              else {
 +                      base.AppendTypeName (buf, type);
 +                      if (AddTypeCount) {
 +                              int numArgs = DocUtils.GetGenericArguments (type).Length;
 +                              if (type.DeclaringType != null)
 +                                      numArgs -= DocUtils.GetGenericArguments (type).Length;
 +                              if (numArgs > 0) {
 +                                      buf.Append ('`').Append (numArgs);
 +                              }
 +                      }
 +              }
 +              return buf;
 +      }
 +
 +      protected override StringBuilder AppendGenericType (StringBuilder buf, Type type)
 +      {
 +              if (!AddTypeCount)
 +                      base.AppendGenericType (buf, type);
 +              else
 +                      AppendType (buf, type);
 +              return buf;
 +      }
 +
 +      private StringBuilder AppendType (StringBuilder buf, Type type)
 +      {
 +              int numArgs = DocUtils.GetGenericArguments (type).Length;
 +              if (type.DeclaringType != null) {
 +                      AppendType (buf, type.DeclaringType).Append (NestedTypeSeparator);
 +                      numArgs -= DocUtils.GetGenericArguments (type.DeclaringType).Length;
 +              }
 +              base.AppendTypeName (buf, type);
 +              if (numArgs > 0) {
 +                      buf.Append ('`').Append (numArgs);
 +              }
 +              return buf;
 +      }
 +
 +      protected override string GetConstructorName (ConstructorInfo constructor)
 +      {
 +              return GetMethodBaseName (constructor, "#ctor");
 +      }
 +
 +      protected override string GetMethodName (MethodInfo method)
 +      {
 +              string name = null;
 +              if (!DocUtils.IsExplicitlyImplemented (method))
 +                      name = method.Name;
 +              else {
 +                      Type iface;
 +                      MethodInfo ifaceMethod;
 +                      DocUtils.GetInfoForExplicitlyImplementedMethod (method, out iface, out ifaceMethod);
 +                      AddTypeCount = false;
 +                      name = GetTypeName (iface) + "." + ifaceMethod.Name;
 +                      AddTypeCount = true;
 +              }
 +              return GetMethodBaseName (method, name);
 +      }
 +
 +      private string GetMethodBaseName (MethodBase method, string name)
 +      {
 +              StringBuilder buf = new StringBuilder ();
 +              buf.Append (GetTypeName (method.DeclaringType));
 +              buf.Append ('.');
 +              buf.Append (name.Replace (".", "#"));
 +              if (DocUtils.GetContainsGenericParameters (method)) {
 +                      Type[] genArgs = DocUtils.GetGenericArguments (method);
 +                      if (genArgs.Length > 0)
 +                              buf.Append ("``").Append (genArgs.Length);
 +              }
 +              ParameterInfo[] parameters = method.GetParameters ();
 +              genDeclType = method.DeclaringType;
 +              genDeclMethod = method;
 +              AppendParameters (buf, DocUtils.GetGenericArguments (method.DeclaringType), parameters);
 +              genDeclType = null;
 +              genDeclMethod = null;
 +              return buf.ToString ();
 +      }
 +
 +      private StringBuilder AppendParameters (StringBuilder buf, Type[] genArgs, ParameterInfo[] parameters)
 +      {
 +              if (parameters.Length == 0)
 +                      return buf;
 +
 +              buf.Append ('(');
 +
 +              AppendParameter (buf, genArgs, parameters [0]);
 +              for (int i = 1; i < parameters.Length; ++i) {
 +                      buf.Append (',');
 +                      AppendParameter (buf, genArgs, parameters [i]);
 +              }
 +
 +              return buf.Append (')');
 +      }
 +
 +      private StringBuilder AppendParameter (StringBuilder buf, Type[] genArgs, ParameterInfo parameter)
 +      {
 +              AddTypeCount = false;
 +              buf.Append (GetTypeName (parameter.ParameterType));
 +              AddTypeCount = true;
 +              return buf;
 +      }
 +
 +      protected override string GetPropertyName (PropertyInfo property)
 +      {
 +              string name = null;
 +
 +              MethodInfo method = property.GetGetMethod (true);
 +              if (method == null)
 +                      method = property.GetSetMethod (true);
 +              if (!DocUtils.IsExplicitlyImplemented (method))
 +                      name = property.Name;
 +              else {
 +                      Type iface;
 +                      MethodInfo ifaceMethod;
 +                      DocUtils.GetInfoForExplicitlyImplementedMethod (method, out iface, out ifaceMethod);
 +                      AddTypeCount = false;
 +                      name = string.Join ("#", new string[]{
 +                                      GetTypeName (iface).Replace (".", "#"),
 +                                      DocUtils.GetMember (property.Name)
 +                      });
 +                      AddTypeCount = true;
 +              }
 +
 +              StringBuilder buf = new StringBuilder ();
 +              buf.Append (GetName (property.DeclaringType));
 +              buf.Append ('.');
 +              buf.Append (name);
 +              ParameterInfo[] parameters = property.GetIndexParameters ();
 +              if (parameters.Length > 0) {
 +                      genDeclType = property.DeclaringType;
 +                      buf.Append ('(');
 +                      Type[] genArgs = DocUtils.GetGenericArguments (property.DeclaringType);
 +                      AppendParameter (buf, genArgs, parameters [0]);
 +                      for (int i = 1; i < parameters.Length; ++i) {
 +                               buf.Append (',');
 +                               AppendParameter (buf, genArgs, parameters [i]);
 +                      }
 +                      buf.Append (')');
 +                      genDeclType = null;
 +              }
 +              return buf.ToString ();
 +      }
 +
 +      protected override string GetFieldName (FieldInfo field)
 +      {
 +              return string.Format ("{0}.{1}",
 +                      GetName (field.DeclaringType), field.Name);
 +      }
 +
 +      protected override string GetEventName (EventInfo e)
 +      {
 +              return string.Format ("{0}.{1}",
 +                      GetName (e.DeclaringType), e.Name);
 +      }
 +
 +      protected override string GetTypeDeclaration (Type type)
 +      {
 +              string name = GetName (type);
 +              if (type == null)
 +                      return null;
 +              return "T:" + name;
 +      }
 +
 +      protected override string GetConstructorDeclaration (ConstructorInfo constructor)
 +      {
 +              string name = GetName (constructor);
 +              if (name == null)
 +                      return null;
 +              return "M:" + name;
 +      }
 +
 +      protected override string GetMethodDeclaration (MethodInfo method)
 +      {
 +              string name = GetName (method);
 +              if (name == null)
 +                      return null;
 +              if (method.Name == "op_Implicit" || method.Name == "op_Explicit") {
 +                      genDeclType = method.DeclaringType;
 +                      genDeclMethod = method;
 +                      name += "~" + GetName (method.ReturnType);
 +                      genDeclType = null;
 +                      genDeclMethod = null;
 +              }
 +              return "M:" + name;
 +      }
 +
 +      protected override string GetPropertyDeclaration (PropertyInfo property)
 +      {
 +              string name = GetName (property);
 +              if (name == null)
 +                      return null;
 +              return "P:" + name;
 +      }
 +
 +      protected override string GetFieldDeclaration (FieldInfo field)
 +      {
 +              string name = GetName (field);
 +              if (name == null)
 +                      return null;
 +              return "F:" + name;
 +      }
 +
 +      protected override string GetEventDeclaration (EventInfo e)
 +      {
 +              string name = GetName (e);
 +              if (name == null)
 +                      return null;
 +              return "E:" + name;
 +      }
 +}
 +
 +class FileNameMemberFormatter : SlashDocMemberFormatter {
 +      protected override StringBuilder AppendNamespace (StringBuilder buf, Type type)
 +      {
 +              return buf;
 +      }
 +
 +      protected override char NestedTypeSeparator {
 +              get {return '+';}
 +      }
 +}
 +
 +}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a2fda97168562bde09dfb9350724d1dc031b1a35
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,946 @@@
++<?xml version="1.0" encoding="UTF-8"?>
++<!--
++Author: John Luke <john.luke@gmail.com>
++This is a (not very strict) schema for the monodoc
++ecma-provider format.
++TODO:
++make base type for summary, remarks, returns, etc
++alias duplicate attributes
++make stricter in order and occurance
++add masterdoc support?
++-->
++<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
++
++  <!-- define attributes -->
++  <xs:attribute name="argnames" type="xs:string" />
++  <xs:attribute name="cref" type="xs:string" />
++  <xs:attribute name="Deprecated" type="xs:boolean" />
++  <xs:attribute name="FullName" type="xs:string" />
++  <xs:attribute name="FullNameSP" type="xs:string" />
++  <xs:attribute name="inherited" type="xs:string" />
++  <xs:attribute name="language" type="xs:string" />
++  <xs:attribute name="Language" type="xs:string" />
++  <xs:attribute name="lang" type="xs:string" />
++  <xs:attribute name="langword" type="xs:string" />
++  <xs:attribute name="Library" type="xs:string" />
++  <xs:attribute name="location" type="xs:string" />
++  <xs:attribute name="Maintainer" type="xs:string" />
++  <xs:attribute name="MemberName" type="xs:string" />
++  <xs:attribute name="name" type="xs:string" />
++  <xs:attribute name="Name" type="xs:string" />
++  <xs:attribute name="namespace" type="xs:string" />
++  <xs:attribute name="propertytype" type="xs:string" />
++  <xs:attribute name="qualify" type="xs:boolean" />
++  <xs:attribute name="RefType" type="xs:string" />
++  <xs:attribute name="returntype" type="xs:string" />
++  <xs:attribute name="source" type="xs:string" />
++  <xs:attribute name="subset" type="xs:string" />
++  <xs:attribute name="Value" type="xs:string" />
++  <xs:attribute name="version" type="xs:string" />
++  <xs:attribute name="type" type="xs:string" />
++  <xs:attribute name="Type" type="xs:string" />
++  <xs:attribute name="TypeParamName" type="xs:string" />
++
++  <!-- define simple elements -->
++  <xs:element name="AssemblyName" type="xs:string" />
++  <xs:element name="AssemblyPublicKey" type="xs:string" />
++  <xs:element name="AssemblyVersion" type="xs:string" />
++  <xs:element name="AssemblyCulture" type="xs:string" />
++  <xs:element name="AttributeName" type="xs:string" />
++  <xs:element name="BaseTypeName" type="xs:string" />
++  <xs:element name="Excluded" type="xs:string" />
++  <xs:element name="ExcludedBaseTypeName" type="xs:string" />
++  <xs:element name="ExcludedLibrary" type="xs:string" />
++  <xs:element name="ExcludedLibraryName" type="xs:string" />
++  <xs:element name="ExcludedTypeName" type="xs:string" />
++  <xs:element name="i" type="xs:string" />
++  <xs:element name="InterfaceName" type="xs:string" />
++  <xs:element name="li" type="xs:string" />
++  <xs:element name="MemberOfLibrary" type="xs:string" />
++  <xs:element name="MemberType" type="xs:string" />
++  <xs:element name="MemberValue" type="xs:string" />
++  <xs:element name="onequarter" type="xs:string" />
++  <xs:element name="ReturnType" type="xs:string" />
++  <xs:element name="TypeExcluded" type="xs:string" />
++
++  <!-- define complex elements -->
++  <xs:element name="altcompliant">
++    <xs:complexType>
++      <xs:attribute ref="cref" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="altmember">
++    <xs:complexType>
++      <xs:simpleContent>
++        <xs:extension base="xs:string">
++          <xs:attribute ref="cref" />
++        </xs:extension>
++      </xs:simpleContent>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="AssemblyInfo">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="AssemblyName" minOccurs="0" />
++        <xs:element ref="AssemblyPublicKey" minOccurs="0" />
++        <xs:element ref="AssemblyVersion" minOccurs="0" maxOccurs="unbounded" />
++        <xs:element ref="AssemblyCulture" minOccurs="0" />
++        <xs:element ref="Attributes" minOccurs="0" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Attribute">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="AttributeName" />
++        <xs:element ref="Excluded" minOccurs="0" />
++        <xs:element ref="ExcludedTypeName" minOccurs="0" />
++        <xs:element ref="ExcludedLibraryName" minOccurs="0" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Attributes">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="Attribute" minOccurs="0" maxOccurs="unbounded" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Base">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="BaseTypeName" minOccurs="0" />
++        <xs:element ref="BaseTypeArguments" minOccurs="0" />
++        <xs:element ref="ExcludedBaseTypeName" minOccurs="0" />
++        <xs:element ref="ExcludedLibraryName" minOccurs="0" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="BaseTypeArgument">
++    <xs:complexType mixed="true">
++      <xs:attribute ref="TypeParamName" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="BaseTypeArguments">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="BaseTypeArgument" minOccurs="0" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="block">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="block" />
++        <xs:element ref="c" />
++        <xs:element ref="code" />
++        <xs:element ref="list" />
++        <xs:element ref="para" />
++        <xs:element ref="paramref" />
++        <xs:element ref="see" />
++        <xs:element ref="subscript" />
++        <xs:element ref="sup" />
++        <xs:element ref="typeparamref" />
++      </xs:choice>
++      <xs:attribute ref="subset" />
++      <xs:attribute ref="type" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="c">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="code" />
++        <xs:element ref="para" />
++        <xs:element ref="paramref" />
++        <xs:element ref="see" />
++        <xs:element ref="typeparamref" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="class">
++    <xs:complexType>
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="constructor" />
++        <xs:element ref="property" />
++        <xs:element ref="method" />
++        <xs:element ref="field" />
++        <xs:element ref="operator" />
++        <xs:element ref="event" />
++        <xs:element ref="enum" />
++        <xs:element ref="class" />
++        <xs:element ref="struct" />
++        <xs:element ref="interface" />
++        <xs:element ref="delegate" />
++      </xs:choice>
++      <xs:attribute ref="name" />
++      <xs:attribute ref="namespace" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="code">
++    <xs:complexType>
++      <xs:simpleContent>
++        <xs:extension base="xs:string">
++          <xs:attribute ref="lang" />
++          <xs:attribute ref="language" />
++          <xs:attribute ref="source" />
++        </xs:extension>
++      </xs:simpleContent>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="constructor">
++    <xs:complexType>
++          <xs:attribute ref="name" />
++          <xs:attribute ref="argnames" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="delegate">
++    <xs:complexType>
++      <xs:choice maxOccurs="unbounded">
++        <xs:element ref="constructor" />
++        <xs:element ref="method" />
++        <xs:element ref="property" />
++        <xs:element ref="operator" />
++      </xs:choice>
++      <xs:attribute ref="name" />
++      <xs:attribute ref="namespace" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="description">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="c" />
++        <xs:element ref="block" />
++        <xs:element ref="paramref" />
++        <xs:element ref="para" />
++        <xs:element ref="SPAN" />
++        <xs:element ref="see" />
++        <xs:element ref="sub" />
++        <xs:element ref="typeparamref" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Docs">
++    <xs:complexType>
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="summary" />
++        <xs:element ref="param" />
++        <xs:element ref="exception" />
++        <xs:element ref="returns" />
++        <xs:element ref="remarks" />
++        <xs:element ref="example" />
++        <xs:element ref="value" />
++        <xs:element ref="permission" />
++        <xs:element ref="altmember" />
++        <xs:element ref="altcompliant" />
++        <xs:element ref="since" />
++        <xs:element ref="threadsafe" />
++        <xs:element ref="typeparam" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="enum">
++    <xs:complexType>
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="field" />
++        <xs:element ref="method" />
++      </xs:choice>
++      <xs:attribute ref="name" />
++      <xs:attribute ref="namespace" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="event">
++    <xs:complexType>
++          <xs:attribute ref="name" />
++          <xs:attribute ref="inherited" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="example">
++    <xs:complexType mixed="true">
++      <xs:choice maxOccurs="unbounded">
++        <xs:element ref="para" />
++        <xs:element ref="code" />
++        <xs:element ref="c" />
++        <xs:element ref="list" />
++        <xs:element ref="see" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="exception">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="block" />
++        <xs:element ref="para" />
++        <xs:element ref="paramref" />
++        <xs:element ref="see" />
++        <xs:element ref="SPAN" />
++        <xs:element ref="typeparamref" />
++      </xs:choice>
++      <xs:attribute ref="cref" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="field">
++    <xs:complexType>
++      <xs:attribute ref="name" />
++      <xs:attribute ref="inherited" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="interface">
++    <xs:complexType>
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="constructor" />
++        <xs:element ref="property" />
++        <xs:element ref="method" />
++        <xs:element ref="field" />
++        <xs:element ref="event" />
++      </xs:choice>
++      <xs:attribute ref="name" />
++      <xs:attribute ref="namespace" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Interface">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="InterfaceName" />
++        <xs:element ref="Excluded" minOccurs="0" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Interfaces">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="Interface" minOccurs="0" maxOccurs="unbounded" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="item">
++    <xs:complexType>
++      <xs:sequence>
++          <xs:element ref="term" minOccurs="1" maxOccurs="1" />
++          <xs:element ref="description" minOccurs="0" maxOccurs="unbounded" />
++        </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Libraries">
++    <xs:complexType>
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="Type" minOccurs = "1" maxOccurs="unbounded" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="link">
++    <xs:complexType>
++      <xs:simpleContent>
++        <xs:extension base="xs:string">
++          <xs:attribute ref="location" />
++        </xs:extension>
++      </xs:simpleContent>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="list">
++    <xs:complexType>
++      <xs:sequence>
++          <xs:element ref="listheader" minOccurs="0" maxOccurs="1" />
++          <xs:element ref="item" minOccurs="0" maxOccurs="unbounded" />
++        </xs:sequence>
++        <xs:attribute name="type" type="xs:string" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="listheader">
++    <xs:complexType>
++      <xs:sequence>
++          <xs:element ref="term" />
++          <xs:element ref="description" maxOccurs="unbounded" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="masterdoc">
++    <xs:complexType>
++       <xs:choice minOccurs="0" maxOccurs="unbounded">
++         <xs:element ref="class" />
++         <xs:element ref="delegate" />
++         <xs:element ref="interface" />
++         <xs:element ref="struct" />
++         <xs:element ref="enum" />
++       </xs:choice>
++       <xs:attribute name="assembly" type="xs:string" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="MemberSignature">
++    <xs:complexType>
++      <xs:attribute ref="Language" />
++      <xs:attribute ref="Value" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Link">
++    <xs:complexType>
++      <xs:attribute ref="Type" use="required" />
++      <xs:attribute name="Member" type="xs:string" use="required" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Member">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="MemberSignature" minOccurs="1" maxOccurs="unbounded" />
++        <xs:element ref="MemberType" maxOccurs="1" />
++        <xs:element ref="AssemblyInfo" minOccurs="0" maxOccurs="1" />
++        <xs:element ref="Attributes" minOccurs="0" maxOccurs="1" />
++        <xs:element ref="ReturnValue" minOccurs="0" maxOccurs="1" />
++        <xs:element ref="TypeParameters" minOccurs="0" maxOccurs="1" />
++        <xs:element ref="Parameters" minOccurs="0" maxOccurs="1" />
++        <xs:element ref="MemberValue" minOccurs="0" maxOccurs="1" />
++        <xs:element ref="Docs" maxOccurs="1" />
++        <xs:element ref="Excluded" minOccurs="0" maxOccurs="1" />
++        <xs:element ref="ExcludedLibrary" minOccurs="0" maxOccurs="unbounded" />
++        <xs:element ref="Link" minOccurs="0" maxOccurs="1" />
++      </xs:sequence>
++      <xs:attribute ref="MemberName" />
++      <xs:attribute ref="Deprecated" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Members">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="Member" minOccurs="0" maxOccurs="unbounded" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="method">
++    <xs:complexType>
++      <xs:attribute ref="name" />
++      <xs:attribute ref="argnames" />
++      <xs:attribute ref="inherited" />
++      <xs:attribute ref="returntype" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Namespace">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="Docs" maxOccurs="1" />
++      </xs:sequence>
++      <xs:attribute ref="Name" />
++      <xs:attribute ref="FullName" />
++      <xs:attribute ref="FullNameSP" />
++      <xs:attribute ref="Maintainer" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="operator">
++    <xs:complexType>
++      <xs:attribute ref="name" />
++      <xs:attribute ref="argnames" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="para">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="block" />
++        <xs:element ref="see" />
++        <xs:element ref="list" />
++        <xs:element ref="link" />
++        <xs:element ref="ul" />
++        <xs:element ref="paramref" />
++        <xs:element ref="c" />
++        <xs:element ref="onequarter" />
++        <xs:element ref="sub" />
++        <xs:element ref="sup" />
++        <xs:element ref="SPAN" />
++        <xs:element ref="typeparamref" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="param">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="c" />
++        <xs:element ref="see" />
++        <xs:element ref="block" />
++        <xs:element ref="paramref" />
++        <xs:element ref="para" />
++        <xs:element ref="SPAN" />
++        <xs:element ref="typeparamref" />
++      </xs:choice>
++      <xs:attribute ref="name" use="required" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="paramref">
++    <xs:complexType>
++      <xs:attribute ref="name" use="required" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Parameter">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="Attributes" minOccurs="0" maxOccurs="1" />
++      </xs:sequence>
++      <xs:attribute ref="Name" />
++      <xs:attribute ref="Type" />
++      <xs:attribute ref="RefType" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Parameters">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="Parameter" minOccurs="0" maxOccurs="unbounded" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="permission">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="block" />
++        <xs:element ref="para" />
++        <xs:element ref="paramref" />
++        <xs:element ref="see" />
++        <xs:element ref="typeparamref" />
++      </xs:choice>
++      <xs:attribute ref="cref" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="property">
++    <xs:complexType>
++      <xs:attribute ref="name" />
++      <xs:attribute ref="inherited" />
++      <xs:attribute ref="propertytype" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="remarks">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="block" />
++        <xs:element ref="c" />
++        <xs:element ref="code" />
++        <xs:element ref="para" />
++        <xs:element ref="paramref" />
++        <xs:element ref="see" />
++        <xs:element ref="ul" />
++        <xs:element ref="example" />
++        <xs:element ref="list" />
++        <xs:element ref="SPAN" />
++        <xs:element ref="typeparamref" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="returns">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="list" />
++        <xs:element ref="para" />
++        <xs:element ref="paramref" />
++        <xs:element ref="see" />
++        <xs:element ref="typeparamref" />
++        <xs:element ref="ul" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="ReturnValue">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="ReturnType" minOccurs="0" maxOccurs="1" />
++        <xs:element ref="Attributes" minOccurs="0" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="see">
++    <xs:complexType>
++      <xs:attribute ref="cref" />
++      <xs:attribute ref="langword"  />
++      <xs:attribute ref="qualify"  />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="since">
++    <xs:complexType>
++      <xs:attribute ref="version" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="SPAN">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="block" />
++        <xs:element ref="para" />
++        <xs:element ref="paramref" />
++        <xs:element ref="see" />
++        <xs:element ref="SPAN" />
++        <xs:element ref="typeparamref" />
++      </xs:choice>
++      <xs:attribute ref="version" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="struct">
++    <xs:complexType>
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="constructor" />
++        <xs:element ref="property" />
++        <xs:element ref="method" />
++        <xs:element ref="field" />
++        <xs:element ref="operator" />
++        <xs:element ref="struct" />
++        <xs:element ref="class" />
++      </xs:choice>
++      <xs:attribute ref="name" />
++      <xs:attribute ref="namespace" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="sub">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="paramref" />
++        <xs:element ref="typeparamref" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="subscript">
++    <xs:complexType mixed="true">
++      <xs:attribute name="term" type="xs:string" use="required" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="summary">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="block" />
++        <xs:element ref="para" />
++        <xs:element ref="paramref" />
++        <xs:element ref="see" />
++        <xs:element ref="typeparamref" />
++        <xs:element ref="ul" />
++        <xs:element ref="list" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="sup">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="paramref" />
++        <xs:element ref="typeparamref" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="term">
++    <xs:complexType mixed="true">
++        <xs:choice minOccurs="0" maxOccurs="unbounded">
++          <xs:element ref="block" />
++          <xs:element ref="c" />
++          <xs:element ref="see" />
++          <xs:element ref="para"  />
++          <xs:element ref="paramref" />
++          <xs:element ref="sup" />
++          <xs:element ref="typeparamref" />
++        </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="threadsafe">
++    <xs:complexType>
++     <xs:sequence>
++       <xs:element ref="para" minOccurs="1" />
++     </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="ThreadingSafetyStatement">
++    <xs:complexType mixed="true">
++     <xs:sequence>
++       <xs:element ref="link" minOccurs="0" />
++     </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="ThreadSafetyStatement">
++    <xs:complexType mixed="true">
++     <xs:sequence>
++       <xs:element ref="link" minOccurs="0" />
++     </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Type">
++    <xs:complexType>
++      <xs:choice maxOccurs="unbounded">
++        <xs:element ref="TypeSignature" minOccurs="1" />
++        <xs:element ref="MemberOfLibrary" minOccurs="0" />
++        <xs:element ref="AssemblyInfo" minOccurs="1" />
++        <xs:element ref="TypeParameters" minOccurs="0" maxOccurs="1" />
++        <xs:element ref="ThreadingSafetyStatement" minOccurs="0" />
++        <xs:element ref="ThreadSafetyStatement" minOccurs="0" />
++        <xs:element ref="Docs" minOccurs="1" />
++        <xs:element ref="Base" minOccurs="1" />
++        <xs:element ref="Interfaces" minOccurs="1" />
++        <xs:element ref="Attributes" minOccurs="1" />
++        <xs:element ref="Members" minOccurs="1" />
++        <xs:element ref="Parameters" minOccurs="0" />
++        <xs:element ref="ReturnValue" minOccurs="0" />
++        <xs:element ref="TypeExcluded" minOccurs="0" />
++      </xs:choice>
++      <xs:attribute ref="Name" use="required" />
++      <xs:attribute ref="FullName" use="required" />
++      <xs:attribute ref="FullNameSP" />
++      <xs:attribute ref="Maintainer" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Types">
++    <xs:complexType>
++      <xs:choice minOccurs="1" maxOccurs="unbounded">
++        <xs:element ref="Type" />
++      </xs:choice>
++      <xs:attribute ref="Library" use="required" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="typeparam">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="block" />
++        <xs:element ref="c" />
++        <xs:element ref="para" />
++        <xs:element ref="paramref" />
++        <xs:element ref="see" />
++        <xs:element ref="typeparamref" />
++      </xs:choice>
++      <xs:attribute ref="name" use="required" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="typeparamref">
++    <xs:complexType>
++      <xs:attribute ref="name" use="required" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="TypeParameters">
++    <xs:complexType>
++      <xs:choice maxOccurs="unbounded">
++        <xs:element ref="TypeParameter" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="TypeParameter">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="Attributes" />
++        <xs:element ref="Constraints" />
++      </xs:choice>
++      <xs:attribute ref="Name" use="required" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Constraints">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element name="ParameterAttribute" type="xs:string" />
++        <xs:element ref="BaseTypeName" />
++        <xs:element ref="InterfaceName" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="TypeSignature">
++    <xs:complexType>
++      <xs:attribute ref="Language" use="required" />
++      <xs:attribute ref="Value" use="required" />
++      <xs:attribute ref="Maintainer" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="ul">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="li" minOccurs="1" maxOccurs="unbounded" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="value">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="block" />
++        <xs:element ref="c" />
++        <xs:element ref="para" />
++        <xs:element ref="paramref" />
++        <xs:element ref="see" />
++        <xs:element ref="typeparamref" />
++        <xs:element ref="ul" />
++        <xs:element ref="example" />
++        <xs:element ref="list" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <!-- 
++    index.xml & namespace-name.xml support 
++    -->
++
++  <!-- define attributes -->
++  <xs:attribute name="Version" type="xs:string" />
++  <xs:attribute name="DisplayName" type="xs:string" />
++  <xs:attribute name="Kind" type="xs:string" />
++
++  <!-- define simple elements -->
++  <xs:element name="Title" type="xs:string" />
++
++  <!-- define complex elements -->
++  <xs:element name="Assemblies">
++    <xs:complexType>
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="Assembly" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Assembly">
++    <xs:complexType>
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="Attributes" />
++      </xs:choice>
++      <xs:attribute ref="Name" />
++      <xs:attribute ref="Version" />
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Copyright">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="block" />
++        <xs:element ref="code" />
++        <xs:element ref="example" />
++        <xs:element ref="list" />
++        <xs:element ref="para" />
++        <xs:element ref="paramref" />
++        <xs:element ref="see" />
++        <xs:element ref="typeparamref" />
++        <xs:element ref="ul" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="ExtensionMethods">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element ref="ExtensionMethod" minOccurs="0" maxOccurs="unbounded" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="ExtensionMethod">
++    <xs:complexType>
++      <xs:sequence>
++        <xs:element name="Targets" minOccurs="1" maxOccurs="1">
++          <xs:complexType>
++            <xs:choice minOccurs="1" maxOccurs="unbounded">
++              <xs:element name="Target">
++                <xs:complexType>
++                  <xs:attribute ref="Type" use="required" />
++                </xs:complexType>
++              </xs:element>
++            </xs:choice>
++          </xs:complexType>
++        </xs:element>
++        <xs:element ref="Member" minOccurs="1" maxOccurs="1" />
++      </xs:sequence>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Overview">
++    <xs:complexType>
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="Assemblies" />
++        <xs:element ref="Copyright" />
++        <xs:element ref="Remarks" />
++        <xs:element ref="Title" />
++        <xs:element name="Types">
++          <xs:complexType>
++            <xs:choice minOccurs="0" maxOccurs="unbounded">
++              <xs:element name="Namespace">
++                <xs:complexType>
++                  <xs:choice minOccurs="0" maxOccurs="unbounded">
++                    <xs:element name="Type">
++                      <xs:complexType>
++                        <xs:attribute ref="Name" use="required" />
++                        <xs:attribute ref="DisplayName" />
++                        <xs:attribute ref="Kind" />
++                      </xs:complexType>
++                    </xs:element>
++                  </xs:choice>
++                  <xs:attribute ref="Name" />
++                </xs:complexType>
++              </xs:element>
++            </xs:choice>
++          </xs:complexType>
++        </xs:element>
++        <xs:element ref="ExtensionMethods" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++  <xs:element name="Remarks">
++    <xs:complexType mixed="true">
++      <xs:choice minOccurs="0" maxOccurs="unbounded">
++        <xs:element ref="block" />
++        <xs:element ref="code" />
++        <xs:element ref="example" />
++        <xs:element ref="list" />
++        <xs:element ref="para" />
++        <xs:element ref="paramref" />
++        <xs:element ref="typeparamref" />
++        <xs:element ref="see" />
++        <xs:element ref="ul" />
++      </xs:choice>
++    </xs:complexType>
++  </xs:element>
++
++</xs:schema>
++
diff --cc mcs/tools/mdoc/monodoc-ecma.xsd
index a2fda97168562bde09dfb9350724d1dc031b1a35,a2fda97168562bde09dfb9350724d1dc031b1a35..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,946 -1,946 +1,0 @@@
--<?xml version="1.0" encoding="UTF-8"?>
--<!--
--Author: John Luke <john.luke@gmail.com>
--This is a (not very strict) schema for the monodoc
--ecma-provider format.
--TODO:
--make base type for summary, remarks, returns, etc
--alias duplicate attributes
--make stricter in order and occurance
--add masterdoc support?
---->
--<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
--
--  <!-- define attributes -->
--  <xs:attribute name="argnames" type="xs:string" />
--  <xs:attribute name="cref" type="xs:string" />
--  <xs:attribute name="Deprecated" type="xs:boolean" />
--  <xs:attribute name="FullName" type="xs:string" />
--  <xs:attribute name="FullNameSP" type="xs:string" />
--  <xs:attribute name="inherited" type="xs:string" />
--  <xs:attribute name="language" type="xs:string" />
--  <xs:attribute name="Language" type="xs:string" />
--  <xs:attribute name="lang" type="xs:string" />
--  <xs:attribute name="langword" type="xs:string" />
--  <xs:attribute name="Library" type="xs:string" />
--  <xs:attribute name="location" type="xs:string" />
--  <xs:attribute name="Maintainer" type="xs:string" />
--  <xs:attribute name="MemberName" type="xs:string" />
--  <xs:attribute name="name" type="xs:string" />
--  <xs:attribute name="Name" type="xs:string" />
--  <xs:attribute name="namespace" type="xs:string" />
--  <xs:attribute name="propertytype" type="xs:string" />
--  <xs:attribute name="qualify" type="xs:boolean" />
--  <xs:attribute name="RefType" type="xs:string" />
--  <xs:attribute name="returntype" type="xs:string" />
--  <xs:attribute name="source" type="xs:string" />
--  <xs:attribute name="subset" type="xs:string" />
--  <xs:attribute name="Value" type="xs:string" />
--  <xs:attribute name="version" type="xs:string" />
--  <xs:attribute name="type" type="xs:string" />
--  <xs:attribute name="Type" type="xs:string" />
--  <xs:attribute name="TypeParamName" type="xs:string" />
--
--  <!-- define simple elements -->
--  <xs:element name="AssemblyName" type="xs:string" />
--  <xs:element name="AssemblyPublicKey" type="xs:string" />
--  <xs:element name="AssemblyVersion" type="xs:string" />
--  <xs:element name="AssemblyCulture" type="xs:string" />
--  <xs:element name="AttributeName" type="xs:string" />
--  <xs:element name="BaseTypeName" type="xs:string" />
--  <xs:element name="Excluded" type="xs:string" />
--  <xs:element name="ExcludedBaseTypeName" type="xs:string" />
--  <xs:element name="ExcludedLibrary" type="xs:string" />
--  <xs:element name="ExcludedLibraryName" type="xs:string" />
--  <xs:element name="ExcludedTypeName" type="xs:string" />
--  <xs:element name="i" type="xs:string" />
--  <xs:element name="InterfaceName" type="xs:string" />
--  <xs:element name="li" type="xs:string" />
--  <xs:element name="MemberOfLibrary" type="xs:string" />
--  <xs:element name="MemberType" type="xs:string" />
--  <xs:element name="MemberValue" type="xs:string" />
--  <xs:element name="onequarter" type="xs:string" />
--  <xs:element name="ReturnType" type="xs:string" />
--  <xs:element name="TypeExcluded" type="xs:string" />
--
--  <!-- define complex elements -->
--  <xs:element name="altcompliant">
--    <xs:complexType>
--      <xs:attribute ref="cref" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="altmember">
--    <xs:complexType>
--      <xs:simpleContent>
--        <xs:extension base="xs:string">
--          <xs:attribute ref="cref" />
--        </xs:extension>
--      </xs:simpleContent>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="AssemblyInfo">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="AssemblyName" minOccurs="0" />
--        <xs:element ref="AssemblyPublicKey" minOccurs="0" />
--        <xs:element ref="AssemblyVersion" minOccurs="0" maxOccurs="unbounded" />
--        <xs:element ref="AssemblyCulture" minOccurs="0" />
--        <xs:element ref="Attributes" minOccurs="0" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Attribute">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="AttributeName" />
--        <xs:element ref="Excluded" minOccurs="0" />
--        <xs:element ref="ExcludedTypeName" minOccurs="0" />
--        <xs:element ref="ExcludedLibraryName" minOccurs="0" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Attributes">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="Attribute" minOccurs="0" maxOccurs="unbounded" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Base">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="BaseTypeName" minOccurs="0" />
--        <xs:element ref="BaseTypeArguments" minOccurs="0" />
--        <xs:element ref="ExcludedBaseTypeName" minOccurs="0" />
--        <xs:element ref="ExcludedLibraryName" minOccurs="0" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="BaseTypeArgument">
--    <xs:complexType mixed="true">
--      <xs:attribute ref="TypeParamName" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="BaseTypeArguments">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="BaseTypeArgument" minOccurs="0" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="block">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="block" />
--        <xs:element ref="c" />
--        <xs:element ref="code" />
--        <xs:element ref="list" />
--        <xs:element ref="para" />
--        <xs:element ref="paramref" />
--        <xs:element ref="see" />
--        <xs:element ref="subscript" />
--        <xs:element ref="sup" />
--        <xs:element ref="typeparamref" />
--      </xs:choice>
--      <xs:attribute ref="subset" />
--      <xs:attribute ref="type" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="c">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="code" />
--        <xs:element ref="para" />
--        <xs:element ref="paramref" />
--        <xs:element ref="see" />
--        <xs:element ref="typeparamref" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="class">
--    <xs:complexType>
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="constructor" />
--        <xs:element ref="property" />
--        <xs:element ref="method" />
--        <xs:element ref="field" />
--        <xs:element ref="operator" />
--        <xs:element ref="event" />
--        <xs:element ref="enum" />
--        <xs:element ref="class" />
--        <xs:element ref="struct" />
--        <xs:element ref="interface" />
--        <xs:element ref="delegate" />
--      </xs:choice>
--      <xs:attribute ref="name" />
--      <xs:attribute ref="namespace" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="code">
--    <xs:complexType>
--      <xs:simpleContent>
--        <xs:extension base="xs:string">
--          <xs:attribute ref="lang" />
--          <xs:attribute ref="language" />
--          <xs:attribute ref="source" />
--        </xs:extension>
--      </xs:simpleContent>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="constructor">
--    <xs:complexType>
--          <xs:attribute ref="name" />
--          <xs:attribute ref="argnames" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="delegate">
--    <xs:complexType>
--      <xs:choice maxOccurs="unbounded">
--        <xs:element ref="constructor" />
--        <xs:element ref="method" />
--        <xs:element ref="property" />
--        <xs:element ref="operator" />
--      </xs:choice>
--      <xs:attribute ref="name" />
--      <xs:attribute ref="namespace" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="description">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="c" />
--        <xs:element ref="block" />
--        <xs:element ref="paramref" />
--        <xs:element ref="para" />
--        <xs:element ref="SPAN" />
--        <xs:element ref="see" />
--        <xs:element ref="sub" />
--        <xs:element ref="typeparamref" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Docs">
--    <xs:complexType>
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="summary" />
--        <xs:element ref="param" />
--        <xs:element ref="exception" />
--        <xs:element ref="returns" />
--        <xs:element ref="remarks" />
--        <xs:element ref="example" />
--        <xs:element ref="value" />
--        <xs:element ref="permission" />
--        <xs:element ref="altmember" />
--        <xs:element ref="altcompliant" />
--        <xs:element ref="since" />
--        <xs:element ref="threadsafe" />
--        <xs:element ref="typeparam" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="enum">
--    <xs:complexType>
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="field" />
--        <xs:element ref="method" />
--      </xs:choice>
--      <xs:attribute ref="name" />
--      <xs:attribute ref="namespace" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="event">
--    <xs:complexType>
--          <xs:attribute ref="name" />
--          <xs:attribute ref="inherited" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="example">
--    <xs:complexType mixed="true">
--      <xs:choice maxOccurs="unbounded">
--        <xs:element ref="para" />
--        <xs:element ref="code" />
--        <xs:element ref="c" />
--        <xs:element ref="list" />
--        <xs:element ref="see" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="exception">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="block" />
--        <xs:element ref="para" />
--        <xs:element ref="paramref" />
--        <xs:element ref="see" />
--        <xs:element ref="SPAN" />
--        <xs:element ref="typeparamref" />
--      </xs:choice>
--      <xs:attribute ref="cref" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="field">
--    <xs:complexType>
--      <xs:attribute ref="name" />
--      <xs:attribute ref="inherited" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="interface">
--    <xs:complexType>
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="constructor" />
--        <xs:element ref="property" />
--        <xs:element ref="method" />
--        <xs:element ref="field" />
--        <xs:element ref="event" />
--      </xs:choice>
--      <xs:attribute ref="name" />
--      <xs:attribute ref="namespace" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Interface">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="InterfaceName" />
--        <xs:element ref="Excluded" minOccurs="0" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Interfaces">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="Interface" minOccurs="0" maxOccurs="unbounded" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="item">
--    <xs:complexType>
--      <xs:sequence>
--          <xs:element ref="term" minOccurs="1" maxOccurs="1" />
--          <xs:element ref="description" minOccurs="0" maxOccurs="unbounded" />
--        </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Libraries">
--    <xs:complexType>
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="Type" minOccurs = "1" maxOccurs="unbounded" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="link">
--    <xs:complexType>
--      <xs:simpleContent>
--        <xs:extension base="xs:string">
--          <xs:attribute ref="location" />
--        </xs:extension>
--      </xs:simpleContent>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="list">
--    <xs:complexType>
--      <xs:sequence>
--          <xs:element ref="listheader" minOccurs="0" maxOccurs="1" />
--          <xs:element ref="item" minOccurs="0" maxOccurs="unbounded" />
--        </xs:sequence>
--        <xs:attribute name="type" type="xs:string" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="listheader">
--    <xs:complexType>
--      <xs:sequence>
--          <xs:element ref="term" />
--          <xs:element ref="description" maxOccurs="unbounded" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="masterdoc">
--    <xs:complexType>
--       <xs:choice minOccurs="0" maxOccurs="unbounded">
--         <xs:element ref="class" />
--         <xs:element ref="delegate" />
--         <xs:element ref="interface" />
--         <xs:element ref="struct" />
--         <xs:element ref="enum" />
--       </xs:choice>
--       <xs:attribute name="assembly" type="xs:string" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="MemberSignature">
--    <xs:complexType>
--      <xs:attribute ref="Language" />
--      <xs:attribute ref="Value" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Link">
--    <xs:complexType>
--      <xs:attribute ref="Type" use="required" />
--      <xs:attribute name="Member" type="xs:string" use="required" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Member">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="MemberSignature" minOccurs="1" maxOccurs="unbounded" />
--        <xs:element ref="MemberType" maxOccurs="1" />
--        <xs:element ref="AssemblyInfo" minOccurs="0" maxOccurs="1" />
--        <xs:element ref="Attributes" minOccurs="0" maxOccurs="1" />
--        <xs:element ref="ReturnValue" minOccurs="0" maxOccurs="1" />
--        <xs:element ref="TypeParameters" minOccurs="0" maxOccurs="1" />
--        <xs:element ref="Parameters" minOccurs="0" maxOccurs="1" />
--        <xs:element ref="MemberValue" minOccurs="0" maxOccurs="1" />
--        <xs:element ref="Docs" maxOccurs="1" />
--        <xs:element ref="Excluded" minOccurs="0" maxOccurs="1" />
--        <xs:element ref="ExcludedLibrary" minOccurs="0" maxOccurs="unbounded" />
--        <xs:element ref="Link" minOccurs="0" maxOccurs="1" />
--      </xs:sequence>
--      <xs:attribute ref="MemberName" />
--      <xs:attribute ref="Deprecated" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Members">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="Member" minOccurs="0" maxOccurs="unbounded" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="method">
--    <xs:complexType>
--      <xs:attribute ref="name" />
--      <xs:attribute ref="argnames" />
--      <xs:attribute ref="inherited" />
--      <xs:attribute ref="returntype" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Namespace">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="Docs" maxOccurs="1" />
--      </xs:sequence>
--      <xs:attribute ref="Name" />
--      <xs:attribute ref="FullName" />
--      <xs:attribute ref="FullNameSP" />
--      <xs:attribute ref="Maintainer" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="operator">
--    <xs:complexType>
--      <xs:attribute ref="name" />
--      <xs:attribute ref="argnames" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="para">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="block" />
--        <xs:element ref="see" />
--        <xs:element ref="list" />
--        <xs:element ref="link" />
--        <xs:element ref="ul" />
--        <xs:element ref="paramref" />
--        <xs:element ref="c" />
--        <xs:element ref="onequarter" />
--        <xs:element ref="sub" />
--        <xs:element ref="sup" />
--        <xs:element ref="SPAN" />
--        <xs:element ref="typeparamref" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="param">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="c" />
--        <xs:element ref="see" />
--        <xs:element ref="block" />
--        <xs:element ref="paramref" />
--        <xs:element ref="para" />
--        <xs:element ref="SPAN" />
--        <xs:element ref="typeparamref" />
--      </xs:choice>
--      <xs:attribute ref="name" use="required" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="paramref">
--    <xs:complexType>
--      <xs:attribute ref="name" use="required" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Parameter">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="Attributes" minOccurs="0" maxOccurs="1" />
--      </xs:sequence>
--      <xs:attribute ref="Name" />
--      <xs:attribute ref="Type" />
--      <xs:attribute ref="RefType" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Parameters">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="Parameter" minOccurs="0" maxOccurs="unbounded" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="permission">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="block" />
--        <xs:element ref="para" />
--        <xs:element ref="paramref" />
--        <xs:element ref="see" />
--        <xs:element ref="typeparamref" />
--      </xs:choice>
--      <xs:attribute ref="cref" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="property">
--    <xs:complexType>
--      <xs:attribute ref="name" />
--      <xs:attribute ref="inherited" />
--      <xs:attribute ref="propertytype" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="remarks">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="block" />
--        <xs:element ref="c" />
--        <xs:element ref="code" />
--        <xs:element ref="para" />
--        <xs:element ref="paramref" />
--        <xs:element ref="see" />
--        <xs:element ref="ul" />
--        <xs:element ref="example" />
--        <xs:element ref="list" />
--        <xs:element ref="SPAN" />
--        <xs:element ref="typeparamref" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="returns">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="list" />
--        <xs:element ref="para" />
--        <xs:element ref="paramref" />
--        <xs:element ref="see" />
--        <xs:element ref="typeparamref" />
--        <xs:element ref="ul" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="ReturnValue">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="ReturnType" minOccurs="0" maxOccurs="1" />
--        <xs:element ref="Attributes" minOccurs="0" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="see">
--    <xs:complexType>
--      <xs:attribute ref="cref" />
--      <xs:attribute ref="langword"  />
--      <xs:attribute ref="qualify"  />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="since">
--    <xs:complexType>
--      <xs:attribute ref="version" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="SPAN">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="block" />
--        <xs:element ref="para" />
--        <xs:element ref="paramref" />
--        <xs:element ref="see" />
--        <xs:element ref="SPAN" />
--        <xs:element ref="typeparamref" />
--      </xs:choice>
--      <xs:attribute ref="version" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="struct">
--    <xs:complexType>
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="constructor" />
--        <xs:element ref="property" />
--        <xs:element ref="method" />
--        <xs:element ref="field" />
--        <xs:element ref="operator" />
--        <xs:element ref="struct" />
--        <xs:element ref="class" />
--      </xs:choice>
--      <xs:attribute ref="name" />
--      <xs:attribute ref="namespace" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="sub">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="paramref" />
--        <xs:element ref="typeparamref" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="subscript">
--    <xs:complexType mixed="true">
--      <xs:attribute name="term" type="xs:string" use="required" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="summary">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="block" />
--        <xs:element ref="para" />
--        <xs:element ref="paramref" />
--        <xs:element ref="see" />
--        <xs:element ref="typeparamref" />
--        <xs:element ref="ul" />
--        <xs:element ref="list" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="sup">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="paramref" />
--        <xs:element ref="typeparamref" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="term">
--    <xs:complexType mixed="true">
--        <xs:choice minOccurs="0" maxOccurs="unbounded">
--          <xs:element ref="block" />
--          <xs:element ref="c" />
--          <xs:element ref="see" />
--          <xs:element ref="para"  />
--          <xs:element ref="paramref" />
--          <xs:element ref="sup" />
--          <xs:element ref="typeparamref" />
--        </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="threadsafe">
--    <xs:complexType>
--     <xs:sequence>
--       <xs:element ref="para" minOccurs="1" />
--     </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="ThreadingSafetyStatement">
--    <xs:complexType mixed="true">
--     <xs:sequence>
--       <xs:element ref="link" minOccurs="0" />
--     </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="ThreadSafetyStatement">
--    <xs:complexType mixed="true">
--     <xs:sequence>
--       <xs:element ref="link" minOccurs="0" />
--     </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Type">
--    <xs:complexType>
--      <xs:choice maxOccurs="unbounded">
--        <xs:element ref="TypeSignature" minOccurs="1" />
--        <xs:element ref="MemberOfLibrary" minOccurs="0" />
--        <xs:element ref="AssemblyInfo" minOccurs="1" />
--        <xs:element ref="TypeParameters" minOccurs="0" maxOccurs="1" />
--        <xs:element ref="ThreadingSafetyStatement" minOccurs="0" />
--        <xs:element ref="ThreadSafetyStatement" minOccurs="0" />
--        <xs:element ref="Docs" minOccurs="1" />
--        <xs:element ref="Base" minOccurs="1" />
--        <xs:element ref="Interfaces" minOccurs="1" />
--        <xs:element ref="Attributes" minOccurs="1" />
--        <xs:element ref="Members" minOccurs="1" />
--        <xs:element ref="Parameters" minOccurs="0" />
--        <xs:element ref="ReturnValue" minOccurs="0" />
--        <xs:element ref="TypeExcluded" minOccurs="0" />
--      </xs:choice>
--      <xs:attribute ref="Name" use="required" />
--      <xs:attribute ref="FullName" use="required" />
--      <xs:attribute ref="FullNameSP" />
--      <xs:attribute ref="Maintainer" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Types">
--    <xs:complexType>
--      <xs:choice minOccurs="1" maxOccurs="unbounded">
--        <xs:element ref="Type" />
--      </xs:choice>
--      <xs:attribute ref="Library" use="required" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="typeparam">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="block" />
--        <xs:element ref="c" />
--        <xs:element ref="para" />
--        <xs:element ref="paramref" />
--        <xs:element ref="see" />
--        <xs:element ref="typeparamref" />
--      </xs:choice>
--      <xs:attribute ref="name" use="required" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="typeparamref">
--    <xs:complexType>
--      <xs:attribute ref="name" use="required" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="TypeParameters">
--    <xs:complexType>
--      <xs:choice maxOccurs="unbounded">
--        <xs:element ref="TypeParameter" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="TypeParameter">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="Attributes" />
--        <xs:element ref="Constraints" />
--      </xs:choice>
--      <xs:attribute ref="Name" use="required" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Constraints">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element name="ParameterAttribute" type="xs:string" />
--        <xs:element ref="BaseTypeName" />
--        <xs:element ref="InterfaceName" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="TypeSignature">
--    <xs:complexType>
--      <xs:attribute ref="Language" use="required" />
--      <xs:attribute ref="Value" use="required" />
--      <xs:attribute ref="Maintainer" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="ul">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="li" minOccurs="1" maxOccurs="unbounded" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="value">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="block" />
--        <xs:element ref="c" />
--        <xs:element ref="para" />
--        <xs:element ref="paramref" />
--        <xs:element ref="see" />
--        <xs:element ref="typeparamref" />
--        <xs:element ref="ul" />
--        <xs:element ref="example" />
--        <xs:element ref="list" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <!-- 
--    index.xml & namespace-name.xml support 
--    -->
--
--  <!-- define attributes -->
--  <xs:attribute name="Version" type="xs:string" />
--  <xs:attribute name="DisplayName" type="xs:string" />
--  <xs:attribute name="Kind" type="xs:string" />
--
--  <!-- define simple elements -->
--  <xs:element name="Title" type="xs:string" />
--
--  <!-- define complex elements -->
--  <xs:element name="Assemblies">
--    <xs:complexType>
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="Assembly" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Assembly">
--    <xs:complexType>
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="Attributes" />
--      </xs:choice>
--      <xs:attribute ref="Name" />
--      <xs:attribute ref="Version" />
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Copyright">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="block" />
--        <xs:element ref="code" />
--        <xs:element ref="example" />
--        <xs:element ref="list" />
--        <xs:element ref="para" />
--        <xs:element ref="paramref" />
--        <xs:element ref="see" />
--        <xs:element ref="typeparamref" />
--        <xs:element ref="ul" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="ExtensionMethods">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element ref="ExtensionMethod" minOccurs="0" maxOccurs="unbounded" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="ExtensionMethod">
--    <xs:complexType>
--      <xs:sequence>
--        <xs:element name="Targets" minOccurs="1" maxOccurs="1">
--          <xs:complexType>
--            <xs:choice minOccurs="1" maxOccurs="unbounded">
--              <xs:element name="Target">
--                <xs:complexType>
--                  <xs:attribute ref="Type" use="required" />
--                </xs:complexType>
--              </xs:element>
--            </xs:choice>
--          </xs:complexType>
--        </xs:element>
--        <xs:element ref="Member" minOccurs="1" maxOccurs="1" />
--      </xs:sequence>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Overview">
--    <xs:complexType>
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="Assemblies" />
--        <xs:element ref="Copyright" />
--        <xs:element ref="Remarks" />
--        <xs:element ref="Title" />
--        <xs:element name="Types">
--          <xs:complexType>
--            <xs:choice minOccurs="0" maxOccurs="unbounded">
--              <xs:element name="Namespace">
--                <xs:complexType>
--                  <xs:choice minOccurs="0" maxOccurs="unbounded">
--                    <xs:element name="Type">
--                      <xs:complexType>
--                        <xs:attribute ref="Name" use="required" />
--                        <xs:attribute ref="DisplayName" />
--                        <xs:attribute ref="Kind" />
--                      </xs:complexType>
--                    </xs:element>
--                  </xs:choice>
--                  <xs:attribute ref="Name" />
--                </xs:complexType>
--              </xs:element>
--            </xs:choice>
--          </xs:complexType>
--        </xs:element>
--        <xs:element ref="ExtensionMethods" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--  <xs:element name="Remarks">
--    <xs:complexType mixed="true">
--      <xs:choice minOccurs="0" maxOccurs="unbounded">
--        <xs:element ref="block" />
--        <xs:element ref="code" />
--        <xs:element ref="example" />
--        <xs:element ref="list" />
--        <xs:element ref="para" />
--        <xs:element ref="paramref" />
--        <xs:element ref="typeparamref" />
--        <xs:element ref="see" />
--        <xs:element ref="ul" />
--      </xs:choice>
--    </xs:complexType>
--  </xs:element>
--
--</xs:schema>
--