<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-3339316202894508517</atom:id><lastBuildDate>Sat, 21 Apr 2012 17:10:19 +0000</lastBuildDate><category>randomness</category><category>walking</category><category>cvs</category><category>java</category><category>usalife</category><category>cookies</category><category>san francisco</category><category>apple</category><category>xmlrpc</category><category>bay bridge</category><category>greencard</category><category>terminator</category><category>bash</category><category>concurrency</category><category>life hacks</category><category>drwho</category><category>inbox zero</category><category>jar</category><category>oracle</category><category>jdeveloper</category><category>bloopers</category><category>golden gate bridge</category><category>coding</category><category>investment</category><category>email</category><category>ternary</category><category>tv</category><category>collections</category><category>folders</category><category>thunderbird</category><category>blogging</category><category>chinese</category><category>subversion</category><category>google</category><title>Duffblog 2.0</title><description>Yay! Another blog.</description><link>http://blog.dubh.org/</link><managingEditor>noreply@blogger.com (Brian Duff)</managingEditor><generator>Blogger</generator><openSearch:totalResults>42</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-8894042918069640028</guid><pubDate>Fri, 10 Jul 2009 02:14:00 +0000</pubDate><atom:updated>2009-11-09T09:00:27.744-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>cookies</category><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>xmlrpc</category><title>Cookie handling with Apache XML-RPC</title><description>&lt;p&gt;
The &lt;a href="http://ws.apache.org/xmlrpc/advanced.html"&gt;example&lt;/a&gt; on the Apache website that explains how to pass cookies when calling an XML-RPC service is unfortunately... a bit b0rked. It doesn't compile, for starters. It's also quite a bit more complicated (and handwavy) than it needs to be. I don't know if this is because the API has changed over time. I tend to think it has suffered the copy-paste equivalent of chinese whispers from an origin in some mailing list.&lt;/p&gt;

&lt;p&gt;
Anyway, I needed to send a single sign on (SSO) cookie to an XML-RPC service recently. I'm using Apache XML-RPC 3.1 (I notice in the Javadoc that this code might be slightly different if you're using a later version). Here's roughly what I did:
&lt;/p&gt;

&lt;p&gt;First, the standard, boring stuff:&lt;/p&gt;

&lt;pre&gt;
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("https://myservice.com/api"));
XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);
&lt;/pre&gt;

&lt;p&gt;Now, the juicy part. It's really, really easy. Look, ma, so much less code than the example on the ws.apache.org website, and it's even &lt;i&gt;syntactically correct!&lt;/i&gt;:&lt;/p&gt;

&lt;pre&gt;
XmlRpcTransportFactory factory = new XmlRpcSunHttpTransportFactory(client) {
  public XmlRpcTransport getTransport() {
    return new XmlRpcSunHttpTransport(client) {
      @Override protected void initHttpHeaders(XmlRpcRequest request) throws XmlRpcClientException {
        super.initHttpHeaders(request);
        setRequestHeader("Cookie", myLovelyCookieData);
      }
    }
  }
};
client.setTransportFactory(factory);
&lt;/pre&gt;

&lt;b&gt;Update&lt;/b&gt;: Fixed a bug in the code. Oh, the irony. That'll teach me to be so arrogant :P&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-8894042918069640028?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2009/07/cookie-handling-with-apache-xml-rpc.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-8374701179773055822</guid><pubDate>Fri, 05 Jun 2009 02:15:00 +0000</pubDate><atom:updated>2009-06-04T19:19:31.769-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>jar</category><category domain='http://www.blogger.com/atom/ns#'>bash</category><title>Find a file inside a zip</title><description>&lt;p&gt;Brutally simple shell script I often use to find a class file that I know exists somewhere in a directory tree full of jar files (but generally useful for finding files somewhere in a directory tree of zips):&lt;/p&gt;

&lt;pre&gt;
#!/bin/bash                                                                             
                                                                                        
for zip in $*                                                                           
do                                                                                      
  echo $zip                                                                             
  for file in $(unzip -Z -1 $zip)                                                       
  do                                                                                    
    echo "$zip:$file"                                                                   
  done                                                                                  
done
&lt;/pre&gt;

I put this in a file called zipdump, then do things like this:

&lt;pre&gt;
find -name "*.jar" | xargs zipdump | grep SomeClass
&lt;/pre&gt;

And get:

&lt;pre&gt;
./some/random/path/foo.jar:com/google/whatever/SomeClass.class
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-8374701179773055822?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2009/06/find-file-inside-zip.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-8604038219689389215</guid><pubDate>Thu, 14 May 2009 00:38:00 +0000</pubDate><atom:updated>2009-05-13T17:42:38.245-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>chinese</category><title>Listing Chinese Words by Frequency of Use</title><description>A commenter on my previous blog entry, Yong Huang, pointed me to some wonderful research he did using search engine results to compile a list of Chinese characters in frequency order. I managed to miss his comment when he posted it back in March (d'oh. I really should have paid more attention to my blogger settings), but it's an interesting read and technique:&lt;p&gt;

&lt;a href="http://yong321.freeshell.org/misc/ChineseCharFrequency.html"&gt;http://yong321.freeshell.org/misc/ChineseCharFrequency.html&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-8604038219689389215?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2009/05/listing-chinese-words-by-frequency-of.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-7589127713918679749</guid><pubDate>Sun, 11 Jan 2009 22:02:00 +0000</pubDate><atom:updated>2009-05-13T15:45:55.296-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>chinese</category><title>Getting serious about Mandarin</title><description>I'm finally making a big effort to learn mandarin properly. In addition to taking formal lessons at UC Berkley starting in February, and learning about usage from Cindy, I'm using flash cards to increase my knowledge of Chinese characters and their mandarin pronunciation (including the tones, which I've had a hard job remembering up till now while picking up mandarin informally through random conversation). &lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;I've been using some tricks to memorize characters, and this technique seems to work well for me. &lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;Here's the first set of characters. The first ten are numbers, and mostly pretty easy.&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;一 二 三&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;one (yi1), two (er4), three (san1). These are quite possibly the simplest Chinese characters ever. :)&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;四&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;four (si4). This one is kind of easy for me to remember, since I visited &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;si&lt;/span&gt;chuan last year, and this character was everywhere :) It's also a box with four sides.&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;五&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;five (wu3). I convinced myself that this character has five distinct lines in it, which made it easy to remember (although it actually has only four strokes - the middle horizontal line and the smaller vertical line are combined together as a single stroke). &lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;六&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;six (liu4). I found this one a bit tough. I sort of convinced myself that it looks like a lion (the sound liu4 is a bit like the English "leo", as in "Leo the Lion").&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;七&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;seven (qi1). This was tricky too. Until I turned my flash card upside down and realized it looks like an upside down 7 with a stroke through it. Nice.&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;八&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;eight (ba1). No tricks here, I just remember this character because it's pretty simple.&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;九&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;nine (jiu3). With the right amount of squinting, this character looks like a roman J and lower case i without the dots and with a weird line connecting the J to the top of the i. So if you can remember that jiu3 == nine, it's pretty easy.&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;十&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;ten (shi2). If you have Chinese friends, you might notice that sometimes when they say "ten", they make a hand gesture where they cross both index fingers over each other. If you ever wondered why, this character is the answer :)&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;And here's a random sampling of two more non numeric characters:&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;问&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;ask (wen4). This combines the character for door (门 men2) with the character for mouth (口 kou3). Can think of it as opening the door of your mouth to ask a question. The sound (wen2) is also similar to the sound for door (men2).&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;好&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;good (hao3). This combines the characters for female (女 nü3) and offspring / son / child (子 zi3). I guess that's good and harmonic.&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;&lt;p&gt;Anyway, lots more where those came from. Kind of fun to learn.... :)&lt;/p&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-7589127713918679749?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2009/01/getting-serious-about-mandarin.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>5</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-502128449905602193</guid><pubDate>Fri, 12 Dec 2008 04:10:00 +0000</pubDate><atom:updated>2008-12-11T20:18:36.117-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>jdeveloper</category><category domain='http://www.blogger.com/atom/ns#'>oracle</category><title>Still a bit proud</title><description>Looking at Steve Muench's blog with its &lt;a href="http://radio.weblogs.com/0118231/2008/10/10.html#a919"&gt;screenshot of JDeveloper 11g production&lt;/a&gt; makes me feel a little bit proud of what we built. Somehow I left Oracle with the feeling that I hadn't been very productive for a while, but seeing what Steve posted reminded me that the team really poured a lot of stuff into 11g. &lt;div&gt;
&lt;/div&gt;&lt;div&gt;Just visually from the screenshot, you can see the new look and feel I implemented based on a design from our talented visual design team. It got a lot of flak (experience is teaching me that fear or dislike of change is a very common trait), but apart from being unbelievably &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;blue&lt;/span&gt;, I think it's quite attractive. &lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Also shown in the screenshot is quick search (which, honestly, we always referred to internally as "Google-like search". Hehe). This was something I wanted and so hacked together on a lazy afternoon without any kind of design or project plan while we were supposed to be in bug fixing mode. Despite its birth, it somehow made it into the final product in a very visible way. A very talented member of the team (Neil) did some fantastic work improving the visual design of the component while I was buried under classloading related tasks. One of the things I loved about the JDev team in the early days was the freedom to do this kind of innovation. Although that flexibility to innovate had been almost entirely crushed by the time I left, you could sometimes still get away with it and succeed. &lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Finally, Steve blogs elsewhere about log window search, which people begged and begged for until we finally relented and I was assigned the task late in the day. &lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;I'm still very proud of these things, and even prouder of all the other innovations my old team implemented. &lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-502128449905602193?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2008/12/still-bit-proud.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>3</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-8740119161861250444</guid><pubDate>Sun, 07 Dec 2008 21:57:00 +0000</pubDate><atom:updated>2008-12-07T14:18:47.489-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>google</category><title>The Consequences of Job Hopping</title><description>I was pretty comfortable, and definitely not bored in my old job. Had a lot of stuff to do. The trouble though with saying in the same role for a very long time is that it's really hard to find time, reason, or energy to step outside your main job responsibilities a little bit and learn something new. I must have encountered a gazillion technologies and products that I really wanted to get a chance to play with but never did. 

&lt;p&gt;I wasn't sure when I quit my job at Oracle that working at Google would be any different necessarily. I felt like I'd probably swap my old batch of responsibilities for a new batch of responsibilities, and it would kind of be similar (but hopefully more fun). One thing I somehow failed to realize was that the really great thing about changing jobs is that it gives you that rare chance to really stretch a bit and learn something new. 

&lt;p&gt;So in my three months at Google so far, I've been able to get to know some fun new stuff. And instead of just reading about this stuff, I actually get the chance to play with it all the time. For me, this experience has reignited my passion for learning. I'm hoping that I can keep up the momentum. 

&lt;p&gt;Here are a small subset of the things I've learned about and used so far (not necessarily all Google technologies):

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/gxp/"&gt;GXP&lt;/a&gt; is a templating engine that's really useful for putting together dynamic web pages. I never got much of a chance to play with JSP, JavaServer Faces etc. before. I like that GXP is straightforward and easy to use. Haven't built anything spectacularly complex with it yet, but it works fantastically well for simple dynamic web content.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jetbrains.com/idea/plugins/plugin_developers.html"&gt;IntelliJ Plugin API&lt;/a&gt;. I'm still getting my head around this. It's familiar to me in many respects (there seem to be only so many ways of designing IDE plugin APIs). The API is a tad on the underdocumented side, and there sometimes aren't enough samples. I'm really learning "from the other side" what it's like to have a plugin API without source code. I really wished we'd been able to do better about that at Oracle with JDeveloper, and I hope one day JetBrains might see the light too, and make it easier for its plugin developers by giving them access to source code. But it's still a nice API, and you can get a lot done with it.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.eclipse.org/swt/"&gt;SWT&lt;/a&gt;. I've been using Swing for 10 years, and somehow got into the "SWT is evil" mentality without really giving it a chance. It's actually a pretty fine API for most UI problems. Slightly depressing to see that layout seems to be an intractable problem that all widget toolkits seem to have trouble making straightforward.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://labs.google.com/papers/bigtable.html"&gt;BigTable&lt;/a&gt; is cool :)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/apis/chart/"&gt;Google Chart API&lt;/a&gt; makes it really easy to draw pretty graphs 'n charts 'n stuff&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.debian.org/doc/FAQ/ch-pkgtools.en.html"&gt;Debian package management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gcc.gnu.org/fortran/"&gt;GNU Fortran&lt;/a&gt; don't ask. hehe.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well... that's not a comprehensive list, but I think I've been able to learn quite a bit more over the last few months than I did over about a year or two. Changing jobs is good for your brain :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-8740119161861250444?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2008/12/consequences-of-job-hopping.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-1678324306889734582</guid><pubDate>Fri, 21 Nov 2008 18:38:00 +0000</pubDate><atom:updated>2008-11-21T10:44:42.231-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>oracle</category><title>Brings back memories</title><description>Ah... this brings back memories:

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_hknXBwhowq8/SScBT4BXoyI/AAAAAAAABq8/xN0Ln6Jx6GQ/s1600-h/demotivation.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/_hknXBwhowq8/SScBT4BXoyI/AAAAAAAABq8/xN0Ln6Jx6GQ/s320/demotivation.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5271183329827726114" /&gt;&lt;/a&gt;


Feel motivated yet? (via: &lt;a href="http://thebode.blogspot.com/2006/07/demotivation.html"&gt;http://thebode.blogspot.com/2006/07/demotivation.html&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-1678324306889734582?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2008/11/brings-back-memories.html</link><author>noreply@blogger.com (Brian Duff)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_hknXBwhowq8/SScBT4BXoyI/AAAAAAAABq8/xN0Ln6Jx6GQ/s72-c/demotivation.jpg' height='72' width='72'/><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-8140550454778328686</guid><pubDate>Tue, 09 Sep 2008 22:03:00 +0000</pubDate><atom:updated>2008-09-09T15:20:23.959-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>terminator</category><category domain='http://www.blogger.com/atom/ns#'>tv</category><title>Shirley that's not Shirley</title><description>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_hknXBwhowq8/SMby24L9F6I/AAAAAAAABSI/R15omErO4zs/s1600-h/shirley-manson-terminator-425.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_hknXBwhowq8/SMby24L9F6I/AAAAAAAABSI/R15omErO4zs/s320/shirley-manson-terminator-425.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5244145840728905634" /&gt;&lt;/a&gt;
Warning: herein lie spoilers!&lt;p&gt;
Somewhat surprised to see &lt;a href="http://en.wikipedia.org/wiki/Shirley_Manson"&gt;Shirley Manson&lt;/a&gt;, Scottish lead singer of rock band &lt;a href="http://en.wikipedia.org/wiki/Garbage_(band)"&gt;Garbage&lt;/a&gt; show up in the second season premier of Fox's &lt;a href="http://en.wikipedia.org/wiki/Terminator:_The_Sarah_Connor_Chronicles"&gt;Terminator: The Sarah Connor Chronicles&lt;/a&gt; last night. Bit of a "holy crap, that's Shirley Manson" double take when the scene opened on her as an evil CEO who actually turns out to be a T-1000 model terminator (T-1000 is the gloopy, liquid metal model that Robert Patrick played so well in Terminator 2) hell bent on bringing about the Rise of the Machines.&lt;p&gt;
Haven't quite figured out yet whether she's a good actor or not... She certainly came across as kind of cold, dominating, fearsome, and a little stiff. At first, I thought her acting was a bit iffy, but the reveal that she's actually a T-1000 sort of changed my perception a bit.&lt;p&gt;
Was really nice hearing a genuine Scottish accent on US network television too. Scottish actors don't get to play the Bad Guy (or Lass) in TV sci fi nearly often enough. Witness the saccharinely well behaved &lt;a href="http://en.wikipedia.org/wiki/Carson_Beckett"&gt;Carson Beckett&lt;/a&gt; from Stargate Atlantis (Paul McGillion's accent is also faaar from genuine, probably on account of the fact that he moved to Canada when he was 2)&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-8140550454778328686?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2008/09/shirley-thats-not-shirley.html</link><author>noreply@blogger.com (Brian Duff)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_hknXBwhowq8/SMby24L9F6I/AAAAAAAABSI/R15omErO4zs/s72-c/shirley-manson-terminator-425.jpg' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-6862534007822544634</guid><pubDate>Tue, 09 Sep 2008 04:12:00 +0000</pubDate><atom:updated>2008-09-08T21:18:54.419-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>google</category><title>Nooglerization done (but is it ever, I wonder... ;) )</title><description>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_hknXBwhowq8/SMX3oUSPPPI/AAAAAAAABSA/Vj8br-Mpp-0/s1600-h/photo.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_hknXBwhowq8/SMX3oUSPPPI/AAAAAAAABSA/Vj8br-Mpp-0/s320/photo.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5243869613154843890" /&gt;&lt;/a&gt;
My first two weeks are over, now I'm taking a quick bout of unpaid leave to take Cindy to Paris and Barcelona. She's never been to europe - and even though I'm from Europe, it's a big place and I've never really spent much time in those two cities. We're also going to spend some time with my parents in the south east of Spain.&lt;p&gt;
Cindy swears that I've put on weight in the mere two weeks since I joined google on account of the free food. This is an assertion which I stringently deny, alas to no avail. I try to convince myself that all of the cycling between buildings (or walking in the fairly regular no-available-bikes scenario) is burning off enough calories to make up for the additional input. I may or may not be kidding myself.&lt;p&gt;
I've been using the convenient excuse that, since it takes some period of time after initial employment before registering for the gym is possible, working out and getting rid of the extra pounds is something I can put off until after our vacation.&lt;p&gt;
Anyhow, looking forward to taking a break, and then getting down to some serious geekyness (er.. geekery?) when I get back. I haven't written code for a while, and my fingers are getting twitchy.&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-6862534007822544634?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2008/09/nooglerization-done-but-is-it-ever-i.html</link><author>noreply@blogger.com (Brian Duff)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_hknXBwhowq8/SMX3oUSPPPI/AAAAAAAABSA/Vj8br-Mpp-0/s72-c/photo.jpg' height='72' width='72'/><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-8060825464549876781</guid><pubDate>Thu, 07 Aug 2008 22:07:00 +0000</pubDate><atom:updated>2008-08-07T15:30:13.339-07:00</atom:updated><title>On shortcuts</title><description>I made the Big Switch from Windows to Linux at work several years ago, and never really looked back. For whatever reason, our version control system and builds are always about twice as fast on Linux compared to Windows. I'm also much more comfortable in a UNIX-y shell / scripting environment than I am in Windows Command Prompt, probably because of hours spent in various computer labs at university when I really should have been doing something more fun (like drinking beer).&lt;p&gt;

As well as the raw productivity gain from the faster environment, I also customized my environment a great deal to minimize keypresses. For example, where most other people in my team might type something like this:&lt;p&gt;

&lt;pre&gt;
cd $ADE_VIEW_ROOT/jdevadf/modules/ide/src/oracle/ide
ade co -nc Ide.java MainWindow.java
cd `pwd`
emacs Ide.java MainWindow.java
cd $ADE_VIEW_ROOT/jdevadf
make release
&lt;/pre&gt;

I type:

&lt;pre&gt;
m ide/src/oracle/ide
co Ide.java MainWindow.java
emacs Ide.java MainWindow.java
jdevadf
mrel
&lt;/pre&gt;

Doesn't seem like much, but over many many months and years of coding, all those extra keystrokes add up... Better still, I had some immensely powerful tools in my box that would invoke compound commands to provide interesting information.&lt;p&gt;

So, if I wanted to quickly find a file in our source control system (an operation that can be sped up by grepping some version control metadata files, chopping the file up to make it readable), I'd type &lt;code&gt;wi SomeFile.java&lt;/code&gt; (where is?). If I wanted to know which module (out of about 600 in our system) was responsible for delivering a jar file (again which involved a lot of grepping through multiple files and cleaning up the output), I could ask &lt;code&gt;wm foo.java&lt;/code&gt; (which module?).&lt;p&gt; 

These utilities ran ridiculously quickly, because I figured out tricks that were somewhat specific to our system. For example, grepping the version control files to locate a file is way faster than using "find", since it's a grep on a single file instead of a directory tree traversal. Their real power was in compound commands. I could check out all files with the extension xml that contained the string "brian.duff" with a command like this:&lt;p&gt;

&lt;pre&gt;
wi '\.xml$' | xargs grep -l 'brian\.duff' | xargs co
&lt;/pre&gt;

This is all fine and great, but there's a &lt;i&gt;huge&lt;/i&gt; downside. Every time I sat at someone else's terminal to help them with some problem and attempted to run some commands, I had to remember to type the longwinded versions of all these commands again. Like being thrown back into the dark ages. Worse than that, it actually slowed me down even compared to someone without the shortcuts, since my fingers would frequently forget and type my shortcuts instinctively even though my higher brain was fully aware that they wouldn't work. Finger memory is a strange thing.&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-8060825464549876781?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2008/08/on-shortcuts.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-4036587533413940195</guid><pubDate>Mon, 12 May 2008 23:18:00 +0000</pubDate><atom:updated>2008-05-12T16:19:34.772-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><title>AWT Freudian Slips...</title><description>&lt;pre&gt;
BufferedImage image = new BuggeredImage(...
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-4036587533413940195?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2008/05/awt-freudian-slips.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-7462836160205478460</guid><pubDate>Sat, 24 Nov 2007 01:56:00 +0000</pubDate><atom:updated>2007-11-23T17:56:38.078-08:00</atom:updated><title>Newsmap</title><description>&lt;a href="http://marumushi.com/apps/newsmap/newsmap.cfm?layout=0&amp;selected=uk,us&amp;categories=world,nation,business,technology,entertainment,health"&gt;Newsmap&lt;/a&gt; is a really neat way to visualize news headlines available via the Google News RSS feeds.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-7462836160205478460?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/11/newsmap.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-3219848632987611325</guid><pubDate>Fri, 23 Nov 2007 06:20:00 +0000</pubDate><atom:updated>2007-11-22T22:47:59.108-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>apple</category><title>Configuring Mac OS X Terminal</title><description>&lt;p&gt;I recently installed Leopard (Mac OSX 10.5) on a new mac. There are a few factory settings I usually change on a new installation, although by far fewer than I do typically with Windows. One of them is the default keyboard configuration for Ctrl+Left Arrow, Ctrl+Right Arrow, Page Up, Page Down, Home, and End in Terminal. The default settings drive me a bit potty since I'm used to using Linux and emacs every day at work.&lt;/p&gt;

&lt;p&gt;Changing them is easy, fortunately. Just visit &lt;b&gt;Keyboard&lt;/b&gt; under &lt;b&gt;Settings&lt;/b&gt; in &lt;b&gt;Terminal-&gt;Preferences&lt;/b&gt;, and modify the following keys, so that their action matches the value shown. You can edit the keystroke for an item by double clicking on it, selecting "send string to shell", and typing the indicated keys.&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;
&lt;th align="left"&gt;Key&lt;/th&gt;
&lt;th align="left"&gt;Action&lt;/th&gt;
&lt;th align="left"&gt;Keystrokes&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;control cursor left&lt;/td&gt;
&lt;td&gt;\033b&lt;/td&gt;
&lt;td&gt;ESC b&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;control cursor right&lt;/td&gt;
&lt;td&gt;\033f&lt;/td&gt;
&lt;td&gt;ESC f&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;end&lt;/td&gt;
&lt;td&gt;\005&lt;/td&gt;
&lt;td&gt;CTRL+e&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;home&lt;/td&gt;
&lt;td&gt;\001&lt;/td&gt;
&lt;td&gt;CTRL+a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;page down&lt;/td&gt;
&lt;td&gt;\026&lt;/td&gt;
&lt;td&gt;CTRL+v&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;page up&lt;/td&gt;
&lt;td&gt;\033v&lt;/td&gt;
&lt;td&gt;ESC v&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-3219848632987611325?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/11/configuring-mac-os-x-terminal.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>13</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-4542956456020685224</guid><pubDate>Thu, 15 Nov 2007 01:36:00 +0000</pubDate><atom:updated>2007-11-14T18:34:57.703-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>collections</category><category domain='http://www.blogger.com/atom/ns#'>concurrency</category><title>Detecting Concurrent Changes with the Decorator Pattern</title><description>&lt;p&gt;Recently, our bug tracking system started receiving reports of a &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/ConcurrentModificationException.html"&gt;ConcurrentModificationException&lt;/a&gt;. The API in question was only ever supposed to be used on one thread, and yet a caller somewhere was making modifications on a background thread.&lt;/p&gt;

&lt;p&gt;One thing that makes it tricky to diagnose this kind of problem is that a ConcurrentModificationException thrown during iteration only tells you that a concurrent modification was detected. But no information is present in the stack trace about where the rogue write actually happened. Wouldn't it be nice to have something like this?&lt;/p&gt;

&lt;pre&gt;
java.util.ConcurrentModificationException
  at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
  ...
Caused by: java.lang.Throwable: List modified
  at ...
  at org.foo.SomeRogueCaller.writeOnTheWrongThread(SomeRogueCaller.java:30)
&lt;/pre&gt;

&lt;p&gt;
It's pretty easy to do this using the &lt;a href="http://en.wikipedia.org/wiki/Decorator_pattern"&gt;decorator pattern&lt;/a&gt;. The basic idea is to write a decorator for java.util.List that records a stack trace when modifications are made to the list, and sets the trace of the last modification as the cause of any ConcurrentModificationException thrown while iterating.
&lt;/p&gt;

&lt;p&gt;
I used the &lt;a href="http://code.google.com/p/google-collections/"&gt;Google Collections Library&lt;/a&gt; as part of my implementation, primarily because its &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ForwardingList.html"&gt;ForwardingList&lt;/a&gt;, &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ForwardingListIterator.html"&gt;ForwardingListIterator&lt;/a&gt; and &lt;a href="http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ForwardingIterator.html"&gt;ForwardingIterator&lt;/a&gt; base classes make it really easy to decorate the respective collections classes.
&lt;/p&gt;

&lt;p&gt;
So the basic idea is to write a decorator that can audit writes. I created a subclass of &lt;tt&gt;ForwardingList&lt;/tt&gt; that stores a Throwable representing the last modification. The audit method will be used to record modifications, and the setLastModificationAsCause method is used to initialize the cause of a ConcurrentModificationException to the last modification (if any).&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
final class AuditedWriteList&amp;lt;E&gt; extends ForwardingList&amp;lt;E&gt; {
  private Throwable lastModification;

  protected AuditedWriteList(List&amp;lt;E&gt; delegate) {
    super(delegate);
  }

  private void audit() {
    synchronized (this) {
      lastModification = new Throwable( "List modified" );
    }
  }

  private void setLastModificationAsCause( Throwable t ) {
    synchronized (this) {
      if ( lastModification != null ) t.initCause( lastModification );
    }
  }

  // ...
}
&lt;/pre&gt;

&lt;p&gt;
Now, we override all List methods that modify the list, and make them audit. For example, here's the implementation for add(E):
&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
@Override
public boolean add( E object ) {
  audit();
  return super.add( object );
}
&lt;/pre&gt;

&lt;p&gt;
Finally, we implement the iterator() and listIterator() methods to return a decorator Iterator and ListIterator respectively that catches a ConcurrentModificationException and calls the setLastModificationAndCause method:
&lt;/p&gt;

&lt;pre class="prettyprint"&gt;

@Override
public Iterator&amp;lt;E&gt; iterator() {
  return new AuditingIterator&amp;lt;E&gt;( super.iterator() );
}

// Inner class
private final class AuditingIterator&amp;lt;T&gt; extends ForwardingIterator&amp;lt;T&gt; {
  protected AuditingIterator(Iterator&amp;lt;T&gt; delegate) {
    super( delegate );
  }
  
  @Override
  public T next() {
    try {
      return super.next(); 
    } catch ( ConcurrentModificationException e ) {
      setLastModificationAsCause(e);
      throw e;
    }
  }
}
&lt;/pre&gt;

&lt;p&gt;
Now, if we do something like this:
&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
List&amp;lt;String&gt; list = newAuditedWriteList( Lists.newArrayList( "One", "Two", "Three" ) );
for ( Iterator&amp;lt;String&gt; i = list.iterator(); i.hasNext(); ) {
  i.next();
  list.add( "Four" );
}
&lt;/pre&gt;

&lt;p&gt;
We get a helpful stack trace telling us exactly where the modification took place. The beauty of the decorator approach is that the only change we made to our client code was to wrap the creation of our list with the call to newAuditedWriteList. Since  this diagnostic is likely to be slow when there are a lot of writes, it could be conditionally turned on in debug environments.
&lt;/p&gt;

&lt;p&gt;
The full source code is available in the &lt;a href="http://code.google.com/p/dubh-examples/"&gt;dubh-examples&lt;/a&gt; google code module.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-4542956456020685224?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/11/detecting-concurrent-changes-with.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-1122026417907476875</guid><pubDate>Mon, 03 Sep 2007 08:32:00 +0000</pubDate><atom:updated>2007-09-03T01:44:57.792-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>san francisco</category><category domain='http://www.blogger.com/atom/ns#'>walking</category><category domain='http://www.blogger.com/atom/ns#'>golden gate bridge</category><category domain='http://www.blogger.com/atom/ns#'>bay bridge</category><title>San Francisco Walk: Bay Bridge to Golden Gate</title><description>&lt;p&gt;
I've really started to enjoy walking since I moved to San Francisco. A fun, but somewhat exhausting, walk I've done before was from the Bay Bridge to the Golden Gate Bridge. On Saturday, I wandered along the Embarcadero just to get coffee at the Ferry Terminal, but since it was a nice day, just kind of kept on going. Five and a half hours later, I arrived back home with slightly sore feet...&lt;/p&gt;

&lt;p&gt;
Since I like to engage geek foo with such things, I plotted out the route of this walk (in blue; the red line is another long walk I took last year) on Google Maps:
&lt;/p&gt;

&lt;div align="center"&gt;
&lt;iframe width="300" height="300" frameborder="no" scrolling="no" marginheight="0" marginwidth="0" src="http://maps.google.com/maps/ms?ie=UTF8&amp;hl=en&amp;om=1&amp;s=AARTsJqhvFOQZTmUHiSHfUw_SmxMv-xKmA&amp;msa=0&amp;msid=100027176471948387168.0004391f1cb91446a38b5&amp;ll=37.803816,-122.43576&amp;spn=0.081379,0.102997&amp;z=12&amp;output=embed"&gt;&lt;/iframe&gt;&lt;br/&gt;&lt;a href="http://maps.google.com/maps/ms?ie=UTF8&amp;hl=en&amp;om=1&amp;msa=0&amp;msid=100027176471948387168.0004391f1cb91446a38b5&amp;ll=37.803816,-122.43576&amp;spn=0.081379,0.102997&amp;z=12&amp;source=embed" style="color:#0000FF;text-align:left;font-size:small"&gt;View Larger Map&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;
All in all, it was a great walk. Had some really nice euphoric moments. My iPod was playing uplifting songs, the sun was setting over the Golden Gate Bridge, and it felt pretty good to be living here...
&lt;/p&gt;

&lt;div align="center"&gt;
&lt;a href="http://picasaweb.google.com/cairndubh/RandomStuff/photo#5105894939266087762"&gt;&lt;img src="http://lh4.google.com/cairndubh/RtvIZSNre1I/AAAAAAAAASM/ursj3dzRHf0/s400/DSC00448.JPG" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-1122026417907476875?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/09/san-francisco-walk-bay-bridge-to-golden.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>3</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-1929290800519020076</guid><pubDate>Sat, 25 Aug 2007 22:15:00 +0000</pubDate><atom:updated>2007-08-25T15:13:03.263-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>bloopers</category><category domain='http://www.blogger.com/atom/ns#'>coding</category><title>Java Blooper #2 Solution: Must be a Better Way</title><description>&lt;p&gt;Sorry for the delay in this week's blooper solution. On Monday we saw this code:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
boolean hasThing( List&lt;Thing&gt; things, Thing thing ) {
  for ( int i=0; i &lt; things.size(); i++ ) {
    if ( thing.equals( things.get( i ) ) ) {
      return true;
    }
  }
  return false;
}
&lt;/pre&gt;

&lt;p&gt;Can we simplify this? Sure. It pays to know the class libraries well, and the &lt;a href="http://java.sun.com/docs/books/tutorial/collections/index.html"&gt;collections framework&lt;/a&gt; in Java in particular:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
boolean hasThing( Collection&lt;Thing&gt; things, Thing thing ) {
  return things.contains( thing );
}
&lt;/pre&gt;

&lt;p&gt;As well as being more compact, this idiom is safer if the collection is a &lt;a href="http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html"&gt;synchronized wrapper&lt;/a&gt; (as pointed out by reader alex in the &lt;a href="https://www.blogger.com/comment.g?blogID=3339316202894508517&amp;postID=414492108675997923"&gt;comments&lt;/a&gt;). We were also able to specify the things parameter as a &lt;tt&gt;Collection&lt;/tt&gt; rather than a &lt;tt&gt;List&lt;/tt&gt;, following item 34 in EJ ("Refer to objects by their interfaces"), since we no longer need the ability to iterate items in the collection by index, which may well have been inefficient depending on whatever implementation of list was passed to us.&lt;/p&gt; 

&lt;p&gt;Blog readers &lt;a href="http://aeronaut.wordpress.com/"&gt;jeff&lt;/a&gt; and Mike Kaufman also pointed out that this code doesn't &lt;a href="http://blog.dubh.org/2007/03/check-parameters-for-validity-good.html"&gt;check parameters for validity&lt;/a&gt;. Specifically, if this is a public method, it should check if the two parameters are null, or document the behavior when they are null in its javadoc.&lt;/p&gt;

&lt;p&gt;Indeed, the whole method itself is very likely to be unnecessary in this particular example. But only because I super-simplified the original code, which of course contained some side effects. Joy :)&lt;/p&gt;

&lt;p&gt;Back on Monday with another blooper...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-1929290800519020076?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/08/java-blooper-2-solution-must-be-better.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>10</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-414492108675997923</guid><pubDate>Mon, 20 Aug 2007 07:49:00 +0000</pubDate><atom:updated>2007-12-30T15:25:44.481-08:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>bloopers</category><category domain='http://www.blogger.com/atom/ns#'>coding</category><title>Java Blooper #2: Must be a Better Way...</title><description>&lt;p&gt;It's Monday, which means it's time for another &lt;a href="http://blog.dubh.org/2007/08/java-blooper-1-ternary-insanity.html"&gt;blooper&lt;/a&gt;... What's wrong with this code?&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
boolean hasThing( List&lt;Thing&gt; things, Thing thing ) {
  for ( int i=0; i &lt; things.size(); i++ ) {
    if ( thing.equals( things.get( i ) ) ) {
      return true;
    }
  }
  return false;
}
&lt;/pre&gt;

&lt;i&gt;Update:&lt;/i&gt; Minor edit to add missing parenthesis from if statement that got "lost in translation" en-route to the blog :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-414492108675997923?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/08/java-blooper-2-must-be-better-way.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>13</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-6199217535597614974</guid><pubDate>Fri, 17 Aug 2007 19:29:00 +0000</pubDate><atom:updated>2007-08-17T12:29:31.097-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>bloopers</category><category domain='http://www.blogger.com/atom/ns#'>coding</category><title>Java Blooper #1 Solution: Ternary Insanity</title><description>&lt;pre class="prettyprint"&gt;
class Thing {
  private boolean _visible;

  boolean isVisible() {
    return _visible ? true : false;
  }
}
&lt;/pre&gt;

&lt;p&gt;
This code is unnecessarily using the ternary &lt;a href="http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.25"&gt;conditional operator&lt;/a&gt; when it's not needed.&lt;/p&gt;

&lt;p&gt;Occasionally developers get so captivated by the expressiveness of this operator that they find it tempting to use it when it's not really needed. In this particular example, it almost looks like the original writer forgot that the type of the _visible field was boolean anyway and could just be returned directly:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
class Thing {
  private boolean _visible;

  boolean isVisible() {
    return _visible;
  }
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-6199217535597614974?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/08/java-blooper-1-solution-ternary.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-2597609792817230246</guid><pubDate>Wed, 15 Aug 2007 05:34:00 +0000</pubDate><atom:updated>2007-08-14T22:40:31.069-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>usalife</category><category domain='http://www.blogger.com/atom/ns#'>investment</category><category domain='http://www.blogger.com/atom/ns#'>greencard</category><title>The Ups and Downs</title><description>&lt;p&gt;Great news first thing this morning... I'm now a permanent resident of the United States! The whole process was a lot less painful than I'd expected. It was a terribly exciting start to the day.&lt;/p&gt;

&lt;p&gt;In other news, I lost $1,000 in my portfolio today as the market continues to plummet. Ouch. My finger is twitching over the sell button ;)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-2597609792817230246?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/08/ups-and-downs.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-6778539089061796581</guid><pubDate>Mon, 13 Aug 2007 06:30:00 +0000</pubDate><atom:updated>2007-08-12T23:21:54.391-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>java</category><category domain='http://www.blogger.com/atom/ns#'>bloopers</category><category domain='http://www.blogger.com/atom/ns#'>ternary</category><category domain='http://www.blogger.com/atom/ns#'>coding</category><title>Java Blooper #1: Ternary Insanity</title><description>&lt;p&gt;From time to time, we all write code that could be clearer. Sometimes in the rush of solving a problem, we don't pay attention to the micro details of the code flowing from our fingertips. Other times, we refactor some existing code, and don't necessarily take the opportunity to clean up as much as we could.&lt;/p&gt; 

&lt;p&gt;I find it useful sometimes when reading code to think about whether it could be rewritten in a more straightforward way, and if so whether any lessons can be learned about writing tight and expressive, and most importantly, readable code.&lt;/p&gt;

&lt;p&gt;Over the next few weeks, I'm going to blog weekly examples of some Java code bloopers that I've seen. All the examples are real and have been observed "in the wild". However some have been simplified somewhat to make a point. I'll post each blooper on a Monday, and follow up with a rewritten version the following Friday.&lt;/p&gt;

&lt;p&gt;Most of the examples are pretty simple, and easily cleaned up - feel free to post observations as comments to the entries, and don't be shy to smack me down on the solutions if there's a better way to express the same thing.&lt;/p&gt;

&lt;p&gt;The first installment is called &lt;i&gt;Ternary Insanity&lt;/i&gt;. &lt;/p&gt;

&lt;pre class="prettyprint"&gt;
class Thing {
  private boolean _visible;

  boolean isVisible() {
    return _visible ? true : false;
  }
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-6778539089061796581?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/08/java-blooper-1-ternary-insanity.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>9</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-6298374429210131938</guid><pubDate>Thu, 26 Jul 2007 01:41:00 +0000</pubDate><atom:updated>2007-07-25T19:04:43.040-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>life hacks</category><category domain='http://www.blogger.com/atom/ns#'>inbox zero</category><category domain='http://www.blogger.com/atom/ns#'>email</category><category domain='http://www.blogger.com/atom/ns#'>folders</category><title>More on email inbox bliss</title><description>&lt;p&gt;
So far my attempt to &lt;a href="http://blog.dubh.org/2007/07/asserting-control-over-inbox.html"&gt;maintain an empty inbox&lt;/a&gt; is working out pretty well.
&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_hknXBwhowq8/RqgAspyJ9hI/AAAAAAAAAQs/fjSP1Sb-4Uo/s1600-h/folders.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://bp1.blogger.com/_hknXBwhowq8/RqgAspyJ9hI/AAAAAAAAAQs/fjSP1Sb-4Uo/s400/folders.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5091320145872811538" /&gt;&lt;/a&gt;
&lt;p&gt;
One of the most effective things that worked was to get rid of folders. Previously, I was a folder freak: my email was "organized" into a bewildering,  ever changing, hierarchy of folders. Rather than making it easier to find stuff, it was actually much harder. Before I could find something quickly, I had to try to figure out which folder I had decided to put it into.
&lt;/p&gt;
&lt;p&gt;
I draw a comparison between this and usage of, say, &lt;a href="http://www.google.com"&gt;Google Search&lt;/a&gt; vs. a directory service like &lt;a href="http://dmoz.org/"&gt;dmoz&lt;/a&gt;. Directory services categorize the web into a wonderful hierarchy. But in practice, it's almost always more effective to just search the conceptual single folder containing the whole web via google search. 
&lt;/p&gt;
&lt;p&gt;
I now have a small number of folders. Apart from the inbox, trash, and sent folder, the remaining folders can be categorized as:
&lt;ul&gt;
&lt;li&gt;
&lt;b&gt;A single @Respond folder&lt;/b&gt;. Messages that I need to respond to, but can't do so immediately because they require some investigation go here. I treat this like a todo list, and review it several times a day.
&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;A single Archive folder&lt;/b&gt;. Anything that I don't need to keep track of actively, but might be interesting for future reference goes here. This is where the vast majority of email that I don't delete ends up.
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Important short term projects&lt;/b&gt; for which it's convenient to collocate all the messages. I currently have a single folder that falls into this category, for tracking correspondence related to my green card application. Although I have several other important short term projects, none of them really need a separate folders.&lt;/li&gt;
&lt;li&gt;
&lt;b&gt;High-volume, low value mailing lists auto filters&lt;/b&gt;. For instance, I have a folder called Bugs into which gets automatically filtered all notification emails from our bug database system. I rarely have to act immediately on such emails, but it's useful to review them once or twice a day. I usually mass delete the contents of these folders on a daily basis, since they're basically copies of information available elsewhere.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
As a result of this, I now have roughly 5 folders (not including inbox, trash and sent). This works well for me. It speeds up the rate at which I can process incoming email, since there are fewer choices about which action to take for each incoming message.
&lt;/p&gt;
&lt;p&gt;
Merlin Mann's &lt;a href="http://www.43folders.com/"&gt;43 Folders&lt;/a&gt; site talks about this a lot. His recent &lt;a href="http://video.google.com/videoplay?docid=973149761529535925&amp;hl=en"&gt;tech talk on Inbox Zero&lt;/a&gt; summarizes a lot of the useful content related to email management posted on the site.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-6298374429210131938?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/07/more-on-email-inbox-bliss.html</link><author>noreply@blogger.com (Brian Duff)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_hknXBwhowq8/RqgAspyJ9hI/AAAAAAAAAQs/fjSP1Sb-4Uo/s72-c/folders.png' height='72' width='72'/><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-3828608415244973279</guid><pubDate>Fri, 20 Jul 2007 09:21:00 +0000</pubDate><atom:updated>2007-07-20T02:31:08.792-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>google</category><title>Google Code Project Hosting Gets Upgrades</title><description>&lt;p&gt;
The folks over at &lt;a href="http://code.google.com/"&gt;Google Code&lt;/a&gt; have been doing some sterling work in the last few weeks fixing various &lt;a href="http://code.google.com/p/support/issues/list"&gt;issues&lt;/a&gt; with its project hosting support. Here are some of my favorite fixes:&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Issue &lt;a href="http://code.google.com/p/support/issues/detail?id=250"&gt;250&lt;/a&gt;: Issue summaries are unnecessary abbreviated&lt;/b&gt;. In the issue list, the summaries would be truncated arbitrarily. This was pesky on a large display, since there was plenty of space to see the whole summary.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Issue &lt;a href="http://code.google.com/p/support/issues/detail?id=138"&gt;138&lt;/a&gt;: projectname.googlecode.com should redirect to project page&lt;/b&gt;. So now you can go to &lt;a href="http://jd-ant.googlecode.com"&gt;jd-ant.googlecode.com&lt;/a&gt; as well as &lt;a href="http://code.google.com/p/jd-ant"&gt;code.google.com/p/jd-ant&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Issue &lt;a href="http://code.google.com/p/support/issues/detail?id=306"&gt;306&lt;/a&gt;: IssueTracker: Provide a means of displaying more than 25 issues at a time&lt;/b&gt;. Now you see 100 issues at a time, which makes for less paging about in large issue lists.
&lt;/p&gt;
&lt;p&gt;
Glad to see these improvements. Google's project hosting is straightforward, fast, and very useful.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-3828608415244973279?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/07/google-code-project-hosting-gets.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-40511647681097296</guid><pubDate>Fri, 06 Jul 2007 15:48:00 +0000</pubDate><atom:updated>2007-07-06T09:04:42.224-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>email</category><category domain='http://www.blogger.com/atom/ns#'>thunderbird</category><title>Asserting Control over the INBOX</title><description>&lt;p&gt;
Sometimes I'm a bit disorganized. Last week, after purging my INBOX of some 15,000 messages (discovering quite a few that I had read but not replied to in the process), I decided that it's finally time to assert control over my INBOX.
&lt;/p&gt;
&lt;p&gt;
It's not the first time I've tried this. The lofty goal of maintaining an empty INBOX is very appealing in theory, but it's easy to get lazy. Before you know it, you end up with thousands of disorganized messages again.
&lt;/p&gt;
&lt;p&gt;
The first step in this was turning down my "autocheck" frequency. I think a big part of the reason that I'm a bit disorganized is that email messages arrive in a constant stream throughout my day, and so I'm always processing them while doing other tasks.
&lt;/p&gt;
&lt;p&gt;
My approach now is to set aside 5-10 minute periods every hour or so specifically for triaging email. Any email I can respond to, or action, within that period, I do so immediately. Anything else, I add to my TODO list on the excellent &lt;a href="http://www.rememberthemilk.com"&gt;Remember the Milk&lt;/a&gt; service, and then archive the message to a folder.
&lt;/p&gt;
&lt;p&gt;
The second part of this is making it easy (and I mean really easy) to archive messages. For any message I read in my INBOX, I must do one of the following immediately:
&lt;ul&gt;
&lt;li&gt;Delete it if it's spam, or automated email that I don't care about&lt;/li&gt;
&lt;li&gt;Reply to it if it can be actioned within the 5-10 minute email period, then archive it to a folder or delete it.&lt;/li&gt;
&lt;li&gt;Add a TODO item, then archive it to a folder.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
I've pared down my list of folders to a minimum (3 main folders, with some extras for server side filtered automated email) so that it's easier to figure out the destination for any given message. Thunderbird makes it really easy to search for messages within a folder, so I realized that having a gazillion hierarchical folders was actually making it harder to find old messages.
&lt;/p&gt;
&lt;p&gt;
To make it really easy to quickly move messages into a folder, I'm using the excellent &lt;a href="http://mozilla.dorando.at/readme.html"&gt;keyconfig&lt;/a&gt; extension for Thunderbird to map a &lt;a href="http://deefs.net/2006/07/01/move_messages_in_thunderbird_with_a_single_keystroke"&gt;single keystroke&lt;/a&gt; to moving messages to a folder. For example, I can now hit Ctrl+J on a message to immediately move it to my "JDeveloper" folder. I can't overstate how useful this is. It's probably the single most effective thing I've done to make it easier to control my INBOX.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-40511647681097296?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/07/asserting-control-over-inbox.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-6669941413474922420</guid><pubDate>Sun, 10 Jun 2007 13:06:00 +0000</pubDate><atom:updated>2007-06-11T15:46:10.933-07:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>usalife</category><category domain='http://www.blogger.com/atom/ns#'>drwho</category><category domain='http://www.blogger.com/atom/ns#'>tv</category><title>Scary Statues</title><description>&lt;p align="center"&gt;
&lt;img src="http://upload.wikimedia.org/wikipedia/en/thumb/3/3e/Blink_%28Doctor_Who%29.jpg/350px-Blink_%28Doctor_Who%29.jpg" /&gt;
&lt;/p&gt;
&lt;p&gt;
It may have something to do with that odd tradition they have in the USA of completely shutting down all decent television programs for a block of about four months in the summer and the result that my DVR is being seriously under-used at the moment, but I'm really getting into the latest series of the new Doctor Who.
&lt;/p&gt;
&lt;p&gt;
I've been an unabashed fan boy of &lt;a href="http://www.bbc.co.uk/doctorwho/"&gt;Doctor Who&lt;/a&gt; since I was small enough to effectively hide behind our rather brown, early-eighties sofa in Edinburgh watching Tom Baker, Peter Davison, Colin Baker and Sylvester McCoy do their turns as the Gallifreyan time lord. I'm pretty sure it was the seed of my life long addiction to science fiction books and so-called telefantasy TV shows.
&lt;/p&gt;
&lt;p&gt;
When the series came back a few years ago, I was desperately excited. That excitement carried me through most of the first two series. Even though to be frank, some of the storylines and episodes were pretty poor, with the odd gem here and there (&lt;a href="http://www.bbc.co.uk/doctorwho/episodes/2005/dalek.shtml"&gt;Dalek&lt;/a&gt;, &lt;a href="http://www.bbc.co.uk/doctorwho/episodes/2005/fathersday.shtml"&gt;Father's Day&lt;/a&gt;, &lt;a href="http://www.bbc.co.uk/doctorwho/episodes/2005/emptychild.shtml"&gt;The Empty Child&lt;/a&gt;, &lt;a href="http://www.bbc.co.uk/doctorwho/episodes/2005/partingoftheways.shtml"&gt;The Parting of the Ways&lt;/a&gt;, &lt;a href="http://www.bbc.co.uk/doctorwho/episodes/2006/newearth.shtml"&gt;New Earth&lt;/a&gt;, &lt;a href="http://www.bbc.co.uk/doctorwho/episodes/2006/schoolreunion.shtml"&gt;School Reunion&lt;/a&gt;, &lt;a href="http://www.bbc.co.uk/doctorwho/episodes/2006/girlinthefireplace.shtml"&gt;The Girl in the Fireplace&lt;/a&gt;, and &lt;a href="http://www.bbc.co.uk/doctorwho/episodes/2006/loveandmonsters.shtml"&gt;Love &amp; Monsters&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
I don't know what changed in the third series. Certainly, the Doctor has a new companion in the form of Martha Jones (played with wonderful enthusiasm by &lt;a href="http://en.wikipedia.org/wiki/Freema_Agyeman"&gt;Freema Agyeman&lt;/a&gt;). But the episodes in series three seem to be consistently better than the previous two series. The episodes have that creeping, mysterious fun and fear in exactly the combination that was common in the golden days of the old Doctor Who.
&lt;/p&gt;
&lt;p&gt;
Take this week's &lt;a href="http://www.bbc.co.uk/doctorwho/episodes/2007/310.shtml"&gt;Blink&lt;/a&gt; for instance. Statues. Terrifying, monstrous, looming, &lt;a href="http://en.wikipedia.org/wiki/List_of_Doctor_Who_monsters_and_aliens#Weeping_Angels"&gt;weeping angel&lt;/a&gt; statues that "kill" people by sending them back in time.
&lt;/p&gt;
&lt;p&gt;
In common with one of my other favorite episodes with the new Doctor, &lt;a href="http://www.bbc.co.uk/doctorwho/episodes/2006/loveandmonsters.shtml"&gt;Love &amp;amp; Monsters&lt;/a&gt;, this episode doesn't actually feature the Doctor and his companion much at all (they're stuck in 1969, having been transported there by the statues while the TARDIS remains in the present day). Thanks in great part to the fine acting of guest actress &lt;a href="http://en.wikipedia.org/wiki/Carey_Mulligan"&gt;Carey Mulligan&lt;/a&gt; as Sally Sparrow, the episode remains riveting (not to mention sofa-hidingly scary. I actually yelled out in fear at one point, which isn't something I'm taken to do on a regular basis).
&lt;/p&gt;
&lt;p&gt;
And last week we had &lt;a href="http://www.bbc.co.uk/doctorwho/episodes/2007/309.shtml"&gt;seriously spooky scarecrows&lt;/a&gt;... This new series just keeps getting better :)
&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-6669941413474922420?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/06/scary-statues.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>3</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-3339316202894508517.post-5326806534342995534</guid><pubDate>Mon, 04 Jun 2007 14:35:00 +0000</pubDate><atom:updated>2007-06-04T07:36:17.790-07:00</atom:updated><title>Test From Adobe Contribute</title><description>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;Just a little test entry. I just took the plunge and upgraded my Macromedia Studio 8 to Adobe Creative Suite 3, so I'm testing out Adobe Contribute (which was completely dysfunctional in its previous incarnation with blogger). &lt;/p&gt;                &lt;p&gt;Seems pretty nice so far. Rather scarily, I'm sort of editing this blog entry in-place (or at least, that's the intent of the UI illusion it creates). Quite nifty.&lt;/p&gt;         &lt;p&gt;Notice that there's no spell checking though, which is definitely a step down from regular blog posting via an HTML form with Firefox. Boo. &lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3339316202894508517-5326806534342995534?l=blog.dubh.org' alt='' /&gt;&lt;/div&gt;</description><link>http://blog.dubh.org/2007/06/test-from-adobe-contribute.html</link><author>noreply@blogger.com (Brian Duff)</author><thr:total>0</thr:total></item></channel></rss>
