Merge pull request #495 from nicolas-raoul/fix-for-issue2907-with-no-formatting-changes
[mono.git] / mcs / tools / mdoc / Mono.Documentation / monodocer.cs
index 5dacee6077fd4a1b88a08ff1f15b55618ad1071f..dcb23d2f17c9890b7477423b5c0f73e9717f0598 100644 (file)
 
 using System;
 using System.Collections;
-#if !NET_1_0
 using System.Collections.Generic;
-#endif
+using System.Collections.ObjectModel;
+using System.Diagnostics;
 using System.Globalization;
 using System.IO;
+using System.Linq;
 using System.Text;
-using System.Reflection;
 using System.Xml;
 using System.Xml.XPath;
 
-#if NET_1_0
-using Mono.GetOptions;
-
-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 Mono.Cecil;
 using Mono.Options;
 
-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
 
 namespace Mono.Documentation {
 
-#pragma warning disable 0618
-class MDocUpdaterOptions 
-#if NET_1_0
-       : Options
-#endif
+class MDocUpdater : MDocCommand
 {
-#if NET_1_0
-       [Option("The root {directory} of an assembly's documentation files.")]
-#endif
-       public string path = null;
-
-#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 = true;
-
-#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.")]
-       public string importslashdoc;
+       string srcPath;
+       List<AssemblyDefinition> assemblies;
+       readonly DefaultAssemblyResolver assemblyResolver = new DefaultAssemblyResolver();
        
-       [Option("An ECMA or monodoc-generated XML documemntation {file} to import.")]
-       public string importecmadoc;
-#endif
+       bool delete;
+       bool show_exceptions;
+       bool no_assembly_versions, ignore_missing_types;
+       ExceptionLocations? exceptions;
+       
+       internal int additions = 0, deletions = 0;
 
-#if NET_1_0
-       [Option("Import either a /doc or ECMA documentation file.")]
-#endif
-       public string import;
+       List<DocumentationImporter> importers = new List<DocumentationImporter> ();
 
-#if NET_1_0
-       [Option("Indent the XML files nicely.")]
-#endif
-       public bool pretty = true;
-       
-#if NET_1_0
-       [Option("Create a <since/> element for added types/members with the value {since}.")]
-#endif
-       public string since;
+       DocumentationEnumerator docEnum;
 
-#if NET_1_0
-       [Option("Show full stack trace on error.")]
-#endif
-       public bool show_exceptions;
-}
-#pragma warning restore
+       string since;
 
-class MDocUpdater 
-#if !NET_1_0
-       : MDocCommand
-#endif
-{
-       
-       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 readonly MemberFormatter docTypeFormatter     = new DocTypeMemberFormatter ();
+       static readonly MemberFormatter filenameFormatter    = new FileNameMemberFormatter ();
 
-       static string name;
-       static XmlDocument slashdocs;
-       static XmlReader ecmadocs;
+       static MemberFormatter[] typeFormatters = new MemberFormatter[]{
+               new CSharpMemberFormatter (),
+               new ILMemberFormatter (),
+       };
 
-       static string since;
+       static MemberFormatter[] memberFormatters = new MemberFormatter[]{
+               new CSharpFullMemberFormatter (),
+               new ILFullMemberFormatter (),
+       };
 
-       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 ();
+       internal static readonly MemberFormatter slashdocFormatter    = new SlashDocMemberFormatter ();
 
-       static MyXmlNodeList extensionMethods = new MyXmlNodeList ();
+       MyXmlNodeList extensionMethods = new MyXmlNodeList ();
 
-       const BindingFlags DefaultBindingFlags = 
-               BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
-       
-#if NET_1_0
-       public static void Main(string[] args)
-       {
-               MDocUpdaterOptions opts = new MDocUpdaterOptions ();
-               opts.ProcessArgs(args);
+       HashSet<string> forwardedTypes = new HashSet<string> ();
 
-               if (args.Length == 0) {
-                       opts.DoHelp();
-                       return;
-               }
-               Run (opts);
-       }
-#else
        public override void Run (IEnumerable<string> args)
        {
-               var opts = new MDocUpdaterOptions {
-                       overrides        = true,
-                       pretty           = true,
-                       show_exceptions  = DebugOutput,
-               };
-
-               var  types = new List<string> ();
+               show_exceptions = DebugOutput;
+               var types = new List<string> ();
                var p = new OptionSet () {
-                       { "o|out=",
-                               "Root {DIRECTORY} to generate/update documentation.",
-                               v => opts.path = v },
-                       { "i|import=", 
-                               "Import documentation from {FILE}.",
-                               v => opts.import = v },
                        { "delete",
                                "Delete removed members from the XML files.",
-                               v => opts.delete = v != null },
+                               v => delete = v != null },
+                       { "exceptions:",
+                         "Document potential exceptions that members can generate.  {SOURCES} " +
+                               "is a comma-separated list of:\n" +
+                               "  asm      Method calls in same assembly\n" +
+                               "  depasm   Method calls in dependent assemblies\n" +
+                               "  all      Record all possible exceptions\n" +
+                               "  added    Modifier; only create <exception/>s\n" +
+                               "             for NEW types/members\n" +
+                               "If nothing is specified, then only exceptions from the member will " +
+                               "be listed.",
+                               v => exceptions = ParseExceptionLocations (v) },
+                       { "f=",
+                               "Specify a {FLAG} to alter behavior.  See later -f* options for available flags.",
+                               v => {
+                                       switch (v) {
+                                               case "ignore-missing-types":
+                                                       ignore_missing_types = true;
+                                                       break;
+                                               case "no-assembly-versions":
+                                                       no_assembly_versions = true;
+                                                       break;
+                                               default:
+                                                       throw new Exception ("Unsupported flag `" + v + "'.");
+                                       }
+                               } },
+                       { "fignore-missing-types",
+                               "Do not report an error if a --type=TYPE type\nwas not found.",
+                               v => ignore_missing_types = v != null },
+                       { "fno-assembly-versions",
+                               "Do not generate //AssemblyVersion elements.",
+                               v => no_assembly_versions = v != null },
+                       { "i|import=", 
+                               "Import documentation from {FILE}.",
+                               v => AddImporter (v) },
+                       { "L|lib=",
+                               "Check for assembly references in {DIRECTORY}.",
+                               v => assemblyResolver.AddSearchDirectory (v) },
+                       { "library=",
+                               "Ignored for compatibility with update-ecma-xml.",
+                               v => {} },
+                       { "o|out=",
+                               "Root {DIRECTORY} to generate/update documentation.",
+                               v => srcPath = v },
+                       { "r=",
+                               "Search for dependent assemblies in the directory containing {ASSEMBLY}.\n" +
+                               "(Equivalent to '-L `dirname ASSEMBLY`'.)",
+                               v => assemblyResolver.AddSearchDirectory (Path.GetDirectoryName (v)) },
                        { "since=",
-                               "Manually specify the assembly version that new members were added in.",
-                               v => opts.since = v },
+                               "Manually specify the assembly {VERSION} that new members were added in.",
+                               v => since = v },
                        { "type=",
                          "Only update documentation for {TYPE}.",
                                v => types.Add (v) },
                };
-               List<string> extra = Parse (p, args, "update", 
+               var assemblies = Parse (p, args, "update", 
                                "[OPTIONS]+ ASSEMBLIES",
                                "Create or update documentation from ASSEMBLIES.");
-               if (extra == null)
+               if (assemblies == null)
                        return;
-               if (extra.Count == 0)
+               if (assemblies.Count == 0)
                        Error ("No assemblies specified.");
-               opts.assembly = extra.ToArray ();
-               if (types.Count > 0)
-                       opts.type = types.ToArray ();
 
-               Run (opts);
-               opts.name = ""; // remove warning about unused member
-       }
-#endif
+               foreach (var dir in assemblies
+                               .Where (a => a.Contains (Path.DirectorySeparatorChar))
+                               .Select (a => Path.GetDirectoryName (a)))
+                       assemblyResolver.AddSearchDirectory (dir);
+
+               // PARSE BASIC OPTIONS AND LOAD THE ASSEMBLY TO DOCUMENT
                
-       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;
+               if (srcPath == null)
+                       throw new InvalidOperationException("The --out option is required.");
+               
+               this.assemblies = assemblies.Select (a => LoadAssembly (a)).ToList ();
 
-               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;
+               // Store types that have been forwarded to avoid duplicate generation
+               GatherForwardedTypes ();
 
-                       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 NET_1_0
-                       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;
-                               }
-                       }
+               docEnum = docEnum ?? new DocumentationEnumerator ();
+               
+               // PERFORM THE UPDATES
+               
+               if (types.Count > 0) {
+                       types.Sort ();
+                       DoUpdateTypes (srcPath, types, srcPath);
+               }
+#if false
+               else if (opts.@namespace != null)
+                       DoUpdateNS (opts.@namespace, Path.Combine (opts.path, opts.@namespace),
+                                       Path.Combine (dest_dir, opts.@namespace));
 #endif
+               else
+                       DoUpdateAssemblies (srcPath, srcPath);
 
-                       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;
+               Console.WriteLine("Members Added: {0}, Members Deleted: {1}", additions, deletions);
+       }
+
+       void AddImporter (string path)
+       {
+               try {
+                       XmlReader r = new XmlTextReader (path);
+                       if (r.Read ()) {
+                               while (r.NodeType != XmlNodeType.Element) {
+                                       if (!r.Read ())
+                                               Error ("Unable to read XML file: {0}.", path);
+                               }
+                               if (r.LocalName == "doc") {
+                                       importers.Add (new MsxdocDocumentationImporter (path));
                                }
+                               else if (r.LocalName == "Libraries") {
+                                       var ecmadocs = new XmlTextReader (path);
+                                       docEnum = new EcmaDocumentationEnumerator (this, ecmadocs);
+                                       importers.Add (new EcmaDocumentationImporter (ecmadocs));
+                               }
+                               else
+                                       Error ("Unsupported XML format within {0}.", path);
                        }
-                       
-                       // 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);
+                       r.Close ();
+               } catch (Exception e) {
                        Environment.ExitCode = 1;
+                       Error ("Could not load XML file: {0}.", e.Message);
                }
+       }
 
-               Console.WriteLine("Members Added: {0}, Members Deleted: {1}", additions, deletions);
+       void GatherForwardedTypes ()
+       {
+               foreach (var asm in assemblies)
+                       foreach (var type in asm.MainModule.ExportedTypes.Where (t => t.IsForwarder).Select (t => t.FullName))
+                               forwardedTypes.Add (type);
        }
 
-       private static 
-#if !NET_1_0
-               new 
-#endif
-               void Error (string format, params object[] args)
+       static ExceptionLocations ParseExceptionLocations (string s)
+       {
+               ExceptionLocations loc = ExceptionLocations.Member;
+               if (s == null)
+                       return loc;
+               foreach (var type in s.Split (',')) {
+                       switch (type) {
+                               case "added":   loc |= ExceptionLocations.AddedMembers; break;
+                               case "all":     loc |= ExceptionLocations.Assembly | ExceptionLocations.DependentAssemblies; break;
+                               case "asm":     loc |= ExceptionLocations.Assembly; break;
+                               case "depasm":  loc |= ExceptionLocations.DependentAssemblies; break;
+                               default:        throw new NotSupportedException ("Unsupported --exceptions value: " + type);
+                       }
+               }
+               return loc;
+       }
+
+       internal void Warning (string format, params object[] args)
        {
-               Console.Error.Write ("monodocer: ");
-               Console.Error.WriteLine (format, args);
+               Message (TraceLevel.Warning, "mdoc: " + format, args);
        }
        
-       private static Assembly LoadAssembly (string name)
+       private AssemblyDefinition LoadAssembly (string name)
        {
-               Assembly assembly = null;
+               AssemblyDefinition assembly = null;
                try {
-                       assembly = Assembly.LoadFile (name);
+                       assembly = AssemblyDefinition.ReadAssembly (name, new ReaderParameters { AssemblyResolver = assemblyResolver });
                } catch (System.IO.FileNotFoundException) { }
 
-               if (assembly == null) {
-                       try {
-#pragma warning disable 0612
-                               assembly = Assembly.LoadWithPartialName (name);
-#pragma warning restore
-                       } catch (Exception) { }
-               }
-                       
                if (assembly == null)
                        throw new InvalidOperationException("Assembly " + name + " not found.");
 
@@ -357,6 +245,16 @@ class MDocUpdater
                output.WriteLine();     
        }
 
+       private static void WriteFile (string filename, FileMode mode, Action<TextWriter> action)
+       {
+               Action<string> creator = file => {
+                       using (var writer = OpenWrite (file, mode))
+                               action (writer);
+               };
+
+               MdocFile.UpdateFile (filename, creator);
+       }
+
        private static void OrderTypeAttributes (XmlElement e)
        {
                foreach (XmlElement type in e.SelectNodes ("//Type")) {
@@ -398,13 +296,14 @@ class MDocUpdater
                }
        }
        
-       private static XmlDocument CreateIndexStub() {
+       private XmlDocument CreateIndexStub()
+       {
                XmlDocument index = new XmlDocument();
 
                XmlElement index_root = index.CreateElement("Overview");
                index.AppendChild(index_root);
 
-               if (assemblies.Length == 0)
+               if (assemblies.Count == 0)
                        throw new Exception ("No assembly");
 
                XmlElement index_assemblies = index.CreateElement("Assemblies");
@@ -443,32 +342,94 @@ class MDocUpdater
                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);
-               }
+               WriteFile (outdir + "/ns-" + ns + ".xml", FileMode.CreateNew, 
+                               writer => 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);
+       public void DoUpdateTypes (string basepath, List<string> typenames, string dest)
+       {
+               var index = CreateIndexForTypes (dest);
+
+               var found = new HashSet<string> ();
+               foreach (AssemblyDefinition assembly in assemblies) {
+                       foreach (TypeDefinition type in docEnum.GetDocumentationTypes (assembly, typenames)) {
+                               string relpath = DoUpdateType (type, basepath, dest);
+                               if (relpath == null)
+                                       continue;
+
+                               found.Add (type.FullName);
+
+                               if (index == null)
+                                       continue;
+
+                               index.Add (assembly);
+                               index.Add (type);
                        }
                }
-               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)));
+
+               if (index != null)
+                       index.Write ();
+               
+               if (ignore_missing_types)
+                       return;
+
+               var notFound = from n in typenames where !found.Contains (n) select n;
+               if (notFound.Any ())
+                       throw new InvalidOperationException("Type(s) not found: " + string.Join (", ", notFound.ToArray ()));
+       }
+
+       class IndexForTypes {
+
+               MDocUpdater app;
+               string indexFile;
+
+               XmlDocument index;
+               XmlElement index_types;
+               XmlElement index_assemblies;
+
+               public IndexForTypes (MDocUpdater app, string indexFile, XmlDocument index)
+               {
+                       this.app        = app;
+                       this.indexFile  = indexFile;
+                       this.index      = index;
+
+                       index_types = WriteElement (index.DocumentElement, "Types");
+                       index_assemblies = WriteElement (index.DocumentElement, "Assemblies");
+               }
+
+               public void Add (AssemblyDefinition assembly)
+               {
+                       if (index_assemblies.SelectSingleNode ("Assembly[@Name='" + assembly.Name.Name + "']") != null)
+                               return;
+
+                       app.AddIndexAssembly (assembly, index_assemblies);
+               }
+
+               public void Add (TypeDefinition type)
+               {
+                       app.AddIndexType (type, index_types);
+               }
+
+               public void Write ()
+               {
+                       SortIndexEntries (index_types);
+                       WriteFile (indexFile, FileMode.Create, 
+                                       writer => WriteXml (index.DocumentElement, writer));
+               }
+       }
+
+       IndexForTypes CreateIndexForTypes (string dest)
+       {
+               string indexFile = Path.Combine (dest, "index.xml");
+               if (File.Exists (indexFile))
+                       return null;
+               return new IndexForTypes (this, indexFile, CreateIndexStub ());
        }
 
-       public static string DoUpdateType(Type type, string basepath, string dest, XmlReader ecmaDocsType)
+       public string DoUpdateType (TypeDefinition type, string basepath, string dest)
        {
                if (type.Namespace == null)
-                       Error ("warning: The type `{0}' is in the root namespace.  This may cause problems with display within monodoc.",
+                       Warning ("warning: The type `{0}' is in the root namespace.  This may cause problems with display within monodoc.",
                                        type.FullName);
                if (!IsPublic (type))
                        return null;
@@ -476,7 +437,7 @@ class MDocUpdater
                // Must get the A+B form of the type name.
                string typename = GetTypeFileName(type);
                
-               string reltypefile = DocUtils.PathCombine (type.Namespace, typename + ".xml");
+               string reltypefile = DocUtils.PathCombine (DocUtils.GetNamespace (type), typename + ".xml");
                string typefile = Path.Combine (basepath, reltypefile);
                System.IO.FileInfo file = new System.IO.FileInfo(typefile);
 
@@ -492,17 +453,16 @@ class MDocUpdater
                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);
+                       DoUpdateType2("Updating", basefile, type, output, false);
                } else {
                        // Stub
-                       XmlElement td = StubType(type, output, ecmaDocsType);
+                       XmlElement td = StubType(type, output);
                        if (td == null)
                                return null;
                        
@@ -515,27 +475,13 @@ class MDocUpdater
                return reltypefile;
        }
 
-       private static XPathNavigator SelectSingleNode (XPathNavigator n, string xpath)
+       public void DoUpdateNS (string ns, string nspath, string outpath)
        {
-#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
-       }
+               Dictionary<TypeDefinition, object> seenTypes = new Dictionary<TypeDefinition,object> ();
+               AssemblyDefinition                  assembly = assemblies [0];
 
-       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);
@@ -545,28 +491,28 @@ class MDocUpdater
 
                        string typename = 
                                GetTypeFileName (basefile.SelectSingleNode("Type/@FullName").InnerText);
-                       Type type = assembly.GetType(typename, false);
+                       TypeDefinition type = assembly.GetType(typename);
                        if (type == null) {
-                               Error ("Type no longer in assembly: " + typename);
+                               Warning ("Type no longer in assembly: " + typename);
                                continue;
                        }                       
 
                        seenTypes[type] = seenTypes;
-                       DoUpdateType2("Updating", basefile, type, Path.Combine(outpath, file.Name), false, null);
+                       DoUpdateType2("Updating", basefile, type, Path.Combine(outpath, file.Name), false);
                }
                
                // Stub types not in the directory
-               foreach (DocsTypeInfo docsTypeInfo in GetTypes (assembly, null)) {
-                       Type type = docsTypeInfo.Type;
+               foreach (TypeDefinition type in docEnum.GetDocumentationTypes (assembly, null)) {
                        if (type.Namespace != ns || seenTypes.ContainsKey(type))
                                continue;
 
-                       XmlElement td = StubType(type, Path.Combine(outpath, GetTypeFileName(type) + ".xml"), docsTypeInfo.EcmaDocs);
+                       XmlElement td = StubType(type, Path.Combine(outpath, GetTypeFileName(type) + ".xml"));
                        if (td == null) continue;
                }
        }
        
-       private static string GetTypeFileName(Type type) {
+       private static string GetTypeFileName (TypeReference type)
+       {
                return filenameFormatter.GetName (type);
        }
 
@@ -604,17 +550,62 @@ class MDocUpdater
                return filename.ToString ();
        }
 
-       
-       private static void AddIndexAssembly (Assembly assembly, XmlElement parent)
+       private void AddIndexAssembly (AssemblyDefinition 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);
+               index_assembly.SetAttribute ("Name", assembly.Name.Name);
+               index_assembly.SetAttribute ("Version", assembly.Name.Version.ToString());
+
+               AssemblyNameDefinition name = assembly.Name;
+               if (name.HasPublicKey) {
+                       XmlElement pubkey = parent.OwnerDocument.CreateElement ("AssemblyPublicKey");
+                       var key = new StringBuilder (name.PublicKey.Length*3 + 2);
+                       key.Append ("[");
+                       foreach (byte b in name.PublicKey)
+                               key.AppendFormat ("{0,2:x2} ", b);
+                       key.Append ("]");
+                       pubkey.InnerText = key.ToString ();
+                       index_assembly.AppendChild (pubkey);
+               }
+
+               if (!string.IsNullOrEmpty (name.Culture)) {
+                       XmlElement culture = parent.OwnerDocument.CreateElement ("AssemblyCulture");
+                       culture.InnerText = name.Culture;
+                       index_assembly.AppendChild (culture);
+               }
+
+               MakeAttributes (index_assembly, GetCustomAttributes (assembly.CustomAttributes, ""));
                parent.AppendChild(index_assembly);
        }
 
