<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>George V. Reilly&amp;#39;s Technical BLog</title><link>http://weblogs.asp.net/george_v_reilly/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Preload Ajax Data as JSON</title><link>http://weblogs.asp.net/george_v_reilly/archive/2008/05/29/preload-ajax-data-as-json.aspx</link><pubDate>Fri, 30 May 2008 06:27:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6231987</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=6231987</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2008/05/29/preload-ajax-data-as-json.aspx#comments</comments><description>&lt;p&gt;
&lt;a href="http://blogs.cozi.com/tech/2008/05/preloading-ajax.html" mce_href="http://blogs.cozi.com/tech/2008/05/preloading-ajax.html"&gt;
&lt;img src="http://blogs.cozi.com/photos/uncategorized/2008/05/27/preloadajaxdata.png" mce_src="http://blogs.cozi.com/photos/uncategorized/2008/05/27/preloadajaxdata.png" class="right-float" alt="http://blogs.cozi.com/photos/uncategorized/2008/05/27/preloadajaxdata.png" title="ASP.NET - Ajax + JSON = speed"&gt;
&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Preloading Ajax data as JSON has helped 
improve the load time and perceived performance of our family software application.
Most of the pages in our web client are dynamically generated
in the browser from a complex set of JavaScript and CSS,
so we're always looking out for ways to make them appear more quickly.
&lt;/p&gt;

&lt;p&gt;
More &lt;a href="http://blogs.cozi.com/tech/2008/05/preloading-ajax.html" mce_href="http://blogs.cozi.com/tech/2008/05/preloading-ajax.html" title="at the Cozi Tech Blog"&gt;at the Cozi Tech Blog&lt;/a&gt;.
&lt;/p&gt;
&lt;img src="http://www.georgevreilly.com/blog/cptrk.ashx?id=be259dd5-a613-4cf6-9bb0-0191be88fcc6" mce_src="http://www.georgevreilly.com/blog/cptrk.ashx?id=be259dd5-a613-4cf6-9bb0-0191be88fcc6" height="0" width="0"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6231987" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/General+Software+Development/default.aspx">General Software Development</category><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/Ajax/default.aspx">Ajax</category></item><item><title>Sharing Dotfiles between Windows and *nix</title><link>http://weblogs.asp.net/george_v_reilly/archive/2008/05/13/sharing-dotfiles-between-windows-and-nix.aspx</link><pubDate>Wed, 14 May 2008 06:28:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6188309</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=6188309</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2008/05/13/sharing-dotfiles-between-windows-and-nix.aspx#comments</comments><description>&lt;img src="http://www.georgevreilly.com/blog/content/binary/shared-dotfiles.png" alt="Sharing Dotfiles between Windows and *nix" mce_src="http://www.georgevreilly.com/blog/content/binary/shared-dotfiles.png"&gt;
&lt;p&gt;Tomas Restrepo wrote a post about
&lt;a href="http://www.winterdom.com/weblog/2008/05/09/SharingDotfilesBetweenWindowsAndUbuntu.aspx" class="reference external" mce_href="http://www.winterdom.com/weblog/2008/05/09/SharingDotfilesBetweenWindowsAndUbuntu.aspx"&gt;sharing dotfiles between Windows and Ubuntu&lt;/a&gt;,
specifically about sharing &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;.vimrc&lt;/span&gt;&lt;/tt&gt; (Linux) and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;_vimrc&lt;/span&gt;&lt;/tt&gt; (Windows)
and the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;.vim&lt;/span&gt;&lt;/tt&gt; (Linux) and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;vimfiles&lt;/span&gt;&lt;/tt&gt; (Windows) directories.&lt;/p&gt;
&lt;p&gt;I have a different solution.
On Windows, my &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C:\AutoExec.bat&lt;/span&gt;&lt;/tt&gt; includes:&lt;/p&gt;
&lt;pre class="literal-block"&gt;set HOME=C:\gvr&lt;br&gt;set VIM=C:\Vim&lt;br&gt;set VIMDIR=%VIM%\vim71&lt;br&gt;set EDITOR=%VIMDIR%\gvim.exe&lt;br&gt;set PATH=%PATH%;C:\Win32app;C:\GnuWin32\bin;C:\UnxUtils;C:\SysInternals;C:\Python25\Scripts&lt;br&gt;&lt;/pre&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;%HOME%&lt;/span&gt;&lt;/tt&gt; (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C:\gvr&lt;/span&gt;&lt;/tt&gt;) contains &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;_vimrc&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;vimfiles&lt;/span&gt;&lt;/tt&gt;,
and other stuff accumulated over many years.
This directory is stored in a personal Subversion repository at &lt;a href="http://www.devjavu.com/" class="reference external" mce_href="http://www.devjavu.com/"&gt;DevjaVu&lt;/a&gt;.
All my Vim files are stored with Unix LF endings, not Windows CR-LFs,
so that they'll work on my Mac OS X and Linux boxen.
I play some games with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;if&lt;/span&gt; &lt;span class="pre"&gt;has("win32")&lt;/span&gt;&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;if&lt;/span&gt; &lt;span class="pre"&gt;has('gui_macvim')&lt;/span&gt;&lt;/tt&gt; to ensure that my &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;_vimrc&lt;/span&gt;&lt;/tt&gt;
works cross-platform.&lt;/p&gt;
&lt;p&gt;On my *nix boxes, the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;gvr&lt;/span&gt;&lt;/tt&gt; folder lives under my home directory at &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/gvr&lt;/span&gt;&lt;/tt&gt;,
and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.vimrc&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.vim&lt;/span&gt;&lt;/tt&gt; are symlinks:&lt;/p&gt;
&lt;pre class="literal-block"&gt;$ ln -s ~/gvr/_vimrc ~/.vimrc&lt;br&gt;$ ln -s ~/gvr/vimfiles/ ~/.vim&lt;br&gt;&lt;/pre&gt;
&lt;p&gt;In addition, the dotfiles that I keep in SVN are stored locally in
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/gvr/dotfiles&lt;/span&gt;&lt;/tt&gt; without a leading period in their names,
which makes them easy to see:&lt;/p&gt;
&lt;pre class="literal-block"&gt;$ ln -s ~/gvr/dotfiles/bashrc ~/.bashrc&lt;br&gt;&lt;/pre&gt;
&lt;p&gt;This arrangement works well for me.&lt;/p&gt;
&lt;img src="http://www.georgevreilly.com/blog/cptrk.ashx?id=0a266839-1ad3-4e55-a818-781a1b239e8b" mce_src="http://www.georgevreilly.com/blog/cptrk.ashx?id=0a266839-1ad3-4e55-a818-781a1b239e8b" height="0" width="0"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6188309" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/General+Software+Development/default.aspx">General Software Development</category></item><item><title>Multiple Firefox Profiles: Run Firefox 2 and 3 Side-By-Side, and More</title><link>http://weblogs.asp.net/george_v_reilly/archive/2008/04/02/multiple-firefox-profiles-run-firefox-2-and-3-side-by-side-and-more.aspx</link><pubDate>Wed, 02 Apr 2008 17:35:13 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6061442</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=6061442</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2008/04/02/multiple-firefox-profiles-run-firefox-2-and-3-side-by-side-and-more.aspx#comments</comments><description>
&lt;p&gt;
&lt;a href="http://blogs.cozi.com/tech/2008/04/multiple-firefo.html"&gt;
&lt;img src="http://blogs.cozi.com/tech/images/2008/03/31/multiplebrowsers.png" class="right-float" alt="http://blogs.cozi.com/tech/images/2008/03/31/multiplebrowsers.png" title="Multiple Firefox Profiles: Run Firefox 2 and 3 Side-By-Side, and More"&gt;
&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
I find it useful to have multiple Firefox profiles for developing and testing.
A clean profile for testing allows you to replicate most users' environments,
who don't install extensions.
Running a development profile in a separate profile lets you
restart the browser without messing with your default environment.
You can also run Firefox 2 and Firefox 3 side-by-side in separate profiles.
&lt;/p&gt;

