Merge pull request #495 from nicolas-raoul/fix-for-issue2907-with-no-formatting-changes
[mono.git] / mcs / tools / mdoc / Mono.Documentation / monodocer.cs
index ca02170344ccb05efb3647eab0d53d860dbd72d3..dcb23d2f17c9890b7477423b5c0f73e9717f0598 100644 (file)
@@ -5,6 +5,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Diagnostics;
 using System.Globalization;
 using System.IO;
@@ -42,19 +43,28 @@ class MDocUpdater : MDocCommand
 
        string since;
 
-       static readonly MemberFormatter csharpFullFormatter  = new CSharpFullMemberFormatter ();
-       static readonly MemberFormatter csharpFormatter      = new CSharpMemberFormatter ();
        static readonly MemberFormatter docTypeFormatter     = new DocTypeMemberFormatter ();
        static readonly MemberFormatter filenameFormatter    = new FileNameMemberFormatter ();
 
+       static MemberFormatter[] typeFormatters = new MemberFormatter[]{
+               new CSharpMemberFormatter (),
+               new ILMemberFormatter (),
+       };
+
+       static MemberFormatter[] memberFormatters = new MemberFormatter[]{
+               new CSharpFullMemberFormatter (),
+               new ILFullMemberFormatter (),
+       };
+
        internal static readonly MemberFormatter slashdocFormatter    = new SlashDocMemberFormatter ();
 
        MyXmlNodeList extensionMethods = new MyXmlNodeList ();
 
+       HashSet<string> forwardedTypes = new HashSet<string> ();
+
        public override void Run (IEnumerable<string> args)
        {
                show_exceptions = DebugOutput;
-               string import = null;
                var types = new List<string> ();
                var p = new OptionSet () {
                        { "delete",
@@ -134,6 +144,9 @@ class MDocUpdater : MDocCommand
                
                this.assemblies = assemblies.Select (a => LoadAssembly (a)).ToList ();
 
+               // Store types that have been forwarded to avoid duplicate generation
+               GatherForwardedTypes ();
+
                docEnum = docEnum ?? new DocumentationEnumerator ();
                
                // PERFORM THE UPDATES
@@ -180,6 +193,13 @@ class MDocUpdater : MDocCommand
                }
        }
 
+       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);
+       }
+
        static ExceptionLocations ParseExceptionLocations (string s)
        {
                ExceptionLocations loc = ExceptionLocations.Member;
@@ -206,13 +226,12 @@ class MDocUpdater : MDocCommand
        {
                AssemblyDefinition assembly = null;
                try {
-                       assembly = AssemblyFactory.GetAssembly (name);
+                       assembly = AssemblyDefinition.ReadAssembly (name, new ReaderParameters { AssemblyResolver = assemblyResolver });
                } catch (System.IO.FileNotFoundException) { }
 
                if (assembly == null)
                        throw new InvalidOperationException("Assembly " + name + " not found.");
 
-               assembly.Resolver = assemblyResolver;
                return assembly;
        }
 
@@ -329,15 +348,28 @@ class MDocUpdater : MDocCommand
 
        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)
-                                       found.Add (type.FullName);
+                               if (relpath == null)
+                                       continue;
+
+                               found.Add (type.FullName);
+
+                               if (index == null)
+                                       continue;
+
+                               index.Add (assembly);
+                               index.Add (type);
                        }
                }
 
+               if (index != null)
+                       index.Write ();
+               
                if (ignore_missing_types)
                        return;
 
@@ -346,6 +378,54 @@ class MDocUpdater : MDocCommand
                        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 string DoUpdateType (TypeDefinition type, string basepath, string dest)
        {
                if (type.Namespace == null)
@@ -498,6 +578,33 @@ class MDocUpdater : MDocCommand
                parent.AppendChild(index_assembly);
        }
 
+       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";
@@ -523,7 +630,7 @@ class MDocUpdater : MDocCommand
                index_assemblies.RemoveAll ();
 
 