-       private static void DoUpdateAssemblies (string source, string dest) 
+       private void AddIndexType (TypeDefinition type, XmlElement index_types)
+       {
+               string typename = GetTypeFileName(type);
+
+               // Add namespace and type nodes into the index file as needed
+               string ns = DocUtils.GetNamespace (type);
+               XmlElement nsnode = (XmlElement) index_types.SelectSingleNode ("Namespace[@Name='" + ns + "']");
+               if (nsnode == null) {
+                       nsnode = index_types.OwnerDocument.CreateElement("Namespace");
+                       nsnode.SetAttribute ("Name", ns);
+                       index_types.AppendChild (nsnode);
+               }
+               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));
+       }
+
+       private void DoUpdateAssemblies (string source, string dest) 
        {
                string indexfile = dest + "/index.xml";
                XmlDocument index;
@@ -629,22 +620,19 @@ class MDocUpdater
                        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);
-               }
+               string defaultTitle = "Untitled";
+               if (assemblies.Count == 1)
+                       defaultTitle = assemblies[0].Name.Name;
+               WriteElementInitialText(index.DocumentElement, "Title", defaultTitle);
                
                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) {
+
+               HashSet<string> goodfiles = new HashSet<string> (StringComparer.OrdinalIgnoreCase);
+
+               foreach (AssemblyDefinition assm in assemblies) {
                        AddIndexAssembly (assm, index_assemblies);
                        DoUpdateAssembly (assm, index_types, source, dest, goodfiles);
                }
@@ -655,43 +643,25 @@ class MDocUpdater
                CleanupIndexTypes (index_types, goodfiles);
                CleanupExtensions (index_types);
 
-               using (TextWriter writer = OpenWrite (indexfile, FileMode.Create))
-                       WriteXml(index.DocumentElement, writer);
+               WriteFile (indexfile, FileMode.Create, 
+                               writer => WriteXml(index.DocumentElement, writer));
        }
                
        private static char[] InvalidFilenameChars = {'\\', '/', ':', '*', '?', '"', '<', '>', '|'};
 
-       private static void DoUpdateAssembly (Assembly assembly, XmlElement index_types, string source, string dest, Hashtable goodfiles) 
+       private void DoUpdateAssembly (AssemblyDefinition assembly, XmlElement index_types, string source, string dest, HashSet<string> goodfiles) 
        {
-               foreach (DocsTypeInfo docTypeInfo in GetTypes (assembly, null)) {
-                       Type type = docTypeInfo.Type;
-                       if (!IsPublic (type) || type.FullName.IndexOfAny (InvalidFilenameChars) >= 0)
+               foreach (TypeDefinition type in docEnum.GetDocumentationTypes (assembly, null)) {
+                       string typename = GetTypeFileName(type);
+                       if (!IsPublic (type) || typename.IndexOfAny (InvalidFilenameChars) >= 0 || forwardedTypes.Contains (type.FullName))
                                continue;
 
-                       string reltypepath = DoUpdateType (type, source, dest, docTypeInfo.EcmaDocs);
+                       string reltypepath = DoUpdateType (type, source, dest);
                        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));
+                       AddIndexType (type, index_types);
                                
                        // Ensure the namespace index file exists
                        string onsdoc = DocUtils.PathCombine (dest, type.Namespace + ".xml");
@@ -705,74 +675,7 @@ class MDocUpdater
                                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
-               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);
+                       goodfiles.Add (reltypepath);
                }
        }
 
@@ -797,10 +700,7 @@ class MDocUpdater
                }
        }
 
-       abstract class XmlNodeComparer : IComparer 
-#if !NET_1_0
-               , IComparer<XmlNode>
-#endif
+       abstract class XmlNodeComparer : IComparer, IComparer<XmlNode>
        {
                public abstract int Compare (XmlNode x, XmlNode y);
 
@@ -811,9 +711,21 @@ class MDocUpdater
        }
 
        class AttributeNameComparer : XmlNodeComparer {
+               string attribute;
+
+               public AttributeNameComparer ()
+                       : this ("Name")
+               {
+               }
+
+               public AttributeNameComparer (string attribute)
+               {
+                       this.attribute = attribute;
+               }
+
                public override int Compare (XmlNode x, XmlNode y)
                {
-                       return x.Attributes ["Name"].Value.CompareTo (y.Attributes ["Name"].Value);
+                       return x.Attributes [attribute].Value.CompareTo (y.Attributes [attribute].Value);
                }
        }
        
@@ -835,7 +747,7 @@ class MDocUpdater
                }
        }
 
-       private static string GetTypeKind (Type type)
+       private static string GetTypeKind (TypeDefinition type)
        {
                if (type.IsEnum)
                        return "Enumeration";
@@ -843,44 +755,45 @@ class MDocUpdater
                        return "Structure";
                if (type.IsInterface)
                        return "Interface";
-               if (IsDelegate (type))
+               if (DocUtils.IsDelegate (type))
                        return "Delegate";
-               if (type.IsClass || type == typeof(System.Enum))
+               if (type.IsClass || type.FullName == "System.Enum") // FIXME
                        return "Class";
                throw new ArgumentException ("Unknown kind for type: " + type.FullName);
        }
 
-       private static bool IsPublic (Type type)
+       private static bool IsPublic (TypeDefinition type)
        {
-               Type decl = type;
+               TypeDefinition decl = type;
                while (decl != null) {
-                       if (!(decl.IsPublic || decl.IsNestedPublic)) {
+                       if (!(decl.IsPublic || decl.IsNestedPublic ||
+                                               decl.IsNestedFamily || decl.IsNestedFamily || decl.IsNestedFamilyOrAssembly)) {
                                return false;
                        }
-                       decl = decl.DeclaringType;
+                       decl = (TypeDefinition) decl.DeclaringType;
                }
                return true;
        }
 
-       private static void CleanupFiles (string dest, Hashtable goodfiles)
+       private void CleanupFiles (string dest, HashSet<string> 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)) {
+                               if (!goodfiles.Contains (relTypeFile)) {
                                        XmlDocument doc = new XmlDocument ();
                                        doc.Load (typefile.FullName);
                                        XmlElement e = doc.SelectSingleNode("/Type") as XmlElement;
-                                       if (UpdateAssemblyVersions(e, GetAssemblyVersions(), false)) {
+                                       if (!no_assembly_versions && UpdateAssemblyVersions(e, GetAssemblyVersions(), false)) {
                                                using (TextWriter writer = OpenWrite (typefile.FullName, FileMode.Truncate))
                                                        WriteXml(doc.DocumentElement, writer);
-                                               goodfiles [relTypeFile] = goodfiles;
+                                               goodfiles.Add (relTypeFile);
                                                continue;
                                        }
                                        string newname = typefile.FullName + ".remove";
                                        try { System.IO.File.Delete(newname); } catch (Exception) { }
-                                       try { typefile.MoveTo(newname); } catch (Exception) { }                                 
+                                       try { typefile.MoveTo(newname); } catch (Exception) { }
                                        Console.WriteLine("Class no longer present; file renamed: " + Path.Combine(nsdir.Name, typefile.Name));
                                }
                        }
@@ -889,27 +802,26 @@ class MDocUpdater
 
        private static TextWriter OpenWrite (string path, FileMode mode)
        {
-               return new StreamWriter (
+               var w = new StreamWriter (
                        new FileStream (path, mode),
                        new UTF8Encoding (false)
                );
+               w.NewLine = "\n";
+               return w;
        }
 
-       private static string[] GetAssemblyVersions ()
+       private 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);
+               return (from a in assemblies select GetAssemblyVersion (a)).ToArray ();
        }
-               
-       private static void CleanupIndexTypes (XmlElement index_types, Hashtable goodfiles)
+
+       private static void CleanupIndexTypes (XmlElement index_types, HashSet<string> 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)) {
+                       if (!goodfiles.Contains (fulltypename)) {
                                remove.Add (typenode);
                        }
                }
@@ -917,13 +829,13 @@ class MDocUpdater
                        n.ParentNode.RemoveChild (n);
        }
 