&lt;p&gt;
More &lt;a href="http://blogs.cozi.com/tech/2008/04/multiple-firefo.html" title="at the Cozi Tech Blog"&gt;at the Cozi Tech Blog&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.georgevreilly.com/blog/cptrk.ashx?id=7d7e5b29-c8ac-4ae3-ae90-a077a896f0db"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6061442" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/General+Software+Development/default.aspx">General Software Development</category></item><item><title>Debugging JavaScript in IE from Visual Web Developer 2008 Express Edition</title><link>http://weblogs.asp.net/george_v_reilly/archive/2008/03/19/debugging-javascript-in-ie-from-visual-web-developer-2008-express-edition.aspx</link><pubDate>Wed, 19 Mar 2008 20:34:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:5999600</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=5999600</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2008/03/19/debugging-javascript-in-ie-from-visual-web-developer-2008-express-edition.aspx#comments</comments><description>&lt;p&gt;
&lt;a href="http://blogs.cozi.com/tech/2008/03/debugging-javas.html" mce_href="http://blogs.cozi.com/tech/2008/03/debugging-javas.html"&gt;
&lt;img src="http://blogs.cozi.com/tech/images/2008/03/19/vwdscreenshot_2.png" mce_src="http://blogs.cozi.com/tech/images/2008/03/19/vwdscreenshot_2.png" class="right-float" alt="http://blogs.cozi.com/tech/images/2008/03/19/vwdscreenshot_2.png" title="Debugging JavaScript in IE from Visual Web Developer 2008 Express Edition"&gt;
&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
It's not at all obvious how to use &lt;a href="http://www.microsoft.com/express/vwd/Default.aspx" mce_href="http://www.microsoft.com/express/vwd/Default.aspx" title="Visual Web Developer 2008 Express Edition"&gt;Visual Web Developer 2008 Express Edition&lt;/a&gt;
to debug JavaScript in Internet Explorer.
So I wrote it up &lt;a href="http://blogs.cozi.com/tech/2008/03/debugging-javas.html" mce_href="http://blogs.cozi.com/tech/2008/03/debugging-javas.html" title="at the Cozi Tech Blog"&gt;at the Cozi Tech Blog&lt;/a&gt;.
&lt;/p&gt;
&lt;img src="http://www.georgevreilly.com/blog/cptrk.ashx?id=3086159e-65ef-4e2a-a89f-840a9aa14e19" mce_src="http://www.georgevreilly.com/blog/cptrk.ashx?id=3086159e-65ef-4e2a-a89f-840a9aa14e19" height="0" width="0"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5999600" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/General+Software+Development/default.aspx">General Software Development</category></item><item><title>Daylight Savings Time and JavaScript</title><link>http://weblogs.asp.net/george_v_reilly/archive/2008/03/13/daylight-savings-time-and-javascript.aspx</link><pubDate>Thu, 13 Mar 2008 20:58:27 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:5962430</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=5962430</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2008/03/13/daylight-savings-time-and-javascript.aspx#comments</comments><description>
&lt;p&gt;
&lt;a href="http://blogs.cozi.com/tech/2008/03/daylight-saving.html"&gt;
&lt;img src="http://www.georgevreilly.com/blog/content/binary/js-date-dst2.png" class="right-float" alt="http://www.georgevreilly.com/blog/content/binary/js-date-dst2.png" title="Daylight Savings Time and JavaScript"&gt;
&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
The JavaScript engines in Firefox 2 (Windows) and IE6
can't handle the new Daylight Savings Time rules in the U.S.
The &lt;code&gt;Date()&lt;/code&gt; function returns a value that is off by an hour
if the system time is between the second Sunday of March
and the first Sunday of April.
&lt;/p&gt;

&lt;p&gt;
&lt;a href="http://blogs.cozi.com/tech/2008/03/daylight-saving.html" title="More at the Cozi Tech Blog"&gt;More at the Cozi Tech Blog&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;Update 2008/03/14&lt;/strong&gt;: &lt;em&gt;Mea culpa&lt;/em&gt;.
This is &lt;em&gt;not&lt;/em&gt; a widespread problem.
It is caused by the presence of &lt;code&gt;set TZ=PST8PDT&lt;/code&gt;
in my &lt;code&gt;C:\AutoExec.bat&lt;/code&gt;.
Per &lt;a href="http://support.microsoft.com/kb/932590" title="KB932590"&gt;KB932590&lt;/a&gt;, the existence of the &lt;code&gt;TZ&lt;/code&gt; environment variable
will cause the CRT to use the old DST rules.
(I can't remember why I set &lt;code&gt;TZ&lt;/code&gt; several years ago.
It's part of the accumulated mess of files that
I bring everywhere with me.)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.georgevreilly.com/blog/cptrk.ashx?id=0d34a849-81a6-4c9a-8c6a-ecefa21f2f31"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5962430" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/General+Software+Development/default.aspx">General Software Development</category></item><item><title>Transparent PNGs can Deadlock IE6</title><link>http://weblogs.asp.net/george_v_reilly/archive/2008/03/10/transparent-pngs-can-deadlock-ie6.aspx</link><pubDate>Mon, 10 Mar 2008 21:47:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:5946555</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=5946555</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2008/03/10/transparent-pngs-can-deadlock-ie6.aspx#comments</comments><description>&lt;p&gt;
&lt;a href="http://nedbatchelder.com/blog/200801/deadlock_in_real_life.html" mce_href="http://nedbatchelder.com/blog/200801/deadlock_in_real_life.html"&gt;
&lt;img src="http://www.georgevreilly.com/blog/content/binary/deadlock_thumb.jpg" mce_src="http://www.georgevreilly.com/blog/content/binary/deadlock_thumb.jpg" class="right-float" alt="http://www.georgevreilly.com/blog/content/binary/deadlock_thumb.jpg" title="Deadlock in Real Life"&gt;
&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Over at &lt;a href="http://www.cozi.com/" mce_href="http://www.cozi.com/" title="Cozi"&gt;Cozi&lt;/a&gt;, we've started a new &lt;a href="http://blogs.cozi.com/tech/" mce_href="http://blogs.cozi.com/tech/" title="technical blog"&gt;technical blog&lt;/a&gt;.
I just put my &lt;a href="http://blogs.cozi.com/tech/2008/03/transparent-png.html" mce_href="http://blogs.cozi.com/tech/2008/03/transparent-png.html" title="first post"&gt;first post&lt;/a&gt; up,
describing a nasty problem we had late last year.
&lt;/p&gt;

