<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;CE4AQHYyfSp7ImA9WxRQFEU.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478</id><updated>2008-10-08T17:22:21.895+01:00</updated><title>David Peterson</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/david_peterson" type="application/atom+xml" /><entry gd:etag="W/&quot;CUECQ30-fip7ImA9WxRQFE0.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-3375993026919100789</id><published>2008-10-07T19:15:00.005+01:00</published><updated>2008-10-07T19:21:02.356+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-07T19:21:02.356+01:00</app:edited><title>Please apply the patch and reboot.</title><content type="html">&lt;img style="border: 0" src="http://www.davidpeterson.co.uk/image/cartoon/patch.jpg" alt="Cartoon showing two image of the same woman, with different footwear and an eye patch. The caption reads: 'Please apply the patch and reboot.'" /&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/3375993026919100789/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=3375993026919100789" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/3375993026919100789?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/3375993026919100789?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2008/10/please-apply-patch-and-reboot.html" title="Please apply the patch and reboot." /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;A0ENSXw_cSp7ImA9WxdSEkQ.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-8052312355889166434</id><published>2008-05-19T22:17:00.021+01:00</published><updated>2008-05-20T17:08:18.249+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-20T17:08:18.249+01:00</app:edited><title>How do we widen agile adoption?</title><content type="html">&lt;p&gt;Millions of software projects still aren't being run in an agile way. What can we do to widen agile adoption? Let's look at marketing strategy...&lt;/p&gt;&lt;p&gt;&lt;b&gt;First: eXtreme Programming&lt;/b&gt;&lt;br /&gt;In the beginning there was eXtreme Programming. Actually, Tom Gilb created an iterative method at least 10 years before that, called "Evo", which was (and is) in many ways better than XP, but, being based around metrics, it didn't have much sex appeal and never took off. Whereas the "eXtreme" branding appealed to innovators, or at least got them talking, and helped to spread the word.&lt;/p&gt;&lt;div&gt;&lt;img src="http://www.davidpeterson.co.uk/image/chasm/1.png" style="border: 0px; padding: 16px" alt="Step 1" /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;Then: Rebranding as Agile&lt;/b&gt;&lt;br /&gt;The word "eXtreme" may have appealed to innovators but it didn't appeal to their managers, so a few &lt;a href="http://agilemanifesto.org/"&gt;clever people&lt;/a&gt; came up with a new word that would serve to encompass not just XP but a whole genre of methods. You might not want to be extreme, but who wouldn't want to be &lt;em&gt;agile&lt;/em&gt;?&lt;/p&gt;&lt;p&gt;This marketing masterstroke led to early adopters (media, telecoms, IT firms etc.) beginning to take on agile practices.&lt;div&gt;&lt;img src="http://www.davidpeterson.co.uk/image/chasm/2.png" style="border: 0px; padding: 16px" alt="Step 2" /&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;Today: The Chasm&lt;/b&gt;&lt;br /&gt;Unfortunately, at this point, agile adoption began to stutter. This is where we are now, and where we have been for the last few years. The vast majority of organizations still aren't using agile methods. It's like a chasm has opened up and we haven't worked out how to cross it.&lt;/p&gt;&lt;div&gt;&lt;img src="http://www.davidpeterson.co.uk/image/chasm/3.png" style="border: 0px; padding: 16px" alt="Step 3" /&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;So, what do we do?&lt;/b&gt;&lt;br /&gt;Clarke Ching believes &lt;a href="http://www.clarkeching.com/2008/05/there-is-no-agi.html"&gt;the chasm is a mirage &lt;/a&gt; and that another rebranding ("EverydayAgile") is all that's needed to cross it. Brian Marick, on the other hand, thinks the chasm is so wide we might as well &lt;a href="http://www.exampler.com/blog/2008/01/21/uncrossing-the-chasm/"&gt;throw in the towel&lt;/a&gt; and retreat to more innovative companies.&lt;/p&gt;&lt;p&gt;My view is that the issue is real and is too important for us to simply give up on. If you consider how much time and money is wasted around the world on software projects that deliver late and don't actually do what the customer needs, the mind boggles. We have been "&lt;a href="http://agilemanifesto.org/"&gt;uncovering better ways of delivering software&lt;/a&gt;"; it seems criminal not to help others do the same.&lt;/p&gt;&lt;p&gt;I'm not convinced that a rebranding is necessary but, if it is, I think "Lean" or "JIT" might be better candidates than "EverydayAgile". I can see the idea of "EverydayAgile" is to try to make agile seem less daunting, but I don't think this is the problem. Organizations aren't scared off by the word "agile". Quite the opposite! They're drawn to it, to the extent that they'll claim to be "agile" when they're absolutely not. They see "agile" as a synonym for quality. If we were to rebrand, the purpose should be to stop the brand being diluted to the point that no-one knows what it actually means. However, though aging, the &lt;a href="http://agilemanifesto.org/"&gt;agile manifesto&lt;/a&gt; still seems to be doing a sufficiently good job of maintaining a sense of the brand values.&lt;/p&gt;&lt;p&gt;What I think we should do is follow &lt;a href="http://geoffmoore.blogs.com/"&gt;Geoffrey Moore&lt;/a&gt;'s advice about crossing the chasm:&lt;br /&gt;&lt;blockquote style="font-style: italic; line-spacing: 130%"&gt;"The fundamental principle for crossing the chasm is to target a specific niche market as your point of attack and focus all your resources on achieving the dominant leadership position in that segment."&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.davidpeterson.co.uk/image/chasm/4.png" style="border: 0px; padding: 16px" alt="Step 4" /&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;Where should we focus?&lt;/b&gt;&lt;br /&gt;I suggest we focus on &lt;em&gt;investment banks&lt;/em&gt;. They're on the left-hand edge of the early majority. They're financially-savvy and IT-heavy, so an improvement will be noticed, but they are also large and bureaucratic. They pay well, they're influential, they want to adopt agile, but they just can't work out how.&lt;/p&gt;&lt;p&gt;Rather than generic Agile conferences, we should organise a string of global conferences about &lt;em&gt;Agile Investment Banking&lt;/em&gt;, we should have our big-wigs talk to their big-wigs, build agile tool support to meet their specific needs, and focus our entire community's effort on helping them to become agile.&lt;/p&gt;&lt;p&gt;After we have demonstrated a track-record of success in investment banks, we will have crossed the chasm, and convincing everyone else should be a lot easier. That's the theory anyway...&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;img src="http://www.davidpeterson.co.uk/image/chasm/5.png" style="border: 0px; padding: 16px" alt="Step 5" /&gt;&lt;/div&gt;</content><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/8052312355889166434?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/8052312355889166434?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2008/05/how-do-we-widen-agile-adoption.html" title="How do we widen agile adoption?" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;DkYHSHoyeSp7ImA9WxdTEks.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-5406283648187350081</id><published>2008-05-08T11:10:00.007+01:00</published><updated>2008-05-08T17:28:59.491+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-08T17:28:59.491+01:00</app:edited><title>A False Sense of Security</title><content type="html">&lt;img src="http://www.davidpeterson.co.uk/image/cartoon/safe.png" alt="Security Safe" style="border: 0; padding: 0px 0px 12px 12px; float: right;"/&gt;&lt;br /&gt;Sometimes when you're testing, it's easy to get carried away with little edge cases and forget about things that are much more important.&lt;br /&gt;&lt;br /&gt;I saw a real-life example recently at a conference: The security safe in my hotel bedroom was designed to take a laptop and had a small hole in the top for passing in a power cable, so you could charge your machine while you were out of the room. It seemed like a clever idea, but then the exploratory tester in me took over.&lt;br /&gt;&lt;br /&gt;Two minutes later I had successfully broken in without the keycode: I bent a wire coat hanger (handily provided by the hotel), poked it through the hole, hit the little red reset button on the inside edge of the door, keyed-in a new 6&amp;nbsp;digit code, and watched as the door swung open. &lt;br /&gt;&lt;br /&gt;Shielding around the reset button might have solved that issue, but in fact the whole idea was &lt;i&gt;fundamentally flawed&lt;/i&gt;: The way the hotel room worked was that the lights and electric power sockets in the room only switched on when you placed your door-card into a slot by the door. That meant that even if you left your laptop in the safe with its power cable attached, it wouldn't be charging while you were out.&lt;br /&gt;&lt;br /&gt;This is why customer-level acceptance tests are so important. You can unit test your 6&amp;nbsp;digit security lock to your heart's content, but it's a complete waste of time if you're not actually solving the customer's problem.</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/5406283648187350081/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=5406283648187350081" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/5406283648187350081?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/5406283648187350081?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2008/05/false-sense-of-security.html" title="A False Sense of Security" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;C0UHQHY9eyp7ImA9WxZaF0k.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-1371225360603521590</id><published>2008-05-02T16:04:00.006+01:00</published><updated>2008-05-02T16:13:51.863+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-02T16:13:51.863+01:00</app:edited><title>Concordion for Ruby and Maven</title><content type="html">&lt;b&gt;Concordion for Ruby&lt;/b&gt;&lt;br/&gt;Ben Goodspeed has written a very neat &lt;a href="http://code.google.com/p/rcor/"&gt;Ruby port of Concordion&lt;/a&gt; and packaged it as a &lt;a href="http://code.google.com/p/rcor/downloads/list"&gt;gem&lt;/a&gt;. There are currently some &lt;a href="http://code.google.com/p/rcor/wiki/DifferencesBetweenRcorAndConcordion"&gt;minor syntactical differences&lt;/a&gt; between the Java version and the Ruby version because the Ruby version doesn't do &lt;a href="http://www.concordion.org/Tutorial.html#executeUnusualSentences"&gt;lookahead variable bindings&lt;/a&gt; yet (Ben's working on that) but the core functionality is already implemented (set, execute, assertEquals, and verifyRows).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Maven Integration&lt;/b&gt;&lt;br/&gt;Several people requested that the Java version of Concordion be added to Maven repositories and thanks to &lt;a href="http://jmbeas.blogspot.com/"&gt;José Manuel Beas&lt;/a&gt;, Wang Yi Zhou, &lt;a href="http://www.jroller.com/habuma/"&gt;Craig Walls&lt;/a&gt;, and others, this is now done (instructions for usage with Maven are &lt;a href="http://code.google.com/p/concordion/wiki/MavenizedSamples"&gt;here&lt;/a&gt;). Concordion 1.3.0 has the same functionality as 1.2.0 but with Maven support.</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/1371225360603521590/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=1371225360603521590" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/1371225360603521590?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/1371225360603521590?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2008/05/concordion-for-ruby-and-maven.html" title="Concordion for Ruby and Maven" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;CUIERXw-eip7ImA9WxZbEk0.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-5454336496364319424</id><published>2008-04-14T20:08:00.017+01:00</published><updated>2008-04-14T21:05:04.252+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-14T21:05:04.252+01:00</app:edited><title>High-Trust Negotiation</title><content type="html">I enjoyed David Anderson's article "&lt;a href="http://www.agilemanagement.net/Articles/Papers/StopNegotiatingStartColla.html"&gt;Stop Negotiating, Start Collaborating&lt;/a&gt;" but the title doesn't make sense to me. Surely collaboration is a form of negotiation?&lt;br /&gt;&lt;br /&gt;The way I see it is that there is a scale of trust underpinning any negotiation: At the low-trust end, you have lawyers involved, you're not budging an inch, and your aim is to hang your opponent out to dry. At the high-trust end, you're chatting over a cup of coffee. You've both got goals, but you're not going to screw each other over because the long-term relationship matters more to both of you than anything else. At this end of the scale you're still negotiating but it's a collaborative effort; you're trying to find solutions that will work out well for both of you.&lt;br /&gt;&lt;br /&gt;&lt;img style="padding: 16px; border: 0px" src="http://www.davidpeterson.co.uk/image/misc/FormsOfNegotiation.png" alt="Forms of Negotiation" /&gt;&lt;br /&gt;&lt;br /&gt;Negotiation isn't the problem. Lack of trust is the problem and there are no quick fixes. Building trust is about building relationships and that takes time.&lt;br /&gt;&lt;br /&gt;Transparency helps - in that it's tricky to build a relationship with someone who won't give any information away - but too much transparency can actually make decisions harder:&lt;br /&gt;&lt;div style="background-color: #e5e5e5; padding: 12px 24px 12px 24px;"&gt;&lt;b&gt;Manager:&lt;/b&gt;&lt;div style="padding-left: 72px"&gt;Jim, we'd like to hire you. The most we can offer you is $250K. I have been open with you. Now please be open with me: What is the minimum you would accept?&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Jim:&lt;/b&gt;&lt;div style="padding-left: 72px"&gt;&lt;i&gt;Erm... well, the minimum I would accept is $100K, but obviously I'd like more than that.&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;It would be ridiculous to expect the candidate to say that, but, if he did, how do you resolve the situation? Whatever you do, someone's going to feel unhappy knowing they could have done better out of the deal.&lt;br /&gt;&lt;br /&gt;People aren't robots. There's psychology at play and personal goals and emotions and that means, no matter what you might wish, collaboration is still negotiation, but a high-trust form.</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/5454336496364319424/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=5454336496364319424" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/5454336496364319424?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/5454336496364319424?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2008/04/high-trust-negotiation.html" title="High-Trust Negotiation" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;A0ICQH4zfyp7ImA9WxZWFUQ.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-2482824208183804654</id><published>2008-03-15T16:25:00.008Z</published><updated>2008-03-15T16:46:01.087Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-15T16:46:01.087Z</app:edited><title>Concordion 1.2.0</title><content type="html">I've released a new version of &lt;a href="http://www.concordion.org"&gt;Concordion&lt;/a&gt;.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Support for full set of JUnit4.4 annotations (&lt;i&gt;@Before, @After&lt;/i&gt; etc.)&lt;/li&gt;&lt;li&gt;New command: &lt;b&gt;assertTrue&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;For example, this instrumented specification:&lt;pre style="font-size: 10pt; background-color: #f7f7f7; padding: 4px;"&gt;&amp;lt;p&amp;gt;&lt;br /&gt;    The first name &amp;lt;span concordion:set="#firstName"&amp;gt;Bob&amp;lt;/span&amp;gt;,&lt;br /&gt;    &amp;lt;span &lt;b&gt;concordion:assertTrue="#firstName.startsWith(#letter)"&lt;/b&gt;&amp;gt;&lt;br /&gt;    starts with the letter &amp;lt;b concordion:set="#letter"&amp;gt;B&amp;lt;/b&amp;gt;&amp;lt;/span&amp;gt;.&lt;br /&gt;&amp;lt;/p&amp;gt;&lt;/pre&gt;Will result in the following output:&lt;br /&gt;&lt;img style="border: 0" alt="Success" src="http://www.davidpeterson.co.uk/image/misc/concordion-1.2.0-assertTrue-success.png"/&gt;&lt;br /&gt;&lt;br /&gt;A failure would look like this:&lt;br /&gt;&lt;img style="border: 0" alt="Failure" src="http://www.davidpeterson.co.uk/image/misc/concordion-1.2.0-assertTrue-failure.png"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/2482824208183804654/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=2482824208183804654" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/2482824208183804654?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/2482824208183804654?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2008/03/concordion-120.html" title="Concordion 1.2.0" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;DkADR30yeip7ImA9WxZWFU8.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-6515429463856834318</id><published>2008-03-13T12:21:00.011Z</published><updated>2008-03-14T19:59:36.392Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-14T19:59:36.392Z</app:edited><title>Big Hairy Tables</title><content type="html">I like Keith Braithwaite's "software gauges" metaphor. As &lt;a href="http://peripateticaxiom.blogspot.com/2007/09/gauges.html"&gt;he explains&lt;/a&gt;, a gauge is a shortcut for deciding whether something passes or fails some criteria. For example, if your bag fits inside the metal cage at an airport then it can be taken onboard as hand luggage. You don't need to use a tape measure. What's interesting about gauges is that you don't necessarily need to be able to articulate "the rules"; if you need to know the rules you can infer them from the gauge.&lt;br /&gt;&lt;br /&gt;However, I'm not convinced with what &lt;a href="http://peripateticaxiom.blogspot.com/2008/03/tests-and-gauges.html"&gt;Keith says&lt;/a&gt; about trader spreadsheets making good gauges. Obviously he's had success with them, so they definitely can be made to work, but would they have worked even better another way? Basically what it boils down to is that I like tables; I just don't like &lt;span style="font-style:italic;"&gt;big hairy tables&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;If the hand-luggage cage can be taken as an example of good practice then some of the properties of a good gauge appear to be: sturdy and reliable; correct enough for all practical purposes; obvious; unambiguous; quick to use; and simple to understand by the gauge user.&lt;br /&gt;&lt;br /&gt;The spreadsheets Keith showed me contained a large number of sparsely populated columns of denormalised data with lots of magic numbers and magic strings. This doesn't seem to stack up well against the list of desirable traits for a gauge. They're not designed with the gauge user in mind. If your domain model doesn't fit the gauge, is it because the model is wrong? Or the gauge is wrong? Or your interpretation of the gauge is wrong? With so many moving parts, it's got to be difficult to work out, even with help from the traders.&lt;br /&gt;&lt;br /&gt;Isn't it better to treat the spreadsheets as a starting point rather than an ending point? And then have someone skilled at analysis and abstraction work with the traders and extract smaller, more practical gauges. There's nothing to stop you holding these gauges in spreadsheets too. I have a lot of respect for the customer, but I don't see why, just because the traders have written a spreadsheet, you can't help them improve it. They've got their skills you've got yours.</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/6515429463856834318/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=6515429463856834318" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/6515429463856834318?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/6515429463856834318?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2008/03/big-hairy-tables.html" title="Big Hairy Tables" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;C04HSHw8eyp7ImA9WxZWEEQ.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-5247658967136994055</id><published>2008-03-09T17:10:00.009Z</published><updated>2008-03-09T19:45:39.273Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-09T19:45:39.273Z</app:edited><title>Acceptance Test Driven Development</title><content type="html">Most of the examples on the &lt;a href="http://www.concordion.org"&gt;Concordion website&lt;/a&gt; are technical in nature, so I've put together a short business-focused example. Please &lt;a href="http://www.concordion.org/Example.html"&gt;take a look&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'm not trying to push Concordion on you. You can do something similar with other test frameworks. It's really the approach that I'm trying to get across: focusing the acceptance tests on goals, not solutions; and decomposing behaviours, keeping each test as isolated and simple as you can.&lt;br /&gt;&lt;br /&gt;While I'm here, let me join in the &lt;a href="http://www.testing.com/cgi-bin/blog/2003/08/21#agile-testing-project-1"&gt;2x2 matrix&lt;/a&gt; &lt;a href="http://www.testingreflections.com/node/view/6704"&gt;fun&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;img style="border: 0px" alt="2x2 Matrix: Abstract vs Concrete / Goal vs Solution" src="http://www.davidpeterson.co.uk/image/misc/GoalOriented.png"/&gt;&lt;br /&gt;&lt;br /&gt;The user-interface (UI) of an application is a solution, not a goal. I often see people writing test scripts in terms of direct user interface interactions (e.g. using a record/playback/verify tool like Selenium) unaware that by doing so they're locking themselves into a particular design.&lt;br /&gt;&lt;br /&gt;If, instead, they &lt;a href="http://www.concordion.org/Technique.html"&gt;hid the scripting&lt;/a&gt; behind goal-oriented acceptance tests they would leave themselves a lot more freedom to change the solution. I guess not all teams need that kind of freedom. But I wonder how many even know there's a choice?</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/5247658967136994055/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=5247658967136994055" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/5247658967136994055?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/5247658967136994055?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2008/03/acceptance-test-driven-development.html" title="Acceptance Test Driven Development" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;DEEGQnw-fCp7ImA9WxZRFkg.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-4252474055805754741</id><published>2008-02-09T20:31:00.000Z</published><updated>2008-02-10T15:17:03.254Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-10T15:17:03.254Z</app:edited><title>What do I mean by a "Scripting DSL"?</title><content type="html">I have had a couple of e-mail questions recently, from people who have read the &lt;a href="http://www.concordion.org"&gt;Concordion&lt;/a&gt; documentation, asking for more detail about what I mean by a DSL (Domain-Specific Language) for scripting, as shown in this diagram:&lt;br /&gt;&lt;br /&gt;&lt;img border="0" style="border: 0px;" src="http://www.concordion.org/image/technique/SpecFixtureScriptingSystem.png"/&gt;&lt;br /&gt;I think it's easiest to explain with a realistic implementation of a fixture:&lt;br /&gt;&lt;pre style="font-size: 10pt"&gt;&lt;br /&gt;&lt;b&gt;public&lt;/b&gt; String getGreetingFor(String firstName) {&lt;br /&gt;    User user = &lt;b&gt;new&lt;/b&gt; UserBuilder()&lt;br /&gt;        .withReasonableDefaults()&lt;br /&gt;        .withFirstName(firstName)&lt;br /&gt;        .build();&lt;br /&gt;    BrowserSession session = &lt;b&gt;new&lt;/b&gt; BrowserSession();&lt;br /&gt;    &lt;b&gt;new&lt;/b&gt; UserAdminAction(session).setUp(user);&lt;br /&gt;    &lt;b&gt;new&lt;/b&gt; LoginDriver(session).login(user);&lt;br /&gt;    &lt;b&gt;return new&lt;/b&gt; HomePageDriver(session).scrapeGreeting()&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;In this case, the DSL is made up of the Builder, Action and Driver classes. These implement and hide all the dirty work of setting up the user and navigating around the website.&lt;br /&gt;&lt;br /&gt;The Driver classes extend an AbstractDriver class. The abstract base class provides protected methods for clicking on links, scraping the contents of elements, typing text, selecting radio buttons etc. &lt;br /&gt;&lt;pre style="font-size: 10pt"&gt;&lt;br /&gt;&lt;b&gt;public abstract class&lt;/b&gt; AbstractDriver {&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;private&lt;/b&gt; BrowserSession session;&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;public&lt;/b&gt; AbstractDriver(BrowserSession session) {&lt;br /&gt;        this.setSession(session);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;protected&lt;/b&gt; HtmlPage getHtmlPage() {&lt;br /&gt;        &lt;b&gt;return&lt;/b&gt; session.getHtmlPage();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;protected&lt;/b&gt; HtmlElement getElement(String id) {&lt;br /&gt;        &lt;b&gt;return&lt;/b&gt; getHtmlPage().getHtmlElementById(id);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;protected&lt;/b&gt; String scrapeText(String id) {&lt;br /&gt;        &lt;b&gt;return&lt;/b&gt; getElement(id).asText();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;protected&lt;/b&gt; void click(String id) {&lt;br /&gt;        ((ClickableElement) getElement(id)).click();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // etc.&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;The subclasses use these methods, but do not reveal them publicly. The public interface is at a higher level of abstraction.&lt;br /&gt;&lt;pre style="font-size: 10pt"&gt;&lt;br /&gt;&lt;b&gt;public class&lt;/b&gt; HomePageDriver &lt;b&gt;extends&lt;/b&gt; AbstractDriver {&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;public&lt;/b&gt; HomePageDriver(BrowserSession session) {&lt;br /&gt;        super(session);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;public&lt;/b&gt; String scrapeGreeting() {&lt;br /&gt;        &lt;b&gt;return&lt;/b&gt; scrapeText(HomePage.GREETING_ID);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;public void&lt;/b&gt; clickSearch() {&lt;br /&gt;        click(HomePage.SEARCH_LINK_ID);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // etc.&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Actions encapsulate a series of driver clicks to perform some higher-level action and remove duplication across tests. For example, behind the scenes the UserAdminAction may use a LoginDriver, UserAdminPageDriver, UserDetailsPageDriver, LogoutDriver. Actions may be nested.&lt;br /&gt;&lt;br /&gt;You should also read Nat Pryce's series of blog posts on &lt;a href="http://nat.truemesh.com/archives/000714.html"&gt;Test Data Builders&lt;/a&gt;.</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/4252474055805754741/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=4252474055805754741" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/4252474055805754741?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/4252474055805754741?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2008/02/what-do-i-mean-by-scripting-dsl.html" title="What do I mean by a &quot;Scripting DSL&quot;?" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;DEQMQXk8cCp7ImA9WxZSFEg.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-3335321671784184515</id><published>2008-01-27T17:29:00.000Z</published><updated>2008-01-27T17:53:00.778Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-27T17:53:00.778Z</app:edited><title>Concordion 1.1.0</title><content type="html">I've released a new version of my Java acceptance testing framework: &lt;a href="http://www.concordion.org"&gt;Concordion&lt;/a&gt;. The main new feature is support for &lt;a href="http://www.junit.org"&gt;JUnit&amp;nbsp;4&lt;/a&gt; test runners.&lt;br /&gt;&lt;br /&gt;For example this &lt;code&gt;Demo.html&lt;/code&gt; specification:&lt;br /&gt;&lt;pre&gt;&amp;lt;html &lt;b&gt;xmlns:concordion="http://www.concordion.org/2007/concordion"&lt;/b&gt;&amp;gt;&lt;br /&gt;    &amp;lt;body&amp;gt;&lt;br /&gt;        &amp;lt;p&amp;gt;&lt;br /&gt;            The greeting for user &amp;lt;span &lt;b&gt;concordion:set="#firstName"&amp;gt;Bob&amp;lt;&lt;/b&gt;/span&amp;gt;&lt;br /&gt;            will be:&lt;br /&gt;            &amp;lt;span &lt;b&gt;concordion:assertEquals="greetingFor(#firstName)"&lt;/b&gt;&amp;gt;Hello Bob!&amp;lt;/span&amp;gt;&lt;br /&gt;        &amp;lt;/p&amp;gt;&lt;br /&gt;    &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Can be run with the following JUnit 4 test case:&lt;br /&gt;&lt;pre&gt;&lt;b&gt;import&lt;/b&gt; org.concordion.integration.junit4.ConcordionRunner;&lt;br /&gt;&lt;b&gt;import&lt;/b&gt; org.junit.runner.RunWith;&lt;br /&gt;&lt;br /&gt;@RunWith(ConcordionRunner&lt;b&gt;.class&lt;/b&gt;)&lt;br /&gt;&lt;b&gt;public class&lt;/b&gt; DemoTest {&lt;br /&gt;&lt;br /&gt;    &lt;b&gt;public&lt;/b&gt; String greetingFor(String firstName) {&lt;br /&gt;        &lt;b&gt;return&lt;/b&gt; String.format("Hello %s!", firstName);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And will result in the following output:&lt;br /&gt;&lt;img border="0" style="border: 0px" alt="Concordion 1.1.0" src="http://www.davidpeterson.co.uk/image/misc/concordion-1.1.0-results.png" /&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/3335321671784184515/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=3335321671784184515" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/3335321671784184515?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/3335321671784184515?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2008/01/concordion-110.html" title="Concordion 1.1.0" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;DkYHQn48fSp7ImA9WxZSE0s.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-2582849245307693753</id><published>2008-01-26T16:08:00.000Z</published><updated>2008-01-26T16:15:33.075Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-26T16:15:33.075Z</app:edited><title>There's only one thing for it...</title><content type="html">&lt;img border="0" style="border: 0px" alt="There's only one thing for it... We'll have to stop measuring." src="http://www.davidpeterson.co.uk/image/cartoon/stop-measuring.png"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/2582849245307693753/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=2582849245307693753" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/2582849245307693753?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/2582849245307693753?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2008/01/theres-only-one-thing-for-it-well-have.html" title="There's only one thing for it..." /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;CUEERHo-eyp7ImA9WB9bGEU.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-6160459714774348261</id><published>2007-12-05T20:56:00.000Z</published><updated>2007-12-28T23:13:25.453Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-12-28T23:13:25.453Z</app:edited><title>Groupthink</title><content type="html">Being an agile developer in a largely waterfall organisation has reminded me of a game we played in one of my MBA lectures where we were put into groups and asked to solve a problem.&lt;br /&gt;&lt;br /&gt;One guy in one of the groups (unbeknownst to us) had been primed by the lecturer to disagree with every idea that his group came up with. At the end of the session, that group had markedly better results than all the other groups. The constant voice of dissent had helped them to uncover their assumptions. &lt;br /&gt;&lt;br /&gt;Of course, before revealing the results, the lecturer asked each group to vote a person out and the disagreement-guy was unanimously given the boot.</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/6160459714774348261/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=6160459714774348261" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/6160459714774348261?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/6160459714774348261?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2007/12/avoiding-groupthink.html" title="Groupthink" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;A0MMQ3g_eCp7ImA9WB9VEU0.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-5349962042977667583</id><published>2007-11-26T20:15:00.000Z</published><updated>2007-11-26T20:38:02.640Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-11-26T20:38:02.640Z</app:edited><title>Knowing When to Refactor</title><content type="html">You're in the middle of implementing some new functionality when you stumble across some poorly written code. Fixing it properly will take some time and, for the stuff you're working on, you can get away with making a couple of tweaks. What should you do? Refactor it now? Or leave it for another time? If so, when?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.citconf.com/wiki/index.php?title=Douglas_Squirrel"&gt;Douglas Squirrel&lt;/a&gt; told me about a neat solution that I hadn't heard of before. The idea is that the first time you come across some smelly code you write a comment that says &lt;code&gt;FIXME&lt;/code&gt;. Each time you encounter the code again, or someone else does, an extra &lt;code&gt;X&lt;/code&gt; is added so it becomes &lt;code&gt;FIXXME&lt;/code&gt;, &lt;code&gt;FIXXXME&lt;/code&gt; etc. By the time the comment screams &lt;code&gt;FIXXXXXXXME&lt;/code&gt;, you know what you have to do!</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/5349962042977667583/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=5349962042977667583" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/5349962042977667583?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/5349962042977667583?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2007/11/knowing-when-to-refactor.html" title="Knowing When to Refactor" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;DkMDRnw-cSp7ImA9WB9aE0s.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-2347718461367084784</id><published>2007-11-17T19:07:00.000Z</published><updated>2008-01-03T12:47:57.259Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-03T12:47:57.259Z</app:edited><title>UNICOM Agile Conference - February 2008</title><content type="html">I will be speaking about &lt;span style="font-style: italic;"&gt;Acceptance Test-Driven Development&lt;/span&gt; at the &lt;a href="http://www.unicom.co.uk/product_detail.asp?prdid=1547"&gt;UNICOM agile conference&lt;/a&gt; in London, 12/13 February 2008. The conference has a good line-up of speakers including &lt;a href="http://duncanpierce.org/"&gt;Duncan Pierce&lt;/a&gt;, &lt;a href="http://peripateticaxiom.blogspot.com/"&gt;Keith Braithwaite&lt;/a&gt;, and &lt;a href="http://twelve71.typepad.com/rachel/"&gt;Rachel Davies&lt;/a&gt;. Early-bird fees are on offer till 18th January.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update&lt;/b&gt;: If you're interested in attending, &lt;a href="mailto:david@crowdsoft.com"&gt;contact me&lt;/a&gt;. I can probably get you a discount.</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/2347718461367084784/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=2347718461367084784" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/2347718461367084784?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/2347718461367084784?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2007/11/unicom-agile-conference-february-2008.html" title="UNICOM Agile Conference - February 2008" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry><entry gd:etag="W/&quot;CkYEQn84fCp7ImA9WB9XGEw.&quot;"><id>tag:blogger.com,1999:blog-3933266989882835478.post-3695805646107272681</id><published>2007-06-28T18:57:00.000+01:00</published><updated>2007-11-11T19:41:43.134Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-11-11T19:41:43.134Z</app:edited><title>Tapestry 5 (Alpha)</title><content type="html">&lt;p&gt; I've been working with &lt;a href="http://tapestry.apache.org/tapestry5/"&gt;Tapestry 5&lt;/a&gt;, for a few weeks now, and I'm loving it. It's a big step up from Tapestry 4 and I think it could become a realistic competitor to Ruby on Rails. It has similar characteristics: convention over configuration and an almost religious devotion by its creator, &lt;a href="http://tapestryjava.blogspot.com/"&gt;Howard Lewis-Ship&lt;/a&gt;, to driving out duplication. &lt;/p&gt;  &lt;p&gt; Sometimes he possibly goes too far. For example, if your page class is &lt;code&gt;/article/ArticleEdit&lt;/code&gt; the duplication of the word "article" is removed from the URL, so the URL becomes &lt;code&gt;/article/edit&lt;/code&gt;. It seems like an improvement, but actually introduces ambiguity and has caused confusion, judging by queries on the mailing list. &lt;/p&gt;    &lt;p&gt;At the moment, you'd be taking a risk using Tapestry 5 in a production application. It's still "alpha" and unstable both in terms of the API, which hasn't fully settled down, and in terms of defects: There are lots of minor, and a handful of more serious, defects reported in JIRA. But if you're developing a non-mission-critical web application you might want to give it some serious consideration. It's already very good and only going to get better. &lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.davidpeterson.co.uk/feeds/3695805646107272681/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3933266989882835478&amp;postID=3695805646107272681" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/3695805646107272681?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3933266989882835478/posts/default/3695805646107272681?v=2" /><link rel="alternate" type="text/html" href="http://blog.davidpeterson.co.uk/2007/11/ive-been-working-with-tapestry-5-for.html" title="Tapestry 5 (Alpha)" /><author><name>David Peterson</name><uri>http://www.blogger.com/profile/03475136061061572446</uri><email>noreply@blogger.com</email></author></entry></feed>
