<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type='text/xsl' href='http://arildf.spaces.live.com/mmm2008-04-25_07.02/rsspretty.aspx?rssquery=en-US;http%3a%2f%2farildf.spaces.live.com%2fcategory%2f__x1NET%2ffeed.rss' version='1.0'?><rss version="2.0" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:msn="http://schemas.microsoft.com/msn/spaces/2005/rss" xmlns:live="http://schemas.microsoft.com/live/spaces/2006/rss" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:cf="http://www.microsoft.com/schemas/rss/core/2005" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Random thoughts about AnkhSVN, .NET, Powershell and other stuff: .NET</title><description /><link>http://arildf.spaces.live.com/?_c11_BlogPart_BlogPart=blogview&amp;_c=BlogPart&amp;partqs=cat__x1NET</link><language>en-US</language><pubDate>Mon, 12 May 2008 09:18:37 GMT</pubDate><lastBuildDate>Mon, 12 May 2008 09:18:37 GMT</lastBuildDate><generator>Microsoft Spaces v1.1</generator><docs>http://www.rssboard.org/rss-specification</docs><ttl>60</ttl><cf:parentRSS>http://arildf.spaces.live.com/blog/feed.rss</cf:parentRSS><live:type>blogcategory</live:type><live:identity><live:id>-1612417020300539472</live:id><live:alias>arildf</live:alias></live:identity><cf:listinfo><cf:group ns="http://schemas.microsoft.com/live/spaces/2006/rss" element="typelabel" label="Type" /><cf:group ns="http://schemas.microsoft.com/live/spaces/2006/rss" element="tag" label="Tag" /><cf:group element="category" label="Category" /><cf:sort element="pubDate" label="Date" data-type="date" default="true" /><cf:sort element="title" label="Title" data-type="string" /><cf:sort ns="http://purl.org/rss/1.0/modules/slash/" element="comments" label="Comments" data-type="number" /></cf:listinfo><item><title>Debugging more events</title><link>http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!171.entry</link><description>&lt;p&gt;A couple of months ago, I &lt;a href="http://arildf.spaces.live.com/blog/cns!E99F8B43533149B0!114.entry"&gt;posted a class&lt;/a&gt; that used the new DynamicMethod class in .NET to dynamically hook up events to all events declared on an object and display a string in VS' output pane whenever that event is raised. While quite useful, it has some drawbacks; most importantly, if you are doing this to multiple objects of the same or similar type (think multiple controls, all of which share a large number of events), it's &lt;em&gt;very&lt;/em&gt; hard to see which particular object the event is coming from.  &lt;p&gt;In some cases, you might also want to hook up only a particular event or set of events on a class, or exclude certain events. For example, all the Mouse-related events (MouseEnter, MouseMove, MouseLeave) can quickly clog up your output and hide the information you are looking for. &lt;p&gt;With this in mind, I decided to make a better version of this method. The new version is vastly improved: &lt;ul&gt; &lt;li&gt;It now supports a filter string which lets you specify a regex that has to match the name of the event(s) you are after  &lt;li&gt;It now supports a custom format string which lets you output a lot of relevant information whenever the event is raised&lt;/ul&gt; &lt;p&gt;The filter string can be used like this: &lt;p&gt;&lt;tt&gt;DebugUtils.DebugEvents(someControl, null, &amp;quot;.*Changed&amp;quot;); // only monitor the *Changed events on the control (think databinding events)&lt;/tt&gt; &lt;p&gt;That's pretty much all there is to the filter string, if you know your regular expressions. The format string is a little more involved, though. It supports the following special keywords (yeah, I stole some of these from the VS 2005 tracepoint syntax, so sue me...): &lt;ul&gt; &lt;li&gt;&lt;tt&gt;$EVENT&lt;/tt&gt; - Replaced with the name of the event raised (you almost always want this one).  &lt;li&gt;&lt;tt&gt;$TYPE&lt;/tt&gt; - Replaced with the fully qualified type name of the object raising the event.  &lt;li&gt;&lt;tt&gt;$TIMESTAMP&lt;/tt&gt; - Replaced with the current time.  &lt;li&gt;&lt;tt&gt;$CALLER&lt;/tt&gt; - Replaced with the fully qualified method name (and possibly line number if symbols are available) of the method that raised the event.  &lt;li&gt;&lt;tt&gt;$STACKTRACE&lt;/tt&gt; - Replaced with a full stack trace of the code that eventually raised the event in question.&lt;/ul&gt; &lt;p&gt;You probably don't want to use the last one unless you also have some filtering on the events (or very few events on the object to begin with); it generates a &lt;em&gt;lot &lt;/em&gt;of output. However, it can often be very useful if you need to see why a particular event is being raised. Line numbers and file names will be included if debug symbols are available. &lt;p&gt;In addition to the special keywords, it can also evaluate simple property and field expressions on the two arguments passed into the event. These are designated as &amp;quot;&lt;tt&gt;sender&lt;/tt&gt;&amp;quot; and &amp;quot;&lt;tt&gt;e&lt;/tt&gt;&amp;quot;, respectively (as is the custom for naming event arguments in .NET). For example: &lt;p&gt;&lt;tt&gt;DebugUtils.DebugEvents(this.reportsListView, &amp;quot;$TIMESTAMP: $EVENT raised, e.InvalidRect is {e.Invalidrect}&amp;quot;, &amp;quot;Invalidated&amp;quot;);&lt;/tt&gt; &lt;p&gt;Which prints the following output to VS' Output Pane: &lt;p&gt;&lt;pre&gt;22:53:32.995125: Invalidated raised, e.InvalidRect is {X=0,Y=0,Width=627,Height=269}
22:53:33.010750: Invalidated raised, e.InvalidRect is {X=0,Y=0,Width=627,Height=269}
22:53:39.932625: Invalidated raised, e.InvalidRect is {X=0,Y=0,Width=627,Height=269}
&lt;/pre&gt;
&lt;p&gt;
&lt;p&gt;(etc...) 
&lt;p&gt;The source for this file can be found in the SVN repository at &lt;a href="http://ankhsvn.com/svn/Utils/trunk/Utils/Debugging/DebugUtils.cs"&gt;http://ankhsvn.com/svn/Utils/trunk/Utils/Debugging/DebugUtils.cs&lt;/a&gt;, and unit tests: &lt;a href="http://ankhsvn.com/svn/Utils/trunk/UtilsTest/Debugging/DebugUtilsTest.cs"&gt;http://ankhsvn.com/svn/Utils/trunk/UtilsTest/Debugging/DebugUtilsTest.cs&lt;/a&gt;. To use it for yourself, either copy the file as is or check out the entire VS 2005 project from &lt;a href="http://ankhsvn.com/svn/Utils/trunk/"&gt;http://ankhsvn.com/svn/Utils/trunk/&lt;/a&gt; and build it. The class is made available under a &lt;a href="http://ankhsvn.com/svn/Utils/trunk/LICENSE.txt"&gt;slightly modified MIT license&lt;/a&gt; (I removed the clause requiring derivatives to carry the notice). 
&lt;p&gt;UPDATE: I've removed the use of the ListUtils class so that people who want to copy the file in itself won't need to also get the ListUtils class. I've also added XML doc comments to the various overloads.&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-1612417020300539472&amp;page=RSS%3a+Debugging+more+events&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=arildf.spaces.live.com&amp;amp;GT1=arildf"&gt;</description><comments>http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!171.entry#comment</comments><guid isPermaLink="true">http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!171.entry</guid><pubDate>Wed, 06 Sep 2006 21:10:23 GMT</pubDate><slash:comments>4</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://arildf.spaces.live.com/blog/cns!E99F8B43533149B0!171/comments/feed.rss</wfw:commentRss><wfw:comment>http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!171.entry#comment</wfw:comment><dcterms:modified>2006-09-07T17:04:37Z</dcterms:modified></item><item><title>The ”Members” and ”Types” dropdowns in VS.NET</title><link>http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!131.entry</link><description>&lt;p&gt;The code editor window in VS.NET has two dropdowns on top, one containing the types present in the current file and the other containing the members present in that file.  This is a pretty good idea, and makes it easy to navigate through a code file. However, I found that I never really used it all that much. I’m not all that big on having to use the mouse to navigate in VS.NET in the first place, and it was usually faster to just search through the file either manually  with arrow keys and PgUp/PgDwn (using the Eyeball Mk I feature shipped with most Visual Studio users) or with incremental search (Ctrl+I).
&lt;p&gt;It seems that the main trouble with those two dropdowns is that they’re not easily accessible through the keyboard. There is no built-in VS command that drops them down. However, you can set the focus on the navigation bar by pressing Ctrl-F2. That’ll leave the Types dropdown focused, so you can use Down Arrow to navigate it, or press TAB to get to the Members dropdown.  This means that if you want to use the Members dropdown to navigate to another member in the current class, you have to do Ctrl-F2 + TAB + Down Arrow before you can start selecting the member you want. For me, this is too much (and Ctrl-F2 is a very awkward key combination as well unless you have very big hands or use both hands to press it).
&lt;p&gt;The lack of a decent key binding for those two dropdowns kept annoying me to the point where I decided to do something about it.  So I wrote a small VS addin that adds two new commands to Visual Studio, one to drop down the Types combo and one to drop down the Members combo. It also sets focus on the dropdowns, so you can navigate right away using arrow keys and/or the first letter in the member you’re looking for.
&lt;p&gt;When starting up for the first time, the addin will ask you if it should install key bindings for the two commands, Ctrl-D, Ctrl-P (for tyPes) and Ctrl-D, Ctrl-M (for Members). I considered Ctrl-D, Ctrl-T for the Types one, but it felt a lot more awkward to use, so I settled on the current choice.
&lt;p&gt;You can of course remap the key bindings for the commands yourself using the Keyboard options page under Tools-&amp;gt;Options. The commands are named “MemberDropDown.DropDownMembers” and “MemberDropDown.DropDownTypes”.
&lt;p&gt;The addin will presently only work for Visual Studio 2005, however, I might consider making it work for all VSes if there’s interest. You can find an MSI installer &lt;a href="http://ankhsvn.com/images/MemberDropDownAddin.msi"&gt;here&lt;/a&gt; and the source is in a Subversion repository &lt;a href="http://ankhsvn.com/svn/Utils/trunk/MemberDropDown/"&gt;here&lt;/a&gt;.
&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-1612417020300539472&amp;page=RSS%3a+The+%e2%80%9dMembers%e2%80%9d+and+%e2%80%9dTypes%e2%80%9d+dropdowns+in+VS.NET&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=arildf.spaces.live.com&amp;amp;GT1=arildf"&gt;</description><comments>http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!131.entry#comment</comments><guid isPermaLink="true">http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!131.entry</guid><pubDate>Tue, 04 Jul 2006 21:37:33 GMT</pubDate><slash:comments>3</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://arildf.spaces.live.com/blog/cns!E99F8B43533149B0!131/comments/feed.rss</wfw:commentRss><wfw:comment>http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!131.entry#comment</wfw:comment><dcterms:modified>2006-07-04T21:37:33Z</dcterms:modified></item><item><title>Debugging events and the joys of DynamicMethod</title><link>http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!114.entry</link><description>&lt;p&gt;The &lt;span style="font-family:Courier New"&gt;DynamicMethod &lt;/span&gt;class is new to .NET 2.0. It is believed that it was added as a consequence of Jim Hugunin being hired by Microsoft to work on &lt;a href="http://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython"&gt;IronPython&lt;/a&gt;, a CLR version of the Python language. Dynamic languages like Python, Perl, JavaScript and PHP usually provide a function called &lt;span style="font-family:Courier New"&gt;eval &lt;/span&gt;or something similar, which allows the evaluation of code provided as a string. In other words, you could do something like &lt;span style="font-family:Courier New"&gt;s = “print(“ + a + “ + “ + b )”; eval( s )&lt;/span&gt; to dynamically print the result of a  calculation (ok, the example’s a little silly in that there are easier ways to accomplish this, but anyway…). 
&lt;p&gt;In versions of IronPython that ran on .NET 1.x, &lt;span style="font-family:Courier New"&gt;eval &lt;/span&gt;was implemented by evaluating the expression and emitting CIL code using the functionality in the &lt;span style="font-family:Courier New"&gt;System.Reflection.Emit&lt;/span&gt; namespace to generate a method in a new .NET assembly. This assembly would then be loaded into the runtime and the method would be called. Unfortunately, .NET has no way of unloading an assembly from an appdomain once it was loaded, so those versions of Ironpython had an implicit memory leak every time you used &lt;span style="font-family:Courier New"&gt;eval.
&lt;/span&gt;&lt;p&gt;&lt;span style="font-family:Courier New"&gt;DynamicMethod &lt;/span&gt;was introduced as a way to achieve this functionality without having the overhead of creating a new assembly merely to create and execute a dynamically provided method.  &lt;span style="font-family:Courier New"&gt;DynamicMethod &lt;/span&gt;is also a part of the &lt;span style="font-family:Courier New"&gt;System.Reflection.Emit &lt;/span&gt;and lets you emit code in the same way you would to an assembly on disk. However, with &lt;span style="font-family:Courier New"&gt;DynamicMethod&lt;/span&gt;  there is no need to create a new assembly. Instead, the CIL code is generated directly to memory, and .NET’s inability to unload assemblies from an appdomain are no longer relevant.
&lt;p&gt;I encountered a situation recently where I had the need to see what events a particular Windows Forms component raised and in which order. The documentation was of no real help, so I started looking for other ways to investigate this. Manually hooking up each event to a handler wasn’t very tempting, even with the help of anonymous delegates. I knew I could get a list of the available events through reflection, and even hook up event handlers this way dynamically, but how could I create event handler methods for all of them that would actually give me information on which event was raised?
&lt;p&gt;While attending Oslo University for my masters, I had both taken a class on compiler implementation and design and been a teaching assistant in the same class. During those two semesters, I wrote two compilers that emitted CIL code using the functionality in &lt;span style="font-family:Courier New"&gt;System.Reflection.Emit&lt;/span&gt;, so I had some experience with code generation and CIL. While I’d never actually used it, I had heard of the &lt;span style="font-family:Courier New"&gt;DynamicMethod&lt;/span&gt; class and knew roughly how it worked. It struck me that it would be a good fit for this problem; with &lt;span style="font-family:Courier New"&gt;DynamicMethod&lt;/span&gt;, I could dynamically emit custom event handlers for every event on the object I wanted to monitor.
&lt;p&gt;It turned out that using &lt;span style="font-family:Courier New"&gt;DynamicMethod&lt;/span&gt; was little different from the “traditional” way of using S.R.E to emit CIL code. You obtain an &lt;span style="font-family:Courier New"&gt;ILGenerator object&lt;/span&gt;, which has a bunch of overloaded Emit methods to create the various opcodes. In my case, I decided to emit a call to &lt;span style="font-family:Courier New"&gt;System.Debug.WriteLine&lt;/span&gt; with the full name of the event as a parameter.
&lt;p&gt;The code is as follows:
&lt;span style="font-family:Consolas;font-size:9"&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;[&lt;span style="color:teal"&gt;Conditional&lt;/span&gt;(&lt;span style="color:maroon"&gt;&amp;quot;DEBUG&amp;quot;&lt;/span&gt;)]
&lt;/span&gt;&lt;p&gt;&lt;span style="color:blue;background-color:white"&gt;public&lt;/span&gt;&lt;span style="background-color:white"&gt;
				&lt;span style="color:blue"&gt;static&lt;/span&gt;
				&lt;span style="color:blue"&gt;void&lt;/span&gt; DebugEvents( &lt;span style="color:blue"&gt;params&lt;/span&gt;
				&lt;span style="color:blue"&gt;object&lt;/span&gt;[] objects )
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;{
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;    &lt;span style="color:blue"&gt;foreach&lt;/span&gt; ( &lt;span style="color:blue"&gt;object&lt;/span&gt; o &lt;span style="color:blue"&gt;in&lt;/span&gt; objects )
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;    {
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;        &lt;span style="color:blue"&gt;foreach&lt;/span&gt; ( &lt;span style="color:teal"&gt;EventInfo&lt;/span&gt; info &lt;span style="color:blue"&gt;in&lt;/span&gt; o.GetType().GetEvents( &lt;span style="color:teal"&gt;BindingFlags&lt;/span&gt;.FlattenHierarchy | &lt;span style="color:teal"&gt;BindingFlags&lt;/span&gt;.Instance | &lt;span style="color:teal"&gt;BindingFlags&lt;/span&gt;.Public ) )
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;        {
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;            &lt;span style="color:teal"&gt;MethodInfo&lt;/span&gt; mi = info.EventHandlerType.GetMethod( &lt;span style="color:maroon"&gt;&amp;quot;Invoke&amp;quot;&lt;/span&gt; );
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;            &lt;span style="color:teal"&gt;Type&lt;/span&gt;[] parmTypes = ListUtils.ToArray(
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;                ListUtils.Map&amp;lt;&lt;span style="color:teal"&gt;ParameterInfo&lt;/span&gt;, &lt;span style="color:teal"&gt;Type&lt;/span&gt;&amp;gt;( mi.GetParameters(), &lt;span style="color:blue"&gt;delegate&lt;/span&gt;( &lt;span style="color:teal"&gt;ParameterInfo&lt;/span&gt; par )
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;                {
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;                    &lt;span style="color:blue"&gt;return&lt;/span&gt; par.ParameterType;
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;                } )
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;            );
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;            &lt;span style="color:teal"&gt;DynamicMethod&lt;/span&gt; m = &lt;span style="color:blue"&gt;new&lt;/span&gt;
				&lt;span style="color:teal"&gt;DynamicMethod&lt;/span&gt;( info.Name + &lt;span style="color:maroon"&gt;&amp;quot;Handler&amp;quot;&lt;/span&gt;, &lt;span style="color:blue"&gt;typeof&lt;/span&gt;( &lt;span style="color:blue"&gt;void&lt;/span&gt; ), parmTypes, o.GetType() );
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;            &lt;span style="color:teal"&gt;ILGenerator&lt;/span&gt; generator = m.GetILGenerator();
&lt;/span&gt;&lt;/span&gt;&lt;p&gt;
 &lt;span style="font-family:Consolas;font-size:9"&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;            &lt;span style="color:blue"&gt;string&lt;/span&gt; eventInfoString = &lt;span style="color:teal"&gt;String&lt;/span&gt;.Format( &lt;span style="color:maroon"&gt;&amp;quot;Event raised: {0}.{1}&amp;quot;&lt;/span&gt;, o.GetType().FullName, info.Name );
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;            generator.Emit( &lt;span style="color:teal"&gt;OpCodes&lt;/span&gt;.Ldstr, eventInfoString );
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;            generator.EmitCall( &lt;span style="color:teal"&gt;OpCodes&lt;/span&gt;.Call, &lt;span style="color:blue"&gt;typeof&lt;/span&gt;( Debug ).GetMethod( &lt;span style="color:maroon"&gt;&amp;quot;WriteLine&amp;quot;&lt;/span&gt;, &lt;span style="color:blue"&gt;new&lt;/span&gt;
				&lt;span style="color:teal"&gt;Type&lt;/span&gt;[] { &lt;span style="color:blue"&gt;typeof&lt;/span&gt;( &lt;span style="color:blue"&gt;string&lt;/span&gt; ) } ), &lt;span style="color:blue"&gt;null&lt;/span&gt; );
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;            generator.Emit( &lt;span style="color:teal"&gt;OpCodes&lt;/span&gt;.Ret );
&lt;/span&gt;&lt;/span&gt;&lt;p&gt;
 &lt;p&gt;&lt;span style="font-family:Consolas;font-size:9;background-color:white"&gt;            &lt;span style="color:teal"&gt;Delegate&lt;/span&gt; del = m.CreateDelegate( info.EventHandlerType );
&lt;/span&gt;&lt;p&gt;
 &lt;span style="font-family:Consolas;font-size:9"&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;            info.AddEventHandler( o, del );
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;        }
&lt;/span&gt;&lt;p&gt;&lt;span style="background-color:white"&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;p&gt;&lt;span style="font-family:Consolas;font-size:9;background-color:white"&gt;}&lt;/span&gt;
	&lt;p&gt;As you can see, it uses reflection to obtain &lt;span style="font-family:Courier New"&gt;EventInfo&lt;/span&gt; objects for all events on the passed-in objects. It then gets the parameter list for its Invoke method and creates a &lt;span style="font-family:Courier New"&gt;DynamicMethod&lt;/span&gt; object that has the same signature. Through the &lt;span style="font-family:Courier New"&gt;ILGenerator&lt;/span&gt; object, a call to &lt;span style="font-family:Courier New"&gt;Debug.WriteLine&lt;/span&gt; is emitted with a string containing the name of the event as the sole parameter. A delegate is created from the &lt;span style="font-family:Courier New"&gt;DynamicMethod&lt;/span&gt; which is then added as an event handler for the event.
&lt;p&gt;Anything sent to &lt;span style="font-family:Courier New"&gt;Debug.WriteLine&lt;/span&gt; goes to the Debug window in VS.NET if you run an application under the debugger, so if you call &lt;span style="font-family:Courier New"&gt;DebugEvents&lt;/span&gt; passing in a very plain Windows Forms form as an argument you should see something like this:
&lt;p&gt;
 &lt;p&gt;
 &lt;p&gt;The &lt;span style="font-family:Courier New"&gt;ListUtils&lt;/span&gt; class referenced in the code can be found &lt;a href="http://ankhsvn.com/svn/Utils/trunk/Utils/Collections/ListUtils.cs"&gt;here&lt;/a&gt;.&lt;div&gt;&lt;table cellspacing="0" border="0"&gt;&lt;tr height="8"&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p&gt;&lt;a href="http://byfiles.storage.live.com&amp;#47;y1pQpbQ0XR6mUCkRqKsPl8DvCQ7UuiWPYfPXFQjrgxkMjaQ-DVWsdcV3Je6MVq4ZRrIze-NMRotfYo"&gt;&lt;img src="http://storage.live.com&amp;#47;items&amp;#47;E99F8B43533149B0&amp;#33;115&amp;#58;thumbnail" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&lt;td width="15"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-1612417020300539472&amp;page=RSS%3a+Debugging+events+and+the+joys+of+DynamicMethod&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=arildf.spaces.live.com&amp;amp;GT1=arildf"&gt;</description><comments>http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!114.entry#comment</comments><guid isPermaLink="true">http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!114.entry</guid><pubDate>Thu, 15 Jun 2006 18:53:50 GMT</pubDate><slash:comments>8</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://arildf.spaces.live.com/blog/cns!E99F8B43533149B0!114/comments/feed.rss</wfw:commentRss><wfw:comment>http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!114.entry#comment</wfw:comment><dcterms:modified>2006-06-15T19:13:58Z</dcterms:modified></item><item><title>MSDN Man</title><link>http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!111.entry</link><description>&lt;p&gt;&lt;a href="http://pluralsight.com/blogs/craig/archive/2006/06/12/27288.aspx"&gt;Huh, neat&lt;/a&gt;:
&lt;blockquote&gt;&lt;p&gt;&lt;span style="color:black"&gt;Msdnman is a command-line documentation tool that exposes the content in the Microsoft/TechNet Publishing System in a manner reminiscent of the *nix &amp;quot;man&amp;quot; command.
&lt;/span&gt;&lt;/blockquote&gt;&lt;img src="http://c.services.spaces.live.com/CollectionWebService/c.gif?cid=-1612417020300539472&amp;page=RSS%3a+MSDN+Man&amp;referrer=" width="1px" height="1px" border="0" alt=""&gt;&lt;img style="position:absolute" alt="" width="0px" height="0px" src="http://c.live.com/c.gif?NC=31263&amp;amp;NA=1149&amp;amp;PI=73329&amp;amp;RF=&amp;amp;DI=3919&amp;amp;PS=85545&amp;amp;TP=arildf.spaces.live.com&amp;amp;GT1=arildf"&gt;</description><comments>http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!111.entry#comment</comments><guid isPermaLink="true">http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!111.entry</guid><pubDate>Tue, 13 Jun 2006 15:07:00 GMT</pubDate><slash:comments>1</slash:comments><msn:type>blogentry</msn:type><live:type>blogentry</live:type><live:typelabel>Blog entry</live:typelabel><wfw:commentRss>http://arildf.spaces.live.com/blog/cns!E99F8B43533149B0!111/comments/feed.rss</wfw:commentRss><wfw:comment>http://arildf.spaces.live.com/Blog/cns!E99F8B43533149B0!111.entry#comment</wfw:comment><dcterms:modified>2006-06-13T15:07:00Z</dcterms:modified></item></channel></rss>