&lt;p&gt;
Here's the summary:
&lt;/p&gt;

    &lt;blockquote&gt;

    &lt;p&gt;
    Internet Explorer 6 does not support transparency in PNG images.
    The best-known solution is to use the DirectX &lt;a href="http://www.satzansatz.de/cssd/tmp/alphatransparency.html" mce_href="http://www.satzansatz.de/cssd/tmp/alphatransparency.html" title="AlphaImageLoader"&gt;AlphaImageLoader&lt;/a&gt; CSS filter.
    It's less well known that using AlphaImageLoader sometimes leads to a deadlock in IE6.
    There are two workarounds.
    Either wait until after the image has been downloaded
    to apply the filter to the image's &lt;code&gt;style&lt;/code&gt;,
    or use the little-known transparent &lt;a href="http://www.sitepoint.com/blogs/2007/09/18/png8-the-clear-winner/" mce_href="http://www.sitepoint.com/blogs/2007/09/18/png8-the-clear-winner/" title="PNG8"&gt;PNG8&lt;/a&gt; format instead of the filter.
    &lt;/p&gt;

    &lt;/blockquote&gt;

&lt;p&gt;
&lt;a href="http://blogs.cozi.com/tech/2008/03/transparent-png.html" mce_href="http://blogs.cozi.com/tech/2008/03/transparent-png.html" title="More here"&gt;More here&lt;/a&gt;.
&lt;/p&gt;
&lt;img src="http://www.georgevreilly.com/blog/cptrk.ashx?id=85685fbe-455b-49cf-9123-953967772fcb" mce_src="http://www.georgevreilly.com/blog/cptrk.ashx?id=85685fbe-455b-49cf-9123-953967772fcb" height="0" width="0"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=5946555" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/General+Software+Development/default.aspx">General Software Development</category></item><item><title>Er, er</title><link>http://weblogs.asp.net/george_v_reilly/archive/2007/10/25/er-er.aspx</link><pubDate>Thu, 25 Oct 2007 07:12:34 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:4738757</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=4738757</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2007/10/25/er-er.aspx#comments</comments><description>
&lt;p&gt;

&lt;img src="http://www.georgevreilly.com/blog/content/binary/ErEr.png" alt="http://www.georgevreilly.com/blog/content/binary/ErEr.png" title="Er, er"&gt;

&lt;/p&gt;

&lt;p&gt;
I've grown fond of the JavaScript &lt;code&gt;||&lt;/code&gt; idiom:
&lt;/p&gt;