-       private static void CleanupExtensions (XmlElement index_types)
+       private void CleanupExtensions (XmlElement index_types)
        {
                XmlNode e = index_types.SelectSingleNode ("/Overview/ExtensionMethods");
                if (extensionMethods.Count == 0) {
                        if (e == null)
                                return;
-                       index_types.RemoveChild (e);
+                       index_types.SelectSingleNode ("/Overview").RemoveChild (e);
                        return;
                }
                if (e == null) {
@@ -958,39 +870,32 @@ class MDocUpdater
 
        static readonly XmlNodeComparer DefaultExtensionMethodComparer = new ExtensionMethodComparer ();
                
-       public static void DoUpdateType2(string message, XmlDocument basefile, Type type, string output, bool insertSince, XmlReader ecmaDocsType) {
+       public void DoUpdateType2 (string message, XmlDocument basefile, TypeDefinition type, string output, bool insertSince)
+       {
                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;
-               }
+               UpdateType(basefile.DocumentElement, type);
 
                // 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) {
+               if (true) {
                        MyXmlNodeList todelete = new MyXmlNodeList ();
-                       foreach (DocsNodeInfo info in GetDocumentationMembers (basefile, type, ecmaDocsType)) {
+                       foreach (DocsNodeInfo info in docEnum.GetDocumentationMembers (basefile, type)) {
                                XmlElement oldmember  = info.Node;
-                               MemberInfo oldmember2 = info.Member;
-                               string sig = oldmember2 != null ? MakeMemberSignature(oldmember2) : null;
+                               MemberReference oldmember2 = info.Member;
+                               string sig = oldmember2 != null ? memberFormatters [0].GetDeclaration (oldmember2) : null;
 
                                // Interface implementations and overrides are deleted from the docs
                                // unless the overrides option is given.
-                               if (oldmember2 != null && (!IsNew(oldmember2) || sig == null))
+                               if (oldmember2 != null && sig == null)
                                        oldmember2 = null;
                                
                                // Deleted (or signature changed)
                                if (oldmember2 == null) {
-                                       if (UpdateAssemblyVersions (oldmember, new string[]{GetAssemblyVersion (type.Assembly)}, false))
+                                       if (!no_assembly_versions && UpdateAssemblyVersions (oldmember, new string[]{ GetAssemblyVersion (type.Module.Assembly) }, false))
                                                continue;
                                        DeleteMember ("Member Removed", output, oldmember, todelete);
                                        continue;
@@ -1004,7 +909,7 @@ class MDocUpdater
                                        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);
+                                               Warning ("TODO: found a duplicate member '{0}', but it's not identical to the prior member found!", sig);
                                        continue;
                                }
                                
@@ -1017,19 +922,15 @@ class MDocUpdater
                                oldmember.ParentNode.RemoveChild (oldmember);
                }
                
-               if (!IsDelegate(type) && !ignoremembers) {
+               if (!DocUtils.IsDelegate (type)) {
                        XmlNode members = WriteElement (basefile.DocumentElement, "Members");
-                       foreach (MemberInfo m in Sort (type.GetMembers(DefaultBindingFlags))) {
-                               if (m is Type) continue;
+                       foreach (MemberReference m in type.GetMembers()) {
+                               if (m is TypeDefinition) continue;
                                
-                               string sig = MakeMemberSignature(m);
+                               string sig = memberFormatters [0].GetDeclaration (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 );
@@ -1065,23 +966,20 @@ class MDocUpdater
                        SortTypeMembers (m);
                } while (false);
 
-               System.IO.TextWriter writer;
                if (output == null)
-                       writer = Console.Out;
+                       WriteXml(basefile.DocumentElement, 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);
+                       WriteFile (output, FileMode.Create,
+                                       writer => WriteXml(basefile.DocumentElement, writer));
                }
-
-               using (writer)
-                       WriteXml(basefile.DocumentElement, writer);
        }
 
-       private static string GetCodeSource (string lang, string file)
+       private string GetCodeSource (string lang, string file)
        {
                int anchorStart;
                if (lang == "C#" && (anchorStart = file.IndexOf (".cs#")) >= 0) {
@@ -1109,7 +1007,7 @@ class MDocUpdater
                                        return src.ToString ();
                                }
                        } catch (Exception e) {
-                               Error ("Could not load <code/> file '{0}' region '{1}': {2}",
+                               Warning ("Could not load <code/> file '{0}' region '{1}': {2}",
                                                file, region, show_exceptions ? e.ToString () : e.Message);
                                return null;
                        }
@@ -1118,110 +1016,24 @@ class MDocUpdater
                        using (StreamReader reader = new StreamReader (file))
                                return reader.ReadToEnd ();
                } catch (Exception e) {
-                       Error ("Could not load <code/> file '" + file + "': " + e.Message);
+                       Warning ("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)
+       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,
+               Warning (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.");
+                       Warning ("Member deletions must be enabled with the --delete option.");
                } else {
                        todelete.Add (member);
                        deletions++;
@@ -1316,234 +1128,25 @@ class MDocUpdater
                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;
-       }
+       // UPDATE HELPER FUNCTIONS
        
        // CREATE A STUB DOCUMENTATION FILE     
 
-       public static XmlElement StubType(Type type, string output, XmlReader ecmaDocsType) {
-               string typesig = MakeTypeSignature(type);
+       public XmlElement StubType (TypeDefinition type, string output)
+       {
+               string typesig = typeFormatters [0].GetDeclaration (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);
+               DoUpdateType2 ("New Type", doc, type, output, true);
                
                return root;
        }
 
-       private static XmlElement CreateSinceNode (XmlDocument doc)
+       private XmlElement CreateSinceNode (XmlDocument doc)
        {
                XmlElement s = doc.CreateElement ("since");
                s.SetAttribute ("version", since);
@@ -1552,18 +1155,29 @@ class MDocUpdater
        
        // STUBBING/UPDATING FUNCTIONS
        
-       public static void UpdateType(XmlElement root, Type type, XmlReader ecmaDocsType) {
+       public void UpdateType (XmlElement root, TypeDefinition type)
+       {
                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));
+               foreach (MemberFormatter f in typeFormatters) {
+                       string element = "TypeSignature[@Language='" + f.Language + "']";
+                       WriteElementAttribute (root, element, "Language", f.Language);
+                       WriteElementAttribute (root, element, "Value", f.GetDeclaration (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);
+               WriteElementText(ass, "AssemblyName", type.Module.Assembly.Name.Name);
+               if (!no_assembly_versions) {
+                       UpdateAssemblyVersions (root, type, true);
+               }
+               else {
+                       var versions = ass.SelectNodes ("AssemblyVersion").Cast<XmlNode> ().ToList ();
+                       foreach (var version in versions)
+                               ass.RemoveChild (version);
+               }
+               if (!string.IsNullOrEmpty (type.Module.Assembly.Name.Culture))
+                       WriteElementText(ass, "AssemblyCulture", type.Module.Assembly.Name.Culture);
                else
                        ClearElement(ass, "AssemblyCulture");
                
@@ -1577,8 +1191,8 @@ class MDocUpdater
                
                NormalizeWhitespace(ass);
                
-               if (DocUtils.IsGenericType (type)) {
-                       MakeTypeParameters (root, DocUtils.GetGenericArguments (type));
+               if (type.IsGenericType ()) {
+                       MakeTypeParameters (root, type.GenericParameters);
                } else {
                        ClearElement(root, "TypeParameters");
                }
@@ -1591,35 +1205,35 @@ class MDocUpdater
                        WriteElementText(root, "Base/BaseTypeName", basetypename);
                        
                        // Document how this type instantiates the generic parameters of its base type
-                       if (DocUtils.IsGenericType (type.BaseType)) {
+                       TypeReference origBase = type.BaseType.GetElementType ();
+                       if (origBase.IsGenericType ()) {
                                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];
-                                       
+                               GenericInstanceType baseInst             = type.BaseType as GenericInstanceType;
+                               IList<TypeReference> baseGenArgs    = baseInst == null ? null : baseInst.GenericArguments;
+                               IList<GenericParameter> baseGenParams = origBase.GenericParameters;
+                               if (baseGenArgs.Count != baseGenParams.Count)
+                                       throw new InvalidOperationException ("internal error: number of generic arguments doesn't match number of generic parameters.");
+                               for (int i = 0; baseGenArgs != null && i < baseGenArgs.Count; i++) {
+                                       GenericParameter param = baseGenParams [i];
+                                       TypeReference    value = baseGenArgs [i];
+
                                        XmlElement bta = WriteElement(basenode, "BaseTypeArguments");
                                        XmlElement arg = bta.OwnerDocument.CreateElement("BaseTypeArgument");
                                        bta.AppendChild(arg);
-                                       arg.SetAttribute("TypeParamName", typeparam.Name);
-                                       arg.InnerText = GetDocTypeFullName (typearg);
+                                       arg.SetAttribute ("TypeParamName", param.Name);
+                                       arg.InnerText = GetDocTypeFullName (value);
                                }
                        }
                } 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();
+               if (!DocUtils.IsDelegate (type) && !type.IsEnum) {
+                       IEnumerable<TypeReference> userInterfaces = DocUtils.GetUserImplementedInterfaces (type);
+                       List<string> interface_names = userInterfaces
+                                       .Select (iface => GetDocTypeFullName (iface))
+                                       .OrderBy (s => s)
+                                       .ToList ();
 
                        XmlElement interfaces = WriteElement(root, "Interfaces");
                        interfaces.RemoveAll();
@@ -1632,112 +1246,202 @@ class MDocUpdater
                        ClearElement(root, "Interfaces");
                }
 
-               MakeAttributes(root, type, false);
+               MakeAttributes (root, GetCustomAttributes (type));
                
-               if (IsDelegate(type)) {
-                       MakeTypeParameters (root, DocUtils.GetGenericArguments (type));
-                       MakeParameters(root, type.GetMethod("Invoke").GetParameters());
+               if (DocUtils.IsDelegate (type)) {
+                       MakeTypeParameters (root, type.GenericParameters);
+                       MakeParameters(root, type.GetMethod("Invoke").Parameters);
                        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))
+               if (!DocUtils.IsDelegate (type))
                        WriteElement (root, "Members");
 
+               OrderTypeNodes (root, root.ChildNodes);
                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 ();
+       static readonly string[] TypeNodeOrder = {
+               "TypeSignature",
+               "MemberOfLibrary",
+               "AssemblyInfo",
+               "ThreadingSafetyStatement",
+               "ThreadSafetyStatement",
+               "TypeParameters",
+               "Base",
+               "Interfaces",
+               "Attributes",
+               "Parameters",
+               "ReturnValue",
+               "Docs",
+               "Members",
+               "TypeExcluded",
+       };
 
-       private static MemberInfo[] Sort (MemberInfo[] members)
+       static void OrderTypeNodes (XmlNode member, XmlNodeList children)
        {
-#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
+               ReorderNodes (member, children, TypeNodeOrder);
        }
 
-#if NET_1_0
-       static IEnumerable Sort (IEnumerable list)
-       {
-               ArrayList l = new ArrayList (list as ICollection);
-               l.Sort ();
-               return l;
-       }
-#else
-       static IEnumerable<T> Sort<T> (IEnumerable<T> list)
+       internal 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) {   
+
+       private 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));
+               MemberReference mi = info.Member;
+
+               foreach (MemberFormatter f in memberFormatters) {
+                       string element = "MemberSignature[@Language='" + f.Language + "']";
+                       WriteElementAttribute (me, element, "Language", f.Language);
+                       WriteElementAttribute (me, element, "Value", f.GetDeclaration (mi));
+               }
 
                WriteElementText(me, "MemberType", GetMemberType(mi));
                
-               UpdateAssemblyVersions(me, mi, true);
-               MakeAttributes(me, mi, false);
+               if (!no_assembly_versions) {
+                       UpdateAssemblyVersions (me, mi, true);
+               }
+               else {
+                       ClearElement (me, "AssemblyInfo");
+               }
+
+               MakeAttributes (me, GetCustomAttributes (mi));
+
                MakeReturnValue(me, mi);
-               if (mi is MethodBase) {
-                       MethodBase mb = (MethodBase) mi;
-                       if (DocUtils.GetContainsGenericParameters (mb))
-                               MakeTypeParameters (me, DocUtils.GetGenericArguments (mb));
+               if (mi is MethodReference) {
+                       MethodReference mb = (MethodReference) mi;
+                       if (mb.IsGenericMethod ())
+                               MakeTypeParameters (me, mb.GenericParameters);
                }
                MakeParameters(me, mi);
                
                string fieldValue;
-               if (mi is FieldInfo && GetFieldConstValue((FieldInfo)mi, out fieldValue))
+               if (mi is FieldDefinition && GetFieldConstValue ((FieldDefinition)mi, out fieldValue))
                        WriteElementText(me, "MemberValue", fieldValue);
                
                info.Node = WriteElement (me, "Docs");
                MakeDocNode (info);
+               OrderMemberNodes (me, me.ChildNodes);
                UpdateExtensionMethods (me, info);
        }
 
+       static readonly string[] MemberNodeOrder = {
+               "MemberSignature",
+               "MemberType",
+               "AssemblyInfo",
+               "Attributes",
+               "ReturnValue",
+               "TypeParameters",
+               "Parameters",
+               "MemberValue",
+               "Docs",
+               "Excluded",
+               "ExcludedLibrary",
+               "Link",
+       };
+
+       static void OrderMemberNodes (XmlNode member, XmlNodeList children)
+       {
+               ReorderNodes (member, children, MemberNodeOrder);
+       }
+
+       static void ReorderNodes (XmlNode node, XmlNodeList children, string[] ordering)
+       {
+               MyXmlNodeList newChildren = new MyXmlNodeList (children.Count);
+               for (int i = 0; i < ordering.Length; ++i) {
+                       for (int j = 0; j < children.Count; ++j) {
+                               XmlNode c = children [j];
+                               if (c.Name == ordering [i]) {
+                                       newChildren.Add (c);
+                               }
+                       }
+               }
+               if (newChildren.Count >= 0)
+                       node.PrependChild ((XmlNode) newChildren [0]);
+               for (int i = 1; i < newChildren.Count; ++i) {
+                       XmlNode prev = (XmlNode) newChildren [i-1];
+                       XmlNode cur  = (XmlNode) newChildren [i];
+                       node.RemoveChild (cur);
+                       node.InsertAfter (cur, prev);
+               }
+       }
+
+       IEnumerable<string> GetCustomAttributes (MemberReference mi)
+       {
+               IEnumerable<string> attrs = Enumerable.Empty<string>();
+
+               ICustomAttributeProvider p = mi as ICustomAttributeProvider;
+               if (p != null)
+                       attrs = attrs.Concat (GetCustomAttributes (p.CustomAttributes, ""));
+
+               PropertyDefinition pd = mi as PropertyDefinition;
+               if (pd != null) {
+                       if (pd.GetMethod != null)
+                               attrs = attrs.Concat (GetCustomAttributes (pd.GetMethod.CustomAttributes, "get: "));
+                       if (pd.SetMethod != null)
+                               attrs = attrs.Concat (GetCustomAttributes (pd.SetMethod.CustomAttributes, "set: "));
+               }
+
+               EventDefinition ed = mi as EventDefinition;
+               if (ed != null) {
+                       if (ed.AddMethod != null)
+                               attrs = attrs.Concat (GetCustomAttributes (ed.AddMethod.CustomAttributes, "add: "));
+                       if (ed.RemoveMethod != null)
+                               attrs = attrs.Concat (GetCustomAttributes (ed.RemoveMethod.CustomAttributes, "remove: "));
+               }
+
+               return attrs;
+       }
+
+       IEnumerable<string> GetCustomAttributes (IList<CustomAttribute> attributes, string prefix)
+       {
+               foreach (CustomAttribute attribute in attributes.OrderBy (ca => ca.AttributeType.FullName)) {
+
+                       TypeDefinition attrType = attribute.AttributeType as TypeDefinition;
+                       if (attrType != null && !IsPublic (attrType))
+                               continue;
+                       if (slashdocFormatter.GetName (attribute.AttributeType) == null)
+                               continue;
+                       
+                       if (Array.IndexOf (IgnorableAttributes, attribute.AttributeType.FullName) >= 0)
+                               continue;
+                       
+                       StringList fields = new StringList ();
+
+                       for (int i = 0; i < attribute.ConstructorArguments.Count; ++i) {
+                               CustomAttributeArgument argument = attribute.ConstructorArguments [i];
+                               fields.Add (MakeAttributesValueString (
+                                               argument.Value,
+                                               argument.Type));
+                       }
+                       var namedArgs =
+                               (from namedArg in attribute.Fields
+                                select new { Type=namedArg.Argument.Type, Name=namedArg.Name, Value=namedArg.Argument.Value })
+                               .Concat (
+                                               (from namedArg in attribute.Properties
+                                                select new { Type=namedArg.Argument.Type, Name=namedArg.Name, Value=namedArg.Argument.Value }))
+                               .OrderBy (v => v.Name);
+                       foreach (var d in namedArgs)
+                               fields.Add (string.Format ("{0}={1}", d.Name, 
+                                               MakeAttributesValueString (d.Value, d.Type)));
+
+                       string a2 = String.Join(", ", fields.ToArray ());
+                       if (a2 != "") a2 = "(" + a2 + ")";
+
+                       string name = attribute.GetDeclaringType();
+                       if (name.EndsWith("Attribute")) name = name.Substring(0, name.Length-"Attribute".Length);
+                       yield return prefix + name + a2;
+               }
+       }
+
        static readonly string[] ValidExtensionMembers = {
                "Docs",
                "MemberSignature",
@@ -1753,12 +1457,12 @@ class MDocUpdater
                "typeparam",
        };
 
-       private static void UpdateExtensionMethods (XmlElement e, DocsNodeInfo info)
+       private void UpdateExtensionMethods (XmlElement e, DocsNodeInfo info)
        {
-               MethodInfo me = info.Member as MethodInfo;
+               MethodDefinition me = info.Member as MethodDefinition;
                if (me == null)
                        return;
-               if (info.Parameters.Length < 1)
+               if (info.Parameters.Count < 1)
                        return;
                if (!DocUtils.IsExtensionMethod (me))
                        return;
@@ -1799,32 +1503,33 @@ class MDocUpdater
        {
                XmlElement targets = member.OwnerDocument.CreateElement ("Targets");
                member.PrependChild (targets);
-               if (!DocUtils.IsGenericParameter (info.Parameters [0].ParameterType))
+               if (!(info.Parameters [0].ParameterType is GenericParameter)) {
                        AppendElementAttributeText (targets, "Target", "Type",
                                slashdocFormatter.GetDeclaration (info.Parameters [0].ParameterType));
+               }
                else {
-                       Type[] constraints = DocUtils.GetGenericParameterConstraints (
-                               info.Parameters [0].ParameterType);
-                       if (constraints.Length == 0)
+                       GenericParameter gp = (GenericParameter) info.Parameters [0].ParameterType;
+                       IList<TypeReference> constraints = gp.Constraints;
+                       if (constraints.Count == 0)
                                AppendElementAttributeText (targets, "Target", "Type", "System.Object");
                        else
-                               foreach (Type c in constraints)
+                               foreach (TypeReference c in constraints)
                                        AppendElementAttributeText(targets, "Target", "Type",
                                                slashdocFormatter.GetDeclaration (c));
                }
        }
        
-       private static bool GetFieldConstValue(FieldInfo field, out string value) {
+       private static bool GetFieldConstValue (FieldDefinition 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;
-                       }
+               TypeDefinition type = field.DeclaringType.Resolve ();
+               if (type != null && type.IsEnum) return false;
+               
+               if (type != null && type.IsGenericType ()) return false;
+               if (!field.HasConstant)
+                       return false;
+               if (field.IsLiteral) {
+                       object val = field.Constant;
                        if (val == null) value = "null";
                        else if (val is Enum) value = val.ToString();
                        else if (val is IFormattable) {
@@ -1840,7 +1545,7 @@ class MDocUpdater
        
        // XML HELPER FUNCTIONS
        
-       private static XmlElement WriteElement(XmlNode parent, string element) {
+       internal static XmlElement WriteElement(XmlNode parent, string element) {
                XmlElement ret = (XmlElement)parent.SelectSingleNode(element);
                if (ret == null) {
                        string[] path = element.Split('/');
@@ -1865,7 +1570,6 @@ class MDocUpdater
                node.InnerText = value;
        }
 
-#if !NET_1_0
        static XmlElement AppendElementText (XmlNode parent, string element, string value)
        {
                XmlElement n = parent.OwnerDocument.CreateElement (element);
@@ -1873,7 +1577,6 @@ class MDocUpdater
                n.InnerText = value;
                return n;
        }
-#endif
 
        static XmlElement AppendElementAttributeText (XmlNode parent, string element, string attribute, string value)
        {
@@ -1883,7 +1586,7 @@ class MDocUpdater
                return n;
        }
 
-       private static XmlNode CopyNode (XmlNode source, XmlNode dest)
+       internal static XmlNode CopyNode (XmlNode source, XmlNode dest)
        {
                XmlNode copy = dest.OwnerDocument.ImportNode (source, true);
                dest.AppendChild (copy);
@@ -1902,7 +1605,7 @@ class MDocUpdater
                if (node.GetAttribute(attribute) == value) return;
                node.SetAttribute(attribute, value);
        }
-       private static void ClearElement(XmlElement parent, string name) {
+       internal static void ClearElement(XmlElement parent, string name) {
                XmlElement node = (XmlElement)parent.SelectSingleNode(name);
                if (node != null)
                        parent.RemoveChild(node);
@@ -1910,11 +1613,11 @@ class MDocUpdater
        
        // DOCUMENTATION HELPER FUNCTIONS
        
-       private static void MakeDocNode (DocsNodeInfo info)
+       private void MakeDocNode (DocsNodeInfo info)
        {
-               Type[] genericParams        = info.GenericParameters;
-               ParameterInfo[] parameters  = info.Parameters;
-               Type returntype             = info.ReturnType;
+               List<GenericParameter> genericParams      = info.GenericParameters;
+               IList<ParameterDefinition> parameters  = info.Parameters;
+               TypeReference returntype                  = info.ReturnType;
                bool returnisreturn         = info.ReturnIsReturn;
                XmlElement e                = info.Node;
                bool addremarks             = info.AddRemarks;
@@ -1922,21 +1625,21 @@ class MDocUpdater
                WriteElementInitialText(e, "summary", "To be added.");
                
                if (parameters != null) {
-                       string[] values = new string [parameters.Length];
+                       string[] values = new string [parameters.Count];
                        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];
+                       string[] values = new string [genericParams.Count];
                        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)) {
+               if (returntype != null && returntype.FullName != "System.Void") { // FIXME
                        retnodename = returnisreturn ? "returns" : "value";
                        string retnodename_other = !returnisreturn ? "returns" : "value";
                        
@@ -1958,129 +1661,13 @@ class MDocUpdater
                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;
-                                       }
-                               }
-                       }
+               if (exceptions.HasValue && info.Member != null &&
+                               (exceptions.Value & ExceptionLocations.AddedMembers) == 0) {
+                       UpdateExceptions (e, info.Member);
                }
+
+               foreach (DocumentationImporter importer in importers)
+                       importer.ImportDocumentation (info);
                
                OrderDocsNodes (e, e.ChildNodes);
                NormalizeWhitespace(e);
@@ -2092,27 +1679,11 @@ class MDocUpdater
 
        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);
-               }
+               ReorderNodes (docs, children, DocsNodeOrder);
        }
        
 
-       private static void UpdateParameters (XmlElement e, string element, string[] values)
+       private void UpdateParameters (XmlElement e, string element, string[] values)
        {       
                if (values != null) {
                        XmlNode[] paramnodes = new XmlNode[values.Length];
@@ -2154,20 +1725,20 @@ class MDocUpdater
                                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: ");
+                                               Warning ("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}\"]",
+                                                       Warning ("\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}\"]",
+                                                       Warning ("\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);
+                                               Warning ("\tValue={0}", paramnode.OuterXml);
                                        } else {
                                                todelete.Add (paramnode);
                                        }
@@ -2212,6 +1783,54 @@ class MDocUpdater
                                paramref.SetAttribute ("name", newName);
        }
 
+       class CrefComparer : XmlNodeComparer {
+
+               public CrefComparer ()
+               {
+               }
+
+               public override int Compare (XmlNode x, XmlNode y)
+               {
+                       string xType = x.Attributes ["cref"].Value;
+                       string yType = y.Attributes ["cref"].Value;
+                       string xNamespace = GetNamespace (xType);
+                       string yNamespace = GetNamespace (yType);
+
+                       int c = xNamespace.CompareTo (yNamespace);
+                       if (c != 0)
+                               return c;
+                       return xType.CompareTo (yType);
+               }
+
+               static string GetNamespace (string type)
+               {
+                       int n = type.LastIndexOf ('.');
+                       if (n >= 0)
+                               return type.Substring (0, n);
+                       return string.Empty;
+               }
+       }
+       
+       private void UpdateExceptions (XmlNode docs, MemberReference member)
+       {
+               foreach (var source in new ExceptionLookup (exceptions.Value)[member]) {
+                       string cref = slashdocFormatter.GetDeclaration (source.Exception);
+                       var node = docs.SelectSingleNode ("exception[@cref='" + cref + "']");
+                       if (node != null)
+                               continue;
+                       XmlElement e = docs.OwnerDocument.CreateElement ("exception");
+                       e.SetAttribute ("cref", cref);
+                       e.InnerXml = "To be added; from: <see cref=\"" + 
+                               string.Join ("\" />, <see cref=\"", 
+                                               source.Sources.Select (m => slashdocFormatter.GetDeclaration (m))
+                                               .ToArray ()) +
+                               "\" />";
+                       docs.AppendChild (e);
+               }
+               SortXmlNodes (docs, docs.SelectNodes ("exception"), 
+                               new CrefComparer ());
+       }
+
        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.
@@ -2223,17 +1842,17 @@ class MDocUpdater
                                n.ParentNode.RemoveChild(n);
        }
        
-       private static bool UpdateAssemblyVersions(XmlElement root, MemberInfo member, bool add)
+       private static bool UpdateAssemblyVersions (XmlElement root, MemberReference member, bool add)
        {
-               Type type = member as Type;
+               TypeDefinition type = member as TypeDefinition;
                if (type == null)
-                       type = member.DeclaringType;
-               return UpdateAssemblyVersions(root, new string[]{ GetAssemblyVersion(type.Assembly) }, add);
+                       type = member.DeclaringType as TypeDefinition;
+               return UpdateAssemblyVersions(root, new string[]{ GetAssemblyVersion (type.Module.Assembly) }, add);
        }
        
-       private static string GetAssemblyVersion(Assembly assembly)
+       private static string GetAssemblyVersion (AssemblyDefinition assembly)
        {
-               return assembly.GetName().Version.ToString();
+               return assembly.Name.Version.ToString();
        }
        
        private static bool UpdateAssemblyVersions(XmlElement root, string[] assemblyVersions, bool add)
@@ -2243,12 +1862,9 @@ class MDocUpdater
                        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);
-               }
+               List<XmlNode> matches = e.SelectNodes ("AssemblyVersion").Cast<XmlNode>()
+                       .Where(v => Array.IndexOf (assemblyVersions, v.InnerText) >= 0)
+                       .ToList ();
                // matches.Count > 0 && add: ignore -- already present
                if (matches.Count > 0 && !add) {
                        foreach (XmlNode c in matches)
@@ -2269,175 +1885,124 @@ class MDocUpdater
                return avs.Count != 0;
        }
 
-#if !NET_1_0
-       private static Type[] IgnorableAttributes = {
+       // FIXME: get TypeReferences instead of string comparison?
+       private static string[] IgnorableAttributes = {
                // Security related attributes
-               typeof (System.Reflection.AssemblyKeyFileAttribute),
-               typeof (System.Reflection.AssemblyDelaySignAttribute),
+               "System.Reflection.AssemblyKeyFileAttribute",
+               "System.Reflection.AssemblyDelaySignAttribute",
                // Present in @RefType
-               typeof (System.Runtime.InteropServices.OutAttribute),
+               "System.Runtime.InteropServices.OutAttribute",
                // For naming the indexer to use when not using indexers
-               typeof (System.Reflection.DefaultMemberAttribute),
+               "System.Reflection.DefaultMemberAttribute",
                // for decimal constants
-               typeof (System.Runtime.CompilerServices.DecimalConstantAttribute),
+               "System.Runtime.CompilerServices.DecimalConstantAttribute",
                // compiler generated code
-               typeof (System.Runtime.CompilerServices.CompilerGeneratedAttribute),
+               "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),
+               "System.Diagnostics.DebuggerHiddenAttribute",
+               "System.Runtime.CompilerServices.FixedBufferAttribute",
+               "System.Runtime.CompilerServices.UnsafeValueTypeAttribute",
                // extension methods
-               typeof (System.Runtime.CompilerServices.ExtensionAttribute),
+               "System.Runtime.CompilerServices.ExtensionAttribute",
+               // Used to differentiate 'object' from C#4 'dynamic'
+               "System.Runtime.CompilerServices.DynamicAttribute",
        };
-#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");
+       private void MakeAttributes (XmlElement root, IEnumerable<string> attributes)
+       {
+               if (!attributes.Any ()) {
+                       ClearElement (root, "Attributes");
                        return;
                }
 
-               bool b = false;
                XmlElement e = (XmlElement)root.SelectSingleNode("Attributes");
                if (e != null)
                        e.RemoveAll();
-               else
+               else if (e == null)
                        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 + ")";
-                       
+               foreach (string attribute in attributes) {
                        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);
+                       WriteElementText(ae, "AttributeName", attribute);
                }
-#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)
+               if (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();
+
+       public static string MakeAttributesValueString (object v, TypeReference valueType)
+       {
+               if (v == null)
+                       return "null";
+               if (valueType.FullName == "System.Type")
+                       return "typeof(" + v.ToString () + ")";
+               if (valueType.FullName == "System.String")
+                       return "\"" + v.ToString () + "\"";
+               if (valueType.FullName == "System.Char")
+                       return "'" + v.ToString () + "'";
+               if (v is Boolean)
+                       return (bool)v ? "true" : "false";
+               TypeDefinition valueDef = valueType.Resolve ();
+               if (valueDef == null || !valueDef.IsEnum)
+                       return v.ToString ();
+               string typename = GetDocTypeFullName (valueType);
+               var values = GetEnumerationValues (valueDef);
+               long c = ToInt64 (v);
+               if (values.ContainsKey (c))
+                       return typename + "." + values [c];
+               if (valueDef.CustomAttributes.Any (ca => ca.AttributeType.FullName == "System.FlagsAttribute")) {
+                       return string.Join (" | ",
+                                       (from i in values.Keys
+                                        where (c & i) != 0
+                                        select typename + "." + values [i])
+                                       .DefaultIfEmpty (v.ToString ()).ToArray ());
+               }
+               return "(" + GetDocTypeFullName (valueType) + ") " + v.ToString ();
+       }
+
+       private static Dictionary<long, string> GetEnumerationValues (TypeDefinition type)
+       {
+               var values = new Dictionary<long, string> ();
+               foreach (var f in 
+                               (from f in type.Fields
+                                where !(f.IsRuntimeSpecialName || f.IsSpecialName)
+                                select f)) {
+                       values [ToInt64 (f.Constant)] = f.Name;
+               }
+               return values;
+       }
+
+       static long ToInt64 (object value)
+       {
+               if (value is ulong)
+                       return (long) (ulong) value;
+               return Convert.ToInt64 (value);
        }
-#endif
        
-       private static void MakeParameters(XmlElement root, ParameterInfo[] parameters) {
+       private void MakeParameters (XmlElement root, IList<ParameterDefinition> parameters)
+       {
                XmlElement e = WriteElement(root, "Parameters");
                e.RemoveAll();
-               foreach (ParameterInfo p in parameters) {
+               foreach (ParameterDefinition 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.ParameterType is ByReferenceType) {
                                if (p.IsOut) pe.SetAttribute("RefType", "out");
                                else pe.SetAttribute("RefType", "ref");
                        }
-                       MakeAttributes(pe, p, false);
+                       MakeAttributes (pe, GetCustomAttributes (p.CustomAttributes, ""));
                }
        }
        
-       private static void MakeTypeParameters(XmlElement root, Type[] typeParams)
+       private void MakeTypeParameters (XmlElement root, IList<GenericParameter> typeParams)
        {
-               if (typeParams == null || typeParams.Length == 0) {
+               if (typeParams == null || typeParams.Count == 0) {
                        XmlElement f = (XmlElement) root.SelectSingleNode ("TypeParameters");
                        if (f != null)
                                root.RemoveChild (f);
@@ -2445,16 +2010,15 @@ class MDocUpdater
                }
                XmlElement e = WriteElement(root, "TypeParameters");
                e.RemoveAll();
-               foreach (Type t in typeParams) {
+               foreach (GenericParameter 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
+                       MakeAttributes (pe, GetCustomAttributes (t.CustomAttributes, ""));
                        XmlElement ce = (XmlElement) e.SelectSingleNode ("Constraints");
-                       GenericParameterAttributes attrs = t.GenericParameterAttributes;
-                       Type[] constraints = t.GetGenericParameterConstraints ();
-                       if (attrs == GenericParameterAttributes.None && constraints.Length == 0) {
+                       IList<TypeReference> constraints = t.Constraints;
+                       GenericParameterAttributes attrs = t.Attributes;
+                       if (attrs == GenericParameterAttributes.NonVariant && constraints.Count == 0) {
                                if (ce != null)
                                        e.RemoveChild (ce);
                                continue;
@@ -2475,64 +2039,76 @@ class MDocUpdater
                                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));
+                       foreach (TypeReference c in constraints) {
+                               TypeDefinition cd = c.Resolve ();
+                               AppendElementText (ce,
+                                               (cd != null && cd.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();
+       private void MakeParameters (XmlElement root, MemberReference mi)
+       {
+               if (mi is MethodDefinition && ((MethodDefinition) mi).IsConstructor)
+                       MakeParameters (root, ((MethodDefinition)mi).Parameters);
+               else if (mi is MethodDefinition) {
+                       MethodDefinition mb = (MethodDefinition) mi;
+                       IList<ParameterDefinition> parameters = mb.Parameters;
                        MakeParameters(root, parameters);
-                       if (parameters.Length > 0 && DocUtils.IsExtensionMethod (mb)) {
+                       if (parameters.Count > 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)
+               else if (mi is PropertyDefinition) {
+                       IList<ParameterDefinition> parameters = ((PropertyDefinition)mi).Parameters;
+                       if (parameters.Count > 0)
                                MakeParameters(root, parameters);
                        else
                                return;
                }
-               else if (mi is FieldInfo) return;
-               else if (mi is EventInfo) return;
+               else if (mi is FieldDefinition) return;
+               else if (mi is EventDefinition) return;
                else throw new ArgumentException();
        }
 
-       private static string GetDocParameterType (Type type)
+       internal static string GetDocParameterType (TypeReference type)
        {
                return GetDocTypeFullName (type).Replace ("@", "&");
        }
 
-       private static void MakeReturnValue(XmlElement root, Type type, ICustomAttributeProvider attributes) {
+       private void MakeReturnValue (XmlElement root, TypeReference type, IList<CustomAttribute> attributes) 
+       {
                XmlElement e = WriteElement(root, "ReturnValue");
                e.RemoveAll();
                WriteElementText(e, "ReturnType", GetDocTypeFullName (type));
                if (attributes != null)
-                       MakeAttributes(e, attributes, false);
+                       MakeAttributes(e, GetCustomAttributes (attributes, ""));
        }
        
-       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 void MakeReturnValue (XmlElement root, MemberReference mi)
+       {
+               if (mi is MethodDefinition && ((MethodDefinition) mi).IsConstructor)
+                       return;
+               else if (mi is MethodDefinition)
+                       MakeReturnValue (root, ((MethodDefinition)mi).ReturnType, ((MethodDefinition)mi).MethodReturnType.CustomAttributes);
+               else if (mi is PropertyDefinition)
+                       MakeReturnValue (root, ((PropertyDefinition)mi).PropertyType, null);
+               else if (mi is FieldDefinition)
+                       MakeReturnValue (root, ((FieldDefinition)mi).FieldType, null);
+               else if (mi is EventDefinition)
+                       MakeReturnValue (root, ((EventDefinition)mi).EventType, 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;
+       private XmlElement MakeMember(XmlDocument doc, DocsNodeInfo info)
+       {
+               MemberReference mi = info.Member;
+               if (mi is TypeDefinition) return null;
 
-               string sigs = MakeMemberSignature(mi);
+               string sigs = memberFormatters [0].GetDeclaration (mi);
                if (sigs == null) return null; // not publicly visible
                
                // no documentation for property/event accessors.  Is there a better way of doing this?
@@ -2547,6 +2123,9 @@ class MDocUpdater
                
                info.Node = me;
                UpdateMember(info);
+               if (exceptions.HasValue && 
+                               (exceptions.Value & ExceptionLocations.AddedMembers) != 0)
+                       UpdateExceptions (info.Node, info.Member);
 
                if (since != null) {
                        XmlNode docs = me.SelectSingleNode("Docs");
@@ -2556,11 +2135,11 @@ class MDocUpdater
                return me;
        }
 
-       private static string GetMemberName (MemberInfo mi)
+       internal static string GetMemberName (MemberReference mi)
        {
-               MethodBase mb = mi as MethodBase;
+               MethodDefinition mb = mi as MethodDefinition;
                if (mb == null) {
-                       PropertyInfo pi = mi as PropertyInfo;
+                       PropertyDefinition pi = mi as PropertyDefinition;
                        if (pi == null)
                                return mi.Name;
                        return DocUtils.GetPropertyName (pi);
@@ -2569,177 +2148,58 @@ class MDocUpdater
                if (!DocUtils.IsExplicitlyImplemented (mb))
                        sb.Append (mi.Name);
                else {
-                       Type iface;
-                       MethodInfo ifaceMethod;
+                       TypeReference iface;
+                       MethodReference 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) {
+               if (mb.IsGenericMethod ()) {
+                       IList<GenericParameter> typeParams = mb.GenericParameters;
+                       if (typeParams.Count > 0) {
                                sb.Append ("<");
                                sb.Append (typeParams [0].Name);
-                               for (int i = 1; i < typeParams.Length; ++i)
+                               for (int i = 1; i < typeParams.Count; ++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);
+       internal static bool IsPrivate (MemberReference mi)
+       {
+               return memberFormatters [0].GetDeclaration (mi) == null;
        }
 
-       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";
+       internal static string GetMemberType (MemberReference mi)
+       {
+               if (mi is MethodDefinition && ((MethodDefinition) mi).IsConstructor)
+                       return "Constructor";
+               if (mi is MethodDefinition)
+                       return "Method";
+               if (mi is PropertyDefinition)
+                       return "Property";
+               if (mi is FieldDefinition)
+                       return "Field";
+               if (mi is EventDefinition)
+                       return "Event";
                throw new ArgumentException();
        }
 
-       private static string GetDocTypeName (Type type)
+       private static string GetDocTypeName (TypeReference type)
        {
                return docTypeFormatter.GetName (type);
        }
 
-       private static string GetDocTypeFullName (Type type)
-       {
-               return DocTypeFullMemberFormatter.Default.GetName (type);
-       }
-
-       private static string GetCSharpFullName (Type type)
+       internal static string GetDocTypeFullName (TypeReference 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)
+       internal static string GetXPathForMember (DocumentationMember member)
        {
                StringBuilder xpath = new StringBuilder ();
                xpath.Append ("//Members/Member[@MemberName=\"")
@@ -2762,10 +2222,10 @@ class MDocUpdater
        {
                StringBuilder xpath = new StringBuilder ();
                xpath.Append ("//Type[@FullName=\"")
-                       .Append (SelectSingleNode (member, "../../@FullName").Value)
+                       .Append (member.SelectSingleNode ("../../@FullName").Value)
                        .Append ("\"]/");
                xpath.Append ("Members/Member[@MemberName=\"")
-                       .Append (SelectSingleNode (member, "@MemberName").Value)
+                       .Append (member.SelectSingleNode ("@MemberName").Value)
                        .Append ("\"]");
                XPathNodeIterator parameters = member.Select ("Parameters/Parameter");
                if (parameters.Count > 0) {
@@ -2783,7 +2243,7 @@ class MDocUpdater
                return xpath.ToString ();
        }
 
-       public static string GetXPathForMember (MemberInfo member)
+       public static string GetXPathForMember (MemberReference member)
        {
                StringBuilder xpath = new StringBuilder ();
                xpath.Append ("//Type[@FullName=\"")
@@ -2793,16 +2253,16 @@ class MDocUpdater
                        .Append (GetMemberName (member))
                        .Append ("\"]");
 
-               ParameterInfo[] parameters = null;
-               if (member is MethodBase)
-                       parameters = ((MethodBase) member).GetParameters ();
-               else if (member is PropertyInfo) {
-                       parameters = ((PropertyInfo) member).GetIndexParameters ();
+               IList<ParameterDefinition> parameters = null;
+               if (member is MethodDefinition)
+                       parameters = ((MethodDefinition) member).Parameters;
+               else if (member is PropertyDefinition) {
+                       parameters = ((PropertyDefinition) member).Parameters;
                }
-               if (parameters != null && parameters.Length > 0) {
+               if (parameters != null && parameters.Count > 0) {
                        xpath.Append ("/Parameters[count(Parameter) = ")
-                               .Append (parameters.Length);
-                       for (int i = 0; i < parameters.Length; ++i) {
+                               .Append (parameters.Count);
+                       for (int i = 0; i < parameters.Count; ++i) {
                                xpath.Append (" and Parameter [").Append (i+1).Append ("]/@Type=\"");
                                xpath.Append (GetDocParameterType (parameters [i].ParameterType));
                                xpath.Append ("\"");
@@ -2813,80 +2273,135 @@ class MDocUpdater
        }
 }
 
-static class DocUtils {
-       public static bool GetContainsGenericParameters (Type type)
+static class CecilExtensions {
+       public static string GetDeclaringType(this CustomAttribute attribute)
        {
-#if NET_1_0
-               return false;
-#else
-               return type.ContainsGenericParameters;
-#endif
+               return attribute.Constructor.DeclaringType.FullName;
        }
 
-       public static bool GetContainsGenericParameters (MethodBase mb)
+       public static IEnumerable<MemberReference> GetMembers (this TypeDefinition type)
        {
-#if NET_1_0
-               return false;
-#else
-               return mb.ContainsGenericParameters;
-#endif
+               foreach (var c in type.Methods.Where (m => m.IsConstructor))
+                       yield return (MemberReference) c;
+               foreach (var e in type.Events)
+                       yield return (MemberReference) e;
+               foreach (var f in type.Fields)
+                       yield return (MemberReference) f;
+               foreach (var m in type.Methods.Where (m => !m.IsConstructor))
+                       yield return (MemberReference) m;
+               foreach (var t in type.NestedTypes)
+                       yield return (MemberReference) t;
+               foreach (var p in type.Properties)
+                       yield return (MemberReference) p;
        }
 
-       public static Type[] GetGenericArguments (Type type)
+       public static IEnumerable<MemberReference> GetMembers (this TypeDefinition type, string member)
        {
-#if NET_1_0
-               return new Type [0];
-#else
-               return type.GetGenericArguments ();
-#endif
+               return GetMembers (type).Where (m => m.Name == member);
        }
 
-       public static Type[] GetGenericArguments (MethodBase mb)
+       public static MemberReference GetMember (this TypeDefinition type, string member)
        {
-#if NET_1_0
-               return new Type [0];
-#else
-               return mb.GetGenericArguments ();
-#endif
+               return GetMembers (type, member).EnsureZeroOrOne ();
        }
 
-       public static Type GetGenericTypeDefinition (Type type)
+       static T EnsureZeroOrOne<T> (this IEnumerable<T> source)
        {
-#if NET_1_0
-               return null;
-#else
-               return type.GetGenericTypeDefinition ();
-#endif
+               if (source.Count () > 1)
+                       throw new InvalidOperationException ("too many matches");
+               return source.FirstOrDefault ();
        }
 
-       public static Type[] GetGenericParameterConstraints (Type type)
+       public static MethodDefinition GetMethod (this TypeDefinition type, string method)
        {
-#if NET_1_0
-               return null;
-#else
-               return type.GetGenericParameterConstraints ();
-#endif
+               return type.Methods
+                       .Where (m => m.Name == method)
+                       .EnsureZeroOrOne ();
        }
 
-       public static bool IsGenericType (Type type)
+       public static IEnumerable<MemberReference> GetDefaultMembers (this TypeReference type)
        {
-#if NET_1_0
-               return false;
-#else
-               return type.IsGenericType;
-#endif
+               TypeDefinition def = type as TypeDefinition;
+               if (def == null)
+                       return new MemberReference [0];
+               CustomAttribute defMemberAttr = def.CustomAttributes
+                               .FirstOrDefault (c => c.AttributeType.FullName == "System.Reflection.DefaultMemberAttribute");
+               if (defMemberAttr == null)
+                       return new MemberReference [0];
+               string name = (string) defMemberAttr.ConstructorArguments [0].Value;
+               return def.Properties
+                               .Where (p => p.Name == name)
+                               .Select (p => (MemberReference) p);
        }
 
-       public static bool IsGenericParameter (Type type)
+       public static IEnumerable<TypeDefinition> GetTypes (this AssemblyDefinition assembly)
        {
-#if NET_1_0
-               return false;
-#else
-               return type.IsGenericParameter;
-#endif
+               return assembly.Modules.SelectMany (md => md.GetAllTypes ());
+       }
+
+       public static TypeDefinition GetType (this AssemblyDefinition assembly, string type)
+       {
+               return GetTypes (assembly)
+                       .Where (td => td.FullName == type)
+                       .EnsureZeroOrOne ();
+       }
+
+       public static bool IsGenericType (this TypeReference type)
+       {
+               return type.GenericParameters.Count > 0;
+       }
+
+       public static bool IsGenericMethod (this MethodReference method)
+       {
+               return method.GenericParameters.Count > 0;
+       }
+
+       public static MemberReference Resolve (this MemberReference member)
+       {
+               FieldReference fr = member as FieldReference;
+               if (fr != null)
+                       return fr.Resolve ();
+               MethodReference mr = member as MethodReference;
+               if (mr != null)
+                       return mr.Resolve ();
+               TypeReference tr = member as TypeReference;
+               if (tr != null)
+                       return tr.Resolve ();
+               PropertyReference pr = member as PropertyReference;
+               if (pr != null)
+                       return pr;
+               EventReference er = member as EventReference;
+               if (er != null)
+                       return er;
+               throw new NotSupportedException ("Cannot find definition for " + member.ToString ());
+       }
+
+       public static TypeReference GetUnderlyingType (this TypeDefinition type)
+       {
+               if (!type.IsEnum)
+                       return type;
+               return type.Fields.First (f => f.Name == "value__").FieldType;
        }
 
-       public static bool IsExplicitlyImplemented (MethodBase method)
+       public static IEnumerable<TypeDefinition> GetAllTypes (this ModuleDefinition self)
+       {
+               return self.Types.SelectMany (t => t.GetAllTypes ());
+       }
+
+       static IEnumerable<TypeDefinition> GetAllTypes (this TypeDefinition self)
+       {
+               yield return self;
+
+               if (!self.HasNestedTypes)
+                       yield break;
+
+               foreach (var type in self.NestedTypes.SelectMany (t => t.GetAllTypes ()))
+                       yield return type;
+       }
+}
+
+static class DocUtils {
+       public static bool IsExplicitlyImplemented (MethodDefinition method)
        {
                return method.IsPrivate && method.IsFinal && method.IsVirtual;
        }
@@ -2913,50 +2428,47 @@ static class DocUtils {
        }
 
        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)
+                       MethodDefinition method, out TypeReference iface, out MethodReference ifaceMethod)
        {
-#if NET_1_0
-               return (string[]) list.ToArray (typeof(string));
-#else
-               return list.ToArray ();
-#endif
+               iface = null;
+               ifaceMethod = null;
+               if (method.Overrides.Count != 1)
+                       throw new InvalidOperationException ("Could not determine interface type for explicitly-implemented interface member " + method.Name);
+               iface = method.Overrides [0].DeclaringType;
+               ifaceMethod = method.Overrides [0];
        }
 
-       public static string GetPropertyName (PropertyInfo pi)
+       public static string GetPropertyName (PropertyDefinition 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);
+               MethodDefinition method = pi.GetMethod;
                if (method == null)
-                       method = pi.GetSetMethod (true);
+                       method = pi.SetMethod;
                if (!IsExplicitlyImplemented (method))
                        return pi.Name;
 
                // Need to determine appropriate namespace for this member.
-               Type iface;
-               MethodInfo ifaceMethod;
+               TypeReference iface;
+               MethodReference ifaceMethod;
                GetInfoForExplicitlyImplementedMethod (method, out iface, out ifaceMethod);
                return string.Join (".", new string[]{
                                DocTypeFullMemberFormatter.Default.GetName (iface),
                                GetMember (pi.Name)});
        }
 
+       public static string GetNamespace (TypeReference type)
+       {
+               if (type.GetElementType ().IsNested)
+                       type = type.GetElementType ();
+               while (type != null && type.IsNested)
+                       type = type.DeclaringType;
+               if (type == null)
+                       return string.Empty;
+               return type.Namespace;
+       }
+
        public static string PathCombine (string dir, string path)
        {
                if (dir == null)
@@ -2966,47 +2478,764 @@ static class DocUtils {
                return Path.Combine (dir, path);
        }
 
-       public static bool IsExtensionMethod (MethodBase method)
+       public static bool IsExtensionMethod (MethodDefinition 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
+               return
+                       method.CustomAttributes
+                                       .Any (m => m.AttributeType.FullName == "System.Runtime.CompilerServices.ExtensionAttribute")
+                       && method.DeclaringType.CustomAttributes
+                                       .Any (m => m.AttributeType.FullName == "System.Runtime.CompilerServices.ExtensionAttribute");
        }
-}
 
-class DocumentationMember {
-       public StringToStringMap MemberSignatures = new StringToStringMap ();
-       public string ReturnType;
-       public StringList Parameters;
-       public string MemberName;
-       public string MemberType;
+       public static bool IsDelegate (TypeDefinition type)
+       {
+               TypeReference baseRef = type.BaseType;
+               if (baseRef == null)
+                       return false;
+               return !type.IsAbstract && baseRef.FullName == "System.Delegate" || // FIXME
+                               baseRef.FullName == "System.MulticastDelegate";
+       }
 
-       public DocumentationMember (XmlReader reader)
+       public static List<TypeReference> GetDeclaringTypes (TypeReference type)
        {
-               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)
+               List<TypeReference> decls = new List<TypeReference> ();
+               decls.Add (type);
+               while (type.DeclaringType != null) {
+                       decls.Add (type.DeclaringType);
+                       type = type.DeclaringType;
+               }
+               decls.Reverse ();
+               return decls;
+       }
+
+       public static int GetGenericArgumentCount (TypeReference type)
+       {
+               GenericInstanceType inst = type as GenericInstanceType;
+               return inst != null
+                               ? inst.GenericArguments.Count
+                               : type.GenericParameters.Count;
+       }
+
+       public static IEnumerable<TypeReference> GetUserImplementedInterfaces (TypeDefinition type)
+       {
+               HashSet<string> inheritedInterfaces = GetInheritedInterfaces (type);
+               List<TypeReference> userInterfaces = new List<TypeReference> ();
+               foreach (TypeReference iface in type.Interfaces) {
+                       TypeReference lookup = iface.Resolve () ?? iface;
+                       if (!inheritedInterfaces.Contains (GetQualifiedTypeName (lookup)))
+                               userInterfaces.Add (iface);
+               }
+               return userInterfaces;
+       }
+
+       private static string GetQualifiedTypeName (TypeReference type)
+       {
+               return "[" + type.Scope.Name + "]" + type.FullName;
+       }
+
+       private static HashSet<string> GetInheritedInterfaces (TypeDefinition type)
+       {
+               HashSet<string> inheritedInterfaces = new HashSet<string> ();
+               Action<TypeDefinition> a = null;
+               a = t => {
+                       if (t == null) return;
+                       foreach (TypeReference r in t.Interfaces) {
+                               inheritedInterfaces.Add (GetQualifiedTypeName (r));
+                               a (r.Resolve ());
+                       }
+               };
+               TypeReference baseRef = type.BaseType;
+               while (baseRef != null) {
+                       TypeDefinition baseDef = baseRef.Resolve ();
+                       if (baseDef != null) {
+                               a (baseDef);
+                               baseRef = baseDef.BaseType;
+                       }
+                       else
+                               baseRef = null;
+               }
+               foreach (TypeReference r in type.Interfaces)
+                       a (r.Resolve ());
+               return inheritedInterfaces;
+       }
+}
+
+class DocsNodeInfo {
+       public DocsNodeInfo (XmlElement node)
+       {
+               this.Node = node;
+       }
+
+       public DocsNodeInfo (XmlElement node, TypeDefinition type)
+               : this (node)
+       {
+               SetType (type);
+       }
+
+       public DocsNodeInfo (XmlElement node, MemberReference member)
+               : this (node)
+       {
+               SetMemberInfo (member);
+       }
+
+       void SetType (TypeDefinition type)
+       {
+               if (type == null)
+                       throw new ArgumentNullException ("type");
+               Type = type;
+               GenericParameters = new List<GenericParameter> (type.GenericParameters);
+               List<TypeReference> declTypes = DocUtils.GetDeclaringTypes (type);
+               int maxGenArgs = DocUtils.GetGenericArgumentCount (type);
+               for (int i = 0; i < declTypes.Count - 1; ++i) {
+                       int remove = System.Math.Min (maxGenArgs, 
+                                       DocUtils.GetGenericArgumentCount (declTypes [i]));
+                       maxGenArgs -= remove;
+                       while (remove-- > 0)
+                               GenericParameters.RemoveAt (0);
+               }
+               if (DocUtils.IsDelegate (type)) {
+                       Parameters = type.GetMethod("Invoke").Parameters;
+                       ReturnType = type.GetMethod("Invoke").ReturnType;
+                       ReturnIsReturn = true;
+               }
+       }
+
+       void SetMemberInfo (MemberReference member)
+       {
+               if (member == null)
+                       throw new ArgumentNullException ("member");
+               ReturnIsReturn = true;
+               AddRemarks = true;
+               Member = member;
+               
+               if (member is MethodReference ) {
+                       MethodReference mr = (MethodReference) member;
+                       Parameters = mr.Parameters;
+                       if (mr.IsGenericMethod ()) {
+                               GenericParameters = new List<GenericParameter> (mr.GenericParameters);
+                       }
+               }
+               else if (member is PropertyDefinition) {
+                       Parameters = ((PropertyDefinition) member).Parameters;
+               }
+                       
+               if (member is MethodDefinition) {
+                       ReturnType = ((MethodDefinition) member).ReturnType;
+               } else if (member is PropertyDefinition) {
+                       ReturnType = ((PropertyDefinition) member).PropertyType;
+                       ReturnIsReturn = false;
+               }
+
+               // no remarks section for enum members
+               if (member.DeclaringType != null && ((TypeDefinition) member.DeclaringType).IsEnum)
+                       AddRemarks = false;
+       }
+
+       public TypeReference ReturnType;
+       public List<GenericParameter> GenericParameters;
+       public IList<ParameterDefinition> Parameters;
+       public bool ReturnIsReturn;
+       public XmlElement Node;
+       public bool AddRemarks = true;
+       public MemberReference Member;
+       public TypeDefinition Type;
+}
+
+class DocumentationEnumerator {
+
+       public virtual IEnumerable<TypeDefinition> GetDocumentationTypes (AssemblyDefinition assembly, List<string> forTypes)
+       {
+               return GetDocumentationTypes (assembly, forTypes, null);
+       }
+
+       protected IEnumerable<TypeDefinition> GetDocumentationTypes (AssemblyDefinition assembly, List<string> forTypes, HashSet<string> seen)
+       {
+               foreach (TypeDefinition type in assembly.GetTypes()) {
+                       if (forTypes != null && forTypes.BinarySearch (type.FullName) < 0)
+                               continue;
+                       if (seen != null && seen.Contains (type.FullName))
+                               continue;
+                       yield return type;
+                       foreach (TypeDefinition nested in type.NestedTypes)
+                               yield return nested;
+               }
+       }
+
+       public virtual IEnumerable<DocsNodeInfo> GetDocumentationMembers (XmlDocument basefile, TypeDefinition type)
+       {
+               foreach (XmlElement oldmember in basefile.SelectNodes("Type/Members/Member")) {
+                       if (oldmember.GetAttribute ("__monodocer-seen__") == "true") {
+                               oldmember.RemoveAttribute ("__monodocer-seen__");
+                               continue;
+                       }
+                       MemberReference m = GetMember (type, new DocumentationMember (oldmember));
+                       if (m == null) {
+                               yield return new DocsNodeInfo (oldmember);
+                       }
+                       else {
+                               yield return new DocsNodeInfo (oldmember, m);
+                       }
+               }
+       }
+
+       protected static MemberReference GetMember (TypeDefinition 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 (MemberReference mi in GetReflectionMembers (type, docName)) {
+                       if (mi is TypeDefinition) continue;
+                       if (MDocUpdater.GetMemberType(mi) != membertype) continue;
+
+                       if (MDocUpdater.IsPrivate (mi))
+                               continue;
+
+                       IList<ParameterDefinition> pis = null;
+                       string[] typeParams = null;
+                       if (mi is MethodDefinition) {
+                               MethodDefinition mb = (MethodDefinition) mi;
+                               pis = mb.Parameters;
+                               if (docTypeParams != null && mb.IsGenericMethod ()) {
+                                       IList<GenericParameter> args = mb.GenericParameters;
+                                       if (args.Count == docTypeParams.Length) {
+                                               typeParams = args.Select (p => p.Name).ToArray ();
+                                       }
+                               }
+                       }
+                       else if (mi is PropertyDefinition)
+                               pis = ((PropertyDefinition)mi).Parameters;
+                       
+                       int mcount = member.Parameters == null ? 0 : member.Parameters.Count;
+                       int pcount = pis == null ? 0 : pis.Count;
+                       if (mcount != pcount)
+                               continue;
+
+                       MethodDefinition mDef = mi as MethodDefinition;
+                       if (mDef != null && !mDef.IsConstructor) {
+                               // Casting operators can overload based on return type.
+                               if (returntype != GetReplacedString (
+                                                       MDocUpdater.GetDocTypeFullName (((MethodDefinition)mi).ReturnType), 
+                                                       typeParams, docTypeParams)) {
+                                       continue;
+                               }
+                       }
+
+                       if (pcount == 0)
+                               return mi;
+                       bool good = true;
+                       for (int i = 0; i < pis.Count; i++) {
+                               string paramType = GetReplacedString (
+                                       MDocUpdater.GetDocParameterType (pis [i].ParameterType),
+                                       typeParams, docTypeParams);
+                               if (paramType != (string) member.Parameters [i]) {
+                                       good = false;
+                                       break;
+                               }
+                       }
+                       if (!good) continue;
+
+                       return mi;
+               }
+               
+               return null;
+       }
+
+       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 types.ToArray ();
+       }
+
+       protected static IEnumerable<MemberReference> GetReflectionMembers (TypeDefinition 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 (MemberReference mi in type.GetMembers (docName))
+                               yield return mi;
+                       if (CountChars (docName, '.') > 0)
+                               // might be a property; try only type.member instead of
+                               // namespace.type.member.
+                               foreach (MemberReference mi in 
+                                               type.GetMembers (DocUtils.GetTypeDotMember (docName)))
+                                       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 (MemberReference mi in type.GetMembers (refName))
+                       yield return mi;
+
+               // case 4
+               foreach (MemberReference mi in type.GetMembers (refName.Substring (startType + 1)))
+                       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 (MemberReference mi in type.GetMembers ()) {
+                       if (MDocUpdater.GetMemberName (mi) == docName)
+                               yield return mi;
+               }
+       }
+
+       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;
+       }
+
+       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;
+       }
+}
+
+class EcmaDocumentationEnumerator : DocumentationEnumerator {
+
+       XmlReader ecmadocs;
+       MDocUpdater app;
+
+       public EcmaDocumentationEnumerator (MDocUpdater app, XmlReader ecmaDocs)
+       {
+               this.app      = app;
+               this.ecmadocs = ecmaDocs;
+       }
+
+       public override IEnumerable<TypeDefinition> GetDocumentationTypes (AssemblyDefinition assembly, List<string> forTypes)
+       {
+               HashSet<string> seen = new HashSet<string> ();
+               return GetDocumentationTypes (assembly, forTypes, seen)
+                       .Concat (base.GetDocumentationTypes (assembly, forTypes, seen));
+       }
+
+       new IEnumerable<TypeDefinition> GetDocumentationTypes (AssemblyDefinition assembly, List<string> forTypes, HashSet<string> seen)
+       {
+               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 <TypeDefinition/> element?
+                                               continue;
+                                       string typename = ecmadocs.GetAttribute ("FullName");
+                                       string typename2 = MDocUpdater.GetTypeFileName (typename);
+                                       if (forTypes != null && 
+                                                       forTypes.BinarySearch (typename) < 0 &&
+                                                       typename != typename2 &&
+                                                       forTypes.BinarySearch (typename2) < 0)
+                                               continue;
+                                       TypeDefinition t;
+                                       if ((t = assembly.GetType (typename)) == null && 
+                                                       (t = assembly.GetType (typename2)) == null)
+                                               continue;
+                                       seen.Add (typename);
+                                       if (typename != typename2)
+                                               seen.Add (typename2);
+                                       Console.WriteLine ("  Import: {0}", t.FullName);
+                                       if (ecmadocs.Name != "Docs") {
+                                               int depth = ecmadocs.Depth;
+                                               while (ecmadocs.Read ()) {
+                                                       if (ecmadocs.Name == "Docs" && ecmadocs.Depth == depth + 1)
+                                                               break;
+                                               }
+                                       }
+                                       if (!ecmadocs.IsStartElement ("Docs"))
+                                               throw new InvalidOperationException ("Found " + ecmadocs.Name + "; expecting <Docs/>!");
+                                       yield return t;
+                                       break;
+                               }
+                               default:
+                                       break;
+                       }
+               }
+       }
+
+       public override IEnumerable<DocsNodeInfo> GetDocumentationMembers (XmlDocument basefile, TypeDefinition type)
+       {
+               return GetMembers (basefile, type)
+                       .Concat (base.GetDocumentationMembers (basefile, type));
+       }
+
+       private IEnumerable<DocsNodeInfo> GetMembers (XmlDocument basefile, TypeDefinition type)
+       {
+               while (ecmadocs.Name != "Members" && ecmadocs.Read ()) {
+                       // do nothing
+               }
+               if (ecmadocs.IsEmptyElement)
+                       yield break;
+
+               int membersDepth = ecmadocs.Depth;
+               bool go = true;
+               while (go && ecmadocs.Read ()) {
+                       switch (ecmadocs.Name) {
+                               case "Member": {
+                                       if (membersDepth != ecmadocs.Depth - 1 || ecmadocs.NodeType != XmlNodeType.Element)
+                                               continue;
+                                       DocumentationMember dm = new DocumentationMember (ecmadocs);
+                                       string xp = MDocUpdater.GetXPathForMember (dm);
+                                       XmlElement oldmember = (XmlElement) basefile.SelectSingleNode (xp);
+                                       MemberReference m;
+                                       if (oldmember == null) {
+                                               m = GetMember (type, dm);
+                                               if (m == null) {
+                                                       app.Warning ("Could not import ECMA docs for `{0}'s `{1}': Member 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 (MDocUpdater.GetXPathForMember (m));
+                                               if (oldmember == null) {
+                                                       XmlElement members = MDocUpdater.WriteElement (basefile.DocumentElement, "Members");
+                                                       oldmember = basefile.CreateElement ("Member");
+                                                       oldmember.SetAttribute ("MemberName", dm.MemberName);
+                                                       members.AppendChild (oldmember);
+                                                       foreach (string key in MDocUpdater.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}", oldmember.SelectSingleNode("MemberSignature[@Language='C#']/@Value").InnerText);
+                                                       app.additions++;
+                                               }
+                                       }
+                                       else {
+                                               m = GetMember (type, new DocumentationMember (oldmember));
+                                               if (m == null) {
+                                                       app.Warning ("Could not import ECMA docs for `{0}'s `{1}': Member not found.",
+                                                                       type.FullName, dm.MemberSignatures ["C#"]);
+                                                       continue;
+                                               }
+                                               oldmember.SetAttribute ("__monodocer-seen__", "true");
+                                       }
+                                       DocsNodeInfo node = new DocsNodeInfo (oldmember, m);
+                                       if (ecmadocs.Name != "Docs")
+                                               throw new InvalidOperationException ("Found " + ecmadocs.Name + "; expected <Docs/>!");
+                                       yield return node;
+                                       break;
+                               }
+                               case "Members":
+                                       if (membersDepth == ecmadocs.Depth && ecmadocs.NodeType == XmlNodeType.EndElement) {
+                                               go = false;
+                                       }
+                                       break;
+                       }
+               }
+       }
+}
+
+abstract class DocumentationImporter {
+
+       public abstract void ImportDocumentation (DocsNodeInfo info);
+}
+
+class MsxdocDocumentationImporter : DocumentationImporter {
+
+       XmlDocument slashdocs;
+
+       public MsxdocDocumentationImporter (string file)
+       {
+               var xml = File.ReadAllText (file);
+
+               // Ensure Unix line endings
+               xml = xml.Replace ("\r", "");
+
+               slashdocs = new XmlDocument();
+               slashdocs.LoadXml (xml);
+       }
+
+       public override void ImportDocumentation (DocsNodeInfo info)
+       {
+               XmlNode elem = GetDocs (info.Member ?? info.Type);
+
+               if (elem == null)
+                       return;
+
+               XmlElement e = info.Node;
+
+               if (elem.SelectSingleNode("summary") != null)
+                       MDocUpdater.ClearElement(e, "summary");
+               if (elem.SelectSingleNode("remarks") != null)
+                       MDocUpdater.ClearElement(e, "remarks");
+               if (elem.SelectSingleNode ("value") != null || elem.SelectSingleNode ("returns") != null) {
+                       MDocUpdater.ClearElement(e, "value");
+                       MDocUpdater.ClearElement(e, "returns");
+               }
+
+               foreach (XmlNode child in elem.ChildNodes) {
+                       switch (child.Name) {
+                               case "param":
+                               case "typeparam": {
+                                       XmlAttribute name = child.Attributes ["name"];
+                                       if (name == null)
+                                               break;
+                                       XmlElement p2 = (XmlElement) e.SelectSingleNode (child.Name + "[@name='" + name.Value + "']");
+                                       if (p2 != null)
+                                               p2.InnerXml = child.InnerXml;
+                                       break;
+                               }
+                               // Occasionally XML documentation will use <returns/> on
+                               // properties, so let's try to normalize things.
+                               case "value":
+                               case "returns": {
+                                       XmlElement v = e.OwnerDocument.CreateElement (info.ReturnIsReturn ? "returns" : "value");
+                                       v.InnerXml = child.InnerXml;
+                                       e.AppendChild (v);
+                                       break;
+                               }
+                               case "altmember":
+                               case "exception":
+                               case "permission": {
+                                       XmlAttribute cref = child.Attributes ["cref"] ?? child.Attributes ["name"];
+                                       if (cref == null)
+                                               break;
+                                       XmlElement a = (XmlElement) e.SelectSingleNode (child.Name + "[@cref='" + 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": {
+                                       XmlAttribute cref = child.Attributes ["cref"];
+                                       if (cref == null)
+                                               break;
+                                       XmlElement a = (XmlElement) e.SelectSingleNode ("altmember[@cref='" + cref.Value + "']");
+                                       if (a == null) {
+                                               a = e.OwnerDocument.CreateElement ("altmember");
+                                               a.SetAttribute ("cref", child.Attributes ["cref"].Value);
+                                               e.AppendChild (a);
+                                       }
+                                       break;
+                               }
+                               default: {
+                                       bool add = true;
+                                       if (child.NodeType == XmlNodeType.Element && 
+                                                       e.SelectNodes (child.Name).Cast<XmlElement>().Any (n => n.OuterXml == child.OuterXml))
+                                               add = false;
+                                       if (add)
+                                               MDocUpdater.CopyNode (child, e);
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       private XmlNode GetDocs (MemberReference member)
+       {
+               string slashdocsig = MDocUpdater.slashdocFormatter.GetDeclaration (member);
+               if (slashdocsig != null)
+                       return slashdocs.SelectSingleNode ("doc/members/member[@name='" + slashdocsig + "']");
+               return null;
+       }
+}
+
+class EcmaDocumentationImporter : DocumentationImporter {
+
+       XmlReader ecmadocs;
+
+       public EcmaDocumentationImporter (XmlReader ecmaDocs)
+       {
+               this.ecmadocs = ecmaDocs;
+       }
+
+       public override void ImportDocumentation (DocsNodeInfo info)
+       {
+               if (!ecmadocs.IsStartElement ("Docs")) {
+                       return;
+               }
+
+               XmlElement e = info.Node;
+
+               int depth = ecmadocs.Depth;
+               ecmadocs.ReadStartElement ("Docs");
+               while (ecmadocs.Read ()) {
+                       if (ecmadocs.Name == "Docs") {
+                               if (ecmadocs.Depth == depth && ecmadocs.NodeType == XmlNodeType.EndElement)
+                                       break;
+                               else
+                                       throw new InvalidOperationException ("Skipped past current <Docs/> element!");
+                       }
+                       if (!ecmadocs.IsStartElement ())
+                               continue;
+                       switch (ecmadocs.Name) {
+                               case "param":
+                               case "typeparam": {
+                                       string name = ecmadocs.GetAttribute ("name");
+                                       if (name == null)
+                                               break;
+                                       XmlNode doc = e.SelectSingleNode (
+                                                       ecmadocs.Name + "[@name='" + name + "']");
+                                       string value = ecmadocs.ReadInnerXml ();
+                                       if (doc != null)
+                                               doc.InnerXml = value.Replace ("\r", "");
+                                       break;
+                               }
+                               case "altmember":
+                               case "exception":
+                               case "permission":
+                               case "seealso": {
+                                       string name = ecmadocs.Name;
+                                       string cref = ecmadocs.GetAttribute ("cref");
+                                       if (cref == null)
+                                               break;
+                                       XmlNode doc = e.SelectSingleNode (
+                                                       ecmadocs.Name + "[@cref='" + cref + "']");
+                                       string value = ecmadocs.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 = ecmadocs.Name;
+                                       string xpath = ecmadocs.Name;
+                                       StringList attributes = new StringList (ecmadocs.AttributeCount);
+                                       if (ecmadocs.MoveToFirstAttribute ()) {
+                                               do {
+                                                       attributes.Add ("@" + ecmadocs.Name + "=\"" + ecmadocs.Value + "\"");
+                                               } while (ecmadocs.MoveToNextAttribute ());
+                                               ecmadocs.MoveToContent ();
+                                       }
+                                       if (attributes.Count > 0) {
+                                               xpath += "[" + string.Join (" and ", attributes.ToArray ()) + "]";
+                                       }
+                                       XmlNode doc = e.SelectSingleNode (xpath);
+                                       string value = ecmadocs.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;
+                               }
+                       }
+               }
+       }
+}
+
+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":
@@ -3046,82 +3275,126 @@ class DocumentationMember {
        }
 }
 
+public class DynamicParserContext {
+       public ReadOnlyCollection<bool> TransformFlags;
+       public int TransformIndex;
+
+       public DynamicParserContext (ICustomAttributeProvider provider)
+       {
+               CustomAttribute da;
+               if (provider.HasCustomAttributes &&
+                               (da = (provider.CustomAttributes.Cast<CustomAttribute>()
+                                       .SingleOrDefault (ca => ca.GetDeclaringType() == "System.Runtime.CompilerServices.DynamicAttribute"))) != null) {
+                       CustomAttributeArgument[] values = da.ConstructorArguments.Count == 0
+                               ? new CustomAttributeArgument [0]
+                               : (CustomAttributeArgument[]) da.ConstructorArguments [0].Value;
+
+                       TransformFlags = new ReadOnlyCollection<bool> (values.Select (t => (bool) t.Value).ToArray());
+               }
+       }
+}
+
+public enum MemberFormatterState {
+       None,
+       WithinGenericTypeParameters,
+}
+
 public abstract class MemberFormatter {
-       public string GetName (MemberInfo member)
+
+       public virtual string Language {
+               get {return "";}
+       }
+
+       public string GetName (MemberReference member)
+       {
+               return GetName (member, null);
+       }
+
+       public virtual string GetName (MemberReference member, DynamicParserContext context)
        {
-               Type type = member as Type;
+               TypeReference type = member as TypeReference;
                if (type != null)
-                       return GetTypeName (type);
-               ConstructorInfo ctor = member as ConstructorInfo;
-               if (ctor != null)
-                       return GetConstructorName (ctor);
-               MethodInfo method = member as MethodInfo;
+                       return GetTypeName (type, context);
+               MethodReference method  = member as MethodReference;
+               if (method != null && method.Name == ".ctor") // method.IsConstructor
+                       return GetConstructorName (method);
                if (method != null)
                        return GetMethodName (method);
-               PropertyInfo prop = member as PropertyInfo;
+               PropertyReference prop = member as PropertyReference;
                if (prop != null)
                        return GetPropertyName (prop);
-               FieldInfo field = member as FieldInfo;
+               FieldReference field = member as FieldReference;
                if (field != null)
                        return GetFieldName (field);
-               EventInfo e = member as EventInfo;
+               EventReference e = member as EventReference;
                if (e != null)
                        return GetEventName (e);
-               throw new NotSupportedException ("Can't handle: " + member.GetType().ToString());
+               throw new NotSupportedException ("Can't handle: " +
+                                       (member == null ? "null" : member.GetType().ToString()));
+       }
+
+       protected virtual string GetTypeName (TypeReference type)
+       {
+               return GetTypeName (type, null);
        }
 
-       protected virtual string GetTypeName (Type type)
+       protected virtual string GetTypeName (TypeReference type, DynamicParserContext context)
        {
                if (type == null)
                        throw new ArgumentNullException ("type");
-               return _AppendTypeName (new StringBuilder (type.Name.Length), type).ToString ();
+               return _AppendTypeName (new StringBuilder (type.Name.Length), type, context).ToString ();
        }
 
        protected virtual char[] ArrayDelimeters {
                get {return new char[]{'[', ']'};}
        }
 
-       protected StringBuilder _AppendTypeName (StringBuilder buf, Type type)
+       protected virtual MemberFormatterState MemberFormatterState { get; set; }
+
+       protected StringBuilder _AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
-               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 is ArrayType) {
+                       TypeSpecification spec = type as TypeSpecification;
+                       _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType (), context);
+                       return AppendArrayModifiers (buf, (ArrayType) type);
                }
-               if (type.IsByRef) {
-                       return AppendRefTypeName (buf, type);
+               if (type is ByReferenceType) {
+                       return AppendRefTypeName (buf, type, context);
                }
-               if (type.IsPointer) {
-                       return AppendPointerTypeName (buf, type);
+               if (type is PointerType) {
+                       return AppendPointerTypeName (buf, type, context);
                }
                AppendNamespace (buf, type);
-               if (DocUtils.IsGenericParameter (type)) {
-                       return AppendTypeName (buf, type);
+               if (type is GenericParameter) {
+                       return AppendTypeName (buf, type, context);
                }
-               if (!DocUtils.IsGenericType (type)) {
-                       return AppendFullTypeName (buf, type);
+               GenericInstanceType genInst = type as GenericInstanceType;
+               if (type.GenericParameters.Count == 0 &&
+                               (genInst == null ? true : genInst.GenericArguments.Count == 0)) {
+                       return AppendFullTypeName (buf, type, context);
                }
-               return AppendGenericType (buf, type);
+               return AppendGenericType (buf, type, context);
        }
 
-       protected virtual StringBuilder AppendNamespace (StringBuilder buf, Type type)
+       protected virtual StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
        {
-               if (type.Namespace != null && type.Namespace.Length > 0)
-                       buf.Append (type.Namespace).Append ('.');
+               string ns = DocUtils.GetNamespace (type);
+               if (ns != null && ns.Length > 0)
+                       buf.Append (ns).Append ('.');
                return buf;
        }
 
-       private StringBuilder AppendFullTypeName (StringBuilder buf, Type type)
+       protected virtual StringBuilder AppendFullTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                if (type.DeclaringType != null)
-                       AppendFullTypeName (buf, type.DeclaringType).Append (NestedTypeSeparator);
-               return AppendTypeName (buf, type);
+                       AppendFullTypeName (buf, type.DeclaringType, context).Append (NestedTypeSeparator);
+               return AppendTypeName (buf, type, context);
        }
 
-       protected virtual StringBuilder AppendTypeName (StringBuilder buf, Type type)
+       protected virtual StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
+               if (context != null)
+                       context.TransformIndex++;
                return AppendTypeName (buf, type.Name);
        }
 
@@ -3133,214 +3406,774 @@ public abstract class MemberFormatter {
                return buf.Append (typename);
        }
 
+       protected virtual StringBuilder AppendArrayModifiers (StringBuilder buf, ArrayType array)
+       {
+               buf.Append (ArrayDelimeters [0]);
+               int rank = array.Rank;
+               if (rank > 1)
+                       buf.Append (new string (',', rank-1));
+               return buf.Append (ArrayDelimeters [1]);
+       }
+
        protected virtual string RefTypeModifier {
                get {return "@";}
        }
 
-       protected virtual StringBuilder AppendRefTypeName (StringBuilder buf, Type type)
+       protected virtual StringBuilder AppendRefTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
+       {
+               TypeSpecification spec = type as TypeSpecification;
+               return _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType (), context)
+                               .Append (RefTypeModifier);
+       }
+
+       protected virtual string PointerModifier {
+               get {return "*";}
+       }
+
+       protected virtual StringBuilder AppendPointerTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
+       {
+               TypeSpecification spec = type as TypeSpecification;
+               return _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType (), context)
+                               .Append (PointerModifier);
+       }
+
+       protected virtual char[] GenericTypeContainer {
+               get {return new char[]{'<', '>'};}
+       }
+
+       protected virtual char NestedTypeSeparator {
+               get {return '.';}
+       }
+
+       protected virtual StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, DynamicParserContext context)
+       {
+               List<TypeReference> decls = DocUtils.GetDeclaringTypes (
+                               type is GenericInstanceType ? type.GetElementType () : type);
+               List<TypeReference> genArgs = GetGenericArguments (type);
+               int argIdx = 0;
+               int prev = 0;
+               bool insertNested = false;
+               foreach (var decl in decls) {
+                       TypeReference declDef = decl.Resolve () ?? decl;
+                       if (insertNested) {
+                               buf.Append (NestedTypeSeparator);
+                       }
+                       insertNested = true;
+                       AppendTypeName (buf, declDef, context);
+                       int ac = DocUtils.GetGenericArgumentCount (declDef);
+                       int c = ac - prev;
+                       prev = ac;
+                       if (c > 0) {
+                               buf.Append (GenericTypeContainer [0]);
+                               var origState = MemberFormatterState;
+                               MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters;
+                               _AppendTypeName (buf, genArgs [argIdx++], context);
+                               for (int i = 1; i < c; ++i) {
+                                       _AppendTypeName (buf.Append (","), genArgs [argIdx++], context);
+                               }
+                               MemberFormatterState = origState;
+                               buf.Append (GenericTypeContainer [1]);
+                       }
+               }
+               return buf;
+       }
+
+       protected List<TypeReference> GetGenericArguments (TypeReference type)
+       {
+               var args = new List<TypeReference> ();
+               GenericInstanceType inst = type as GenericInstanceType;
+               if (inst != null)
+                       args.AddRange (inst.GenericArguments.Cast<TypeReference> ());
+               else
+                       args.AddRange (type.GenericParameters.Cast<TypeReference> ());
+               return args;
+       }
+
+       protected virtual StringBuilder AppendGenericTypeConstraints (StringBuilder buf, TypeReference type)
+       {
+               return buf;
+       }
+
+       protected virtual string GetConstructorName (MethodReference constructor)
+       {
+               return constructor.Name;
+       }
+
+       protected virtual string GetMethodName (MethodReference method)
+       {
+               return method.Name;
+       }
+
+       protected virtual string GetPropertyName (PropertyReference property)
+       {
+               return property.Name;
+       }
+
+       protected virtual string GetFieldName (FieldReference field)
+       {
+               return field.Name;
+       }
+
+       protected virtual string GetEventName (EventReference e)
+       {
+               return e.Name;
+       }
+
+       public virtual string GetDeclaration (MemberReference member)
+       {
+               if (member == null)
+                       throw new ArgumentNullException ("member");
+               TypeDefinition type = member as TypeDefinition;
+               if (type != null)
+                       return GetTypeDeclaration (type);
+               MethodDefinition method = member as MethodDefinition;
+               if (method != null && method.IsConstructor)
+                       return GetConstructorDeclaration (method);
+               if (method != null)
+                       return GetMethodDeclaration (method);
+               PropertyDefinition prop = member as PropertyDefinition;
+               if (prop != null)
+                       return GetPropertyDeclaration (prop);
+               FieldDefinition field = member as FieldDefinition;
+               if (field != null)
+                       return GetFieldDeclaration (field);
+               EventDefinition e = member as EventDefinition;
+               if (e != null)
+                       return GetEventDeclaration (e);
+               throw new NotSupportedException ("Can't handle: " + member.GetType().ToString());
+       }
+
+       protected virtual string GetTypeDeclaration (TypeDefinition type)
+       {
+               if (type == null)
+                       throw new ArgumentNullException ("type");
+               StringBuilder buf = new StringBuilder (type.Name.Length);
+               _AppendTypeName (buf, type, null);
+               AppendGenericTypeConstraints (buf, type);
+               return buf.ToString ();
+       }
+
+       protected virtual string GetConstructorDeclaration (MethodDefinition constructor)
+       {
+               return GetConstructorName (constructor);
+       }
+
+       protected virtual string GetMethodDeclaration (MethodDefinition method)
+       {
+               if (method.HasCustomAttributes && method.CustomAttributes.Cast<CustomAttribute>().Any(
+                                       ca => ca.GetDeclaringType() == "System.Diagnostics.Contracts.ContractInvariantMethodAttribute"))
+                       return null;
+
+               // Special signature for destructors.
+               if (method.Name == "Finalize" && method.Parameters.Count == 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 (GetTypeName (method.ReturnType, new DynamicParserContext (method.MethodReturnType))).Append (" ");
+
+               AppendMethodName (buf, method);
+               AppendGenericMethod (buf, method).Append (" ");
+               AppendParameters (buf, method, method.Parameters);
+               AppendGenericMethodConstraints (buf, method);
+               return buf.ToString ();
+       }
+
+       protected virtual StringBuilder AppendMethodName (StringBuilder buf, MethodDefinition method)
+       {
+               return buf.Append (method.Name);
+       }
+
+       protected virtual string GetFinalizerName (MethodDefinition method)
+       {
+               return "Finalize";
+       }
+
+       protected virtual StringBuilder AppendVisibility (StringBuilder buf, MethodDefinition method)
+       {
+               return buf;
+       }
+
+       protected virtual StringBuilder AppendModifiers (StringBuilder buf, MethodDefinition method)
+       {
+               return buf;
+       }
+
+       protected virtual StringBuilder AppendGenericMethod (StringBuilder buf, MethodDefinition method)
+       {
+               return buf;
+       }
+
+       protected virtual StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters)
+       {
+               return buf;
+       }
+
+       protected virtual StringBuilder AppendGenericMethodConstraints (StringBuilder buf, MethodDefinition method)
+       {
+               return buf;
+       }
+
+       protected virtual string GetPropertyDeclaration (PropertyDefinition property)
+       {
+               return GetPropertyName (property);
+       }
+
+       protected virtual string GetFieldDeclaration (FieldDefinition field)
+       {
+               return GetFieldName (field);
+       }
+
+       protected virtual string GetEventDeclaration (EventDefinition e)
+       {
+               return GetEventName (e);
+       }
+}
+
+class ILFullMemberFormatter : MemberFormatter {
+
+       public override string Language {
+               get {return "ILAsm";}
+       }
+
+       protected override char NestedTypeSeparator {
+               get {
+                       return '/';
+               }
+       }
+
+       protected override StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
+       {
+               if (GetBuiltinType (type.FullName) != null)
+                       return buf;
+               string ns = DocUtils.GetNamespace (type);
+               if (ns != null && ns.Length > 0) {
+                       if (type.IsValueType)
+                               buf.Append ("valuetype ");
+                       else
+                               buf.Append ("class ");
+                       buf.Append (ns).Append ('.');
+               }
+               return buf;
+       }
+
+       private static string GetBuiltinType (string t)
+       {
+               switch (t) {
+               case "System.Byte":    return "unsigned int8";
+               case "System.SByte":   return "int8";
+               case "System.Int16":   return "int16";
+               case "System.Int32":   return "int32";
+               case "System.Int64":   return "int64";
+               case "System.IntPtr":  return "native int";
+
+               case "System.UInt16":  return "unsigned int16";
+               case "System.UInt32":  return "unsigned int32";
+               case "System.UInt64":  return "unsigned int64";
+               case "System.UIntPtr": return "native unsigned int";
+
+               case "System.Single":  return "float32";
+               case "System.Double":  return "float64";
+               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, string typename)
+       {
+               return buf.Append (typename);
+       }
+
+       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
+       {
+               if (type is GenericParameter) {
+                       AppendGenericParameterConstraints (buf, (GenericParameter) type).Append (type.Name);
+                       return buf;
+               }
+
+               string s = GetBuiltinType (type.FullName);
+               if (s != null) {
+                       return buf.Append (s);
+               }
+               return base.AppendTypeName (buf, type, context);
+       }
+
+       private StringBuilder AppendGenericParameterConstraints (StringBuilder buf, GenericParameter type)
+       {
+               if (MemberFormatterState != MemberFormatterState.WithinGenericTypeParameters) {
+                       return buf.Append (type.Owner is TypeReference ? "!" : "!!");
+               }
+               GenericParameterAttributes attrs = type.Attributes;
+               if ((attrs & GenericParameterAttributes.ReferenceTypeConstraint) != 0)
+                       buf.Append ("class ");
+               if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
+                       buf.Append ("struct ");
+               if ((attrs & GenericParameterAttributes.DefaultConstructorConstraint) != 0)
+                       buf.Append (".ctor ");
+               IList<TypeReference> constraints = type.Constraints;
+               MemberFormatterState = 0;
+               if (constraints.Count > 0) {
+                       var full = new ILFullMemberFormatter ();
+                       buf.Append ("(").Append (full.GetName (constraints [0]));
+                       for (int i = 1; i < constraints.Count; ++i) {
+                               buf.Append (", ").Append (full.GetName (constraints [i]));
+                       }
+                       buf.Append (") ");
+               }
+               MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters;
+
+               if ((attrs & GenericParameterAttributes.Covariant) != 0)
+                       buf.Append ("+ ");
+               if ((attrs & GenericParameterAttributes.Contravariant) != 0)
+                       buf.Append ("- ");
+               return buf;
+       }
+
+       protected override string GetTypeDeclaration (TypeDefinition type)
+       {
+               string visibility = GetTypeVisibility (type.Attributes);
+               if (visibility == null)
+                       return null;
+
+               StringBuilder buf = new StringBuilder ();
+
+               buf.Append (".class ");
+               if (type.IsNested)
+                       buf.Append ("nested ");
+               buf.Append (visibility).Append (" ");
+               if (type.IsInterface)
+                       buf.Append ("interface ");
+               if (type.IsSequentialLayout)
+                       buf.Append ("sequential ");
+               if (type.IsAutoLayout)
+                       buf.Append ("auto ");
+               if (type.IsAnsiClass)
+                       buf.Append ("ansi ");
+               if (type.IsAbstract)
+                       buf.Append ("abstract ");
+               if (type.IsSerializable)
+                       buf.Append ("serializable ");
+               if (type.IsSealed)
+                       buf.Append ("sealed ");
+               if (type.IsBeforeFieldInit)
+                       buf.Append ("beforefieldinit ");
+               var state = MemberFormatterState;
+               MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters;
+               buf.Append (GetName (type));
+               MemberFormatterState = state;
+               var full = new ILFullMemberFormatter ();
+               if (type.BaseType != null) {
+                       buf.Append (" extends ");
+                       if (type.BaseType.FullName == "System.Object")
+                               buf.Append ("System.Object");
+                       else
+                               buf.Append (full.GetName (type.BaseType).Substring ("class ".Length));
+               }
+               bool first = true;
+               foreach (var name in type.Interfaces
+                               .Select (i => full.GetName (i))
+                               .OrderBy (n => n)) {
+                       if (first) {
+                               buf.Append (" implements ");
+                               first = false;
+                       }
+                       else {
+                               buf.Append (", ");
+                       }
+                       buf.Append (name);
+               }
+
+               return buf.ToString ();
+       }
+
+       protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, DynamicParserContext context)
+       {
+               List<TypeReference> decls = DocUtils.GetDeclaringTypes (
+                               type is GenericInstanceType ? type.GetElementType () : type);
+               bool first = true;
+               foreach (var decl in decls) {
+                       TypeReference declDef = decl.Resolve () ?? decl;
+                       if (!first) {
+                               buf.Append (NestedTypeSeparator);
+                       }
+                       first = false;
+                       AppendTypeName (buf, declDef, context);
+               }
+               buf.Append ('<');
+               first = true;
+               foreach (TypeReference arg in GetGenericArguments (type)) {
+                       if (!first)
+                               buf.Append (", ");
+                       first = false;
+                       _AppendTypeName (buf, arg, context);
+               }
+               buf.Append ('>');
+               return buf;
+       }
+
+       static string GetTypeVisibility (TypeAttributes ta)
        {
-               return _AppendTypeName (buf, type.GetElementType ()).Append (RefTypeModifier);
-       }
-
-       protected virtual string PointerModifier {
-               get {return "*";}
-       }
+               switch (ta & TypeAttributes.VisibilityMask) {
+               case TypeAttributes.Public:
+               case TypeAttributes.NestedPublic:
+                       return "public";
 
-       protected virtual StringBuilder AppendPointerTypeName (StringBuilder buf, Type type)
-       {
-               return _AppendTypeName (buf, type.GetElementType ()).Append (PointerModifier);
-       }
+               case TypeAttributes.NestedFamily:
+               case TypeAttributes.NestedFamORAssem:
+                       return "protected";
 
-       protected virtual char[] GenericTypeContainer {
-               get {return new char[]{'<', '>'};}
+               default:
+                       return null;
+               }
        }
 
-       protected virtual char NestedTypeSeparator {
-               get {return '.';}
+       protected override string GetConstructorDeclaration (MethodDefinition constructor)
+       {
+               return GetMethodDeclaration (constructor);
        }
 
-       protected virtual StringBuilder AppendGenericType (StringBuilder buf, Type type)
+       protected override string GetMethodDeclaration (MethodDefinition method)
        {
-               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++]);
+               if (method.IsPrivate && !DocUtils.IsExplicitlyImplemented (method))
+                       return null;
+
+               var buf = new StringBuilder ();
+               buf.Append (".method ");
+               AppendVisibility (buf, method);
+               if (method.IsStatic)
+                       buf.Append ("static ");
+               if (method.IsHideBySig)
+                       buf.Append ("hidebysig ");
+               if (method.IsPInvokeImpl) {
+                       var info = method.PInvokeInfo;
+                       buf.Append ("pinvokeimpl (\"")
+                               .Append (info.Module.Name)
+                               .Append ("\" as \"")
+                               .Append (info.EntryPoint)
+                               .Append ("\"");
+                       if (info.IsCharSetAuto)
+                               buf.Append (" auto");
+                       if (info.IsCharSetUnicode)
+                               buf.Append (" unicode");
+                       if (info.IsCharSetAnsi)
+                               buf.Append (" ansi");
+                       if (info.IsCallConvCdecl)
+                               buf.Append (" cdecl");
+                       if (info.IsCallConvStdCall)
+                               buf.Append (" stdcall");
+                       if (info.IsCallConvWinapi)
+                               buf.Append (" winapi");
+                       if (info.IsCallConvThiscall)
+                               buf.Append (" thiscall");
+                       if (info.SupportsLastError)
+                               buf.Append (" lasterr");
+                       buf.Append (")");
+               }
+               if (method.IsSpecialName)
+                       buf.Append ("specialname ");
+               if (method.IsRuntimeSpecialName)
+                       buf.Append ("rtspecialname ");
+               if (method.IsNewSlot)
+                       buf.Append ("newslot ");
+               if (method.IsVirtual)
+                       buf.Append ("virtual ");
+               if (!method.IsStatic)
+                       buf.Append ("instance ");
+               _AppendTypeName (buf, method.ReturnType, new DynamicParserContext (method.MethodReturnType));
+               buf.Append (' ')
+                       .Append (method.Name);
+               if (method.IsGenericMethod ()) {
+                       var state = MemberFormatterState;
+                       MemberFormatterState = MemberFormatterState.WithinGenericTypeParameters;
+                       IList<GenericParameter> args = method.GenericParameters;
+                       if (args.Count > 0) {
+                               buf.Append ("<");
+                               _AppendTypeName (buf, args [0], null);
+                               for (int i = 1; i < args.Count; ++i)
+                                       _AppendTypeName (buf.Append (", "), args [i], null);
+                               buf.Append (">");
                        }
-                       buf.Append (GenericTypeContainer [1]);
+                       MemberFormatterState = state;
                }
-               return buf;
-       }
 
-       protected virtual StringBuilder AppendGenericTypeConstraints (StringBuilder buf, Type type)
-       {
-               return buf;
+               buf.Append ('(');
+               bool first = true;
+               for (int i = 0; i < method.Parameters.Count; ++i) {
+                       if (!first)
+                               buf.Append (", ");
+                       first = false;
+                       _AppendTypeName (buf, method.Parameters [i].ParameterType, new DynamicParserContext (method.Parameters [i]));
+                       buf.Append (' ');
+                       buf.Append (method.Parameters [i].Name);
+               }
+               buf.Append (')');
+               if (method.IsIL)
+                       buf.Append (" cil");
+               if (method.IsRuntime)
+                       buf.Append (" runtime");
+               if (method.IsManaged)
+                       buf.Append (" managed");
+
+               return buf.ToString ();
        }
 
-       protected virtual string GetConstructorName (ConstructorInfo constructor)
+       protected override StringBuilder AppendMethodName (StringBuilder buf, MethodDefinition method)
        {
-               return constructor.Name;
+               if (DocUtils.IsExplicitlyImplemented (method)) {
+                       TypeReference iface;
+                       MethodReference 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 virtual string GetMethodName (MethodInfo method)
-       {
-               return method.Name;
+       protected override string RefTypeModifier {
+               get {return "";}
        }
 
-       protected virtual string GetPropertyName (PropertyInfo property)
+       protected override StringBuilder AppendVisibility (StringBuilder buf, MethodDefinition method)
        {
-               return property.Name;
+               if (method.IsPublic)
+                       return buf.Append ("public ");
+               if (method.IsFamilyAndAssembly)
+                       return buf.Append ("familyandassembly");
+               if (method.IsFamilyOrAssembly)
+                       return buf.Append ("familyorassembly");
+               if (method.IsFamily)
+                       return buf.Append ("family");
+               return buf;
        }
 
-       protected virtual string GetFieldName (FieldInfo field)
+       protected override StringBuilder AppendModifiers (StringBuilder buf, MethodDefinition method)
        {
-               return field.Name;
+               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";
+               }
+               TypeDefinition declType = (TypeDefinition) method.DeclaringType;
+               if (method.IsAbstract && !declType.IsInterface) modifiers += " abstract";
+               if (method.IsFinal) modifiers += " sealed";
+               if (modifiers == " virtual sealed") modifiers = "";
+
+               return buf.Append (modifiers);
        }
 
-       protected virtual string GetEventName (EventInfo e)
+       protected override StringBuilder AppendGenericMethod (StringBuilder buf, MethodDefinition method)
        {
-               return e.Name;
+               if (method.IsGenericMethod ()) {
+                       IList<GenericParameter> args = method.GenericParameters;
+                       if (args.Count > 0) {
+                               buf.Append ("<");
+                               buf.Append (args [0].Name);
+                               for (int i = 1; i < args.Count; ++i)
+                                       buf.Append (",").Append (args [i].Name);
+                               buf.Append (">");
+                       }
+               }
+               return buf;
        }
 
-       public string GetDeclaration (MemberInfo member)
+       protected override StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters)
        {
-               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());
+               return AppendParameters (buf, method, parameters, '(', ')');
        }
 
-       protected virtual string GetTypeDeclaration (Type type)
+       private StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters, char begin, char end)
        {
-               if (type == null)
-                       throw new ArgumentNullException ("type");
-               StringBuilder buf = new StringBuilder (type.Name.Length);
-               _AppendTypeName (buf, type);
-               AppendGenericTypeConstraints (buf, type);
-               return buf.ToString ();
+               buf.Append (begin);
+
+               if (parameters.Count > 0) {
+                       if (DocUtils.IsExtensionMethod (method))
+                               buf.Append ("this ");
+                       AppendParameter (buf, parameters [0]);
+                       for (int i = 1; i < parameters.Count; ++i) {
+                               buf.Append (", ");
+                               AppendParameter (buf, parameters [i]);
+                       }
+               }
+
+               return buf.Append (end);
        }
 
-       protected virtual string GetConstructorDeclaration (ConstructorInfo constructor)
+       private StringBuilder AppendParameter (StringBuilder buf, ParameterDefinition parameter)
        {
-               return GetConstructorName (constructor);
+               if (parameter.ParameterType is ByReferenceType) {
+                       if (parameter.IsOut)
+                               buf.Append ("out ");
+                       else
+                               buf.Append ("ref ");
+               }
+               buf.Append (GetName (parameter.ParameterType)).Append (" ");
+               return buf.Append (parameter.Name);
        }
 
-       protected virtual string GetMethodDeclaration (MethodInfo method)
+       protected override string GetPropertyDeclaration (PropertyDefinition property)
        {
-               // Special signature for destructors.
-               if (method.Name == "Finalize" && method.GetParameters().Length == 0)
-                       return GetFinalizerName (method);
+               MethodDefinition gm = null, sm = null;
 
-               StringBuilder buf = new StringBuilder ();
+               string get_visible = null;
+               if ((gm = property.GetMethod) != null &&
+                               (DocUtils.IsExplicitlyImplemented (gm) ||
+                                (!gm.IsPrivate && !gm.IsAssembly && !gm.IsFamilyAndAssembly)))
+                       get_visible = AppendVisibility (new StringBuilder (), gm).ToString ();
+               string set_visible = null;
+               if ((sm = property.SetMethod) != null &&
+                               (DocUtils.IsExplicitlyImplemented (sm) ||
+                                (!sm.IsPrivate && !sm.IsAssembly && !sm.IsFamilyAndAssembly)))
+                       set_visible = AppendVisibility (new StringBuilder (), sm).ToString ();
 
-               AppendVisibility (buf, method);
-               if (buf.Length == 0 && 
-                               !(DocUtils.IsExplicitlyImplemented (method) && !method.IsSpecialName))
+               if ((set_visible == null) && (get_visible == null))
                        return null;
 
-               AppendModifiers (buf, method);
+               StringBuilder buf = new StringBuilder ()
+                       .Append (".property ");
+               if (!(gm ?? sm).IsStatic)
+                       buf.Append ("instance ");
+               _AppendTypeName (buf, property.PropertyType, new DynamicParserContext (property));
+               buf.Append (' ').Append (property.Name);
+               if (!property.HasParameters || property.Parameters.Count == 0)
+                       return buf.ToString ();
 
-               if (buf.Length != 0)
-                       buf.Append (" ");
-               buf.Append (GetName (method.ReturnType)).Append (" ");
+               buf.Append ('(');
+               bool first = true;
+               foreach (ParameterDefinition p in property.Parameters) {
+                       if (!first)
+                               buf.Append (", ");
+                       first = false;
+                       _AppendTypeName (buf, p.ParameterType, new DynamicParserContext (p));
+               }
+               buf.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)
+       protected override string GetFieldDeclaration (FieldDefinition field)
        {
-               return buf.Append (method.Name);
-       }
+               TypeDefinition declType = (TypeDefinition) field.DeclaringType;
+               if (declType.IsEnum && field.Name == "value__")
+                       return null; // This member of enums aren't documented.
 
-       protected virtual string GetFinalizerName (MethodInfo method)
-       {
-               return "Finalize";
-       }
+               StringBuilder buf = new StringBuilder ();
+               AppendFieldVisibility (buf, field);
+               if (buf.Length == 0)
+                       return null;
 
-       protected virtual StringBuilder AppendVisibility (StringBuilder buf, MethodBase method)
-       {
-               return buf;
-       }
+               buf.Insert (0, ".field ");
 
-       protected virtual StringBuilder AppendModifiers (StringBuilder buf, MethodInfo method)
-       {
-               return buf;
-       }
+               if (field.IsStatic)
+                       buf.Append ("static ");
+               if (field.IsInitOnly)
+                       buf.Append ("initonly ");
+               if (field.IsLiteral)
+                       buf.Append ("literal ");
+               _AppendTypeName (buf, field.FieldType, new DynamicParserContext (field));
+               buf.Append (' ').Append (field.Name);
+               AppendFieldValue (buf, field);
 
-       protected virtual StringBuilder AppendGenericMethod (StringBuilder buf, MethodInfo method)
-       {
-               return buf;
+               return buf.ToString ();
        }
 
-       protected virtual StringBuilder AppendParameters (StringBuilder buf, MethodBase method, ParameterInfo[] parameters)
+       static StringBuilder AppendFieldVisibility (StringBuilder buf, FieldDefinition field)
        {
+               if (field.IsPublic)
+                       return buf.Append ("public ");
+               if (field.IsFamilyAndAssembly)
+                       return buf.Append ("familyandassembly ");
+               if (field.IsFamilyOrAssembly)
+                       return buf.Append ("familyorassembly ");
+               if (field.IsFamily)
+                       return buf.Append ("family ");
                return buf;
        }
 
-       protected virtual StringBuilder AppendGenericMethodConstraints (StringBuilder buf, MethodInfo method)
+       static StringBuilder AppendFieldValue (StringBuilder buf, FieldDefinition field)
        {
+               // enums have a value__ field, which we ignore
+               if (field.DeclaringType.IsGenericType ())
+                       return buf;
+               if (field.HasConstant && field.IsLiteral) {
+                       object val = null;
+                       try {
+                               val   = field.Constant;
+                       } catch {
+                               return buf;
+                       }
+                       if (val == null)
+                               buf.Append (" = ").Append ("null");
+                       else if (val is Enum)
+                               buf.Append (" = ")
+                                       .Append (GetBuiltinType (field.DeclaringType.GetUnderlyingType ().FullName))
+                                       .Append ('(')
+                                       .Append (val.ToString ())
+                                       .Append (')');
+                       else if (val is IFormattable) {
+                               string value = ((IFormattable)val).ToString();
+                               buf.Append (" = ");
+                               if (val is string)
+                                       buf.Append ("\"" + value + "\"");
+                               else
+                                       buf.Append (GetBuiltinType (field.DeclaringType.GetUnderlyingType ().FullName))
+                                               .Append ('(')
+                                               .Append (value)
+                                               .Append (')');
+                       }
+               }
                return buf;
        }
 
-       protected virtual string GetPropertyDeclaration (PropertyInfo property)
+       protected override string GetEventDeclaration (EventDefinition e)
        {
-               return GetPropertyName (property);
-       }
+               StringBuilder buf = new StringBuilder ();
+               if (AppendVisibility (buf, e.AddMethod).Length == 0) {
+                       return null;
+               }
 
-       protected virtual string GetFieldDeclaration (FieldInfo field)
-       {
-               return GetFieldName (field);
+               buf.Length = 0;
+               buf.Append (".event ")
+                       .Append (GetName (e.EventType))
+                       .Append (' ')
+                       .Append (e.Name);
+
+               return buf.ToString ();
        }
+}
 
-       protected virtual string GetEventDeclaration (EventInfo e)
+class ILMemberFormatter : ILFullMemberFormatter {
+       protected override StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
        {
-               return GetEventName (e);
+               return buf;
        }
 }
 
 class CSharpFullMemberFormatter : MemberFormatter {
 
-       protected override StringBuilder AppendNamespace (StringBuilder buf, Type type)
+       public override string Language {
+               get {return "C#";}
+       }
+
+       protected override StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
        {
-               if (GetCSharpType (type.FullName) == null && type.Namespace != null && type.Namespace.Length > 0 && type.Namespace != "System")
-                       buf.Append (type.Namespace).Append ('.');
+               string ns = DocUtils.GetNamespace (type);
+               if (GetCSharpType (type.FullName) == null && ns != null && ns.Length > 0 && ns != "System")
+                       buf.Append (ns).Append ('.');
                return buf;
        }
 
@@ -3369,23 +4202,46 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return null;
        }
 
-       protected override StringBuilder AppendTypeName (StringBuilder buf, Type type)
+       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
-               if (DocUtils.IsGenericParameter (type))
-                       return buf.Append (type.Name);
+               if (context != null && context.TransformFlags != null &&
+                               (context.TransformFlags.Count == 0 || context.TransformFlags [context.TransformIndex])) {
+                       context.TransformIndex++;
+                       return buf.Append ("dynamic");
+               }
+
+               if (type is GenericParameter)
+                       return AppendGenericParameterConstraints (buf, (GenericParameter) type, context).Append (type.Name);
                string t = type.FullName;
                if (!t.StartsWith ("System.")) {
-                       return base.AppendTypeName (buf, type);
+                       return base.AppendTypeName (buf, type, context);
                }
 
                string s = GetCSharpType (t);
-               if (s != null)
+               if (s != null) {
+                       if (context != null)
+                               context.TransformIndex++;
                        return buf.Append (s);
+               }
                
-               return base.AppendTypeName (buf, type);
+               return base.AppendTypeName (buf, type, context);
        }
 
-       protected override string GetTypeDeclaration (Type type)
+       private StringBuilder AppendGenericParameterConstraints (StringBuilder buf, GenericParameter type, DynamicParserContext context)
+       {
+               if (MemberFormatterState != MemberFormatterState.WithinGenericTypeParameters)
+                       return buf;
+               GenericParameterAttributes attrs = type.Attributes;
+               bool isout = (attrs & GenericParameterAttributes.Covariant) != 0;
+               bool isin  = (attrs & GenericParameterAttributes.Contravariant) != 0;
+               if (isin)
+                       buf.Append ("in ");
+               else if (isout)
+                       buf.Append ("out ");
+               return buf;
+       }
+
+       protected override string GetTypeDeclaration (TypeDefinition type)
        {
                string visibility = GetTypeVisibility (type.Attributes);
                if (visibility == null)
@@ -3398,12 +4254,12 @@ class CSharpFullMemberFormatter : MemberFormatter {
 
                MemberFormatter full = new CSharpFullMemberFormatter ();
 
-               if (IsDelegate(type)) {
+               if (DocUtils.IsDelegate (type)) {
                        buf.Append("delegate ");
-                       MethodInfo invoke = type.GetMethod ("Invoke");
-                       buf.Append (full.GetName (invoke.ReturnType)).Append (" ");
+                       MethodDefinition invoke = type.GetMethod ("Invoke");
+                       buf.Append (full.GetName (invoke.ReturnType, new DynamicParserContext (invoke.MethodReturnType))).Append (" ");
                        buf.Append (GetName (type));
-                       AppendParameters (buf, invoke, invoke.GetParameters ());
+                       AppendParameters (buf, invoke, invoke.Parameters);
                        AppendGenericTypeConstraints (buf, type);
                        buf.Append (";");
 
@@ -3412,7 +4268,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
                
                if (type.IsAbstract && !type.IsInterface)
                        buf.Append("abstract ");
-               if (type.IsSealed && !IsDelegate(type) && !type.IsValueType)
+               if (type.IsSealed && !DocUtils.IsDelegate (type) && !type.IsValueType)
                        buf.Append("sealed ");
                buf.Replace ("abstract sealed", "static");
 
@@ -3423,17 +4279,15 @@ class CSharpFullMemberFormatter : MemberFormatter {
                                : type.Name);
 
                if (!type.IsEnum) {
-                       Type basetype = type.BaseType;
-                       if (basetype == typeof(object) || type.IsValueType) // don't show this in signatures
+                       TypeReference basetype = type.BaseType;
+                       if (basetype != null && basetype.FullName == "System.Object" || type.IsValueType)       // FIXME
                                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 ();
-                       
+
+                       List<string> interface_names = DocUtils.GetUserImplementedInterfaces (type)
+                                       .Select (iface => full.GetName (iface))
+                                       .OrderBy (s => s)
+                                       .ToList ();
+
                        if (basetype != null || interface_names.Count > 0)
                                buf.Append (" : ");
                        
@@ -3454,16 +4308,16 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return buf.ToString ();
        }
 
-       static string GetTypeKind (Type t)
+       static string GetTypeKind (TypeDefinition t)
        {
                if (t.IsEnum)
                        return "enum";
-               if (t.IsClass || t == typeof(System.Enum))
+               if (t.IsValueType)
+                       return "struct";
+               if (t.IsClass || t.FullName == "System.Enum")
                        return "class";
                if (t.IsInterface)
                        return "interface";
-               if (t.IsValueType)
-                       return "struct";
                throw new ArgumentException(t.FullName);
        }
 
@@ -3483,39 +4337,29 @@ class CSharpFullMemberFormatter : MemberFormatter {
                }
        }
 
-       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)
+       protected override StringBuilder AppendGenericTypeConstraints (StringBuilder buf, TypeReference type)
        {
-               if (!DocUtils.GetContainsGenericParameters (type))
+               if (type.GenericParameters.Count == 0)
                        return buf;
-               return AppendConstraints (buf, DocUtils.GetGenericArguments (type));
+               return AppendConstraints (buf, type.GenericParameters);
        }
 
-       private StringBuilder AppendConstraints (StringBuilder buf, Type[] genArgs)
+       private StringBuilder AppendConstraints (StringBuilder buf, IList<GenericParameter> 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)
+               foreach (GenericParameter genArg in genArgs) {
+                       GenericParameterAttributes attrs = genArg.Attributes;
+                       IList<TypeReference> constraints = genArg.Constraints;
+                       if (attrs == GenericParameterAttributes.NonVariant && constraints.Count == 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 && !isvt && !isnew && constraints.Count == 0)
+                               continue;
+                       buf.Append (" where ").Append (genArg.Name).Append (" : ");
                        if (isref) {
                                buf.Append ("class");
                                comma = true;
@@ -3524,11 +4368,11 @@ class CSharpFullMemberFormatter : MemberFormatter {
                                buf.Append ("struct");
                                comma = true;
                        }
-                       if (constraints.Length > 0 && !isvt) {
+                       if (constraints.Count > 0 && !isvt) {
                                if (comma)
                                        buf.Append (", ");
                                buf.Append (GetTypeName (constraints [0]));
-                               for (int i = 1; i < constraints.Length; ++i)
+                               for (int i = 1; i < constraints.Count; ++i)
                                        buf.Append (", ").Append (GetTypeName (constraints [i]));
                        }
                        if (isnew && !isvt) {
@@ -3537,11 +4381,10 @@ class CSharpFullMemberFormatter : MemberFormatter {
                                buf.Append ("new()");
                        }
                }
-#endif
                return buf;
        }
 
-       protected override string GetConstructorDeclaration (ConstructorInfo constructor)
+       protected override string GetConstructorDeclaration (MethodDefinition constructor)
        {
                StringBuilder buf = new StringBuilder ();
                AppendVisibility (buf, constructor);
@@ -3550,13 +4393,13 @@ class CSharpFullMemberFormatter : MemberFormatter {
 
                buf.Append (' ');
                base.AppendTypeName (buf, constructor.DeclaringType.Name).Append (' ');
-               AppendParameters (buf, constructor, constructor.GetParameters ());
+               AppendParameters (buf, constructor, constructor.Parameters);
                buf.Append (';');
 
                return buf.ToString ();
        }
        
-       protected override string GetMethodDeclaration (MethodInfo method)
+       protected override string GetMethodDeclaration (MethodDefinition method)
        {
                string decl = base.GetMethodDeclaration (method);
                if (decl != null)
@@ -3564,11 +4407,11 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return null;
        }
 
-       protected override StringBuilder AppendMethodName (StringBuilder buf, MethodBase method)
+       protected override StringBuilder AppendMethodName (StringBuilder buf, MethodDefinition method)
        {
                if (DocUtils.IsExplicitlyImplemented (method)) {
-                       Type iface;
-                       MethodInfo ifaceMethod;
+                       TypeReference iface;
+                       MethodReference ifaceMethod;
                        DocUtils.GetInfoForExplicitlyImplementedMethod (method, out iface, out ifaceMethod);
                        return buf.Append (new CSharpMemberFormatter ().GetName (iface))
                                .Append ('.')
@@ -3577,23 +4420,23 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return base.AppendMethodName (buf, method);
        }
 
-       protected override StringBuilder AppendGenericMethodConstraints (StringBuilder buf, MethodInfo method)
+       protected override StringBuilder AppendGenericMethodConstraints (StringBuilder buf, MethodDefinition method)
        {
-               if (!DocUtils.GetContainsGenericParameters (method))
+               if (method.GenericParameters.Count == 0)
                        return buf;
-               return AppendConstraints (buf, DocUtils.GetGenericArguments (method));
+               return AppendConstraints (buf, method.GenericParameters);
        }
 
        protected override string RefTypeModifier {
                get {return "";}
        }
 
-       protected override string GetFinalizerName (MethodInfo method)
+       protected override string GetFinalizerName (MethodDefinition method)
        {
                return "~" + method.DeclaringType.Name + " ()"; 
        }
 
-       protected override StringBuilder AppendVisibility (StringBuilder buf, MethodBase method)
+       protected override StringBuilder AppendVisibility (StringBuilder buf, MethodDefinition method)
        {
                if (method == null)
                        return buf;
@@ -3604,7 +4447,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return buf;
        }
 
-       protected override StringBuilder AppendModifiers (StringBuilder buf, MethodInfo method)
+       protected override StringBuilder AppendModifiers (StringBuilder buf, MethodDefinition method)
        {
                string modifiers = String.Empty;
                if (method.IsStatic) modifiers += " static";
@@ -3612,21 +4455,22 @@ class CSharpFullMemberFormatter : MemberFormatter {
                        if ((method.Attributes & MethodAttributes.NewSlot) != 0) modifiers += " virtual";
                        else modifiers += " override";
                }
-               if (method.IsAbstract && !method.DeclaringType.IsInterface) modifiers += " abstract";
+               TypeDefinition declType = (TypeDefinition) method.DeclaringType;
+               if (method.IsAbstract && !declType.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)
+       protected override StringBuilder AppendGenericMethod (StringBuilder buf, MethodDefinition method)
        {
-               if (DocUtils.GetContainsGenericParameters (method)) {
-                       Type[] args = DocUtils.GetGenericArguments (method);
-                       if (args.Length > 0) {
+               if (method.IsGenericMethod ()) {
+                       IList<GenericParameter> args = method.GenericParameters;
+                       if (args.Count > 0) {
                                buf.Append ("<");
                                buf.Append (args [0].Name);
-                               for (int i = 1; i < args.Length; ++i)
+                               for (int i = 1; i < args.Count; ++i)
                                        buf.Append (",").Append (args [i].Name);
                                buf.Append (">");
                        }
@@ -3634,20 +4478,20 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return buf;
        }
 
-       protected override StringBuilder AppendParameters (StringBuilder buf, MethodBase method, ParameterInfo[] parameters)
+       protected override StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters)
        {
                return AppendParameters (buf, method, parameters, '(', ')');
        }
 
-       private StringBuilder AppendParameters (StringBuilder buf, MethodBase method, ParameterInfo[] parameters, char begin, char end)
+       private StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters, char begin, char end)
        {
                buf.Append (begin);
 
-               if (parameters.Length > 0) {
+               if (parameters.Count > 0) {
                        if (DocUtils.IsExtensionMethod (method))
                                buf.Append ("this ");
                        AppendParameter (buf, parameters [0]);
-                       for (int i = 1; i < parameters.Length; ++i) {
+                       for (int i = 1; i < parameters.Count; ++i) {
                                buf.Append (", ");
                                AppendParameter (buf, parameters [i]);
                        }
@@ -3656,29 +4500,33 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return buf.Append (end);
        }
 
-       private StringBuilder AppendParameter (StringBuilder buf, ParameterInfo parameter)
+       private StringBuilder AppendParameter (StringBuilder buf, ParameterDefinition parameter)
        {
-               if (parameter.ParameterType.IsByRef) {
+               if (parameter.ParameterType is ByReferenceType) {
                        if (parameter.IsOut)
                                buf.Append ("out ");
                        else
                                buf.Append ("ref ");
                }
-               buf.Append (GetName (parameter.ParameterType)).Append (" ");
-               return buf.Append (parameter.Name);
+               buf.Append (GetTypeName (parameter.ParameterType, new DynamicParserContext (parameter))).Append (" ");
+               buf.Append (parameter.Name);
+               if (parameter.HasDefault && parameter.IsOptional && parameter.HasConstant) {
+                       buf.AppendFormat (" = {0}", MDocUpdater.MakeAttributesValueString (parameter.Constant, parameter.ParameterType));
+               }
+               return buf;
        }
 
-       protected override string GetPropertyDeclaration (PropertyInfo property)
+       protected override string GetPropertyDeclaration (PropertyDefinition property)
        {
-               MethodInfo method;
+               MethodDefinition method;
 
                string get_visible = null;
-               if ((method = property.GetGetMethod (true)) != null && 
+               if ((method = property.GetMethod) != 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 &&
+               if ((method = property.SetMethod) != null &&
                                (DocUtils.IsExplicitlyImplemented (method) || 
                                 (!method.IsPrivate && !method.IsAssembly && !method.IsFamilyAndAssembly)))
                        set_visible = AppendVisibility (new StringBuilder (), method).ToString ();
@@ -3696,9 +4544,9 @@ class CSharpFullMemberFormatter : MemberFormatter {
                        buf.Append (visibility = "public");
 
                // Pick an accessor to use for static/virtual/override/etc. checks.
-               method = property.GetSetMethod (true);
+               method = property.SetMethod;
                if (method == null)
-                       method = property.GetGetMethod (true);
+                       method = property.GetMethod;
        
                string modifiers = String.Empty;
                if (method.IsStatic) modifiers += " static";
@@ -3708,7 +4556,8 @@ class CSharpFullMemberFormatter : MemberFormatter {
                                else
                                        modifiers += " override";
                }
-               if (method.IsAbstract && !method.DeclaringType.IsInterface)
+               TypeDefinition declDef = (TypeDefinition) method.DeclaringType;
+               if (method.IsAbstract && !declDef.IsInterface)
                        modifiers += " abstract";
                if (method.IsFinal)
                        modifiers += " sealed";
@@ -3716,11 +4565,11 @@ class CSharpFullMemberFormatter : MemberFormatter {
                        modifiers = "";
                buf.Append (modifiers).Append (' ');
 
-               buf.Append (GetName (property.PropertyType)).Append (' ');
-       
-               MemberInfo[] defs = property.DeclaringType.GetDefaultMembers ();
+               buf.Append (GetTypeName (property.PropertyType, new DynamicParserContext (property))).Append (' ');
+
+               IEnumerable<MemberReference> defs = property.DeclaringType.GetDefaultMembers ();
                string name = property.Name;
-               foreach (MemberInfo mi in defs) {
+               foreach (MemberReference mi in defs) {
                        if (mi == property) {
                                name = "this";
                                break;
@@ -3728,29 +4577,30 @@ class CSharpFullMemberFormatter : MemberFormatter {
                }
                buf.Append (name == "this" ? name : DocUtils.GetPropertyName (property));
        
-               if (property.GetIndexParameters ().Length != 0) {
-                       AppendParameters (buf, method, property.GetIndexParameters (), '[', ']');
+               if (property.Parameters.Count != 0) {
+                       AppendParameters (buf, method, property.Parameters, '[', ']');
                }
 
                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;");
                }
+               if (set_visible != null) {
+                       if (set_visible != visibility)
+                               buf.Append (' ').Append (set_visible);
+                       buf.Append (" set;");
+               }
                buf.Append (" }");
        
                return buf [0] != ' ' ? buf.ToString () : buf.ToString (1, buf.Length-1);
        }
 
-       protected override string GetFieldDeclaration (FieldInfo field)
+       protected override string GetFieldDeclaration (FieldDefinition field)
        {
-               if (field.DeclaringType.IsEnum && field.Name == "value__")
+               TypeDefinition declType = (TypeDefinition) field.DeclaringType;
+               if (declType.IsEnum && field.Name == "value__")
                        return null; // This member of enums aren't documented.
 
                StringBuilder buf = new StringBuilder ();
@@ -3758,7 +4608,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
                if (buf.Length == 0)
                        return null;
 
-               if (field.DeclaringType.IsEnum)
+               if (declType.IsEnum)
                        return field.Name;
 
                if (field.IsStatic && !field.IsLiteral)
@@ -3768,7 +4618,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
                if (field.IsLiteral)
                        buf.Append (" const");
 
-               buf.Append (' ').Append (GetName (field.FieldType)).Append (' ');
+               buf.Append (' ').Append (GetTypeName (field.FieldType, new DynamicParserContext (field))).Append (' ');
                buf.Append (field.Name);
                AppendFieldValue (buf, field);
                buf.Append (';');
@@ -3776,7 +4626,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return buf.ToString ();
        }
 
-       static StringBuilder AppendFieldVisibility (StringBuilder buf, FieldInfo field)
+       static StringBuilder AppendFieldVisibility (StringBuilder buf, FieldDefinition field)
        {
                if (field.IsPublic)
                        return buf.Append ("public");
@@ -3785,17 +4635,16 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return buf;
        }
 
-       static StringBuilder AppendFieldValue (StringBuilder buf, FieldInfo field)
+       static StringBuilder AppendFieldValue (StringBuilder buf, FieldDefinition 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))
+               // enums have a value__ field, which we ignore
+               if (((TypeDefinition ) field.DeclaringType).IsEnum || 
+                               field.DeclaringType.IsGenericType ())
                        return buf;
-               if (field.IsLiteral || (field.IsStatic && field.IsInitOnly)) {
+               if (field.HasConstant && field.IsLiteral) {
                        object val = null;
                        try {
-                               val   = field.GetValue (null);
+                               val   = field.Constant;
                        } catch {
                                return buf;
                        }
@@ -3813,17 +4662,17 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return buf;
        }
 
-       protected override string GetEventDeclaration (EventInfo e)
+       protected override string GetEventDeclaration (EventDefinition e)
        {
                StringBuilder buf = new StringBuilder ();
-               if (AppendVisibility (buf, e.GetAddMethod (true)).Length == 0) {
+               if (AppendVisibility (buf, e.AddMethod).Length == 0) {
                        return null;
                }
 
-               AppendModifiers (buf, e.GetAddMethod (true));
+               AppendModifiers (buf, e.AddMethod);
 
                buf.Append (" event ");
-               buf.Append (GetName (e.EventHandlerType)).Append (' ');
+               buf.Append (GetTypeName (e.EventType, new DynamicParserContext (e.AddMethod.Parameters [0]))).Append (' ');
                buf.Append (e.Name).Append (';');
 
                return buf.ToString ();
@@ -3831,7 +4680,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
 }
 
 class CSharpMemberFormatter : CSharpFullMemberFormatter {
-       protected override StringBuilder AppendNamespace (StringBuilder buf, Type type)
+       protected override StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
        {
                return buf;
        }
@@ -3846,7 +4695,7 @@ class DocTypeFullMemberFormatter : MemberFormatter {
 }
 
 class DocTypeMemberFormatter : DocTypeFullMemberFormatter {
-       protected override StringBuilder AppendNamespace (StringBuilder buf, Type type)
+       protected override StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
        {
                return buf;
        }
@@ -3860,21 +4709,16 @@ class SlashDocMemberFormatter : MemberFormatter {
 
        private bool AddTypeCount = true;
 
-       protected override string GetTypeName (Type type)
-       {
-               return base.GetTypeName (type);
-       }
+       private TypeReference genDeclType;
+       private MethodReference genDeclMethod;
 
-       private Type genDeclType;
-       private MethodBase genDeclMethod;
-
-       protected override StringBuilder AppendTypeName (StringBuilder buf, Type type)
+       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
-               if (DocUtils.IsGenericParameter (type)) {
+               if (type is GenericParameter) {
                        int l = buf.Length;
                        if (genDeclType != null) {
-                               Type[] genArgs = DocUtils.GetGenericArguments (genDeclType);
-                               for (int i = 0; i < genArgs.Length; ++i) {
+                               IList<GenericParameter> genArgs = genDeclType.GenericParameters;
+                               for (int i = 0; i < genArgs.Count; ++i) {
                                        if (genArgs [i].Name == type.Name) {
                                                buf.Append ('`').Append (i);
                                                break;
@@ -3882,16 +4726,14 @@ class SlashDocMemberFormatter : MemberFormatter {
                                }
                        }
                        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;
+                               IList<GenericParameter> genArgs = null;
+                               if (genDeclMethod.IsGenericMethod ()) {
+                                       genArgs = genDeclMethod.GenericParameters;
+                                       for (int i = 0; i < genArgs.Count; ++i) {
+                                               if (genArgs [i].Name == type.Name) {
+                                                       buf.Append ("``").Append (i);
+                                                       break;
+                                               }
                                        }
                                }
                        }
@@ -3909,11 +4751,11 @@ class SlashDocMemberFormatter : MemberFormatter {
                        }
                }
                else {
-                       base.AppendTypeName (buf, type);
+                       base.AppendTypeName (buf, type, context);
                        if (AddTypeCount) {
-                               int numArgs = DocUtils.GetGenericArguments (type).Length;
+                               int numArgs = type.GenericParameters.Count;
                                if (type.DeclaringType != null)
-                                       numArgs -= DocUtils.GetGenericArguments (type).Length;
+                                       numArgs -= type.GenericParameters.Count;
                                if (numArgs > 0) {
                                        buf.Append ('`').Append (numArgs);
                                }
@@ -3922,79 +4764,111 @@ class SlashDocMemberFormatter : MemberFormatter {
                return buf;
        }
 
-       protected override StringBuilder AppendGenericType (StringBuilder buf, Type type)
+       protected override StringBuilder AppendArrayModifiers (StringBuilder buf, ArrayType array)
+       {
+               buf.Append (ArrayDelimeters [0]);
+               int rank = array.Rank;
+               if (rank > 1) {
+                       buf.Append ("0:");
+                       for (int i = 1; i < rank; ++i) {
+                               buf.Append (",0:");
+                       }
+               }
+               return buf.Append (ArrayDelimeters [1]);
+       }
+
+       protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                if (!AddTypeCount)
-                       base.AppendGenericType (buf, type);
+                       base.AppendGenericType (buf, type, context);
                else
-                       AppendType (buf, type);
+                       AppendType (buf, type, context);
                return buf;
        }
 
-       private StringBuilder AppendType (StringBuilder buf, Type type)
+       private StringBuilder AppendType (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
-               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);
+               List<TypeReference> decls = DocUtils.GetDeclaringTypes (type);
+               bool insertNested = false;
+               int prevParamCount = 0;
+               foreach (var decl in decls) {
+                       if (insertNested)
+                               buf.Append (NestedTypeSeparator);
+                       insertNested = true;
+                       base.AppendTypeName (buf, decl, context);
+                       int argCount = DocUtils.GetGenericArgumentCount (decl);
+                       int numArgs = argCount - prevParamCount;
+                       prevParamCount = argCount;
+                       if (numArgs > 0)
+                               buf.Append ('`').Append (numArgs);
                }
                return buf;
        }
 
-       protected override string GetConstructorName (ConstructorInfo constructor)
+       public override string GetDeclaration (MemberReference member)
+       {
+               TypeReference r = member as TypeReference;
+               if (r != null) {
+                       return "T:" + GetTypeName (r);
+               }
+               return base.GetDeclaration (member);
+       }
+
+       protected override string GetConstructorName (MethodReference constructor)
        {
-               return GetMethodBaseName (constructor, "#ctor");
+               return GetMethodDefinitionName (constructor, "#ctor");
        }
 
-       protected override string GetMethodName (MethodInfo method)
+       protected override string GetMethodName (MethodReference method)
        {
                string name = null;
-               if (!DocUtils.IsExplicitlyImplemented (method))
+               MethodDefinition methodDef = method as MethodDefinition;
+               if (methodDef == null || !DocUtils.IsExplicitlyImplemented (methodDef))
                        name = method.Name;
                else {
-                       Type iface;
-                       MethodInfo ifaceMethod;
-                       DocUtils.GetInfoForExplicitlyImplementedMethod (method, out iface, out ifaceMethod);
+                       TypeReference iface;
+                       MethodReference ifaceMethod;
+                       DocUtils.GetInfoForExplicitlyImplementedMethod (methodDef, out iface, out ifaceMethod);
                        AddTypeCount = false;
                        name = GetTypeName (iface) + "." + ifaceMethod.Name;
                        AddTypeCount = true;
                }
-               return GetMethodBaseName (method, name);
+               return GetMethodDefinitionName (method, name);
        }
 
-       private string GetMethodBaseName (MethodBase method, string name)
+       private string GetMethodDefinitionName (MethodReference 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;
+               if (method.IsGenericMethod ()) {
+                       IList<GenericParameter> genArgs = method.GenericParameters;
+                       if (genArgs.Count > 0)
+                               buf.Append ("``").Append (genArgs.Count);
+               }
+               IList<ParameterDefinition> parameters = method.Parameters;
+               try {
+                       genDeclType   = method.DeclaringType;
+                       genDeclMethod = method;
+                       AppendParameters (buf, method.DeclaringType.GenericParameters, parameters);
+               }
+               finally {
+                       genDeclType   = null;
+                       genDeclMethod = null;
+               }
                return buf.ToString ();
        }
 
-       private StringBuilder AppendParameters (StringBuilder buf, Type[] genArgs, ParameterInfo[] parameters)
+       private StringBuilder AppendParameters (StringBuilder buf, IList<GenericParameter> genArgs, IList<ParameterDefinition> parameters)
        {
-               if (parameters.Length == 0)
+               if (parameters.Count == 0)
                        return buf;
 
                buf.Append ('(');
 
                AppendParameter (buf, genArgs, parameters [0]);
-               for (int i = 1; i < parameters.Length; ++i) {
+               for (int i = 1; i < parameters.Count; ++i) {
                        buf.Append (',');
                        AppendParameter (buf, genArgs, parameters [i]);
                }
@@ -4002,7 +4876,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                return buf.Append (')');
        }
 
-       private StringBuilder AppendParameter (StringBuilder buf, Type[] genArgs, ParameterInfo parameter)
+       private StringBuilder AppendParameter (StringBuilder buf, IList<GenericParameter> genArgs, ParameterDefinition parameter)
        {
                AddTypeCount = false;
                buf.Append (GetTypeName (parameter.ParameterType));
@@ -4010,18 +4884,19 @@ class SlashDocMemberFormatter : MemberFormatter {
                return buf;
        }
 
-       protected override string GetPropertyName (PropertyInfo property)
+       protected override string GetPropertyName (PropertyReference property)
        {
                string name = null;
 
-               MethodInfo method = property.GetGetMethod (true);
-               if (method == null)
-                       method = property.GetSetMethod (true);
-               if (!DocUtils.IsExplicitlyImplemented (method))
+               PropertyDefinition propertyDef = property as PropertyDefinition;
+               MethodDefinition method = null;
+               if (propertyDef != null)
+                       method = propertyDef.GetMethod ?? propertyDef.SetMethod;
+               if (method != null && !DocUtils.IsExplicitlyImplemented (method))
                        name = property.Name;
                else {
-                       Type iface;
-                       MethodInfo ifaceMethod;
+                       TypeReference iface;
+                       MethodReference ifaceMethod;
                        DocUtils.GetInfoForExplicitlyImplementedMethod (method, out iface, out ifaceMethod);
                        AddTypeCount = false;
                        name = string.Join ("#", new string[]{
@@ -4035,13 +4910,13 @@ class SlashDocMemberFormatter : MemberFormatter {
                buf.Append (GetName (property.DeclaringType));
                buf.Append ('.');
                buf.Append (name);
-               ParameterInfo[] parameters = property.GetIndexParameters ();
-               if (parameters.Length > 0) {
+               IList<ParameterDefinition> parameters = property.Parameters;
+               if (parameters.Count > 0) {
                        genDeclType = property.DeclaringType;
                        buf.Append ('(');
-                       Type[] genArgs = DocUtils.GetGenericArguments (property.DeclaringType);
+                       IList<GenericParameter> genArgs = property.DeclaringType.GenericParameters;
                        AppendParameter (buf, genArgs, parameters [0]);
-                       for (int i = 1; i < parameters.Length; ++i) {
+                       for (int i = 1; i < parameters.Count; ++i) {
                                 buf.Append (',');
                                 AppendParameter (buf, genArgs, parameters [i]);
                        }
@@ -4051,19 +4926,19 @@ class SlashDocMemberFormatter : MemberFormatter {
                return buf.ToString ();
        }
 
-       protected override string GetFieldName (FieldInfo field)
+       protected override string GetFieldName (FieldReference field)
        {
                return string.Format ("{0}.{1}",
                        GetName (field.DeclaringType), field.Name);
        }
 
-       protected override string GetEventName (EventInfo e)
+       protected override string GetEventName (EventReference e)
        {
                return string.Format ("{0}.{1}",
                        GetName (e.DeclaringType), e.Name);
        }
 
-       protected override string GetTypeDeclaration (Type type)
+       protected override string GetTypeDeclaration (TypeDefinition type)
        {
                string name = GetName (type);
                if (type == null)
@@ -4071,7 +4946,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                return "T:" + name;
        }
 
-       protected override string GetConstructorDeclaration (ConstructorInfo constructor)
+       protected override string GetConstructorDeclaration (MethodDefinition constructor)
        {
                string name = GetName (constructor);
                if (name == null)
@@ -4079,7 +4954,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                return "M:" + name;
        }
 
-       protected override string GetMethodDeclaration (MethodInfo method)
+       protected override string GetMethodDeclaration (MethodDefinition method)
        {
                string name = GetName (method);
                if (name == null)
@@ -4094,7 +4969,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                return "M:" + name;
        }
 
-       protected override string GetPropertyDeclaration (PropertyInfo property)
+       protected override string GetPropertyDeclaration (PropertyDefinition property)
        {
                string name = GetName (property);
                if (name == null)
@@ -4102,7 +4977,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                return "P:" + name;
        }
 
-       protected override string GetFieldDeclaration (FieldInfo field)
+       protected override string GetFieldDeclaration (FieldDefinition field)
        {
                string name = GetName (field);
                if (name == null)
@@ -4110,7 +4985,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                return "F:" + name;
        }
 
-       protected override string GetEventDeclaration (EventInfo e)
+       protected override string GetEventDeclaration (EventDefinition e)
        {
                string name = GetName (e);
                if (name == null)
@@ -4120,7 +4995,7 @@ class SlashDocMemberFormatter : MemberFormatter {
 }
 
 class FileNameMemberFormatter : SlashDocMemberFormatter {
-       protected override StringBuilder AppendNamespace (StringBuilder buf, Type type)
+       protected override StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
        {
                return buf;
        }