-               HashSet<string> goodfiles = new HashSet<string> ();
+               HashSet<string> goodfiles = new HashSet<string> (StringComparer.OrdinalIgnoreCase);
 
                foreach (AssemblyDefinition assm in assemblies) {
                        AddIndexAssembly (assm, index_assemblies);
@@ -546,7 +653,7 @@ class MDocUpdater : MDocCommand
        {
                foreach (TypeDefinition type in docEnum.GetDocumentationTypes (assembly, null)) {
                        string typename = GetTypeFileName(type);
-                       if (!IsPublic (type) || typename.IndexOfAny (InvalidFilenameChars) >= 0)
+                       if (!IsPublic (type) || typename.IndexOfAny (InvalidFilenameChars) >= 0 || forwardedTypes.Contains (type.FullName))
                                continue;
 
                        string reltypepath = DoUpdateType (type, source, dest);
@@ -554,25 +661,7 @@ class MDocUpdater : MDocCommand
                                continue;
                        
                        // 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));
+                       AddIndexType (type, index_types);
                                
                        // Ensure the namespace index file exists
                        string onsdoc = DocUtils.PathCombine (dest, type.Namespace + ".xml");
@@ -677,7 +766,8 @@ class MDocUpdater : MDocCommand
        {
                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 = (TypeDefinition) decl.DeclaringType;
@@ -695,7 +785,7 @@ class MDocUpdater : MDocCommand
                                        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.Add (relTypeFile);
@@ -795,8 +885,8 @@ class MDocUpdater : MDocCommand
                        MyXmlNodeList todelete = new MyXmlNodeList ();
                        foreach (DocsNodeInfo info in docEnum.GetDocumentationMembers (basefile, type)) {
                                XmlElement oldmember  = info.Node;
-                               IMemberReference 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.
@@ -805,7 +895,7 @@ class MDocUpdater : MDocCommand
                                
                                // Deleted (or signature changed)
                                if (oldmember2 == null) {
-                                       if (UpdateAssemblyVersions (oldmember, new string[]{ GetAssemblyVersion (type.Module.Assembly) }, false))
+                                       if (!no_assembly_versions && UpdateAssemblyVersions (oldmember, new string[]{ GetAssemblyVersion (type.Module.Assembly) }, false))
                                                continue;
                                        DeleteMember ("Member Removed", output, oldmember, todelete);
                                        continue;
@@ -834,10 +924,10 @@ class MDocUpdater : MDocCommand
                
                if (!DocUtils.IsDelegate (type)) {
                        XmlNode members = WriteElement (basefile.DocumentElement, "Members");
-                       foreach (IMemberReference m in type.GetMembers()) {
+                       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;
                                
@@ -1044,7 +1134,7 @@ class MDocUpdater : MDocCommand
 
        public XmlElement StubType (TypeDefinition type, string output)
        {
-               string typesig = MakeTypeSignature(type);
+               string typesig = typeFormatters [0].GetDeclaration (type);
                if (typesig == null) return null; // not publicly visible
                
                XmlDocument doc = new XmlDocument();
@@ -1070,8 +1160,11 @@ class MDocUpdater : MDocCommand
                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.Module.Assembly.Name.Name);
@@ -1112,12 +1205,12 @@ class MDocUpdater : MDocCommand
                        WriteElementText(root, "Base/BaseTypeName", basetypename);
                        
                        // Document how this type instantiates the generic parameters of its base type
-                       TypeReference origBase = type.BaseType.GetOriginalType ();
+                       TypeReference origBase = type.BaseType.GetElementType ();
                        if (origBase.IsGenericType ()) {
                                ClearElement(basenode, "BaseTypeArguments");
                                GenericInstanceType baseInst             = type.BaseType as GenericInstanceType;
-                               GenericArgumentCollection baseGenArgs    = baseInst == null ? null : baseInst.GenericArguments;
-                               GenericParameterCollection baseGenParams = origBase.GenericParameters;
+                               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++) {
@@ -1167,9 +1260,32 @@ class MDocUpdater : MDocCommand
                if (!DocUtils.IsDelegate (type))
                        WriteElement (root, "Members");
 
+               OrderTypeNodes (root, root.ChildNodes);
                NormalizeWhitespace(root);
        }
 
+       static readonly string[] TypeNodeOrder = {
+               "TypeSignature",
+               "MemberOfLibrary",
+               "AssemblyInfo",
+               "ThreadingSafetyStatement",
+               "ThreadSafetyStatement",
+               "TypeParameters",
+               "Base",
+               "Interfaces",
+               "Attributes",
+               "Parameters",
+               "ReturnValue",
+               "Docs",
+               "Members",
+               "TypeExcluded",
+       };
+
+       static void OrderTypeNodes (XmlNode member, XmlNodeList children)
+       {
+               ReorderNodes (member, children, TypeNodeOrder);
+       }
+
        internal static IEnumerable<T> Sort<T> (IEnumerable<T> list)
        {
                List<T> l = new List<T> (list);
@@ -1180,9 +1296,13 @@ class MDocUpdater : MDocCommand
        private void UpdateMember (DocsNodeInfo info)
        {
                XmlElement me = (XmlElement) info.Node;
-               IMemberReference 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));
                
@@ -1209,10 +1329,52 @@ class MDocUpdater : MDocCommand
                
                info.Node = WriteElement (me, "Docs");
                MakeDocNode (info);
+               OrderMemberNodes (me, me.ChildNodes);
                UpdateExtensionMethods (me, info);
        }
 
-       IEnumerable<string> GetCustomAttributes (IMemberReference mi)
+       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>();
 
@@ -1220,18 +1382,16 @@ class MDocUpdater : MDocCommand
                if (p != null)
                        attrs = attrs.Concat (GetCustomAttributes (p.CustomAttributes, ""));
 
-               PropertyReference pr = mi as PropertyReference;
-               if (pr != null) {
-                       PropertyDefinition pd = pr.Resolve ();
+               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: "));
                }
 
-               EventReference er = mi as EventReference;
-               if (er != null) {
-                       EventDefinition ed = er.Resolve ();
+               EventDefinition ed = mi as EventDefinition;
+               if (ed != null) {
                        if (ed.AddMethod != null)
                                attrs = attrs.Concat (GetCustomAttributes (ed.AddMethod.CustomAttributes, "add: "));
                        if (ed.RemoveMethod != null)
@@ -1241,38 +1401,33 @@ class MDocUpdater : MDocCommand
                return attrs;
        }
 
-       IEnumerable<string> GetCustomAttributes (CustomAttributeCollection attributes, string prefix)
+       IEnumerable<string> GetCustomAttributes (IList<CustomAttribute> attributes, string prefix)
        {
-               foreach (CustomAttribute attribute in attributes.Cast<CustomAttribute> ()
-                               .OrderBy (ca => ca.Constructor.DeclaringType.FullName)) {
-                       if (!attribute.Resolve ()) {
-                               // skip?
-                               Warning ("warning: could not resolve type {0}.",
-                                               attribute.Constructor.DeclaringType.FullName);
-                       }
-                       TypeDefinition attrType = attribute.Constructor.DeclaringType as TypeDefinition;
+               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.Constructor.DeclaringType) == null)
+                       if (slashdocFormatter.GetName (attribute.AttributeType) == null)
                                continue;
                        
-                       if (Array.IndexOf (IgnorableAttributes, attribute.Constructor.DeclaringType.FullName) >= 0)
+                       if (Array.IndexOf (IgnorableAttributes, attribute.AttributeType.FullName) >= 0)
                                continue;
                        
                        StringList fields = new StringList ();
 
-                       ParameterDefinitionCollection parameters = attribute.Constructor.Parameters;
-                       for (int i = 0; i < attribute.ConstructorParameters.Count; ++i) {
+                       for (int i = 0; i < attribute.ConstructorArguments.Count; ++i) {
+                               CustomAttributeArgument argument = attribute.ConstructorArguments [i];
                                fields.Add (MakeAttributesValueString (
-                                               attribute.ConstructorParameters [i],
-                                               parameters [i].ParameterType));
+                                               argument.Value,
+                                               argument.Type));
                        }
                        var namedArgs =
-                               (from de in attribute.Fields.Cast<DictionaryEntry> ()
-                                select new { Type=attribute.GetFieldType (de.Key.ToString ()), Name=de.Key, Value=de.Value })
+                               (from namedArg in attribute.Fields
+                                select new { Type=namedArg.Argument.Type, Name=namedArg.Name, Value=namedArg.Argument.Value })
                                .Concat (
-                                               (from de in attribute.Properties.Cast<DictionaryEntry> ()
-                                                select new { Type=attribute.GetPropertyType (de.Key.ToString ()), Name=de.Key, Value=de.Value }))
+                                               (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, 
@@ -1281,7 +1436,7 @@ class MDocUpdater : MDocCommand
                        string a2 = String.Join(", ", fields.ToArray ());
                        if (a2 != "") a2 = "(" + a2 + ")";
 
-                       string name = attribute.Constructor.DeclaringType.FullName;
+                       string name = attribute.GetDeclaringType();
                        if (name.EndsWith("Attribute")) name = name.Substring(0, name.Length-"Attribute".Length);
                        yield return prefix + name + a2;
                }
@@ -1354,7 +1509,7 @@ class MDocUpdater : MDocCommand
                }
                else {
                        GenericParameter gp = (GenericParameter) info.Parameters [0].ParameterType;
-                       ConstraintCollection constraints = gp.Constraints;
+                       IList<TypeReference> constraints = gp.Constraints;
                        if (constraints.Count == 0)
                                AppendElementAttributeText (targets, "Target", "Type", "System.Object");
                        else
@@ -1461,7 +1616,7 @@ class MDocUpdater : MDocCommand
        private void MakeDocNode (DocsNodeInfo info)
        {
                List<GenericParameter> genericParams      = info.GenericParameters;
-               ParameterDefinitionCollection parameters  = info.Parameters;
+               IList<ParameterDefinition> parameters  = info.Parameters;
                TypeReference returntype                  = info.ReturnType;
                bool returnisreturn         = info.ReturnIsReturn;
                XmlElement e                = info.Node;
@@ -1485,7 +1640,7 @@ class MDocUpdater : MDocCommand
 
                string retnodename = null;
                if (returntype != null && returntype.FullName != "System.Void") { // FIXME
-                       info.ReturnNodeName = retnodename = returnisreturn ? "returns" : "value";
+                       retnodename = returnisreturn ? "returns" : "value";
                        string retnodename_other = !returnisreturn ? "returns" : "value";
                        
                        // If it has a returns node instead of a value node, change its name.
@@ -1524,23 +1679,7 @@ class MDocUpdater : MDocCommand
 
        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);
        }
        
 
@@ -1672,7 +1811,7 @@ class MDocUpdater : MDocCommand
                }
        }
        
-       private void UpdateExceptions (XmlNode docs, IMemberReference member)
+       private void UpdateExceptions (XmlNode docs, MemberReference member)
        {
                foreach (var source in new ExceptionLookup (exceptions.Value)[member]) {
                        string cref = slashdocFormatter.GetDeclaration (source.Exception);
@@ -1703,7 +1842,7 @@ class MDocUpdater : MDocCommand
                                n.ParentNode.RemoveChild(n);
        }
        
-       private static bool UpdateAssemblyVersions (XmlElement root, IMemberReference member, bool add)
+       private static bool UpdateAssemblyVersions (XmlElement root, MemberReference member, bool add)
        {
                TypeDefinition type = member as TypeDefinition;
                if (type == null)
@@ -1765,6 +1904,8 @@ class MDocUpdater : MDocCommand
                "System.Runtime.CompilerServices.UnsafeValueTypeAttribute",
                // extension methods
                "System.Runtime.CompilerServices.ExtensionAttribute",
+               // Used to differentiate 'object' from C#4 'dynamic'
+               "System.Runtime.CompilerServices.DynamicAttribute",
        };
 
        private void MakeAttributes (XmlElement root, IEnumerable<string> attributes)
@@ -1793,7 +1934,7 @@ class MDocUpdater : MDocCommand
                NormalizeWhitespace(e);
        }
 
-       private static string MakeAttributesValueString (object v, TypeReference valueType)
+       public static string MakeAttributesValueString (object v, TypeReference valueType)
        {
                if (v == null)
                        return "null";
@@ -1801,6 +1942,8 @@ class MDocUpdater : MDocCommand
                        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 ();
@@ -1811,13 +1954,12 @@ class MDocUpdater : MDocCommand
                long c = ToInt64 (v);
                if (values.ContainsKey (c))
                        return typename + "." + values [c];
-               if (valueDef.CustomAttributes.Cast<CustomAttribute> ()
-                               .Any (ca => ca.Constructor.DeclaringType.FullName == "System.FlagsAttribute")) {
+               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])
-                                       .ToArray ());
+                                       .DefaultIfEmpty (v.ToString ()).ToArray ());
                }
                return "(" + GetDocTypeFullName (valueType) + ") " + v.ToString ();
        }
@@ -1826,7 +1968,7 @@ class MDocUpdater : MDocCommand
        {
                var values = new Dictionary<long, string> ();
                foreach (var f in 
-                               (from f in type.Fields.Cast<FieldDefinition> ()
+                               (from f in type.Fields
                                 where !(f.IsRuntimeSpecialName || f.IsSpecialName)
                                 select f)) {
                        values [ToInt64 (f.Constant)] = f.Name;
@@ -1841,7 +1983,7 @@ class MDocUpdater : MDocCommand
                return Convert.ToInt64 (value);
        }
        
-       private void MakeParameters (XmlElement root, ParameterDefinitionCollection parameters)
+       private void MakeParameters (XmlElement root, IList<ParameterDefinition> parameters)
        {
                XmlElement e = WriteElement(root, "Parameters");
                e.RemoveAll();
@@ -1850,7 +1992,7 @@ class MDocUpdater : MDocCommand
                        e.AppendChild(pe);
                        pe.SetAttribute("Name", p.Name);
                        pe.SetAttribute("Type", GetDocParameterType (p.ParameterType));
-                       if (p.ParameterType is ReferenceType) {
+                       if (p.ParameterType is ByReferenceType) {
                                if (p.IsOut) pe.SetAttribute("RefType", "out");
                                else pe.SetAttribute("RefType", "ref");
                        }
@@ -1858,7 +2000,7 @@ class MDocUpdater : MDocCommand
                }
        }
        
-       private void MakeTypeParameters (XmlElement root, GenericParameterCollection typeParams)
+       private void MakeTypeParameters (XmlElement root, IList<GenericParameter> typeParams)
        {
                if (typeParams == null || typeParams.Count == 0) {
                        XmlElement f = (XmlElement) root.SelectSingleNode ("TypeParameters");
@@ -1874,7 +2016,7 @@ class MDocUpdater : MDocCommand
                        pe.SetAttribute("Name", t.Name);
                        MakeAttributes (pe, GetCustomAttributes (t.CustomAttributes, ""));
                        XmlElement ce = (XmlElement) e.SelectSingleNode ("Constraints");
-                       ConstraintCollection constraints = t.Constraints;
+                       IList<TypeReference> constraints = t.Constraints;
                        GenericParameterAttributes attrs = t.Attributes;
                        if (attrs == GenericParameterAttributes.NonVariant && constraints.Count == 0) {
                                if (ce != null)
@@ -1906,13 +2048,13 @@ class MDocUpdater : MDocCommand
                }
        }
 
-       private void MakeParameters (XmlElement root, IMemberReference mi)
+       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;
-                       ParameterDefinitionCollection parameters = mb.Parameters;
+                       IList<ParameterDefinition> parameters = mb.Parameters;
                        MakeParameters(root, parameters);
                        if (parameters.Count > 0 && DocUtils.IsExtensionMethod (mb)) {
                                XmlElement p = (XmlElement) root.SelectSingleNode ("Parameters/Parameter[position()=1]");
@@ -1920,7 +2062,7 @@ class MDocUpdater : MDocCommand
                        }
                }
                else if (mi is PropertyDefinition) {
-                       ParameterDefinitionCollection parameters = ((PropertyDefinition)mi).Parameters;
+                       IList<ParameterDefinition> parameters = ((PropertyDefinition)mi).Parameters;
                        if (parameters.Count > 0)
                                MakeParameters(root, parameters);
                        else
@@ -1936,7 +2078,7 @@ class MDocUpdater : MDocCommand
                return GetDocTypeFullName (type).Replace ("@", "&");
        }
 
-       private void MakeReturnValue (XmlElement root, TypeReference type, CustomAttributeCollection attributes) 
+       private void MakeReturnValue (XmlElement root, TypeReference type, IList<CustomAttribute> attributes) 
        {
                XmlElement e = WriteElement(root, "ReturnValue");
                e.RemoveAll();
@@ -1945,12 +2087,12 @@ class MDocUpdater : MDocCommand
                        MakeAttributes(e, GetCustomAttributes (attributes, ""));
        }
        
-       private void MakeReturnValue (XmlElement root, IMemberReference mi)
+       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.ReturnType, ((MethodDefinition)mi).ReturnType.CustomAttributes);
+                       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)
@@ -1963,10 +2105,10 @@ class MDocUpdater : MDocCommand
        
        private XmlElement MakeMember(XmlDocument doc, DocsNodeInfo info)
        {
-               IMemberReference mi = info.Member;
+               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?
@@ -1993,7 +2135,7 @@ class MDocUpdater : MDocCommand
                return me;
        }
 
-       internal static string GetMemberName (IMemberReference mi)
+       internal static string GetMemberName (MemberReference mi)
        {
                MethodDefinition mb = mi as MethodDefinition;
                if (mb == null) {
@@ -2014,7 +2156,7 @@ class MDocUpdater : MDocCommand
                        sb.Append (ifaceMethod.Name);
                }
                if (mb.IsGenericMethod ()) {
-                       GenericParameterCollection typeParams = mb.GenericParameters;
+                       IList<GenericParameter> typeParams = mb.GenericParameters;
                        if (typeParams.Count > 0) {
                                sb.Append ("<");
                                sb.Append (typeParams [0].Name);
@@ -2027,18 +2169,12 @@ class MDocUpdater : MDocCommand
        }
        
        /// SIGNATURE GENERATION FUNCTIONS
-       
-       static string MakeTypeSignature (TypeReference type)
+       internal static bool IsPrivate (MemberReference mi)
        {
-               return csharpFormatter.GetDeclaration (type);
+               return memberFormatters [0].GetDeclaration (mi) == null;
        }
 
-       internal static string MakeMemberSignature (IMemberReference mi)
-       {
-               return csharpFullFormatter.GetDeclaration (mi);
-       }
-
-       internal static string GetMemberType (IMemberReference mi)
+       internal static string GetMemberType (MemberReference mi)
        {
                if (mi is MethodDefinition && ((MethodDefinition) mi).IsConstructor)
                        return "Constructor";
@@ -2107,7 +2243,7 @@ class MDocUpdater : MDocCommand
                return xpath.ToString ();
        }
 
-       public static string GetXPathForMember (IMemberReference member)
+       public static string GetXPathForMember (MemberReference member)
        {
                StringBuilder xpath = new StringBuilder ();
                xpath.Append ("//Type[@FullName=\"")
@@ -2117,7 +2253,7 @@ class MDocUpdater : MDocCommand
                        .Append (GetMemberName (member))
                        .Append ("\"]");
 
-               ParameterDefinitionCollection parameters = null;
+               IList<ParameterDefinition> parameters = null;
                if (member is MethodDefinition)
                        parameters = ((MethodDefinition) member).Parameters;
                else if (member is PropertyDefinition) {
@@ -2138,28 +2274,33 @@ class MDocUpdater : MDocCommand
 }
 
 static class CecilExtensions {
-       public static IEnumerable<IMemberReference> GetMembers (this TypeDefinition type)
+       public static string GetDeclaringType(this CustomAttribute attribute)
        {
-               foreach (var c in type.Constructors)
-                       yield return (IMemberReference) c;
+               return attribute.Constructor.DeclaringType.FullName;
+       }
+
+       public static IEnumerable<MemberReference> GetMembers (this TypeDefinition type)
+       {
+               foreach (var c in type.Methods.Where (m => m.IsConstructor))
+                       yield return (MemberReference) c;
                foreach (var e in type.Events)
-                       yield return (IMemberReference) e;
+                       yield return (MemberReference) e;
                foreach (var f in type.Fields)
-                       yield return (IMemberReference) f;
-               foreach (var m in type.Methods)
-                       yield return (IMemberReference) m;
+                       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 (IMemberReference) t;
+                       yield return (MemberReference) t;
                foreach (var p in type.Properties)
-                       yield return (IMemberReference) p;
+                       yield return (MemberReference) p;
        }
 
-       public static IEnumerable<IMemberReference> GetMembers (this TypeDefinition type, string member)
+       public static IEnumerable<MemberReference> GetMembers (this TypeDefinition type, string member)
        {
                return GetMembers (type).Where (m => m.Name == member);
        }
 
-       public static IMemberReference GetMember (this TypeDefinition type, string member)
+       public static MemberReference GetMember (this TypeDefinition type, string member)
        {
                return GetMembers (type, member).EnsureZeroOrOne ();
        }
@@ -2173,31 +2314,29 @@ static class CecilExtensions {
 
        public static MethodDefinition GetMethod (this TypeDefinition type, string method)
        {
-               return type.Methods.Cast<MethodDefinition> ()
+               return type.Methods
                        .Where (m => m.Name == method)
                        .EnsureZeroOrOne ();
        }
 
-       public static IEnumerable<IMemberReference> GetDefaultMembers (this TypeReference type)
+       public static IEnumerable<MemberReference> GetDefaultMembers (this TypeReference type)
        {
                TypeDefinition def = type as TypeDefinition;
                if (def == null)
-                       return new IMemberReference [0];
-               CustomAttribute defMemberAttr = type.CustomAttributes.Cast<CustomAttribute> ()
-                               .Where (c => c.Constructor.DeclaringType.FullName == "System.Reflection.DefaultMemberAttribute")
-                               .FirstOrDefault ();
+                       return new MemberReference [0];
+               CustomAttribute defMemberAttr = def.CustomAttributes
+                               .FirstOrDefault (c => c.AttributeType.FullName == "System.Reflection.DefaultMemberAttribute");
                if (defMemberAttr == null)
-                       return new IMemberReference [0];
-               string name = (string) defMemberAttr.ConstructorParameters [0];
-               return def.Properties.Cast<PropertyDefinition> ()
+                       return new MemberReference [0];
+               string name = (string) defMemberAttr.ConstructorArguments [0].Value;
+               return def.Properties
                                .Where (p => p.Name == name)
-                               .Select (p => (IMemberReference) p);
+                               .Select (p => (MemberReference) p);
        }
 
        public static IEnumerable<TypeDefinition> GetTypes (this AssemblyDefinition assembly)
        {
-               return assembly.Modules.Cast<ModuleDefinition> ()
-                               .SelectMany (md => md.Types.Cast<TypeDefinition> ());
+               return assembly.Modules.SelectMany (md => md.GetAllTypes ());
        }
 
        public static TypeDefinition GetType (this AssemblyDefinition assembly, string type)
@@ -2217,25 +2356,48 @@ static class CecilExtensions {
                return method.GenericParameters.Count > 0;
        }
 
-       public static IMemberReference Resolve (this IMemberReference member)
+       public static MemberReference Resolve (this MemberReference member)
        {
-               EventReference er = member as EventReference;
-               if (er != null)
-                       return er.Resolve ();
                FieldReference fr = member as FieldReference;
                if (fr != null)
                        return fr.Resolve ();
                MethodReference mr = member as MethodReference;
                if (mr != null)
                        return mr.Resolve ();
-               PropertyReference pr = member as PropertyReference;
-               if (pr != null)
-                       return pr.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 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 {
@@ -2298,8 +2460,8 @@ static class DocUtils {
 
        public static string GetNamespace (TypeReference type)
        {
-               if (type.GetOriginalType ().IsNested)
-                       type = type.GetOriginalType ();
+               if (type.GetElementType ().IsNested)
+                       type = type.GetElementType ();
                while (type != null && type.IsNested)
                        type = type.DeclaringType;
                if (type == null)
@@ -2319,12 +2481,10 @@ static class DocUtils {
        public static bool IsExtensionMethod (MethodDefinition method)
        {
                return
-                       method.CustomAttributes.Cast<CustomAttribute> ()
-                                       .Where (m => m.Constructor.DeclaringType.FullName == "System.Runtime.CompilerServices.ExtensionAttribute")
-                                       .Any () &&
-                       method.DeclaringType.CustomAttributes.Cast<CustomAttribute> ()
-                                       .Where (m => m.Constructor.DeclaringType.FullName == "System.Runtime.CompilerServices.ExtensionAttribute")
-                                       .Any ();
+                       method.CustomAttributes
+                                       .Any (m => m.AttributeType.FullName == "System.Runtime.CompilerServices.ExtensionAttribute")
+                       && method.DeclaringType.CustomAttributes
+                                       .Any (m => m.AttributeType.FullName == "System.Runtime.CompilerServices.ExtensionAttribute");
        }
 
        public static bool IsDelegate (TypeDefinition type)
@@ -2412,7 +2572,7 @@ class DocsNodeInfo {
                SetType (type);
        }
 
-       public DocsNodeInfo (XmlElement node, IMemberReference member)
+       public DocsNodeInfo (XmlElement node, MemberReference member)
                : this (node)
        {
                SetMemberInfo (member);
@@ -2423,7 +2583,7 @@ class DocsNodeInfo {
                if (type == null)
                        throw new ArgumentNullException ("type");
                Type = type;
-               GenericParameters = new List<GenericParameter> (type.GenericParameters.Cast<GenericParameter> ());
+               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) {
@@ -2435,11 +2595,12 @@ class DocsNodeInfo {
                }
                if (DocUtils.IsDelegate (type)) {
                        Parameters = type.GetMethod("Invoke").Parameters;
-                       ReturnType = type.GetMethod("Invoke").ReturnType.ReturnType;
+                       ReturnType = type.GetMethod("Invoke").ReturnType;
+                       ReturnIsReturn = true;
                }
        }
 
-       void SetMemberInfo (IMemberReference member)
+       void SetMemberInfo (MemberReference member)
        {
                if (member == null)
                        throw new ArgumentNullException ("member");
@@ -2451,7 +2612,7 @@ class DocsNodeInfo {
                        MethodReference mr = (MethodReference) member;
                        Parameters = mr.Parameters;
                        if (mr.IsGenericMethod ()) {
-                               GenericParameters = new List<GenericParameter> (mr.GenericParameters.Cast<GenericParameter> ());
+                               GenericParameters = new List<GenericParameter> (mr.GenericParameters);
                        }
                }
                else if (member is PropertyDefinition) {
@@ -2459,7 +2620,7 @@ class DocsNodeInfo {
                }
                        
                if (member is MethodDefinition) {
-                       ReturnType = ((MethodDefinition) member).ReturnType.ReturnType;
+                       ReturnType = ((MethodDefinition) member).ReturnType;
                } else if (member is PropertyDefinition) {
                        ReturnType = ((PropertyDefinition) member).PropertyType;
                        ReturnIsReturn = false;
@@ -2472,13 +2633,12 @@ class DocsNodeInfo {
 
        public TypeReference ReturnType;
        public List<GenericParameter> GenericParameters;
-       public ParameterDefinitionCollection Parameters;
+       public IList<ParameterDefinition> Parameters;
        public bool ReturnIsReturn;
        public XmlElement Node;
        public bool AddRemarks = true;
-       public IMemberReference Member;
+       public MemberReference Member;
        public TypeDefinition Type;
-       public string ReturnNodeName;
 }
 
 class DocumentationEnumerator {
@@ -2508,7 +2668,7 @@ class DocumentationEnumerator {
                                oldmember.RemoveAttribute ("__monodocer-seen__");
                                continue;
                        }
-                       IMemberReference m = GetMember (type, new DocumentationMember (oldmember));
+                       MemberReference m = GetMember (type, new DocumentationMember (oldmember));
                        if (m == null) {
                                yield return new DocsNodeInfo (oldmember);
                        }
@@ -2518,7 +2678,7 @@ class DocumentationEnumerator {
                }
        }
 
-       protected static IMemberReference GetMember (TypeDefinition type, DocumentationMember member)
+       protected static MemberReference GetMember (TypeDefinition type, DocumentationMember member)
        {
                string membertype = member.MemberType;
                
@@ -2528,22 +2688,22 @@ class DocumentationEnumerator {
                string[] docTypeParams = GetTypeParameters (docName);
 
                // Loop through all members in this type with the same name
-               foreach (IMemberReference mi in GetReflectionMembers (type, docName)) {
+               foreach (MemberReference mi in GetReflectionMembers (type, docName)) {
                        if (mi is TypeDefinition) continue;
                        if (MDocUpdater.GetMemberType(mi) != membertype) continue;
 
-                       string sig = MDocUpdater.MakeMemberSignature(mi);
-                       if (sig == null) continue; // not publicly visible
+                       if (MDocUpdater.IsPrivate (mi))
+                               continue;
 
-                       ParameterDefinitionCollection pis = null;
+                       IList<ParameterDefinition> pis = null;
                        string[] typeParams = null;
                        if (mi is MethodDefinition) {
                                MethodDefinition mb = (MethodDefinition) mi;
                                pis = mb.Parameters;
                                if (docTypeParams != null && mb.IsGenericMethod ()) {
-                                       GenericParameterCollection args = mb.GenericParameters;
+                                       IList<GenericParameter> args = mb.GenericParameters;
                                        if (args.Count == docTypeParams.Length) {
-                                               typeParams = args.Cast<GenericParameter> ().Select (p => p.Name).ToArray ();
+                                               typeParams = args.Select (p => p.Name).ToArray ();
                                        }
                                }
                        }
@@ -2559,7 +2719,7 @@ class DocumentationEnumerator {
                        if (mDef != null && !mDef.IsConstructor) {
                                // Casting operators can overload based on return type.
                                if (returntype != GetReplacedString (
-                                                       MDocUpdater.GetDocTypeFullName (((MethodDefinition)mi).ReturnType.ReturnType), 
+                                                       MDocUpdater.GetDocTypeFullName (((MethodDefinition)mi).ReturnType), 
                                                        typeParams, docTypeParams)) {
                                        continue;
                                }
@@ -2605,7 +2765,7 @@ class DocumentationEnumerator {
                return types.ToArray ();
        }
 
-       protected static IEnumerable<IMemberReference> GetReflectionMembers (TypeDefinition type, string docName)
+       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
@@ -2624,12 +2784,12 @@ class DocumentationEnumerator {
                //    this as (1) or (2).
                if (docName.IndexOf ('<') == -1 && docName.IndexOf ('[') == -1) {
                        // Cases 1 & 2
-                       foreach (IMemberReference mi in type.GetMembers (docName))
+                       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 (IMemberReference mi in 
+                               foreach (MemberReference mi in 
                                                type.GetMembers (DocUtils.GetTypeDotMember (docName)))
                                        yield return mi;
                        yield break;
@@ -2663,11 +2823,11 @@ class DocumentationEnumerator {
                }
                string refName = startLt == -1 ? docName : docName.Substring (0, startLt);
                // case 3
-               foreach (IMemberReference mi in type.GetMembers (refName))
+               foreach (MemberReference mi in type.GetMembers (refName))
                        yield return mi;
 
                // case 4
-               foreach (IMemberReference mi in type.GetMembers (refName.Substring (startType + 1)))
+               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:
@@ -2681,7 +2841,7 @@ class DocumentationEnumerator {
                // over all member names, convert them into CSC format, and compare... :-(
                if (numDot == 0)
                        yield break;
-               foreach (IMemberReference mi in type.GetMembers ()) {
+               foreach (MemberReference mi in type.GetMembers ()) {
                        if (MDocUpdater.GetMemberName (mi) == docName)
                                yield return mi;
                }
@@ -2725,7 +2885,7 @@ class EcmaDocumentationEnumerator : DocumentationEnumerator {
                        .Concat (base.GetDocumentationTypes (assembly, forTypes, seen));
        }
 
-       IEnumerable<TypeDefinition> GetDocumentationTypes (AssemblyDefinition assembly, List<string> forTypes, HashSet<string> seen)
+       new IEnumerable<TypeDefinition> GetDocumentationTypes (AssemblyDefinition assembly, List<string> forTypes, HashSet<string> seen)
        {
                int typeDepth = -1;
                while (ecmadocs.Read ()) {
@@ -2794,7 +2954,7 @@ class EcmaDocumentationEnumerator : DocumentationEnumerator {
                                        DocumentationMember dm = new DocumentationMember (ecmadocs);
                                        string xp = MDocUpdater.GetXPathForMember (dm);
                                        XmlElement oldmember = (XmlElement) basefile.SelectSingleNode (xp);
-                                       IMemberReference m;
+                                       MemberReference m;
                                        if (oldmember == null) {
                                                m = GetMember (type, dm);
                                                if (m == null) {
@@ -2818,7 +2978,7 @@ class EcmaDocumentationEnumerator : DocumentationEnumerator {
                                                                oldmember.AppendChild (ms);
                                                        }
                                                        oldmember.SetAttribute ("__monodocer-seen__", "true");
-                                                       Console.WriteLine ("Member Added: {0}", MDocUpdater.MakeMemberSignature (m));
+                                                       Console.WriteLine ("Member Added: {0}", oldmember.SelectSingleNode("MemberSignature[@Language='C#']/@Value").InnerText);
                                                        app.additions++;
                                                }
                                        }
@@ -2901,7 +3061,7 @@ class MsxdocDocumentationImporter : DocumentationImporter {
                                // properties, so let's try to normalize things.
                                case "value":
                                case "returns": {
-                                       XmlElement v = e.OwnerDocument.CreateElement (info.ReturnNodeName ?? child.Name);
+                                       XmlElement v = e.OwnerDocument.CreateElement (info.ReturnIsReturn ? "returns" : "value");
                                        v.InnerXml = child.InnerXml;
                                        e.AppendChild (v);
                                        break;
@@ -2946,7 +3106,7 @@ class MsxdocDocumentationImporter : DocumentationImporter {
                }
        }
 
-       private XmlNode GetDocs (IMemberReference member)
+       private XmlNode GetDocs (MemberReference member)
        {
                string slashdocsig = MDocUpdater.slashdocFormatter.GetDeclaration (member);
                if (slashdocsig != null)
@@ -3115,18 +3275,46 @@ 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,
-       WithinArray,
-       WithinGenericTypeContainer,
+       WithinGenericTypeParameters,
 }
 
 public abstract class MemberFormatter {
-       public virtual string GetName (IMemberReference member)
+
+       public virtual string Language {
+               get {return "";}
+       }
+
+       public string GetName (MemberReference member)
+       {
+               return GetName (member, null);
+       }
+
+       public virtual string GetName (MemberReference member, DynamicParserContext context)
        {
                TypeReference type = member as TypeReference;
                if (type != null)
-                       return GetTypeName (type);
+                       return GetTypeName (type, context);
                MethodReference method  = member as MethodReference;
                if (method != null && method.Name == ".ctor") // method.IsConstructor
                        return GetConstructorName (method);
@@ -3146,10 +3334,15 @@ public abstract class MemberFormatter {
        }
 
        protected virtual string GetTypeName (TypeReference type)
+       {
+               return GetTypeName (type, null);
+       }
+
+       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 {
@@ -3158,37 +3351,29 @@ public abstract class MemberFormatter {
 
        protected virtual MemberFormatterState MemberFormatterState { get; set; }
 
-       protected StringBuilder _AppendTypeName (StringBuilder buf, TypeReference type)
+       protected StringBuilder _AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                if (type is ArrayType) {
                        TypeSpecification spec = type as TypeSpecification;
-                       _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetOriginalType ())
-                                       .Append (ArrayDelimeters [0]);
-                       var origState = MemberFormatterState;
-                       MemberFormatterState = MemberFormatterState.WithinArray;
-                       ArrayType array = (ArrayType) type;
-                       int rank = array.Rank;
-                       if (rank > 1)
-                               buf.Append (new string (',', rank-1));
-                       MemberFormatterState = origState;
-                       return buf.Append (ArrayDelimeters [1]);
-               }
-               if (type is ReferenceType) {
-                       return AppendRefTypeName (buf, type);
+                       _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType (), context);
+                       return AppendArrayModifiers (buf, (ArrayType) type);
+               }
+               if (type is ByReferenceType) {
+                       return AppendRefTypeName (buf, type, context);
                }
                if (type is PointerType) {
-                       return AppendPointerTypeName (buf, type);
+                       return AppendPointerTypeName (buf, type, context);
                }
                AppendNamespace (buf, type);
                if (type is GenericParameter) {
-                       return AppendTypeName (buf, type);
+                       return AppendTypeName (buf, type, context);
                }
                GenericInstanceType genInst = type as GenericInstanceType;
                if (type.GenericParameters.Count == 0 &&
                                (genInst == null ? true : genInst.GenericArguments.Count == 0)) {
-                       return AppendFullTypeName (buf, type);
+                       return AppendFullTypeName (buf, type, context);
                }
-               return AppendGenericType (buf, type);
+               return AppendGenericType (buf, type, context);
        }
 
        protected virtual StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
@@ -3199,15 +3384,17 @@ public abstract class MemberFormatter {
                return buf;
        }
 
-       private StringBuilder AppendFullTypeName (StringBuilder buf, TypeReference 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, TypeReference type)
+       protected virtual StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
+               if (context != null)
+                       context.TransformIndex++;
                return AppendTypeName (buf, type.Name);
        }
 
@@ -3219,14 +3406,23 @@ 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, TypeReference type)
+       protected virtual StringBuilder AppendRefTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                TypeSpecification spec = type as TypeSpecification;
-               return _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetOriginalType ())
+               return _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType (), context)
                                .Append (RefTypeModifier);
        }
 
@@ -3234,10 +3430,10 @@ public abstract class MemberFormatter {
                get {return "*";}
        }
 
-       protected virtual StringBuilder AppendPointerTypeName (StringBuilder buf, TypeReference type)
+       protected virtual StringBuilder AppendPointerTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                TypeSpecification spec = type as TypeSpecification;
-               return _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetOriginalType ())
+               return _AppendTypeName (buf, spec != null ? spec.ElementType : type.GetElementType (), context)
                                .Append (PointerModifier);
        }
 
@@ -3249,10 +3445,10 @@ public abstract class MemberFormatter {
                get {return '.';}
        }
 
-       protected virtual StringBuilder AppendGenericType (StringBuilder buf, TypeReference type)
+       protected virtual StringBuilder AppendGenericType (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                List<TypeReference> decls = DocUtils.GetDeclaringTypes (
-                               type is GenericInstanceType ? type.GetOriginalType () : type);
+                               type is GenericInstanceType ? type.GetElementType () : type);
                List<TypeReference> genArgs = GetGenericArguments (type);
                int argIdx = 0;
                int prev = 0;
@@ -3263,17 +3459,18 @@ public abstract class MemberFormatter {
                                buf.Append (NestedTypeSeparator);
                        }
                        insertNested = true;
-                       AppendTypeName (buf, declDef);
+                       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.WithinGenericTypeContainer;
-                               _AppendTypeName (buf, genArgs [argIdx++]);
-                               for (int i = 1; i < c; ++i)
-                                       _AppendTypeName (buf.Append (","), genArgs [argIdx++]);
+                               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]);
                        }
@@ -3281,7 +3478,7 @@ public abstract class MemberFormatter {
                return buf;
        }
 
-       private List<TypeReference> GetGenericArguments (TypeReference type)
+       protected List<TypeReference> GetGenericArguments (TypeReference type)
        {
                var args = new List<TypeReference> ();
                GenericInstanceType inst = type as GenericInstanceType;
@@ -3322,7 +3519,7 @@ public abstract class MemberFormatter {
                return e.Name;
        }
 
-       public virtual string GetDeclaration (IMemberReference member)
+       public virtual string GetDeclaration (MemberReference member)
        {
                if (member == null)
                        throw new ArgumentNullException ("member");
@@ -3351,7 +3548,7 @@ public abstract class MemberFormatter {
                if (type == null)
                        throw new ArgumentNullException ("type");
                StringBuilder buf = new StringBuilder (type.Name.Length);
-               _AppendTypeName (buf, type);
+               _AppendTypeName (buf, type, null);
                AppendGenericTypeConstraints (buf, type);
                return buf.ToString ();
        }
@@ -3363,6 +3560,10 @@ public abstract class MemberFormatter {
 
        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);
@@ -3378,7 +3579,7 @@ public abstract class MemberFormatter {
 
                if (buf.Length != 0)
                        buf.Append (" ");
-               buf.Append (GetName (method.ReturnType.ReturnType)).Append (" ");
+               buf.Append (GetTypeName (method.ReturnType, new DynamicParserContext (method.MethodReturnType))).Append (" ");
 
                AppendMethodName (buf, method);
                AppendGenericMethod (buf, method).Append (" ");
@@ -3412,7 +3613,7 @@ public abstract class MemberFormatter {
                return buf;
        }
 
-       protected virtual StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, ParameterDefinitionCollection parameters)
+       protected virtual StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters)
        {
                return buf;
        }
@@ -3438,8 +3639,536 @@ public abstract class MemberFormatter {
        }
 }
 
+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)
+       {
+               switch (ta & TypeAttributes.VisibilityMask) {
+               case TypeAttributes.Public:
+               case TypeAttributes.NestedPublic:
+                       return "public";
+
+               case TypeAttributes.NestedFamily:
+               case TypeAttributes.NestedFamORAssem:
+                       return "protected";
+
+               default:
+                       return null;
+               }
+       }
+
+       protected override string GetConstructorDeclaration (MethodDefinition constructor)
+       {
+               return GetMethodDeclaration (constructor);
+       }
+
+       protected override string GetMethodDeclaration (MethodDefinition method)
+       {
+               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 (">");
+                       }
+                       MemberFormatterState = state;
+               }
+
+               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 override StringBuilder AppendMethodName (StringBuilder buf, MethodDefinition method)
+       {
+               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 override string RefTypeModifier {
+               get {return "";}
+       }
+
+       protected override StringBuilder AppendVisibility (StringBuilder buf, MethodDefinition method)
+       {
+               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 override StringBuilder AppendModifiers (StringBuilder buf, MethodDefinition method)
+       {
+               string modifiers = String.Empty;
+               if (method.IsStatic) modifiers += " static";
+               if (method.IsVirtual && !method.IsAbstract) {
+                       if ((method.Attributes & MethodAttributes.NewSlot) != 0) modifiers += " virtual";
+                       else modifiers += " override";
+               }
+               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, MethodDefinition method)
+       {
+               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;
+       }
+
+       protected override StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters)
+       {
+               return AppendParameters (buf, method, parameters, '(', ')');
+       }
+
+       private StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters, char begin, char end)
+       {
+               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);
+       }
+
+       private StringBuilder AppendParameter (StringBuilder buf, ParameterDefinition parameter)
+       {
+               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 override string GetPropertyDeclaration (PropertyDefinition property)
+       {
+               MethodDefinition gm = null, sm = null;
+
+               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 ();
+
+               if ((set_visible == null) && (get_visible == null))
+                       return null;
+
+               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 ();
+
+               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 (')');
+
+               return buf.ToString ();
+       }
+
+       protected override string GetFieldDeclaration (FieldDefinition field)
+       {
+               TypeDefinition declType = (TypeDefinition) field.DeclaringType;
+               if (declType.IsEnum && field.Name == "value__")
+                       return null; // This member of enums aren't documented.
+
+               StringBuilder buf = new StringBuilder ();
+               AppendFieldVisibility (buf, field);
+               if (buf.Length == 0)
+                       return null;
+
+               buf.Insert (0, ".field ");
+
+               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);
+
+               return buf.ToString ();
+       }
+
+       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;
+       }
+
+       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 override string GetEventDeclaration (EventDefinition e)
+       {
+               StringBuilder buf = new StringBuilder ();
+               if (AppendVisibility (buf, e.AddMethod).Length == 0) {
+                       return null;
+               }
+
+               buf.Length = 0;
+               buf.Append (".event ")
+                       .Append (GetName (e.EventType))
+                       .Append (' ')
+                       .Append (e.Name);
+
+               return buf.ToString ();
+       }
+}
+
+class ILMemberFormatter : ILFullMemberFormatter {
+       protected override StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
+       {
+               return buf;
+       }
+}
+
 class CSharpFullMemberFormatter : MemberFormatter {
 
+       public override string Language {
+               get {return "C#";}
+       }
+
        protected override StringBuilder AppendNamespace (StringBuilder buf, TypeReference type)
        {
                string ns = DocUtils.GetNamespace (type);
@@ -3473,25 +4202,34 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return null;
        }
 
-       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type)
+       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
+               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).Append (type.Name);
+                       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);
        }
 
-       private StringBuilder AppendGenericParameterConstraints (StringBuilder buf, GenericParameter type)
+       private StringBuilder AppendGenericParameterConstraints (StringBuilder buf, GenericParameter type, DynamicParserContext context)
        {
-               if (MemberFormatterState != MemberFormatterState.WithinGenericTypeContainer)
+               if (MemberFormatterState != MemberFormatterState.WithinGenericTypeParameters)
                        return buf;
                GenericParameterAttributes attrs = type.Attributes;
                bool isout = (attrs & GenericParameterAttributes.Covariant) != 0;
@@ -3519,7 +4257,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
                if (DocUtils.IsDelegate (type)) {
                        buf.Append("delegate ");
                        MethodDefinition invoke = type.GetMethod ("Invoke");
-                       buf.Append (full.GetName (invoke.ReturnType.ReturnType)).Append (" ");
+                       buf.Append (full.GetName (invoke.ReturnType, new DynamicParserContext (invoke.MethodReturnType))).Append (" ");
                        buf.Append (GetName (type));
                        AppendParameters (buf, invoke, invoke.Parameters);
                        AppendGenericTypeConstraints (buf, type);
@@ -3606,11 +4344,11 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return AppendConstraints (buf, type.GenericParameters);
        }
 
-       private StringBuilder AppendConstraints (StringBuilder buf, GenericParameterCollection genArgs)
+       private StringBuilder AppendConstraints (StringBuilder buf, IList<GenericParameter> genArgs)
        {
                foreach (GenericParameter genArg in genArgs) {
                        GenericParameterAttributes attrs = genArg.Attributes;
-                       ConstraintCollection constraints = genArg.Constraints;
+                       IList<TypeReference> constraints = genArg.Constraints;
                        if (attrs == GenericParameterAttributes.NonVariant && constraints.Count == 0)
                                continue;
 
@@ -3728,7 +4466,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
        protected override StringBuilder AppendGenericMethod (StringBuilder buf, MethodDefinition method)
        {
                if (method.IsGenericMethod ()) {
-                       GenericParameterCollection args = method.GenericParameters;
+                       IList<GenericParameter> args = method.GenericParameters;
                        if (args.Count > 0) {
                                buf.Append ("<");
                                buf.Append (args [0].Name);
@@ -3740,12 +4478,12 @@ class CSharpFullMemberFormatter : MemberFormatter {
                return buf;
        }
 
-       protected override StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, ParameterDefinitionCollection parameters)
+       protected override StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters)
        {
                return AppendParameters (buf, method, parameters, '(', ')');
        }
 
-       private StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, ParameterDefinitionCollection parameters, char begin, char end)
+       private StringBuilder AppendParameters (StringBuilder buf, MethodDefinition method, IList<ParameterDefinition> parameters, char begin, char end)
        {
                buf.Append (begin);
 
@@ -3764,14 +4502,18 @@ class CSharpFullMemberFormatter : MemberFormatter {
 
        private StringBuilder AppendParameter (StringBuilder buf, ParameterDefinition parameter)
        {
-               if (parameter.ParameterType is ReferenceType) {
+               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 (PropertyDefinition property)
@@ -3823,11 +4565,11 @@ class CSharpFullMemberFormatter : MemberFormatter {
                        modifiers = "";
                buf.Append (modifiers).Append (' ');
 
-               buf.Append (GetName (property.PropertyType)).Append (' ');
+               buf.Append (GetTypeName (property.PropertyType, new DynamicParserContext (property))).Append (' ');
 
-               IEnumerable<IMemberReference> defs = property.DeclaringType.GetDefaultMembers ();
+               IEnumerable<MemberReference> defs = property.DeclaringType.GetDefaultMembers ();
                string name = property.Name;
-               foreach (IMemberReference mi in defs) {
+               foreach (MemberReference mi in defs) {
                        if (mi == property) {
                                name = "this";
                                break;
@@ -3840,16 +4582,16 @@ class CSharpFullMemberFormatter : MemberFormatter {
                }
 
                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);
@@ -3876,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 (';');
@@ -3930,7 +4672,7 @@ class CSharpFullMemberFormatter : MemberFormatter {
                AppendModifiers (buf, e.AddMethod);
 
                buf.Append (" event ");
-               buf.Append (GetName (e.EventType)).Append (' ');
+               buf.Append (GetTypeName (e.EventType, new DynamicParserContext (e.AddMethod.Parameters [0]))).Append (' ');
                buf.Append (e.Name).Append (';');
 
                return buf.ToString ();
@@ -3970,12 +4712,12 @@ class SlashDocMemberFormatter : MemberFormatter {
        private TypeReference genDeclType;
        private MethodReference genDeclMethod;
 
-       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type)
+       protected override StringBuilder AppendTypeName (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                if (type is GenericParameter) {
                        int l = buf.Length;
                        if (genDeclType != null) {
-                               GenericParameterCollection genArgs = genDeclType.GenericParameters;
+                               IList<GenericParameter> genArgs = genDeclType.GenericParameters;
                                for (int i = 0; i < genArgs.Count; ++i) {
                                        if (genArgs [i].Name == type.Name) {
                                                buf.Append ('`').Append (i);
@@ -3984,7 +4726,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                                }
                        }
                        if (genDeclMethod != null) {
-                               GenericParameterCollection genArgs = null;
+                               IList<GenericParameter> genArgs = null;
                                if (genDeclMethod.IsGenericMethod ()) {
                                        genArgs = genDeclMethod.GenericParameters;
                                        for (int i = 0; i < genArgs.Count; ++i) {
@@ -4009,7 +4751,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                        }
                }
                else {
-                       base.AppendTypeName (buf, type);
+                       base.AppendTypeName (buf, type, context);
                        if (AddTypeCount) {
                                int numArgs = type.GenericParameters.Count;
                                if (type.DeclaringType != null)
@@ -4022,16 +4764,29 @@ class SlashDocMemberFormatter : MemberFormatter {
                return buf;
        }
 
-       protected override StringBuilder AppendGenericType (StringBuilder buf, TypeReference 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, TypeReference type)
+       private StringBuilder AppendType (StringBuilder buf, TypeReference type, DynamicParserContext context)
        {
                List<TypeReference> decls = DocUtils.GetDeclaringTypes (type);
                bool insertNested = false;
@@ -4040,7 +4795,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                        if (insertNested)
                                buf.Append (NestedTypeSeparator);
                        insertNested = true;
-                       base.AppendTypeName (buf, decl);
+                       base.AppendTypeName (buf, decl, context);
                        int argCount = DocUtils.GetGenericArgumentCount (decl);
                        int numArgs = argCount - prevParamCount;
                        prevParamCount = argCount;
@@ -4050,7 +4805,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                return buf;
        }
 
-       public override string GetDeclaration (IMemberReference member)
+       public override string GetDeclaration (MemberReference member)
        {
                TypeReference r = member as TypeReference;
                if (r != null) {
@@ -4088,11 +4843,11 @@ class SlashDocMemberFormatter : MemberFormatter {
                buf.Append ('.');
                buf.Append (name.Replace (".", "#"));
                if (method.IsGenericMethod ()) {
-                       GenericParameterCollection genArgs = method.GenericParameters;
+                       IList<GenericParameter> genArgs = method.GenericParameters;
                        if (genArgs.Count > 0)
                                buf.Append ("``").Append (genArgs.Count);
                }
-               ParameterDefinitionCollection parameters = method.Parameters;
+               IList<ParameterDefinition> parameters = method.Parameters;
                try {
                        genDeclType   = method.DeclaringType;
                        genDeclMethod = method;
@@ -4105,7 +4860,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                return buf.ToString ();
        }
 
-       private StringBuilder AppendParameters (StringBuilder buf, GenericParameterCollection genArgs, ParameterDefinitionCollection parameters)
+       private StringBuilder AppendParameters (StringBuilder buf, IList<GenericParameter> genArgs, IList<ParameterDefinition> parameters)
        {
                if (parameters.Count == 0)
                        return buf;
@@ -4121,7 +4876,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                return buf.Append (')');
        }
 
-       private StringBuilder AppendParameter (StringBuilder buf, GenericParameterCollection genArgs, ParameterDefinition parameter)
+       private StringBuilder AppendParameter (StringBuilder buf, IList<GenericParameter> genArgs, ParameterDefinition parameter)
        {
                AddTypeCount = false;
                buf.Append (GetTypeName (parameter.ParameterType));
@@ -4155,11 +4910,11 @@ class SlashDocMemberFormatter : MemberFormatter {
                buf.Append (GetName (property.DeclaringType));
                buf.Append ('.');
                buf.Append (name);
-               ParameterDefinitionCollection parameters = property.Parameters;
+               IList<ParameterDefinition> parameters = property.Parameters;
                if (parameters.Count > 0) {
                        genDeclType = property.DeclaringType;
                        buf.Append ('(');
-                       GenericParameterCollection genArgs = property.DeclaringType.GenericParameters;
+                       IList<GenericParameter> genArgs = property.DeclaringType.GenericParameters;
                        AppendParameter (buf, genArgs, parameters [0]);
                        for (int i = 1; i < parameters.Count; ++i) {
                                 buf.Append (',');
@@ -4207,7 +4962,7 @@ class SlashDocMemberFormatter : MemberFormatter {
                if (method.Name == "op_Implicit" || method.Name == "op_Explicit") {
                        genDeclType = method.DeclaringType;
                        genDeclMethod = method;
-                       name += "~" + GetName (method.ReturnType.ReturnType);
+                       name += "~" + GetName (method.ReturnType);
                        genDeclType = null;
                        genDeclMethod = null;
                }