&lt;pre&gt; function FrobImage(img) {&lt;br&gt;     var width  = img.width  || 400;&lt;br&gt;     var height = img.height || 300;&lt;br&gt;     // ...&lt;br&gt; }&lt;br&gt;&lt;br&gt; FrobImage({height: 100, name: "example.png"});&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;
If &lt;code&gt;img.width&lt;/code&gt; exists and it's &lt;a href="http://mattsnider.com/wp-content/uploads/2007/04/FalseTest.html" title="truthy"&gt;truthy&lt;/a&gt;,
then &lt;code&gt;width = img.width&lt;/code&gt;; otherwise, &lt;code&gt;width = 400&lt;/code&gt;.
Here, it will be &lt;code&gt;400&lt;/code&gt; since the &lt;code&gt;img&lt;/code&gt; hash
has no &lt;code&gt;width&lt;/code&gt; property.
More than two alternatives may be used:
&lt;code&gt;x = a || b || c || ... || q;&lt;/code&gt;
&lt;/p&gt;

&lt;p&gt;
A few weeks ago, while cleaning up the error handling in some batch files,
I came across a &lt;a href="http://www.ss64.com/ntsyntax/conditional.html" title="similar idiom"&gt;similar idiom&lt;/a&gt;:
&lt;/p&gt;

&lt;pre&gt; foo.exe bar 123 "some stuff"  || goto :Error&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;
Only if &lt;code&gt;foo.exe&lt;/code&gt; fails (&lt;code&gt;exit()&lt;/code&gt; returns a non-zero value),
is the second clause executed.
&lt;/p&gt;

&lt;p&gt;
&lt;a href="http://perldoc.perl.org/functions/die.html" title="Perl's die"&gt;Perl's die&lt;/a&gt; is typically used in a very similar idom:
&lt;/p&gt;

&lt;pre&gt; chdir '/usr/spool/news' || die "Can't cd to spool: $!\n"&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;
though the &lt;code&gt;or&lt;/code&gt; keyword seems to be preferred nowadays to &lt;code&gt;||&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
This morning, I came across the &lt;a href="http://blog.devstone.com/Aaron/archive/2006/01/02/1404.aspx" title="?? operator in C# 2.0"&gt;?? operator in C# 2.0&lt;/a&gt;,
aka the null coalescing operator:
&lt;/p&gt;

&lt;pre&gt; Customer cust = getCustomer(id) ?? new Customer();&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;
If &lt;code&gt;getCustomer(id)&lt;/code&gt; is not &lt;code&gt;null&lt;/code&gt;, then that's the value that &lt;code&gt;cust&lt;/code&gt; gets;
otherwise it's set to &lt;code&gt;new Customer()&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
All of these idioms are &lt;a href="http://en.wikipedia.org/wiki/Syntactic_sugar" title="syntactic sugar"&gt;syntactic sugar&lt;/a&gt; and all of them are in my toolbox.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.georgevreilly.com/blog/cptrk.ashx?id=0c7d443b-c3b7-4344-8605-daf0148d08ae"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=4738757" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/Software/default.aspx">Software</category></item><item><title>Virtualization</title><link>http://weblogs.asp.net/george_v_reilly/archive/2007/10/23/virtualization.aspx</link><pubDate>Wed, 24 Oct 2007 03:57:53 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:4721530</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=4721530</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2007/10/23/virtualization.aspx#comments</comments><description>&lt;p&gt;

&lt;img src="http://www.georgevreilly.com/blog/content/binary/virtualization.jpg" class="right-float" alt="content/binary/virtualization.jpg" title="Virtualization"&gt;

&lt;/p&gt;

&lt;p&gt;
Picture this.
&lt;/p&gt;

&lt;p&gt;
An external USB hard drive plugged in to a machine running Win64.
The OS has &lt;em&gt;virtualized&lt;/em&gt; the underlying transport so that it's
essentially indistinguishable from an internal IDE, SCSi, or SATA drive.
Call the machine, Boss, and the USB drive, L:.
&lt;/p&gt;

&lt;p&gt;
Boss is running Virtual PC, which is hosting a 32-bit &lt;em&gt;virtual&lt;/em&gt; machine
on top of Boss's 64-bit OS.
Let's call the 32-bit VM, Sidekick.
&lt;/p&gt;

&lt;p&gt;
Sidekick is not only a VM, but a &lt;em&gt;virtual&lt;/em&gt; network host.
Boss is bridging connections to Sidekick, and
Sidekick and Boss both appear on the LAN as separate network hosts.
&lt;/p&gt;

&lt;p&gt;
The USB drive has several ISO images, which Sidekick wants to use.
Sidekick connects to \\Master\L$ over the virtual network,
and uses a tool like &lt;a href="http://jeranderson.wordpress.com/2006/10/17/installing-windows-vista-with-a-virtual-cddvd-drive/" title="VcdTool"&gt;VcdTool&lt;/a&gt; to mount the remote ISO on a
&lt;em&gt;virtual&lt;/em&gt; CD drive.
&lt;/p&gt;

&lt;p&gt;
Amazingly enough, it all just worked for me last night.
&lt;/p&gt;

&lt;p&gt;
I'm trying to set up an environment where I can build
Vim with various 32-bit and 64-bit Microsoft compilers and,
more importantly, run the &lt;a href="http://www.georgevreilly.com/blog/2007/02/20/VimOnWin64Updated.aspx" title="Win64 binary"&gt;Win64 binary&lt;/a&gt;.
I have a set of VM images with distinct flavors of MSVC,
which was necessary to update &lt;a href="http://vim.svn.sourceforge.net/viewvc/vim/vim7/src/INSTALLpc.txt?view=markup" title="INSTALLpc.txt"&gt;INSTALLpc.txt&lt;/a&gt;
and to keep Make_mvc.mak building.
&lt;/p&gt;

&lt;p&gt;
In previous iterations, I got Remote Desktop access to
a colleague's Win64 machine, but that was at Atlas,
so it's no longer an option.
I bought a new AMD64 desktop system a few months ago
and over the weekend set it up to &lt;a href="http://apcmag.com/5485/dualbooting_vista_and_xp" title="dual boot"&gt;dual boot&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.georgevreilly.com/blog/cptrk.ashx?id=5e2071da-5e63-4f91-862c-650540a278ab"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=4721530" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/Software/default.aspx">Software</category></item><item><title>Greasemonkey for demos and mockups</title><link>http://weblogs.asp.net/george_v_reilly/archive/2007/10/11/greasemonkey-for-demos-and-mockups.aspx</link><pubDate>Thu, 11 Oct 2007 07:05:48 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:4521334</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=4521334</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2007/10/11/greasemonkey-for-demos-and-mockups.aspx#comments</comments><description>
&lt;p&gt;
&lt;a href="http://www.greasespot.net/"&gt;
&lt;img src="http://www.wired.com/wired/archive/13.09/images/ST_34_monkey1_f.jpg" alt="http://www.wired.com/wired/archive/13.09/images/ST_34_monkey1_f.jpg" title="Greasemonkey"&gt;
&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
I've been meaning to play around with &lt;a href="http://www.greasespot.net/" title="Greasemonkey"&gt;Greasemonkey&lt;/a&gt; for a couple of years.
Greasemonkey is a Firefox extension that allows users to install
scripts that make on-the-fly changes to the look and feel of third-party websites.
For example, adding price comparisons to Amazon
or thumbnail images to Google search results.
&lt;a href="http://userscripts.org/" title="UserScripts.org"&gt;UserScripts.org&lt;/a&gt; has a large repository of Greasemonkey scripts.
&lt;/p&gt;

&lt;p&gt;
I finally built my first script the other day.
We're putting together a new feature at &lt;a href="http://www.cozi.com/" title="Cozi"&gt;Cozi&lt;/a&gt; that integrates
partner websites with our site.
Since the feature is not yet announced, I'll just say that partners
will add a link to Cozi on many of their database-driven pages.
That link has a complex, page-dependent querystring.
Until the partners do the work to add the link to their sites,
we were limited to testing and demoing with hand-modified pages.
&lt;/p&gt;

&lt;p&gt;
I wrote a little Greasemonkey script that finds the right spot
on the partner pages to place the link,
scrapes some context to construct the querystring,
and inserts the link.
Now we can test against the real sites and show a compelling demo.
Of course, it only works on Firefox and it requires you to
install both Greasemonkey and this script.
Our partners will have to make minor changes to their sites
before ordinary users can take advantage of the feature.
&lt;/p&gt;

&lt;p&gt;
Some gotchas with Greasemonkey.
Inserting, say, &lt;code&gt;&amp;lt;b&amp;gt;Click here&amp;lt;/b&amp;gt;&lt;/code&gt; is as simple as
&lt;code&gt;document.getElementById('spot').innerHTML = &amp;lt;b&amp;gt;Click here&amp;lt;/b&amp;gt;&lt;/code&gt;.
However, inserting a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; node requires:
&lt;/p&gt;

&lt;pre&gt; var scr = document.createElement('script');&lt;br&gt; scr.type = 'text/javascript';&lt;br&gt; scr.text = 'createLink(' + p1 + ', ' + p2 + ', ' + p3 + ');';&lt;br&gt; document.getElementById('spot').appendChild(scr);&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;
Greasemonkey will definitely become part of my repertoire.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.georgevreilly.com/blog/cptrk.ashx?id=52a56d9e-8057-4a94-a0aa-289494afe8bc"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=4521334" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/Software/default.aspx">Software</category></item><item><title>Cozi is Hiring</title><link>http://weblogs.asp.net/george_v_reilly/archive/2007/09/24/cozi-is-hiring.aspx</link><pubDate>Mon, 24 Sep 2007 20:36:06 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:4118650</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=4118650</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2007/09/24/cozi-is-hiring.aspx#comments</comments><description>
&lt;p&gt;
&lt;a href="http://www.cozi.com/about/careers.aspx"&gt;
&lt;img src="http://www.cozi.com/images/cozi_logo_transp.png" class="right-float" alt="http://www.cozi.com/images/cozi_logo_transp.png" title="Cozi"&gt;
&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Cozi is &lt;a href="http://www.cozi.com/about/careers.aspx" title="hiring"&gt;hiring&lt;/a&gt;.
We have positions for Developers and Web Developers.
&lt;/p&gt;

&lt;p&gt;
We're a small Web 2.0 startup, based in the &lt;a href="http://www.smithtower.com/" title="Smith Tower"&gt;Smith Tower&lt;/a&gt; in downtown Seattle.
Our &lt;a href="http://www.cozi.com/products/default.aspx" title="Cozi Central"&gt;Cozi Central&lt;/a&gt; product is groupware for families:
it helps parents manage their own and their kids' schedules,
shopping lists, and reminders, from computers, PDAs, and mobile phones.
&lt;/p&gt;

&lt;p&gt;
If you're interested, let me know.
&lt;/p&gt;

&lt;p&gt;
&lt;em&gt;Update&lt;/em&gt;: we have some non-developer positions too.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.georgevreilly.com/blog/cptrk.ashx?id=6ead984f-073b-4fef-bb78-4081eef681cb"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=4118650" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/General/default.aspx">General</category></item><item><title>Building a REST Web Service, day 1</title><link>http://weblogs.asp.net/george_v_reilly/archive/2007/08/14/building-a-rest-web-service-day-1.aspx</link><pubDate>Wed, 15 Aug 2007 02:58:21 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:3509185</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=3509185</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2007/08/14/building-a-rest-web-service-day-1.aspx#comments</comments><description>&lt;p&gt;
&lt;a href="http://rest.blueoxen.net/"&gt;
&lt;img src="http://upload.wikimedia.org/wikipedia/en/thumb/8/89/Resttriangle.svg/273px-Resttriangle.svg.png" class="right-float" alt="http://upload.wikimedia.org/wikipedia/en/thumb/8/89/Resttriangle.svg/273px-Resttriangle.svg.png" title="The REST Triangle"&gt;
&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
My first project at &lt;a href="http://www.cozi.com/" title="Cozi"&gt;Cozi&lt;/a&gt; is to build a simple &lt;a href="http://rest.blueoxen.net/" title="REST"&gt;REST&lt;/a&gt;-style Web Service.
Nobody here has done that before.
&lt;/p&gt;

&lt;p&gt;
The first thing that I'm trying to get going is a simple &lt;a href="http://msdn2.microsoft.com/en-us/library/ms972974.aspx" title="URL rewriter"&gt;URL rewriter&lt;/a&gt;,
using an ASP.NET HttpModule.
&lt;/p&gt;

&lt;p&gt;
I'm running Vista as my development desktop for the first time.
So far, not bad, but there are lots of new quirks to get used to.
I've been a good boy so far and I've left the User Access Control stuff enabled,
so that I'm not running with administrative privileges by default.
&lt;/p&gt;

&lt;p&gt;
It's my first exposure to IIS 7.
I must say that the IIS UI is much improved
(a low bar to surmount).
&lt;/p&gt;

&lt;p&gt;
My first problem was that &lt;a href="http://www.georgevreilly.com/blog/2005/11/17/SkypeAndSSL.aspx" title="Skype was squatting on port 80"&gt;Skype was squatting on port 80&lt;/a&gt;,
preventing browser requests going to localhost.
This happens to me about once a year on a new dev machine,
and I always forget.
&lt;/p&gt;

&lt;p&gt;
To get the HttpModule going, I had to follow
Mark Rasmussen's detailed instructions on
&lt;a href="http://www.improve.dk/blog/2006/12/11/making-url-rewriting-on-iis7-work-like-iis6" title="making URL rewriting on IIS 7 work like IIS 6"&gt;making URL rewriting on IIS 7 work like IIS 6&lt;/a&gt;.
The code will be deployed on Windows Server 2003,
so IIS 6 compatibility is more important to me than IIS 7 purity.
&lt;/p&gt;

&lt;p&gt;
I was trying to get some debug output appearing in &lt;a href="http://www.microsoft.com/technet/sysinternals/utilities/debugview.mspx" title="DebugView"&gt;DebugView&lt;/a&gt;,
but my &lt;code&gt;Trace.WriteLine&lt;/code&gt;s were not showing up.
Some Googling eventually showed me that I had to enable
&lt;code&gt;Capture Global Win32&lt;/code&gt;, which I never had to do before.
Presumably because ASP.NET is executing in a different desktop session.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.georgevreilly.com/blog/cptrk.ashx?id=ffa0dca2-b0a2-4aa3-b9e1-64953d81f93f"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3509185" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Serializing a NameValueCollection</title><link>http://weblogs.asp.net/george_v_reilly/archive/2007/07/19/serializing-a-namevaluecollection.aspx</link><pubDate>Fri, 20 Jul 2007 06:31:59 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:3231835</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=3231835</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2007/07/19/serializing-a-namevaluecollection.aspx#comments</comments><description>&lt;p&gt;

&lt;img src="http://www.georgevreilly.com/blog/content/binary/serialize-nvc.jpg" alt="content/binary/serialize-nvc.jpg" title="Serializing a NameValueCollection"&gt;

&lt;/p&gt;

&lt;p&gt;
I had a NameValueCollection embedded inside a larger object.
I needed to serialize the larger object into XML and back.
Unfortunately, NameValueCollection is not XML serializable.
Why I do not know.
&lt;/p&gt;

&lt;p&gt;
A blog comment from &lt;a href="http://nayyeri.net/archive/2006/08/11/Serialize-NameValueCollection.aspx#72442" title="Tim Erwin"&gt;Tim Erwin&lt;/a&gt; got me started in the right direction.
Implement &lt;code&gt;IXmlSerializable&lt;/code&gt; and do the work by hand in
&lt;code&gt;ReadXml&lt;/code&gt; and &lt;code&gt;WriteXml&lt;/code&gt;.
&lt;/p&gt;


&lt;p&gt;
Tim's implementation turned out to be overly simple.
It didn't handle an empty collection well,
nor did it leave the &lt;code&gt;XmlReader&lt;/code&gt; in a good state.
&lt;/p&gt;

&lt;p&gt;
I used &lt;a href="http://msdn2.microsoft.com/en-us/library/bk3w6240%28vs.80%29.aspx" title="SGen"&gt;SGen&lt;/a&gt; to examine the deserialization of a
&lt;code&gt;List&amp;lt;String&amp;gt;&lt;/code&gt; to figure out what else needed to be done.
&lt;/p&gt;


&lt;p&gt;
The following &lt;code&gt;ReadXml&lt;/code&gt; seems to work.
If I expected to receive XML from untrusted sources,
I would make this more robust.
&lt;/p&gt;


&lt;pre class="tohtml-cs----inkpot"&gt; &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; ReadXml(XmlReader reader)&lt;br&gt; {&lt;br&gt;     &lt;span class="Statement"&gt;if&lt;/span&gt; (reader.IsEmptyElement)&lt;br&gt;         &lt;span class="Statement"&gt;return&lt;/span&gt;;&lt;br&gt;&lt;br&gt;     &lt;span class="Statement"&gt;while&lt;/span&gt; (reader.Read()&lt;br&gt;         &amp;amp;&amp;amp; reader.NodeType != XmlNodeType.EndElement&lt;br&gt;         &amp;amp;&amp;amp; reader.NodeType != XmlNodeType.None)&lt;br&gt;     {&lt;br&gt;         &lt;span class="Statement"&gt;if&lt;/span&gt; (reader.NodeType == XmlNodeType.Element &amp;amp;&amp;amp; reader.LocalName == &lt;span class="String"&gt;"Header"&lt;/span&gt;)&lt;br&gt;         {&lt;br&gt;             reader.MoveToAttribute(&lt;span class="String"&gt;"name"&lt;/span&gt;);&lt;br&gt;             &lt;span class="Type"&gt;string&lt;/span&gt; name = reader.Value;&lt;br&gt;             reader.MoveToAttribute(&lt;span class="String"&gt;"value"&lt;/span&gt;);&lt;br&gt;             &lt;span class="Type"&gt;string&lt;/span&gt; &lt;span class="Statement"&gt;value&lt;/span&gt; = reader.Value;&lt;br&gt;             Add(name, &lt;span class="Statement"&gt;value&lt;/span&gt;);&lt;br&gt;         }&lt;br&gt;     }&lt;br&gt;     reader.ReadEndElement();&lt;br&gt; }&lt;br&gt;&lt;br&gt; &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; WriteXml(XmlWriter writer)&lt;br&gt; {&lt;br&gt;    &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Type"&gt;string&lt;/span&gt; name &lt;span class="Statement"&gt;in&lt;/span&gt; nvc.Keys)&lt;br&gt;    {&lt;br&gt;        writer.WriteStartElement(&lt;span class="String"&gt;"Header"&lt;/span&gt;);&lt;br&gt;        &lt;span class="Type"&gt;string&lt;/span&gt; &lt;span class="Statement"&gt;value&lt;/span&gt; = nvc[name];&lt;br&gt;        writer.WriteAttributeString(&lt;span class="String"&gt;"name"&lt;/span&gt;,  name);&lt;br&gt;        writer.WriteAttributeString(&lt;span class="String"&gt;"value"&lt;/span&gt;, &lt;span class="Statement"&gt;value&lt;/span&gt;);&lt;br&gt;        writer.WriteEndElement();&lt;br&gt;    }&lt;br&gt; }&lt;br&gt;&lt;br&gt; &lt;span class="Type"&gt;public&lt;/span&gt; XmlSchema GetSchema( )&lt;br&gt; {&lt;br&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;null&lt;/span&gt;;&lt;br&gt; }&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;
I also found that I needed to implement custom &lt;code&gt;Equals&lt;/code&gt;
and &lt;code&gt;GetHashCode&lt;/code&gt;, as the &lt;code&gt;NameValueCollection&lt;/code&gt;
implementations didn't seem to do what I wanted.
&lt;/p&gt;


&lt;pre class="tohtml-cs----inkpot"&gt; &lt;span class="Comment"&gt;// Have to override GetHashCode() as two apparently identical NameValueCollections&lt;/span&gt;
 &lt;span class="Comment"&gt;// will have different hash codes.&lt;/span&gt;
 &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;override&lt;/span&gt; &lt;span class="Type"&gt;int&lt;/span&gt; GetHashCode()&lt;br&gt; {&lt;br&gt;     &lt;span class="Type"&gt;int&lt;/span&gt; hash = nvc.Count;&lt;br&gt;&lt;br&gt;     &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Type"&gt;string&lt;/span&gt; name &lt;span class="Statement"&gt;in&lt;/span&gt; nvc)&lt;br&gt;     {&lt;br&gt;         hash = &lt;span class="Number"&gt;757&lt;/span&gt; * hash  +  &lt;span class="Number"&gt;101&lt;/span&gt; * nvc[name].GetHashCode()  +  name.GetHashCode();&lt;br&gt;     }&lt;br&gt;&lt;br&gt;     &lt;span class="Statement"&gt;return&lt;/span&gt; hash;&lt;br&gt; }&lt;br&gt;&lt;br&gt; &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;bool&lt;/span&gt; Equals(HeadersCollection that)&lt;br&gt; {&lt;br&gt;     &lt;span class="Statement"&gt;if&lt;/span&gt; (ReferenceEquals(that, &lt;span class="Constant"&gt;null&lt;/span&gt;))&lt;br&gt;         &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;false&lt;/span&gt;;&lt;br&gt;&lt;br&gt;     &lt;span class="Statement"&gt;if&lt;/span&gt; (ReferenceEquals(&lt;span class="Statement"&gt;this&lt;/span&gt;, that))&lt;br&gt;         &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;true&lt;/span&gt;;&lt;br&gt;&lt;br&gt;     &lt;span class="Comment"&gt;// Have to explicitly compare the contents of the collections&lt;/span&gt;
     &lt;span class="Comment"&gt;// as NameValueCollection.Equals doesn't seem to do what we want.&lt;/span&gt;
     &lt;span class="Comment"&gt;// Note: this is independent of order.&lt;/span&gt;
     &lt;span class="Statement"&gt;if&lt;/span&gt; (nvc.Count != that.nvc.Count)&lt;br&gt;         &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;false&lt;/span&gt;;&lt;br&gt;&lt;br&gt;     &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Type"&gt;string&lt;/span&gt; name &lt;span class="Statement"&gt;in&lt;/span&gt; nvc)&lt;br&gt;     {&lt;br&gt;         &lt;span class="Statement"&gt;if&lt;/span&gt; (nvc[name] != that.nvc.Get(name))&lt;br&gt;             &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;false&lt;/span&gt;;&lt;br&gt;     }&lt;br&gt;&lt;br&gt;     &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;true&lt;/span&gt;;&lt;br&gt; }&lt;br&gt;&lt;br&gt; &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;bool&lt;/span&gt; Equals(HeadersCollection headersA, HeadersCollection headersB)&lt;br&gt; {&lt;br&gt;     &lt;span class="Statement"&gt;if&lt;/span&gt; (headersA == &lt;span class="Constant"&gt;null&lt;/span&gt;)&lt;br&gt;         &lt;span class="Statement"&gt;return&lt;/span&gt; (headersB == &lt;span class="Constant"&gt;null&lt;/span&gt;);&lt;br&gt;&lt;br&gt;     &lt;span class="Statement"&gt;if&lt;/span&gt; (ReferenceEquals(headersA, headersB))&lt;br&gt;         &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;true&lt;/span&gt;;&lt;br&gt;&lt;br&gt;     &lt;span class="Statement"&gt;return&lt;/span&gt; headersA.Equals(headersB);&lt;br&gt; }&lt;br&gt;&lt;br&gt; &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;override&lt;/span&gt; &lt;span class="Type"&gt;bool&lt;/span&gt; Equals(&lt;span class="Type"&gt;object&lt;/span&gt; obj)&lt;br&gt; {&lt;br&gt;     &lt;span class="Statement"&gt;if&lt;/span&gt; (obj &lt;span class="Statement"&gt;is&lt;/span&gt; HeadersCollection)&lt;br&gt;         &lt;span class="Statement"&gt;return&lt;/span&gt; Equals((HeadersCollection) obj);&lt;br&gt;&lt;br&gt;     &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;false&lt;/span&gt;;&lt;br&gt; }&lt;br&gt;&lt;/pre&gt;
&lt;hints id="hah_hints"&gt;&lt;/hints&gt;&lt;img width="0" height="0" src="http://www.georgevreilly.com/blog/cptrk.ashx?id=8e4c888e-febe-4cb4-8e89-ca04894d32e0"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=3231835" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Hotkey for Clipboard.NET</title><link>http://weblogs.asp.net/george_v_reilly/archive/2007/03/26/hotkey-for-clipboard-net.aspx</link><pubDate>Tue, 27 Mar 2007 03:16:18 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:2108640</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=2108640</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2007/03/26/hotkey-for-clipboard-net.aspx#comments</comments><description>
&lt;p&gt;
&lt;a href="https://clipmon32.bountysource.com/"&gt;
&lt;img src="https://files.bountysource.com/system/files/LibraryEntry/144/screenshot.jpg.medium.jpg" alt="https://files.bountysource.com/system/files/LibraryEntry/144/screenshot.jpg.medium.jpg" title="Clipboard.NET" width="320"&gt;
&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
I use &lt;a href="https://clipmon32.bountysource.com/" title="Clipboard.NET"&gt;Clipboard.NET&lt;/a&gt; as a clipboard manager on Windows.
It stores the last few entries sent to the clipboard.
&lt;/p&gt;

&lt;p&gt;
There's one problem: the default hotkey is Ctrl+Comma,
which also happens to be an important key for Outlook
(previous message).
I figured out a while ago how to &lt;a href="https://clipmon32.bountysource.com/task/show/1213" title="change the hotkey"&gt;change the hotkey&lt;/a&gt;,
but my &lt;a href="https://clipmon32.bountysource.com/task/show/1213" title="report"&gt;report&lt;/a&gt; doesn't show up when you search for it.
&lt;/p&gt;

&lt;p&gt;
Net: using a key name from the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.consolekey.aspx" title="ConsoleKey table"&gt;ConsoleKey table&lt;/a&gt;,
change the value of &lt;code&gt;ShortcutKey&lt;/code&gt; in 
&lt;code&gt;%ProgramFiles%\Tom Medhurst\Clipboard.NET\clipmon32.exe.config&lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt; &amp;lt;applicationSettings&amp;gt;&lt;br&gt;     &amp;lt;clipmon32.Properties.Settings&amp;gt;&lt;br&gt;           &amp;lt;setting name="ShortcutKey" serializeAs="String"&amp;gt;&lt;br&gt;                   &amp;lt;value&amp;gt;OemComma&amp;lt;/value&amp;gt;&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;
The new hotkey will be Ctrl+keyname.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.georgevreilly.com/blog/cptrk.ashx?id=f4447637-ab0d-4c75-b1a2-01ca1a7891f5"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=2108640" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/Software/default.aspx">Software</category></item><item><title>NUnit calling CppUnit</title><link>http://weblogs.asp.net/george_v_reilly/archive/2007/03/21/nunit-calling-cppunit.aspx</link><pubDate>Wed, 21 Mar 2007 19:12:46 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:2075741</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=2075741</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2007/03/21/nunit-calling-cppunit.aspx#comments</comments><description>
&lt;p&gt;

&lt;img src="http://www.georgevreilly.com/blog/content/binary/NUnit-CppUnit.png" class="right-float" alt="http://www.georgevreilly.com/blog/content/binary/NUnit-CppUnit.png" title="NUnit calling CppUnit"&gt;

&lt;/p&gt;

&lt;p&gt;
Over the last few days, I've been adapting an existing native C++ library
so that it can be called from managed code.
I had written a large number of unit tests with &lt;a href="http://cppunit.sourceforge.net/" title="CppUnit"&gt;CppUnit&lt;/a&gt;
and I wanted to be able to call the tests from &lt;a href="http://www.nunit.org/" title="NUnit"&gt;NUnit&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
I suppose that I could have written a new CppUnit &lt;a href="http://cppunit.sourceforge.net/cppunit-wiki/TestRunner" title="TestRunner"&gt;TestRunner&lt;/a&gt; so that I 
could call it from NUnit.
Instead, I took the cheap-n-dirty route, playing with &lt;code&gt;#define&lt;/code&gt;
and include paths.
It took less time to get working than it did to write this blog post.
&lt;/p&gt;

&lt;p&gt;
Here's the original native CppUnit test code
&lt;/p&gt;


&lt;pre class="tohtml-cpp----inkpot"&gt; &lt;span class="Comment"&gt;//-------------------------------&lt;/span&gt;
 &lt;span class="Comment"&gt;// native\FooTest.h&lt;/span&gt;
 &lt;span class="Comment"&gt;//-------------------------------&lt;/span&gt;

&lt;span class="PreProc"&gt; #include &lt;/span&gt;&lt;span class="String"&gt;&amp;lt;cppunit/extensions/HelperMacros.h&amp;gt;&lt;/span&gt;

 &lt;span class="Type"&gt;class&lt;/span&gt; FooTest : &lt;span class="Statement"&gt;public&lt;/span&gt; CppUnit::TestFixture&lt;br&gt; {&lt;br&gt;     CPPUNIT_TEST_SUITE( FooTest );&lt;br&gt;     CPPUNIT_TEST( testAlpha );&lt;br&gt;     CPPUNIT_TEST_SUITE_END();&lt;br&gt; &lt;span class="Statement"&gt;public&lt;/span&gt;:&lt;br&gt;     &lt;span class="Type"&gt;void&lt;/span&gt; testAlpha();&lt;br&gt; };&lt;br&gt;&lt;br&gt; &lt;span class="Comment"&gt;//-------------------------------&lt;/span&gt;
 &lt;span class="Comment"&gt;// native\FooTest.cpp&lt;/span&gt;
 &lt;span class="Comment"&gt;//-------------------------------&lt;/span&gt;

&lt;span class="PreProc"&gt; #include &lt;/span&gt;&lt;span class="String"&gt;"FooTest.h"&lt;/span&gt;

 &lt;span class="Comment"&gt;// Registers the fixture into the test 'registry'&lt;/span&gt;
 CPPUNIT_TEST_SUITE_REGISTRATION( FooTest );

 &lt;span class="Type"&gt;void&lt;/span&gt; FooTest::testAlpha()&lt;br&gt; {&lt;br&gt;     CPPUNIT_ASSERT( &lt;span class="Number"&gt;4&lt;/span&gt; == &lt;span class="Number"&gt;2&lt;/span&gt; + &lt;span class="Number"&gt;2&lt;/span&gt;);&lt;br&gt; }&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;
And here's my managed NUnit-based wrapper.
&lt;/p&gt;


&lt;pre class="tohtml-cpp----inkpot"&gt; &lt;span class="Comment"&gt;//-------------------------------&lt;/span&gt;
 &lt;span class="Comment"&gt;// managed\FooTest.h&lt;/span&gt;
 &lt;span class="Comment"&gt;//-------------------------------&lt;/span&gt;

 &lt;span class="Statement"&gt;using&lt;/span&gt; &lt;span class="Type"&gt;namespace&lt;/span&gt; NUnit::Framework;&lt;br&gt;&lt;br&gt; &lt;span class="Comment"&gt;// Gross hack. Define a completely different NUnit-compatible FooTest&lt;/span&gt;
 &lt;span class="Comment"&gt;// test fixture and use #define's to make the CPPUnit-specific&lt;/span&gt;
 &lt;span class="Comment"&gt;// stuff build.&lt;/span&gt;

 [TestFixture]
 &lt;span class="Statement"&gt;public&lt;/span&gt; ref &lt;span class="Type"&gt;class&lt;/span&gt; FooTest&lt;br&gt; {&lt;br&gt; &lt;span class="Statement"&gt;public&lt;/span&gt;:&lt;br&gt;     [Test] &lt;span class="Type"&gt;void&lt;/span&gt; testAlpha();&lt;br&gt; };&lt;br&gt;&lt;br&gt;&lt;span class="PreProc"&gt; #define CPPUNIT_TEST_SUITE_REGISTRATION(x)&lt;/span&gt;
&lt;span class="PreProc"&gt; #define CPPUNIT_ASSERT(x) Assert::IsTrue(x)&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;
I had to make one change to &lt;code&gt;native\FooTest.cpp&lt;/code&gt;,
to &lt;code&gt;#include &amp;lt;FooTest.h&amp;gt;&lt;/code&gt; (angle brackets).
This picks up the first &lt;code&gt;FooTest.h&lt;/code&gt; in the include path,
so that the managed version of &lt;code&gt;FooTest.cpp&lt;/code&gt;
now picks up &lt;code&gt;managed\FooTest.h&lt;/code&gt;,
instead of the original.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.georgevreilly.com/blog/cptrk.ashx?id=4b7c6cb4-d1cd-4d00-b6b0-39286f27c6c0"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=2075741" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/.NET/default.aspx">.NET</category></item><item><title>NVelocity: loading templates from embedded resources</title><link>http://weblogs.asp.net/george_v_reilly/archive/2007/03/14/nvelocity-loading-templates-from-embedded-resources.aspx</link><pubDate>Wed, 14 Mar 2007 17:50:25 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:2075903</guid><dc:creator>george_v_reilly</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/george_v_reilly/rsscomments.aspx?PostID=2075903</wfw:commentRss><comments>http://weblogs.asp.net/george_v_reilly/archive/2007/03/14/nvelocity-loading-templates-from-embedded-resources.aspx#comments</comments><description>&lt;p&gt;
&lt;a href="http://www.castleproject.org/others/nvelocity/index.html"&gt;
&lt;img src="http://www.codegeneration.net/logos/nvelocity.gif" class="right-float" alt="http://www.codegeneration.net/logos/nvelocity.gif" title="NVelocity"&gt;
&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
In last week's tip on 
using the &lt;a href="http://www.castleproject.org/others/nvelocity/index.html" title="NVelocity"&gt;NVelocity&lt;/a&gt; template formatting engine,
I described what to set to load a template from
an &lt;a href="http://www.georgevreilly.com/blog/2007/03/07/NVelocityTemplatesAndAbsolutePaths.aspx" title="absolute path"&gt;absolute path&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Here's the magic necessary to get NVelocity to load a template from an 
embedded resource:
&lt;/p&gt;


&lt;pre class="tohtml-cs----inkpot"&gt; VelocityEngine engine = &lt;span class="Statement"&gt;new&lt;/span&gt; VelocityEngine();&lt;br&gt; ExtendedProperties properties = &lt;span class="Statement"&gt;new&lt;/span&gt; ExtendedProperties();&lt;br&gt; properties.AddProperty(&lt;span class="String"&gt;"resource.loader"&lt;/span&gt;, &lt;span class="String"&gt;"assembly"&lt;/span&gt;);&lt;br&gt; properties.AddProperty(&lt;span class="String"&gt;"assembly.resource.loader.class"&lt;/span&gt;,&lt;br&gt;     &lt;span class="String"&gt;"NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader, NVelocity"&lt;/span&gt;);&lt;br&gt; properties.AddProperty(&lt;span class="String"&gt;"assembly.resource.loader.assembly"&lt;/span&gt;, &lt;span class="String"&gt;"StencilFormatter"&lt;/span&gt;);&lt;br&gt; engine.Init(properties);&lt;br&gt;&lt;/pre&gt;
&lt;img width="0" height="0" src="http://www.georgevreilly.com/blog/cptrk.ashx?id=b56240c1-ec9d-40a8-95f7-68b291b20df5"&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=2075903" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/george_v_reilly/archive/tags/.NET/default.aspx">.NET</category></item></channel></rss>