string CreateLeftLink(SequencePoint rightSP, FormattingInfo info, int offset = 0)
 {
     if (rightSP != null)
     {
         var rightSPUrl = CreateSequencePointUrl(info.LeftUrl, rightSP, offset);
         return String.Format("[ {0} ]", CreateMarkdownUrl("link", rightSPUrl));
     }
     return "";
 }
        public void WriteOut(Diff diff, TextWriter writer, FormattingInfo info)
        {
            if (diff is EmptyDiff)
            {
                writer.WriteLine("No longer supported");
                return;
            }

            var removePublicTypes = diff.RemovedPublicTypes().ToList();
            if (removePublicTypes.Any())
            {
                writer.WriteLine();
                writer.WriteLine("## The following public types have been removed.");
                writer.WriteLine();
                foreach (var type in removePublicTypes)
                {
                    writer.WriteLine("- `{0}`", type.GetName());
                }
                writer.WriteLine();
            }
            var typesChangedToNonPublic = diff.TypesChangedToNonPublic().ToList();
            if (typesChangedToNonPublic.Any())
            {
                writer.WriteLine();
                writer.WriteLine("## The following public types have been made internal.");
                writer.WriteLine();
                foreach (var type in typesChangedToNonPublic)
                {
                    writer.WriteLine("- `{0}`", type.RightType.GetName());
                }
                writer.WriteLine();
            }

            var matchingTypeDiffs = diff.MatchingTypeDiffs.ToList();
            if (matchingTypeDiffs.Any())
            {
                writer.WriteLine();
                writer.WriteLine("## The following types have differences.");
                writer.WriteLine();
                foreach (var typeDiff in diff.MatchingTypeDiffs)
                {
                    if (!typeDiff.LeftType.IsPublic)
                    {
                        continue;
                    }
                    if (!typeDiff.RightType.IsPublic)
                    {
                        continue;
                    }
                    if (typeDiff.HasDifferences())
                    {
                        WriteOut(typeDiff, writer, info);
                    }
                }
            }
        }
        void WriteOut(TypeDiff typeDiff, TextWriter writer, FormattingInfo info)
        {
            var typeObsoleted = typeDiff.TypeObsoleted();
            writer.WriteLine();
            writer.Write("### {0}", HttpUtility.HtmlEncode(typeDiff.RightType.GetName()));
            if (typeObsoleted)
            {
                writer.Write("(Obsoleted)");
            }

            writer.WriteLine();

            if (typeObsoleted)
            {
                writer.WriteLine(typeDiff.RightType.GetObsoleteString());
            }

            WriteFields(typeDiff, writer);
            WriteMethods(typeDiff, writer, info);

            writer.WriteLine();
        }
        void WriteMethods(TypeDiff typeDiff, TextWriter writer, FormattingInfo info)
        {
            var changedToNonPublic = typeDiff.MethodsChangedToNonPublic().ToList();
            if (changedToNonPublic.Any())
            {
                writer.WriteLine();
                writer.WriteLine("#### Methods changed to non-public");
                writer.WriteLine();
                foreach (var method in changedToNonPublic)
                {
                    writer.WriteLine("  - `{0}`", method.Left.GetName());
                }
            }

            var removed = typeDiff.PublicMethodsRemoved().ToList();
            if (removed.Any())
            {
                writer.WriteLine();
                writer.WriteLine("#### Methods Removed");
                writer.WriteLine();
                foreach (var method in removed)
                {
                    writer.WriteLine("  - `{0}`", method.GetName());
                }
            }

            var obsoleted = typeDiff.PublicMethodsObsoleted().ToList();
            if (obsoleted.Any())
            {
                writer.WriteLine();
                writer.WriteLine("#### Methods Obsoleted");
                writer.WriteLine();
                foreach (var method in obsoleted)
                {
                    writer.WriteLine("  - `{0}`: {1}", method.Right.GetName(), method.Right.GetObsoleteString());
                }
            }

        }
 string CreateLinks(SequencePoint leftSP, SequencePoint rightSP, FormattingInfo info, int offset = 0)
 {
     if (leftSP != null && rightSP != null)
     {
         var leftSPUrl = CreateSequencePointUrl(info.LeftUrl, leftSP, offset);
         var rightSPUrl = CreateSequencePointUrl(info.RightUrl, rightSP, offset);
         return String.Format("[ {0} | {1} ]", CreateMarkdownUrl("old", leftSPUrl), CreateMarkdownUrl("new", rightSPUrl));
     }
     if (leftSP != null)
     {
         var leftSPUrl = CreateSequencePointUrl(info.LeftUrl, leftSP, offset);
         return String.Format("[ {0} ]", CreateMarkdownUrl("old", leftSPUrl));
     }
     if (rightSP != null)
     {
         var rightSPUrl = CreateSequencePointUrl(info.RightUrl, rightSP, offset);
         return String.Format("[ {0} ]", CreateMarkdownUrl("new", rightSPUrl));
     }
     return "";
 }
        void WriteOut(TypeDiff typeDiff, TextWriter writer, FormattingInfo info)
        {
            writer.WriteLine();
            var links = CreateLinks(typeDiff.LeftType.GetValidSequencePoint(), typeDiff.RightType.GetValidSequencePoint(), info);
            writer.Write("### {0}  {1}", HttpUtility.HtmlEncode(typeDiff.RightType.GetName()), links);
            writer.WriteLine();

            WriteFields(typeDiff, writer);
            WriteMethods(typeDiff, writer, info);

            writer.WriteLine();
        }
        void WriteObsoletes(IEnumerable<TypeDefinition> allTypes, TextWriter writer, FormattingInfo info)
        {
            var obsoleteTypes = allTypes.TypeWithObsoletes().ToList();

            if (obsoleteTypes.Any())
            {
                writer.WriteLine();
                writer.WriteLine("## The following types have Obsoletes.");
                writer.WriteLine();
                foreach (var type in obsoleteTypes)
                {
                    var link = CreateRightLink(type.GetValidSequencePoint(), info);
                    writer.WriteLine("### " + HttpUtility.HtmlEncode(type.GetName()) + "  " + link);
                    writer.WriteLine();
                    if (type.HasObsoleteAttribute())
                    {
                        writer.WriteLine(type.GetObsoleteString());
                        writer.WriteLine();
                    }

                    WriteObsoleteFields(type, writer);
                    WriteObsoleteMethods(type, writer, info);
                }
                writer.WriteLine();
            }
        }
 void WriteObsoleteMethods(TypeDefinition type, TextWriter writer, FormattingInfo info)
 {
     var obsoletes = type.GetObsoleteMethods().ToList();
     if (obsoletes.Any())
     {
         writer.WriteLine();
         writer.WriteLine("#### Obsolete Methods");
         writer.WriteLine();
         foreach (var method in obsoletes)
         {
             var link = CreateRightLink(method.GetValidSequencePoint(), info);
             writer.Write("  - `{0}` {1}", method.GetName(), link);
             writer.WriteLine("<br>" + method.GetObsoleteString());
         }
     }
     writer.WriteLine();
 }
        void WriteMethods(TypeDiff typeDiff, TextWriter writer, FormattingInfo info)
        {
            var changedToNonPublic = typeDiff.MethodsChangedToNonPublic().ToList();
            if (changedToNonPublic.Any())
            {
                writer.WriteLine();
                writer.WriteLine("#### Methods changed to non-public");
                writer.WriteLine();
                foreach (var method in changedToNonPublic)
                {
                    var leftSP = method.Left.GetValidSequencePoint();
                    var rightSP = method.Right.GetValidSequencePoint();
                    writer.WriteLine("  - `{0}` {1}", method.Left.GetName(), CreateLinks(leftSP, rightSP, info));
                }
            }

            //var added = typeDiff.RightOrphanMethods.ToList();
            //if (added.Any())
            //{
            //    writer.WriteLine();
            //    writer.WriteLine("#### Methods Added");
            //    writer.WriteLine();
            //    foreach (var method in added)
            //    {
            //        var sequencePoint = method.GetValidSequencePoint();
            //        writer.WriteLine(string.Format("  - {0} {1}", method.HtmlEncodedName(), CreateLinks(null, sequencePoint, 2)));
            //    }
            //}

            var removed = typeDiff.PublicMethodsRemoved().ToList();
            if (removed.Any())
            {
                writer.WriteLine();
                writer.WriteLine("#### Methods Removed");
                writer.WriteLine();
                foreach (var method in removed)
                {
                    var sequencePoint = method.GetValidSequencePoint();
                    writer.WriteLine("  - `{0}` {1}", method.GetName(), CreateLeftLink(sequencePoint, info));
                }
            }
        }