<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:gr="http://www.google.com/schemas/reader/atom/" xmlns:idx="urn:atom-extension:indexing" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" idx:index="no" gr:dir="ltr"><!--
Content-type: Preventing XSRF in IE.

--><generator uri="http://www.google.com/reader">Google Reader</generator><id>tag:google.com,2005:reader/user/03932364210302262295/label/indyndabloggers</id><title type="text">IndyNDA Bloggers</title><gr:continuation>COj13O-D5qYC</gr:continuation><author><name>Jeff</name></author><updated>2011-12-04T03:27:29Z</updated><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/indyndabloggers" /><feedburner:info uri="indyndabloggers" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><subtitle type="html">A blog roll of people that attend the Indianapolis .NET Users Group (IndyNDA) and blog about software development, programming, and .net.</subtitle><entry gr:crawl-timestamp-msec="1322969249565"><id gr:original-id="http://www.aaronlerch.com/blog/?p=257">tag:google.com,2005:reader/item/e30d0b76e4ded12a</id><category term="community" /><category term="programming" /><title type="html">Coderetreatin’</title><published>2011-12-04T03:27:07Z</published><updated>2011-12-04T03:27:07Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/3Gd9D00PN3k/" type="text/html" /><content xml:base="http://www.aaronlerch.com/blog" type="html">&lt;p&gt;&lt;a href="http://www.aaronlerch.com/blog/wp-content/uploads/2011/12/coderetreat-session-1.jpg"&gt;&lt;img title="Session 1 at Global Day of Coderetreat" src="http://www.aaronlerch.com/blog/wp-content/uploads/2011/12/coderetreat-session-1-300x224.jpg" alt="Session 1 at Global Day of Coderetreat" width="300" height="224"&gt;&lt;/a&gt;Today, the Global Day of Coderetreat came to Indianapolis. &lt;em&gt;And it was great.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;13 people chose to spend the whole day on Saturday, December 3rd, in the “common area” at Interactive Intelligence honing their skillz.&lt;/p&gt;
&lt;p&gt;By the way, I want to extend a huge &lt;strong&gt;thanks&lt;/strong&gt; to Interactive Intelligence for providing the space, a catered lunch, and some breakfast! It was awesome!&lt;/p&gt;
&lt;p&gt;This was my first coderetreat, not to mention the first one I’ve hosted and facilitated. I was trusting &lt;a title="Corey Haines" href="http://coreyhaines.com/"&gt;Corey Haines’&lt;/a&gt; experience when it came to the format, and I was very pleased with how it went. We did 6 45-minute sessions, each time pairing up and implementing Conway’s Game of Life. People used a wide variety of languages throughout the day: ruby, python, C#, java, javascript, even some C++.&lt;/p&gt;
&lt;p&gt;Many of the people were new to practices like pairing, and TDD. We also got to explore a lot of design ideas and look at different ways to approach a problem. I really enjoyed being able to throw in various constraints during each session and then to see how it affected the approaches or designs that people came up with.&lt;/p&gt;
&lt;p&gt;Overall, I got very positive feedback – it really seemed like a valuable day for everybody, for a wide variety of reasons. By far, people said that the pairing and the &lt;a title="Ping Pong Programming" href="http://c2.com/cgi/wiki?PairProgrammingPingPongPattern"&gt;ping/pong TDD&lt;/a&gt; were the most enlightening aspects of the day. It was great to have a structured and guided environment for people to explore those concepts that can otherwise be difficult to dig into ad-hoc.&lt;/p&gt;
&lt;p&gt;Other things people learned or enjoyed were designing with the &lt;a title="Tell, Don&amp;#39;t Ask" href="http://pragprog.com/articles/tell-dont-ask"&gt;Tell, Don’t Ask&lt;/a&gt; approach, and getting exposed to some new languages.&lt;/p&gt;
&lt;p&gt;Overall I think it was a huge success. Or at least, I was very pleased with how it went and how it seemed to affect people. &lt;img src="http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif" alt=":)"&gt;  People grew as software developers today! That’s awesome in and of itself. &lt;img src="http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif" alt=":)"&gt; &lt;/p&gt;
&lt;p&gt;Thanks to all who attended!!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.aaronlerch.com/blog/wp-content/uploads/2011/12/coderetreaters.jpg"&gt;&lt;img title="Coderetreaters" src="http://www.aaronlerch.com/blog/wp-content/uploads/2011/12/coderetreaters-300x224.jpg" alt="Coderetreaters" width="300" height="224"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;
&lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=XA7JvrPWaSI:pWV006l3uoY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=XA7JvrPWaSI:pWV006l3uoY:V_sGLiPBpWU" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=XA7JvrPWaSI:pWV006l3uoY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=XA7JvrPWaSI:pWV006l3uoY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=XA7JvrPWaSI:pWV006l3uoY:F7zBnMyn0Lo" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=XA7JvrPWaSI:pWV006l3uoY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=XA7JvrPWaSI:pWV006l3uoY:gIN9vFwOqvQ" border="0"&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/aaronlerch/~4/XA7JvrPWaSI" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/3Gd9D00PN3k" height="1" width="1"/&gt;</content><author><name>aaron</name></author><source gr:stream-id="feed/http://feeds.feedburner.com/aaronlerch"><id>tag:google.com,2005:reader/feed/http://feeds.feedburner.com/aaronlerch</id><title type="html">Aaron Lerch</title><link rel="alternate" href="http://www.aaronlerch.com/blog" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/aaronlerch/~3/XA7JvrPWaSI/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1321886684237"><id gr:original-id="tag:blogger.com,1999:blog-6800934446457898793.post-86529977875835325">tag:google.com,2005:reader/item/ccfb979066f84391</id><title type="html">Life, Death, and Splitting Secrets</title><published>2011-11-21T13:43:00Z</published><updated>2011-11-21T13:55:57Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/BdOM-_VPQQg/life-death-and-splitting-secrets.html" type="text/html" /><link rel="replies" href="http://www.moserware.com/feeds/86529977875835325/comments/default" title="Post Comments" type="application/atom+xml" /><link rel="replies" href="http://www.blogger.com/comment.g?blogID=6800934446457898793&amp;postID=86529977875835325" title="1 Comments" type="text/html" /><content xml:base="http://www.moserware.com/" type="html">&lt;p&gt;(&lt;strong&gt;Summary&lt;/strong&gt;: I created &lt;a href="https://github.com/moserware/SecretSplitter"&gt;a program&lt;/a&gt; to help back up important data like your master password in case something happens to you. By splitting your secret into pieces, it provides a circuit breaker against a single point of failure. I’m giving it away as a free open source program with the hope that others might find it useful in addressing this aspect of our lives. Feel free to &lt;a href="https://github.com/downloads/moserware/SecretSplitter/SecretSplitter.exe"&gt;use the program&lt;/a&gt; and follow along with just the screenshots below or read all sections of this post if you want more context.)&lt;/p&gt;&lt;h4&gt;Background&lt;/h4&gt;&lt;p&gt;I just couldn’t do it.&lt;/p&gt;&lt;p&gt;&lt;img alt="Grandma and Jeff" title="Grandma and Jeff" src="http://3.bp.blogspot.com/-IBcyywvqnWA/TsEou9240BI/AAAAAAAAZBE/a5aM-FeH49I/s320/Grandma+and+Jeff.jpg" align="right" style="border:0;margin:0px 0px 15px 15px;display:inline"&gt;My grandma died at this time last year from a stroke. She was a great woman. I still miss her. In that emotional last week, I was reminded of great memories with her and the fragility of life. I was also reminded about important documents that I still didn’t have.&lt;/p&gt;&lt;p&gt;When something happens to you, be it death or incapacitation, there are some important steps that need to occur that can be greatly assisted by legal documents.  For example:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;An &lt;a href="http://en.wikipedia.org/wiki/Advance_health_care_directive"&gt;advance health care directive&lt;/a&gt; (aka “Living Will”) specifies what actions should (or shouldn’t) be taken with regards to your healthcare if you’re no longer able to make decisions for yourself.&lt;/li&gt;&lt;li&gt;A &lt;a href="http://en.wikipedia.org/wiki/Power_of_attorney#Durable_power_of_attorney"&gt; durable power of attorney&lt;/a&gt; allows you to designate someone to legally act as you if you become incapacitated.&lt;/li&gt;&lt;li&gt;A &lt;a href="http://en.wikipedia.org/wiki/Will_(law)"&gt;last will and testament&lt;/a&gt; allows you to legally assign caregivers for &lt;a href="http://en.wikipedia.org/wiki/Minor_(law)" title="Typically 18 and younger."&gt;minor children&lt;/a&gt; as well as designate where you'd like your possessions to go.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;My grandma had these and it helped reduce stress and anxiety in this difficult time. We knew what she would have wanted and these documents helped legally enforce that.&lt;/p&gt;&lt;p&gt;I had assumed that these documents were expensive and time-consuming to  create. Furthermore, as a guy in my 20’s, death still seems like &lt;a href="http://quotationsbook.com/quote/10024/" title="“Death is a distant rumor to the young.” - Andy Rooney (1919 - 2011)"&gt;a distant rumor&lt;/a&gt;. As a Christian, I’m &lt;a href="http://www.biblegateway.com/passage/?search=Philippians%201:21&amp;amp;version=ESV"&gt;not overly concerned&lt;/a&gt; &lt;a href="http://www.biblegateway.com/passage/?search=1%20Corinthians%2015:54-57&amp;amp;version=ESV"&gt;about death itself&lt;/a&gt;, but my grandma’s death reminded me that these documents  are not really for me, but rather the people I’d leave behind. I knew that if something  happened to me, I’d potentially be leaving behind a mess, and that concern of  irresponsibility compelled me to investigate what I could do.&lt;/p&gt;&lt;p&gt;It turns out that creating these documents is essentially a matter of filling  out a form template. I &lt;a href="http://www.amazon.com/gp/product/B004DLCQZ4/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=moserware-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399369&amp;amp;creativeASIN=B004DLCQZ4" title="I used Quicken Willmaker 2011 Premium edition. I liked the premium edition because it came with a lot of extra books that made for fun reading. The 2012 version will probably be available soon."&gt; bought a program&lt;/a&gt; that made it about as easy as preparing taxes online. In  most cases, you just need disinterested third parties, such as friends or coworkers,  to witness you signing them to make them fully legal. At most, you might have to  get them notarized or filed in your county for a small fee.&lt;/p&gt;&lt;p&gt;One of the steps involved in filling out the “Information for Caregivers  and Survivors” document is to list “&lt;a href="http://www.nolo.com/legal-encyclopedia/help-executor-secured-places-passwords-29669.html"&gt;Secured  Places and Passwords&lt;/a&gt;.” It’s a helpful section that your  &lt;a href="http://en.wikipedia.org/wiki/Executor"&gt;executor&lt;/a&gt; can turn  to if something happened to you in order to do things like unlock your cell phone  or access your online accounts. Sure, your survivors might be able use legal force  to get access without it, but only after months of  &lt;a href="https://mail.google.com/support/bin/answer.py?answer=14300"&gt;sending official documentation&lt;/a&gt;.  That’s a lot of hassle to put someone through. Also, it’s very likely that  a lot of important things will be missed and no one would ever know they  existed.&lt;/p&gt;&lt;p&gt;It’s &lt;a href="http://research.microsoft.com/apps/pubs/?id=80436" title="“The Rational Rejection of Security Advice by Users” provides some interesting counterpoints to security advice out there."&gt;probably  rational&lt;/a&gt; to just write your passwords down and put them in a safe which your  executor knows the location of and can access in a timely matter. Alternatively,  you could pay for an attorney or a  &lt;a href="http://mashable.com/2010/10/11/social-media-after-death/"&gt;third-party service&lt;/a&gt; and leave your password list with them.  However, this seemed like it would cause a maintenance problem, especially as I  might add or update my passwords frequently. These options would also force me to trust someone I haven’t known for a long time. Most importantly, the thought of writing  down my passwords on a piece of paper, even if it was in a relatively safe place,  went against every fiber of my security being.&lt;/p&gt; &lt;p&gt;I just couldn’t do it.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;DISCLAIMER&lt;/strong&gt;: The above simple approaches are probably fine and have worked  for a lot of people over the years. &lt;strong&gt;If you’re comfortable with these basic approaches,  by all means use them and ignore this post&lt;/strong&gt;. These simpler approaches have less moving  parts and are easy to understand. However, if you want a little more security, or need to liven up this process with a little spy novel-esque fun, read on.&lt;/p&gt; &lt;h4&gt;The Modern Password &amp;amp; Encryption Problem&lt;/h4&gt; &lt;p&gt;As an online citizen, you don’t want to be that person. You know, the one  whose password was so &lt;a href="http://blogs.wsj.com/digits/2010/12/13/the-top-50-gawker-media-passwords/" title="If nothing else, promise me that none of your passwords are on this list!"&gt; easy to guess&lt;/a&gt; that his email account was broken into and who “&lt;a href="http://www.nbclosangeles.com/news/tech/Email-Scams-83600577.html"&gt;wrote&lt;/a&gt;”  to you saying that he decided to go to Europe on a whim this past weekend but now  needs you to wire him money right now and he’ll explain everything later: &lt;em&gt;that&lt;/em&gt; guy.&lt;/p&gt; &lt;p&gt;You’ve learned that passwords like “thunder”, “thunder56”, and even “L0u|&amp;gt;Thund3r”  are terrible because they’re &lt;a href="http://www.wired.com/politics/security/commentary/securitymatters/2007/01/72458?currentPage=all" title="Password recovery tools are pretty good these days."&gt; easily guessed&lt;/a&gt;. You now know that the most important aspect of a password is  its &lt;a href="http://xkcd.com/936/" title="“correct horse battery staple” is a start, but character variation and padding help a lot"&gt;length&lt;/a&gt; combined with &lt;a href="https://www.grc.com/haystack.htm" title="Steve Gibson’s Password Haystacks page is worth at least a quick glance."&gt;basic padding and character variation&lt;/a&gt;  such as “/* Thunder is coming! */”, “I hear &amp;lt;em&amp;gt;thunder&amp;lt;/em&amp;gt;!”, or “1.big.BOOM@thunder.mil”.&lt;/p&gt; &lt;p&gt;In fact, you’re probably clever enough that you don’t create or remember  most of your passwords anymore. You use a &lt;a href="http://en.wikipedia.org/wiki/Password_manager"&gt;password manager&lt;/a&gt; like &lt;a href="https://lastpass.com/"&gt;LastPass&lt;/a&gt; or &lt;a href="http://keepass.info/"&gt;KeePass&lt;/a&gt;  to automatically generate and store unique and completely random passwords for all  of your accounts. This has simplified your life so that you only have to remember  your “master password” that will get you into where you keep all the rest of your  usernames and passwords.&lt;/p&gt; &lt;p&gt; &lt;img alt="Skeleton Key" height="320" src="http://3.bp.blogspot.com/-8NBM4ONkCGg/TsRkc_qt7QI/AAAAAAAAZG8/3jYrTXbui-8/s320/450px-Llave_bronce%5B1%5D.jpg" align="left" style="border:0;margin:0px 15px 15px 0px;display:inline" width="240"&gt;&lt;/p&gt; &lt;p&gt;You also understand that your email account credentials are a “&lt;a href="http://www.codinghorror.com/blog/2008/06/please-give-us-your-email-password.html" title="It was especially sad in the Web’s early day when so many sites asked for your email login to effectively spam your contacts. It’s just inexcusable that some sites still do today."&gt;skeleton  key&lt;/a&gt;” for almost everything else due to the widespread use of simple password  reset emails. For this very reason, you probably realize that it’s critical to &lt;a href="http://googleblog.blogspot.com/2011/06/ensuring-your-information-is-safe.html" title="If you do use Gmail, really consider enabling this for your own safety and to prevent yourself from being *that* guy."&gt; protect your email login with “two-factor” authentication&lt;/a&gt;. That is, your email  account should at least be protected by:&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;Something you know (your password) &lt;em&gt;and&lt;/em&gt; &lt;/li&gt;  &lt;li&gt;Something you have (your cellphone), that creates or receives a one-time   use code when you want to login.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;On top of all of this, you try your best to follow the trusty advice that  your passwords should be ones that nobody could guess and you never ever &lt;a href="http://www.schneier.com/blog/archives/2005/06/write_down_your.html" title="Actually, it’s probably reasonable to write them down in keep them in your wallet"&gt;write  them&lt;/a&gt; &lt;a href="http://blog.jgc.org/2010/12/write-your-passwords-down.html"&gt;down&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;But what if something happens to you? If you’ve done everything “right,”  then your master password and all your second factor details go with you.  &lt;/p&gt; &lt;p&gt;And then there are your encrypted files. Maybe you’re keeping a &lt;a href="http://www.youtube.com/watch?feature=player_embedded&amp;amp;v=R4vkVHijdQk" title="You could use an encrypted journal or a separate email account. I wonder if “dear.sophie.lee@gmail.com” had two-factor authentication enabled on it. I mean, what happens if she writes back too early?"&gt; private journal&lt;/a&gt; for your children to read when they grow up. Perhaps you’re  living in some spy novel life where you’re worried that people will take you  out to prevent something you know from being discovered. Wherever you fall on the  spectrum, what do you do with such encrypted data?&lt;/p&gt; &lt;p&gt;Modern encryption is a bit scary because it’s so good. If you use a decent  encryption program with a good password/key, then it’s very likely that no one,  &lt;a href="http://www.extremetech.com/computing/105931-full-disk-encryption-is-too-good-says-us-intelligence-agency"&gt;not even a major government&lt;/a&gt;, could decrypt the file even after hundreds of years.  Encryption is great for keeping prying eyes out, but it could sadden survivors that  you want to have access to your data. The thought of something being lost forever might  make you almost yearn for the days when you just put everything into a good  safe that’s rated by how many &lt;a href="http://en.wikipedia.org/wiki/Safe#Class_TL-15" title="For example, a TL-15 safe will resist abuse for about 15 minutes from people who know what they’re doing."&gt;minutes&lt;/a&gt; it might slow  somebody down.&lt;/p&gt; &lt;p&gt;On a much lighter note, the “something” that happens to you doesn’t have  to be so grim. Maybe you had a really relaxing three week vacation and now you can’t  remember the exact keyboard combination of your password. Given that our brains  have to &lt;a href="http://www.radiolab.org/2007/jun/07/eternal-sunshine-of-the-spotless-rat/" title="Start listening at 16:45 to find out more about this interesting idea."&gt; recreate memories each time you recall something&lt;/a&gt;, it’s possible  that you could stress yourself out so much trying to remember your password that  you effectively “forget” it. What do you do then? &lt;/p&gt; &lt;p&gt;When you put all your eggs into a password manager basket, you really want  to &lt;a href="http://herbison.com/herbison/broken_eggs_watch.html" title="Whether it was Carnegie or Twain, the phrase “Put all your eggs in one basket and --- WATCH THAT BASKET!” is some good advice."&gt;watch that basket&lt;/a&gt;.  Fortunately, creating a basic plan isn’t that hard. &lt;/p&gt; &lt;h4&gt;A Proposed Solution&lt;/h4&gt; &lt;a href="http://en.wikipedia.org/wiki/Permissive_Action_Link"&gt; &lt;img alt="Example nuclear launch keys" height="320" src="http://2.bp.blogspot.com/-ndwAfLFbKIE/TsHnCT1FN0I/AAAAAAAAZBY/fILw-KRvtfY/s320/Nuclear_missile_launch_keys%5B1%5D.jpg" align="right" style="border:0;margin:0px 0px 15px 15px;display:inline" width="212"&gt;&lt;/a&gt; &lt;p&gt;Let’s borrow an &lt;a href="http://www.biblegateway.com/passage/?search=Numbers%2035:30&amp;amp;version=ESV" title="For example, the 2-3 witnesses concept appears several times in the Bible."&gt;ancient&lt;/a&gt; yet incredibly  useful idea: if it’s really important to get your facts right about something, be  sure to have at least two or three witnesses. This is especially true concerning  matters of life and death but it also comes up when protecting really valuable things.&lt;/p&gt; &lt;p&gt;By the 20th century, this “&lt;a href="http://en.wikipedia.org/wiki/Two-man_rule"&gt;two-man  rule&lt;/a&gt;” was implemented in hardware to protect nuclear missiles  from being launched by a lone rogue person without proper authorization. The main  vault at &lt;a href="http://en.wikipedia.org/wiki/United_States_Bullion_Depository#Construction_and_security" title="Also known as the “United States Buillion Depository”"&gt; Fort Knox&lt;/a&gt; is locked by multiple combinations such that no single person is entrusted  with all of them. On the Internet, the master key for protecting the new secure  domain name system (&lt;a href="http://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions"&gt;DNSSEC&lt;/a&gt;) &lt;a href="http://www.schneier.com/blog/archives/2010/07/dnssec_root_key.html"&gt;is  split between among 7 people from 6 different countries&lt;/a&gt; such that at least 5  people are needed to reconstruct it in the event of an Internet catastrophe.&lt;/p&gt; &lt;p&gt;If this idea is good enough for protecting nuclear weapons, the Fort Knox  vault, and one of the most critical security aspects on the Internet, it’s probably  good enough for your password list. Besides, it can make a somewhat uncomfortable  process a little more fun.&lt;/p&gt; &lt;p&gt;Let’s start with a simple example. Let’s say that your master password  is “1.big.BOOM@thunder.mil”. You could  just write it out on a piece of paper and then use scissors to cut it up. This would  work if you wanted to split it among 2 people, but it has some notable downsides:&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;It doesn’t work if you want redundancy (i.e. any 2 of 3 people being   able to reconstruct it)&lt;/li&gt;  &lt;li&gt;Each piece would tell you something about the password and thus has   value on its own. Ideally, we’d like the pieces to be worthless unless a threshold   of people came together.&lt;/li&gt;  &lt;li&gt;It doesn’t really work for more complicated scenarios like requiring 5   of 7 people.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Fortunately, some clever math can fix these issues and give you this ability  for free. I created a program called  &lt;a href="https://github.com/moserware/SecretSplitter"&gt;SecretSplitter&lt;/a&gt; to automate  all of this to hopefully make the whole process painless.&lt;/p&gt; &lt;p&gt;Let’s say you want to require at least 2 witnesses to agree that something  happened to you before your secret is available. You also want to build in  redundancy such that &lt;em&gt;any&lt;/em&gt; pair of people can find out your password. For this scenario, you keep the can use the default settings and press the “split” button:&lt;/p&gt; &lt;p&gt; &lt;a href="http://4.bp.blogspot.com/-2key0wl4WCA/TsmS2sduePI/AAAAAAAAZIU/xU5sv04g6l0/s1600/SplitMessageSpecifyMessageThresholdAndShares.png" title="Specify the message “1.big.BOOM@thunder.mil”"&gt; &lt;img alt="Specifying message" height="353" src="http://4.bp.blogspot.com/-2key0wl4WCA/TsmS2sduePI/AAAAAAAAZIU/xU5sv04g6l0/s576/SplitMessageSpecifyMessageThresholdAndShares.png" width="576"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You’ll get this list of split pieces: &lt;/p&gt; &lt;p&gt; &lt;a href="http://3.bp.blogspot.com/-Or-lhAwWbYo/TsmfaToakII/AAAAAAAAZIg/zN2D719yU8s/s1600/SplitMessageShares.png" title="List of message shares"&gt; &lt;img alt="List of message shares" height="428" src="http://3.bp.blogspot.com/-Or-lhAwWbYo/TsmfaToakII/AAAAAAAAZIg/zN2D719yU8s/s576/SplitMessageShares.png" width="576"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Notice that each piece is twice as long as your original message (about  twice the size of a package tracking number). This is by design. &lt;/p&gt; &lt;p&gt;Now comes the hard part: you have to select three people you trust. You  should have high confidence in anyone you’d entrust with a secret piece. It’s easy to  get caught up in &lt;a href="http://xkcd.com/538/"&gt;gee-whiz cryptography&lt;/a&gt; and miss  fundamentals: you ultimately have to &lt;a href="http://cm.bell-labs.com/who/ken/trust.html" title="“Reflections on Trusting Trust” is a fascinating read about the fundamentals of security."&gt;trust something&lt;/a&gt;, especially  with important matters. SecretSplitter provides a trust circuit breaker just  in case (because even well-meaning people can &lt;a href="http://abcnews.go.com/WN/president-bill-clinton-lost-nuclear-codes-office-book/story?id=11930878" title="Like the nuclear biscuit"&gt; lose&lt;/a&gt; &lt;a href="http://www.theatlantic.com/politics/archive/2010/10/why-clintons-losing-the-nuclear-biscuit-was-really-really-bad/65009/" title="Thankfully it wasn’t needed"&gt;important things&lt;/a&gt;). The splitting process adds a bit of complexity, but so do real circuit breakers.  If you trust no one, then you can’t have anyone help you if something happens.&lt;/p&gt;&lt;p&gt; For  demonstration purposes, let’s say you trust 3 people. &lt;/p&gt; &lt;p&gt;You now have to distribute these secret pieces. You could do all sorts  of clever things like &lt;a href="http://www.hulu.com/watch/24493/back-to-the-future-part-ii-letter-from-doc" title="Like Doc did to Marty in “Back to the Future III”"&gt; send letters to people that will be delivered far in the future&lt;/a&gt; or read them  over the phone. However, distributing them in person is a pretty good option:&lt;/p&gt; &lt;p&gt; &lt;a href="http://1.bp.blogspot.com/-GlUFOp6vyNM/TsSJI4i3XpI/AAAAAAAAZHs/54reXSGrrfA/s1600/CreateShareEnvelope.JPG"&gt; &lt;img alt="Creating an envelope with a share" height="432" src="http://1.bp.blogspot.com/-GlUFOp6vyNM/TsSJI4i3XpI/AAAAAAAAZHs/54reXSGrrfA/s576/CreateShareEnvelope.JPG" width="576"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It can make the upcoming holiday table discussions even more fun:&lt;/p&gt; &lt;p&gt; &lt;a href="http://3.bp.blogspot.com/-Tme-qGpMt3w/TsSIfYsPoYI/AAAAAAAAZHg/1VhIRxy_yCs/s1600/ShareHandoff.JPG"&gt; &lt;img alt="Handing over the envelope with the secret piece" height="432" src="http://3.bp.blogspot.com/-Tme-qGpMt3w/TsSIfYsPoYI/AAAAAAAAZHg/1VhIRxy_yCs/s576/ShareHandoff.JPG" width="576"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Let’s pretend that something happened to you. Two of the three family members that you gave pieces to would  come together and agree that “something” indeed has happened to you. What happens  now?&lt;/p&gt; &lt;p&gt; &lt;a href="http://2.bp.blogspot.com/-bOPvXCcnFP0/TsSJkvTNn5I/AAAAAAAAZH4/jhNLjOp1r5k/s1600/TwoEnvelopesOpened.JPG"&gt; &lt;img alt="Two opened envelopes with secret shares" height="576" src="http://2.bp.blogspot.com/-bOPvXCcnFP0/TsSJkvTNn5I/AAAAAAAAZH4/jhNLjOp1r5k/s576/TwoEnvelopesOpened.JPG" width="432"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Well, either you included a note with each secret piece or you emailed  them previously with instructions that they’d just need to download and run  this small program. The pair comes together at a laptop and they each type their piece in quickly and then press “Recover”:&lt;/p&gt; &lt;p&gt; &lt;a href="http://2.bp.blogspot.com/-x3K9S0BJ0bw/TsminW_VM1I/AAAAAAAAZIs/FV_MZWOj0Yc/s1600/RecoverMessageWithTypo.png"&gt; &lt;img alt="Typing in secret shares with a typo" height="355" src="http://2.bp.blogspot.com/-x3K9S0BJ0bw/TsminW_VM1I/AAAAAAAAZIs/FV_MZWOj0Yc/s576/RecoverMessageWithTypo.png" width="572"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Oops... they typed so quickly that they mixed up one of the digits. It  told us where to look:&lt;/p&gt; &lt;p&gt; &lt;a href="http://4.bp.blogspot.com/-eEgbphrpUvQ/TsmjFmbmHEI/AAAAAAAAZI4/5xqF-rX2MIo/s1600/RecoverMessageTypoWarning.png"&gt; &lt;img alt="Warning about typo" height="359" src="http://4.bp.blogspot.com/-eEgbphrpUvQ/TsmjFmbmHEI/AAAAAAAAZI4/5xqF-rX2MIo/s576/RecoverMessageTypoWarning.png" width="576"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;They fix the typo and press recover again:&lt;/p&gt; &lt;p&gt; &lt;a href="http://1.bp.blogspot.com/-gKwkODAk2tk/TsmoVJV5ZqI/AAAAAAAAZJc/rNwb7aXqfnk/s1600/RecoverMessageTypoFixed.png"&gt; &lt;img alt="Fixed the typo" height="355" src="http://1.bp.blogspot.com/-gKwkODAk2tk/TsmoVJV5ZqI/AAAAAAAAZJc/rNwb7aXqfnk/s576/RecoverMessageTypoFixed.png" width="572"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;And immediately they see:&lt;/p&gt; &lt;p&gt; &lt;a href="http://3.bp.blogspot.com/-WLjHmSNf0O4/Tsmo8cCS3XI/AAAAAAAAZJo/kGqfPTGLvE0/s1600/RecoveredMessage.png"&gt; &lt;img alt="Recovered message" height="355" src="http://3.bp.blogspot.com/-WLjHmSNf0O4/Tsmo8cCS3XI/AAAAAAAAZJo/kGqfPTGLvE0/s576/RecoveredMessage.png" width="572"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Password recovered! They could now use this master password to log into  your password manager where you’ve stored further details.&lt;/p&gt; &lt;p&gt;This “message” approach is useful if you have a small amount of data such as a  password that you could write on a piece of paper. One downside is that each piece is twice the size of the text message.  If your message becomes much larger then it will no longer be feasible to type it in manually.&lt;/p&gt; &lt;p&gt;One alternative approach is to bundle together all of your important files  into a zip file:&lt;/p&gt; &lt;p&gt; &lt;a href="http://1.bp.blogspot.com/-ipAnpuK26Hg/TsKAGXULYBI/AAAAAAAAZDE/Zqf6Wdmfklc/s1600/CompressedFileExample.png"&gt; &lt;img alt="Example of a compressed file contents" height="242" src="http://1.bp.blogspot.com/-ipAnpuK26Hg/TsKAGXULYBI/AAAAAAAAZDE/Zqf6Wdmfklc/s576/CompressedFileExample.png" width="296"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To split this file, you’d click the “Create” tab and then find the file,  set the number of shares and click “Save”:&lt;/p&gt; &lt;p&gt; &lt;a href="http://3.bp.blogspot.com/-WZ9IT1nQ9_8/TsmrHgVFQhI/AAAAAAAAZJ0/SLsA5a_5dGg/s1600/SplitFileSpecifyFileAndShares.png"&gt; &lt;img alt="Splitting up a file" height="299" src="http://3.bp.blogspot.com/-WZ9IT1nQ9_8/TsmrHgVFQhI/AAAAAAAAZJ0/SLsA5a_5dGg/s576/SplitFileSpecifyFileAndShares.png" width="525"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You’ll then be told:&lt;/p&gt; &lt;p&gt; &lt;a href="http://3.bp.blogspot.com/-TOIejemR5HI/TsmsE7ng-XI/AAAAAAAAZKA/37dVpipm_TE/s1600/SplitFileSaveMessageBox.png"&gt; &lt;img alt="MessageBox asking you to save the file" height="171" src="http://3.bp.blogspot.com/-TOIejemR5HI/TsmsE7ng-XI/AAAAAAAAZKA/37dVpipm_TE/s576/SplitFileSaveMessageBox.png" width="431"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;And then you pick where to save the encrypted file:&lt;/p&gt; &lt;p&gt; &lt;a href="http://4.bp.blogspot.com/-K6EedSHTiSM/TsKDt1ngRVI/AAAAAAAAZDo/jXogw62iqQQ/s1600/SplitFileSaveDialog.png"&gt; &lt;img alt="Save file dialog" height="102" src="http://4.bp.blogspot.com/-K6EedSHTiSM/TsKDt1ngRVI/AAAAAAAAZDo/jXogw62iqQQ/s576/SplitFileSaveDialog.png" width="576"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Finally, you’ll see this screen:&lt;/p&gt; &lt;p&gt; &lt;a href="http://4.bp.blogspot.com/-oENayRV6e_Y/TsmtUsGS1aI/AAAAAAAAZKM/HKs8T2qVpqk/s1600/SplitFileShares.png"&gt; &lt;img alt="Split file pieces" height="556" src="http://4.bp.blogspot.com/-oENayRV6e_Y/TsmtUsGS1aI/AAAAAAAAZKM/HKs8T2qVpqk/s576/SplitFileShares.png" width="557"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This creates a slightly more complicated scenario because you now have 2 things  to share: the secret pieces and the encrypted file with all your data. The  encrypted file doesn’t have to be secret at all. You can safely email it to people  that have a secret piece:&lt;/p&gt; &lt;p&gt; &lt;a href="http://4.bp.blogspot.com/-6tgMfuudCcE/TsKKnwFAokI/AAAAAAAAZEQ/er0vI1PDRGw/s1600/SplitFileEmail.png"&gt; &lt;img alt="Sending the fun email" height="365" src="http://4.bp.blogspot.com/-6tgMfuudCcE/TsKKnwFAokI/AAAAAAAAZEQ/er0vI1PDRGw/s576/SplitFileEmail.png" width="576"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Now, if something happens to you, they’d run the program, and type in two  shares and press “Recover”:&lt;/p&gt; &lt;p&gt; &lt;a href="http://2.bp.blogspot.com/-2ycvvqebjac/Tsmu_SrtvXI/AAAAAAAAZKY/1RlJksqIe5E/s1600/RecoverFileShares.png"&gt; &lt;img alt="Entering in file shares" height="398" src="http://2.bp.blogspot.com/-2ycvvqebjac/Tsmu_SrtvXI/AAAAAAAAZKY/1RlJksqIe5E/s576/RecoverFileShares.png" width="525"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It’ll then tell them:&lt;/p&gt; &lt;p&gt; &lt;a href="http://4.bp.blogspot.com/-wTvIkMC4n50/TsmvzpNij-I/AAAAAAAAZKk/nlHumsCNVsQ/s1600/RecoverFileSpecifyEncryptedFileMessageBox.png"&gt; &lt;img alt="Specify encrypted file MessageBox" height="184" src="http://4.bp.blogspot.com/-wTvIkMC4n50/TsmvzpNij-I/AAAAAAAAZKk/nlHumsCNVsQ/s576/RecoverFileSpecifyEncryptedFileMessageBox.png" width="496"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;They’d then go to their email and search for the email from you that includes  your encrypted file:&lt;/p&gt; &lt;p&gt; &lt;a href="http://2.bp.blogspot.com/-UIG-SCT_EMM/TsKM-la3y6I/AAAAAAAAZE0/e4ZXnzLP_DE/s1600/RecoverEmailSearch.png"&gt; &lt;img alt="Searching email" height="38" src="http://2.bp.blogspot.com/-UIG-SCT_EMM/TsKM-la3y6I/AAAAAAAAZE0/e4ZXnzLP_DE/s576/RecoverEmailSearch.png" width="370"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Then they’d find the single message (or the latest one if you sent out  updates) and download your encrypted attachment:&lt;/p&gt; &lt;p&gt; &lt;a href="http://2.bp.blogspot.com/-07Lvyv3E9OU/TsKOQcUYQtI/AAAAAAAAZFM/SaCiYXOISJs/s1600/RecoverEmailFound.png"&gt; &lt;img alt="Found email" height="29" src="http://2.bp.blogspot.com/-07Lvyv3E9OU/TsKOQcUYQtI/AAAAAAAAZFM/SaCiYXOISJs/s576/RecoverEmailFound.png" width="392"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;They’d then go back to the program to open it up:&lt;/p&gt; &lt;p&gt; &lt;a href="http://1.bp.blogspot.com/-p17NqyGAuzQ/TsKPIS3DCJI/AAAAAAAAZFY/XuRjjlQ6qUI/s1600/RecoverFileOpen.png"&gt; &lt;img alt="Opening the file" height="71" src="http://1.bp.blogspot.com/-p17NqyGAuzQ/TsKPIS3DCJI/AAAAAAAAZFY/XuRjjlQ6qUI/s576/RecoverFileOpen.png" width="542"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;and then they’d see a message to be careful where they saved it:&lt;/p&gt; &lt;p&gt; &lt;a href="http://1.bp.blogspot.com/-Boue_w0B6p4/TsmxNb_4voI/AAAAAAAAZKw/c4LwB75ZhxI/s1600/RecoverFileSafetyWarning.png"&gt; &lt;img alt="Will you keep the data safe?" height="199" src="http://1.bp.blogspot.com/-Boue_w0B6p4/TsmxNb_4voI/AAAAAAAAZKw/c4LwB75ZhxI/s576/RecoverFileSafetyWarning.png" width="490"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;and then they’d save it:&lt;/p&gt; &lt;p&gt; &lt;a href="http://2.bp.blogspot.com/-7EBY2HrKshc/TsKQrF5NGsI/AAAAAAAAZF8/SFf_3srCKmw/s1600/SaveDecryptedFile.png"&gt; &lt;img alt="Save decrypted" height="96" src="http://2.bp.blogspot.com/-7EBY2HrKshc/TsKQrF5NGsI/AAAAAAAAZF8/SFf_3srCKmw/s576/SaveDecryptedFile.png" width="554"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;They&amp;#39;d then be asked if they want to open the decrypted file, which they’d say “Yes”:&lt;/p&gt; &lt;p&gt; &lt;a href="http://2.bp.blogspot.com/-g8X74oYh63M/Tsmz9ED6cII/AAAAAAAAZK8/rj_RK1FIZUQ/s1600/RecoverFileOpenDecryptedFileMessageBox.png"&gt; &lt;img alt="Open decrypted file?" height="171" src="http://2.bp.blogspot.com/-g8X74oYh63M/Tsmz9ED6cII/AAAAAAAAZK8/rj_RK1FIZUQ/s576/RecoverFileOpenDecryptedFileMessageBox.png" width="342"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Now they can see everything:&lt;/p&gt; &lt;p&gt; &lt;a href="http://1.bp.blogspot.com/-ipAnpuK26Hg/TsKAGXULYBI/AAAAAAAAZDE/Zqf6Wdmfklc/s1600/CompressedFileExample.png"&gt; &lt;img alt="Example of a compressed file contents" height="242" src="http://1.bp.blogspot.com/-ipAnpuK26Hg/TsKAGXULYBI/AAAAAAAAZDE/Zqf6Wdmfklc/s576/CompressedFileExample.png" width="296"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;It might sound complicated, but if you’re familiar with the process, it  might only take a minute. If you’re not tech savvy and have never done it before  and type slowly, it might take 30 minutes. In either case, it’s faster than having  to drive to your home and search around for a folder and it contains everything  you wanted people to know (especially when things are time sensitive).&lt;/p&gt; &lt;p&gt;That’s it! Your master password and important data are now backed up. The  risk is distributed: if any one piece is compromised (i.e. gets lost or misplaced),  you can have everyone else destroy their secret piece and nothing will be leaked. Also,  the program has an advance feature that lets you save the file encryption key. This feature  allows you to send out updated encrypted files that can be decrypted with the pieces  you’ve already established in person.&lt;/p&gt; &lt;p&gt;SecretSplitter implements a “(t,n) &lt;a href="http://en.wikipedia.org/wiki/Threshold_cryptosystem"&gt;threshold cryptosystem&lt;/a&gt;”  which can be thought of as a mathematical generalization of the physical two-man  rule. The idea is that you split up a secret into pieces (called “shares”) and require  at least a threshold of “t” shares to be present in order to recover the secret.  If you have less than “t” shares, you gain no information about the secret. Whatever  threshold you use, it’s really important that each “shareholder” know the threshold  number of shares.&lt;/p&gt; &lt;p&gt;You can be quite creative in setting the threshold and distributing shares.  For example, you can trust your spouse more by giving her more shares than anyone else. The key idea  is that &lt;strong&gt;a share is an atomic unit of trust&lt;/strong&gt;. You can give more than one unit of trust  to a person, but you can never give less.&lt;/p&gt; &lt;p&gt;Another important practical concern is that you should consider adding  redundancy to any threshold system. This is easily achieved by creating more shares  than the threshold number. The reason is that if you’re going out of your way to  use a threshold system, then you probably want to make sure you have a backup plan  in case one or more of the shares are unavailable.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;IMPORTANT LEGAL NOTE&lt;/strong&gt;: It’s tempting to keep everything, including the important  directives and your will in only electronic form (even when they’re signed). Unfortunately,  most states require the original signed documents to be considered legal and most courts will  not accept a copy. For this reason, you should still have the paper originals somewhere  such as a fireproof safe. However, be careful where you put the originals: although  it might sound convenient to put them in a bank safety deposit box, there’s usually  a rather long waiting period before a before a bank can legally provide access to  your box to a survivor, so don’t put any time sensitive items there. My recommendation  at the current time would be to include copies of the signed originals in your encrypted  file and also include detailed instructions on where the originals are located and  how to access them.&lt;/p&gt; &lt;h4&gt;How It Works&lt;/h4&gt; &lt;p&gt;Given the sensitive nature of the data being protected, I wanted to make  sure I understood every part of the mathematics involved and literally every bit  of the encrypted file. You’re more than welcome to just use the program without  fully understanding the details, but I encourage people to verify my math and code  if you’re able and curious. &lt;/p&gt; &lt;p&gt;To get started, recall that computers work with &lt;a href="http://en.wikipedia.org/wiki/Bit"&gt;bits&lt;/a&gt;: 1’s and 0’s that can represent  anything. For example, the &lt;a href="http://en.wikipedia.org/wiki/UTF-8"&gt;most popular  way of encoding text&lt;/a&gt; will encode “thunder” in binary as &lt;/p&gt; &lt;p&gt;01110100 01101000 01110101 01101110 01100100 01100101 01110010&lt;/p&gt; &lt;p&gt;We can write this more efficiently using &lt;a href="http://en.wikipedia.org/wiki/Hexadecimal"&gt;hexadecimal&lt;/a&gt; notation as:  74 68 75 6E 64 65 72. We can also treat this entire sequence of bits as a single  55 bit number whose decimal representation just happens to be 32,765,950,870,971,762.  In fact, &lt;em&gt;any&lt;/em&gt; piece of data can be converted to a single number.&lt;/p&gt; &lt;p&gt;Now that we have a single number, let’s go back to your algebra class and  remember the equation for a &lt;a href="http://en.wikipedia.org/wiki/Line_(geometry)"&gt;line&lt;/a&gt;:  y=mx+b.&lt;/p&gt; &lt;p&gt; &lt;a href="http://4.bp.blogspot.com/-GxROrVUIspY/TsZ0uhWdD1I/AAAAAAAAZII/T2hs8dwPZGk/s1600/LineShowingIntercept.png"&gt; &lt;img alt="Line showing intercept" height="351" src="http://4.bp.blogspot.com/-GxROrVUIspY/TsZ0uhWdD1I/AAAAAAAAZII/T2hs8dwPZGk/s576/LineShowingIntercept.png" width="346"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In this equation, “b” is the “&lt;a href="http://en.wikipedia.org/wiki/Y-intercept"&gt;y-intercept&lt;/a&gt;”,  which is where the line crosses the y-axis. The “m” value is the  &lt;a href="http://en.wikipedia.org/wiki/Slope"&gt;slope&lt;/a&gt; and represents  how steep the line is (i.e. its “&lt;a href="http://en.wikipedia.org/wiki/Grade_(slope)"&gt;grade&lt;/a&gt;”  if it were a hill).&lt;br&gt; &lt;/p&gt; &lt;p&gt;This is all the core math you need to understand splitting secrets. In  our particular case, our secret message is always represented by the y-intercept  (i.e. “b” in y=mx+b). We want to create a line that will go through this point.  Recall that a line could go through this point at any angle. The slope (i.e. “m”  in y=mx+b) will direct us where it goes. For things to work securely, the slope  must be a random number.&lt;/p&gt; &lt;p&gt;Although we use large numbers in practice for security reasons, let’s keep  it simple here. Let’s say our secret number is “7” and our random slope is “3.”  These choices generate this line:&lt;/p&gt; &lt;p&gt; &lt;a href="http://4.bp.blogspot.com/-IasTDH3sDpU/TsMzQA6quLI/AAAAAAAAZGY/CracopxkEBY/s1600/Line3xp7.png"&gt; &lt;img alt="y=3x+7" height="369" src="http://4.bp.blogspot.com/-IasTDH3sDpU/TsMzQA6quLI/AAAAAAAAZGY/CracopxkEBY/s576/Line3xp7.png" width="440"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;With this equation, we can generate an infinite number of points on the  line. For example, we can pick the first three points: (1, 10), (2,  13), and (3, 16):&lt;/p&gt; &lt;p&gt; &lt;a href="http://3.bp.blogspot.com/-PegkAHn5TSk/TsM1TG4VLLI/AAAAAAAAZGk/ZTZbRW5nmOU/s1600/Line3points.png"&gt; &lt;img alt="3 points" height="492" src="http://3.bp.blogspot.com/-PegkAHn5TSk/TsM1TG4VLLI/AAAAAAAAZGk/ZTZbRW5nmOU/s576/Line3points.png" width="576"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can see that if you had any two of these points, you could find  the y-intercept.&lt;/p&gt; &lt;p&gt;It’s critical to realize that having just one of these points gives us  no useful information about the line. However, having any other point on the line  would allow us to use a ruler and draw a straight line to the y-intercept and thus  reveal the secret (we could also work it out algebraically). Each point represents a secret piece or “share” and has a unique  “x” and “y” value.&lt;/p&gt; &lt;p&gt;The mathematically fascinating part about this idea is that a line is just  a simple &lt;a href="http://en.wikipedia.org/wiki/Polynomial"&gt;polynomial&lt;/a&gt; (curve)  and this technique works for polynomials of arbitrarily large &lt;a href="http://en.wikipedia.org/wiki/Polynomial#Degree"&gt;degrees&lt;/a&gt;. For example,  a second degree polynomial is a &lt;a href="http://en.wikipedia.org/wiki/Parabola"&gt; parabola&lt;/a&gt; that requires 3 unique points to completely define it (one more than  a line). Its equation is of the form y=ax^2 + bx + c. In our case “c” is the y-intercept  and “a” and “b” are random as in y = 2x^2 + 3x + 7:&lt;/p&gt; &lt;p&gt;Given this equation, we can generate as many “shares” as we’d like: (1,12),  (2,21), (3,34), (4,51), etc.&lt;/p&gt; &lt;p&gt;Keep in mind that a parabola requires three points to uniquely define  it. If you just had two points, as in (1,12) and (2,21), you could create an infinite  number of parabolas going through these points and thus have infinite choices  for what the y-intercept (i.e. your secret) could be:&lt;/p&gt; &lt;p&gt; &lt;a href="http://2.bp.blogspot.com/-1isSzAsFj_o/TsPeiJxUYLI/AAAAAAAAZGw/L3Lz5K9abCA/s1600/Parabola6Curves.png"&gt; &lt;img alt="6 parabolas going through the same two points" height="387" src="http://2.bp.blogspot.com/-1isSzAsFj_o/TsPeiJxUYLI/AAAAAAAAZGw/L3Lz5K9abCA/s576/Parabola6Curves.png" width="503"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;However, a third point will define the parabola and its y-intercept  exactly:&lt;/p&gt; &lt;p&gt; &lt;a href="http://4.bp.blogspot.com/-nZwrzYySLmY/TsRmAjsT2xI/AAAAAAAAZHI/Hj4Q9fwFZDI/s1600/ParabolaSingleCurve.png"&gt; &lt;img alt="Unique parabola" height="351" src="http://4.bp.blogspot.com/-nZwrzYySLmY/TsRmAjsT2xI/AAAAAAAAZHI/Hj4Q9fwFZDI/s576/ParabolaSingleCurve.png" width="498"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You’ve just learned that splitting a secret that requires three people is just a matter of creating a parabola. Requiring more people is just a matter of creating a higher-degree polynomial such as a &lt;a href="http://en.wikipedia.org/wiki/Cubic_function"&gt;cubic&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Quartic_function"&gt;quartic&lt;/a&gt; polynomial. If you understand this basic idea,  the rest is just details:&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;Instead of using numbers, we translate the data to a big polynomial  &lt;a href="http://en.wikipedia.org/wiki/GF(2)"&gt;with binary coefficients&lt;/a&gt;.&lt;/li&gt;  &lt;li&gt;Instead of using middle school algebra, we use a “&lt;a href="http://en.wikipedia.org/wiki/Finite_field"&gt;finite   field&lt;/a&gt;.” This helps keep results about the same size as the input and adds   some security.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Don’t be intimidated by these changes. The core ideas are the same as the  basic case. The only noticeable difference is that you have to think of operations  like multiplication and division in a more abstract way. For details, check out my source  code’s use of &lt;a href="https://github.com/moserware/SecretSplitter/blob/1b54b72a87d4bdcc5c84b12b36f17fca382d551d/SecretSplitter/Algebra/FiniteFieldPolynomial.cs#L40"&gt;Horner’s scheme&lt;/a&gt;  for evaluating polynomials, &lt;a href="https://github.com/moserware/SecretSplitter/blob/1b54b72a87d4bdcc5c84b12b36f17fca382d551d/SecretSplitter/Algebra/FiniteFieldPolynomial.cs#L63"&gt;peasant multiplication&lt;/a&gt;, &lt;a href="https://github.com/moserware/SecretSplitter/blob/1b54b72a87d4bdcc5c84b12b36f17fca382d551d/SecretSplitter/Algebra/IrreduciblePolynomial.cs#L12"&gt;irreducible polynomials&lt;/a&gt; &lt;a href="http://math.stackexchange.com/questions/14787/finding-irreducible-polynomials-over-gf2-with-the-fewest-terms"&gt; with the fewest terms&lt;/a&gt;,  &lt;a href="https://github.com/moserware/SecretSplitter/blob/1b54b72a87d4bdcc5c84b12b36f17fca382d551d/SecretSplitter/Algebra/LagrangeInterpolator.cs#L22"&gt;Lagrange polynomial interpolation&lt;/a&gt; to find the y-intercept, and using  &lt;a href="https://github.com/moserware/SecretSplitter/blob/1b54b72a87d4bdcc5c84b12b36f17fca382d551d/SecretSplitter/Algebra/FiniteFieldPolynomial.cs#L106"&gt;Euclidean inverses&lt;/a&gt; for division.&lt;/p&gt; &lt;p&gt;Again, it probably sounds more complicated than it really is. At its core,  it’s simple. This technique is formally known as a &lt;a href="http://securespeech.cs.cmu.edu/reports/shamirturing.pdf" title="See “How to Share a Secret” by Adi Shamir"&gt;Shamir Secret  Sharing Scheme&lt;/a&gt; and it was discovered in the 1970’s.&lt;/p&gt; &lt;p&gt;I didn’t want to invent anything new unless I felt I absolutely had to.  There was already a good tool called “&lt;a href="http://point-at-infinity.org/ssss/"&gt;ssss-split&lt;/a&gt;” that generates  shares similar to how I wanted. This program adds a special twist by scrambling  the resulting y-intercept point and therefore adds an extra layer of protection. Since this program  was already the de-facto standard, I wanted to be fully compatible with it. To make  sure I was compatible, I had to copy its method of “diffusing” (i.e. scrambling)  the bits using the public domain &lt;a href="http://en.wikipedia.org/wiki/XTEA"&gt;XTEA  algorithm&lt;/a&gt;. However, to ensure complete fidelity, I had to look at the source  code. The only problem was that it was originally released under the &lt;a href="http://www.gnu.org/copyleft/gpl.htmlhttp://www.gnu.org/copyleft/gpl.html"&gt;GNU Public  License &lt;/a&gt; (GPL) and it used  &lt;a href="http://en.wikipedia.org/wiki/GNU_Multiple_Precision_Arithmetic_Library"&gt;a GPL library for working with large numbers&lt;/a&gt;. My goal was to make my implementation as open as I could, so I asked  the author if I could look at his code to derive my own implementation that I’d release  under the more permissive  &lt;a href="http://www.opensource.org/licenses/mit-license.php"&gt;MIT license&lt;/a&gt; and he graciously allowed me to do this.&lt;/p&gt; &lt;p&gt;To prove the compatibility, you can use the &lt;a href="http://point-at-infinity.org/ssss/demo.html"&gt;ssss-split demo page&lt;/a&gt; and  paste the results  &lt;a href="https://github.com/downloads/moserware/SecretSplitter/SecretSplitter.exe"&gt;into SecretSplitter&lt;/a&gt; and it’ll work just fine. In addition, I  &lt;a href="https://github.com/moserware/SecretSplitter/downloads"&gt;created  command line programs from scratch&lt;/a&gt; that are fully compatible with ssss-split and ssss-combine.&lt;/p&gt; &lt;p&gt;After some basic usability testing, I decided to make one small adjustment. The “ssss-split”  command allows you to attach a prefix that it ignores. I wanted to add a special prefix that would  tell what type of share it was (i.e. a message or a file) as well as a &lt;a href="http://en.wikipedia.org/wiki/SHA-1"&gt;simple checksum&lt;/a&gt; because  with all those digits it’s easy to mistype one. &lt;/p&gt; &lt;p&gt;Now, you can understand all the pieces of the long share:&lt;/p&gt; &lt;p&gt; &lt;a href="http://3.bp.blogspot.com/-z_DjRnzLXEo/TsRtr-yV1oI/AAAAAAAAZHU/pr4h62fFI_k/s1600/ShareComponents.png"&gt; &lt;img alt="Share components" height="77" src="http://3.bp.blogspot.com/-z_DjRnzLXEo/TsRtr-yV1oI/AAAAAAAAZHU/pr4h62fFI_k/s576/ShareComponents.png" width="576"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In theory, you could “encrypt” a large file directly using this technique.  In practice, it doesn’t work well because each share would be huge and not something  you’d be able to write down by hand or say over the phone, even using the &lt;a href="http://en.wikipedia.org/wiki/NATO_phonetic_alphabet"&gt;phonetic alphabet&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;For lots of data, we use a hybrid approach: encrypt the file using standard  file encryption with a random key and then split the small “key” into pieces.&lt;/p&gt; &lt;p&gt;For file encryption, I again didn’t want to invent anything new. I decided  to use the &lt;a href="http://tools.ietf.org/html/rfc4880"&gt;OpenPGP Message Format&lt;/a&gt;,  the same format used by &lt;a href="http://en.wikipedia.org/wiki/Pretty_Good_Privacy"&gt;PGP&lt;/a&gt; and &lt;a href="http://www.gnupg.org/"&gt;GNU Privacy Guard&lt;/a&gt; (GPG). I didn’t want to have  to worry about licensing restrictions or including a &lt;a href="http://www.bouncycastle.org/" title="Like Bouncy Castle"&gt;third-party library&lt;/a&gt;, so I wrote my own  implementation from scratch that did exactly what I wanted. I &lt;a href="http://commondatastorage.googleapis.com/rhuang/rfc4880.mobi" title="I&amp;#39;m a bit embarrassed to admit I read it on my Kindle by the beach. On the subject, I must admit that RFC2MOBI is a great free app for converting text-based RFCs to Kindle MOBI files. It does a remarkably decent job."&gt;read RFC4880&lt;/a&gt;  and started sketching out what I needed to do. A few bug fixes later and I  had a working implementation that was able to interoperate with GPG. To simplify  my implementation, I only support a limited subset of features:&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;I always use   &lt;a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard"&gt;AES&lt;/a&gt; with a 256-bit key for encryption, even if users select a smaller   effective key size. This means that users can pick any size key they want and thus balance security and share length. I picked AES because it’s strong and  &lt;a href="http://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html"&gt;  understandable with stick figures&lt;/a&gt;.&lt;/li&gt;  &lt;li&gt;The actual file encryption key is always a  &lt;a href="http://tools.ietf.org/html/rfc4880#section-3.7.1.3"&gt;hashed, salted,   and stretched version&lt;/a&gt; of the reconstructed shares text.&lt;/li&gt;  &lt;li&gt;The encrypted file has an  &lt;a href="http://tools.ietf.org/html/rfc4880#section-5.13"&gt;integrity protection   packet&lt;/a&gt; to detect if the file has been modified and ensure it was decrypted correctly.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Since I used common formats, you can verify the correctness of the generated  files using a Linux shell. You can also create files using the shell and  have them interoperate with SecretSplitter. I included  &lt;a href="https://github.com/moserware/SecretSplitter/blob/master/Compatibility.txt"&gt;a sample of how to do this  with the source code&lt;/a&gt;.&lt;/p&gt; &lt;h4&gt;Help Wanted / Future Possibilities&lt;/h4&gt; &lt;p&gt;SecretSplitter still looks and feels like a prototype. There are lots of  possible improvements that could be made:&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;Secret splitting is a relatively complicated idea. In  &lt;a href="http://www.amazon.com/gp/product/0470474246/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=moserware-20&amp;amp;linkCode=as2&amp;amp;camp=217145&amp;amp;creative=399369&amp;amp;creativeASIN=0470474246"&gt;  Cryptography Engineering&lt;/a&gt;, the authors write “secret sharing schemes are   rarely used because they are too complex. They are complex to implement, but   more importantly, they are complex to administrate and operate.” &lt;br&gt;  &lt;br&gt;  Although I tried to simplify the user experience for broad use, it could still   use some user experience enhancements to simplify it further. &lt;/li&gt;  &lt;li&gt;I wrote it in C# for the .net platform because that is what I’m most   familiar with (and it has some built-in powerful primitives like BigIntegers,   AES, and hash functions). I suspect that an HTML5 version using JavaScript, a   nice interface, and coming from a trusted domain would get much broader usage.   In addition, since this is a problem that affects everyone, having great internationalization   support would be a nice touch. It also would be nice to have a polished look with a good logo and other graphics.&lt;/li&gt;  &lt;li&gt;You could use more  &lt;a href="http://en.wikipedia.org/wiki/Verifiable_secret_sharing"&gt;elaborate secret   sharing schemes&lt;/a&gt; than what I implemented in SecretSplitter. I considered   these, but ultimately wanted to use a technique that was already compatible   with widely deployed tools. I also considered enhancing shares with  &lt;a href="http://www.google.com/url?q=http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FTime-based_One-time_Password_Algorithm&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFQjCNEG4XPPcQbdiivr7kuRUBxExU6Aqw"&gt;  two-factor&lt;/a&gt; support or using  &lt;a href="http://en.wikipedia.org/wiki/Public_key_infrastructure"&gt;existing public   key infrastructure&lt;/a&gt;, but decided that added too much complexity. Perhaps   it’s possible to incorporate these in a good design.&lt;/li&gt;  &lt;li&gt;It’d be neat if this scheme or something similar to it was integrated   into LastPass and KeyPass as a core feature. &lt;/li&gt;  &lt;li&gt;Obviously the shares themselves are long. I tried making them shorter   but the downsides outweighed the upsides. Perhaps it could be better. Also, a compelling   graphically designed share card might make it more fun for broader use. The long length   is somewhat of a safety mechanism that prevents people from memorizing with   a quick glance. Also, it discourages overhasty use much like &lt;a href="http://vimeo.com/5735591" title="Although, as this video demonstrates a hammer allows for quick access. However, at least you’d be making a conscious decision at that point."&gt;freezing a credit card&lt;/a&gt;.&lt;/li&gt;  &lt;li&gt;I kept the codes in a format that would be easy to write as well as read over the phone. I used a simple character set that avoids ambiguities like “O” vs “0”.   One additional strategy could be to embed the share as a  &lt;a href="http://qrcodenet.codeplex.com/"&gt;QR code&lt;/a&gt; or something similar. I   didn’t pursue this approach in favor of simplicity, but this could be an option.&lt;/li&gt;  &lt;li&gt;Really paranoid people might want to back up their encrypted file to   paper.  &lt;a href="http://www.codinghorror.com/blog/2009/07/the-paper-data-storage-option.html"&gt;  This is possible&lt;/a&gt;, but I’m not sure if it should belong inside the program   itself.&lt;/li&gt;  &lt;li&gt;It’d be good to have suggestions on how to exchange shares or perhaps   borrow ideas from PGP  &lt;a href="http://en.wikipedia.org/wiki/Key_signing_party"&gt;key signing parties&lt;/a&gt;.   I suspect that if secret splitting were to become popular, then “&lt;a href="http://en.wikipedia.org/wiki/Web_of_trust"&gt;web   of trust&lt;/a&gt;” scenarios would naturally occur (i.e. “I’ll hold your secret share   if you hold mine”).&lt;/li&gt;  &lt;li&gt;It’d be fun to compile a list of non-obvious uses for SecretSplitter   to share with others. For example, it could make for interesting scavenger hunt   clues. &lt;/li&gt; &lt;/ol&gt; &lt;p&gt;If you’d like to donate your time to any of the above ideas, I’d encourage  you to just give it a go. You don’t have to ask for my permission but it would be  nice if you posted your results somewhere or left a comment to this post. You can  use my code for whatever purpose you’d like. My only hope is that you might get  some benefit out of it.&lt;/p&gt; &lt;h4&gt;Conclusion&lt;/h4&gt; &lt;p&gt;SecretSplitter is just a tool that gives another option for backing up  very sensitive information by splitting it up into pieces. It’s not a full solution,  only a tool. By relying on people I trust instead of  &lt;a href="http://mashable.com/2010/10/11/social-media-after-death/" title="Besides, I don&amp;#39;t want to have to worry about a third-party company “dying” before I do."&gt;a third-party company&lt;/a&gt;, it helped me remove one excuse I had for not  preparing somewhat unpleasant but important documents that we should all probably  have. I still don’t have this all figured out, but writing SecretSplitter help me get started. &lt;/p&gt; &lt;p&gt;If you’re young, don’t have any &lt;a href="http://en.wikipedia.org/wiki/Minor_(law)"&gt;minor children&lt;/a&gt;, and don’t  care at all what happens to your stuff, then you could run some mental actuarial  model and convince yourself that the probability of you or your survivors needing  these documents or password recovery procedure anytime soon is low, but you’re not  given any guarantees. &lt;/p&gt; &lt;p&gt;At the very least, it’s a good idea to make sure all of your financial  assets and life insurance policies have a named beneficiary and at perhaps at least  one alternate. You can also declare things like organ donor preferences on your  driver’s license instead of making declarations in other documents. It’s also a good  idea to have an “&lt;a href="http://en.wikipedia.org/wiki/In_case_of_emergency" title="In Case of Emergency"&gt;ICE&lt;/a&gt;”  entry in your cell phone. However, going the extra step and making very basic final  documents doesn’t require that much more work. Besides, once you have baseline documents, keeping them fresh is just a matter of occasional updates due to life events.&lt;/p&gt; &lt;p&gt;The increasing digitization of our lives means that more personal things will only be stored digitally. From our journals to email to videos  to health records, all of this will eventually only exist digitally and likely hidden  behind passwords. This future needs some safety net for backing up sensitive things in  a safe and accessible way.&lt;/p&gt; &lt;p&gt;Everything doesn’t need to be backed up. There are also lots of files,  usernames and passwords that don’t really matter. Don’t include those. SecretSplitter  was built with the assumption that everything that really mattered could be stored  in a file small enough to email to others. This helps focus and pare down to what  really matters.&lt;/p&gt; &lt;p&gt;It’s also good to have a healthy dose of common sense. Instead of holding out a secret until after your death, maybe you should get  that resolved today. You’ll probably live better. My general view is that these  final “secrets” should be mostly boring by just containing account details and  credentials.&lt;/p&gt; &lt;p&gt;Finally, on a more personal level, I think it’s healthy to be reminded  about our own mortality at least once every year or so. It’s a helpful reminder  of how much a gift every day is and helps focus what we do and not worry about things  that don’t matter. &lt;/p&gt; &lt;p&gt;If a little bit of fancy math can help you sleep better at night, well  then, I’d consider it a success.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Special thanks to B. Poettering for creating the original &lt;/em&gt; &lt;a href="http://point-at-infinity.org/ssss/"&gt;&lt;em&gt;ssss&lt;/em&gt;&lt;/a&gt;&lt;em&gt; program and allowing me to  clone its format.&lt;/em&gt;&lt;/p&gt;&lt;div&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/6800934446457898793-86529977875835325?l=www.moserware.com" alt=""&gt;&lt;/div&gt;&lt;div&gt;
&lt;a href="http://feeds.feedburner.com/~ff/Moserware?a=DgDYwGU8zrI:nKYQvQkar2o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Moserware?d=yIl2AUoC8zA" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Moserware?a=DgDYwGU8zrI:nKYQvQkar2o:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Moserware?d=63t7Ie-LG7Y" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Moserware?a=DgDYwGU8zrI:nKYQvQkar2o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Moserware?i=DgDYwGU8zrI:nKYQvQkar2o:V_sGLiPBpWU" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Moserware?a=DgDYwGU8zrI:nKYQvQkar2o:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Moserware?i=DgDYwGU8zrI:nKYQvQkar2o:gIN9vFwOqvQ" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Moserware?a=DgDYwGU8zrI:nKYQvQkar2o:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Moserware?i=DgDYwGU8zrI:nKYQvQkar2o:F7zBnMyn0Lo" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/Moserware?a=DgDYwGU8zrI:nKYQvQkar2o:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/Moserware?i=DgDYwGU8zrI:nKYQvQkar2o:4cEx4HpKnUU" border="0"&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Moserware/~4/DgDYwGU8zrI" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/BdOM-_VPQQg" height="1" width="1"/&gt;</content><author><name>Jeff Moser</name></author><source gr:stream-id="feed/http://feeds.feedburner.com/Moserware"><id>tag:google.com,2005:reader/feed/http://feeds.feedburner.com/Moserware</id><title type="html">Moserware</title><link rel="alternate" href="http://www.moserware.com/" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/Moserware/~3/DgDYwGU8zrI/life-death-and-splitting-secrets.html</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1320976375783"><id gr:original-id="http://www.aaronlerch.com/blog/?p=251">tag:google.com,2005:reader/item/05ef83bb99435910</id><category term="Uncategorized" /><title type="html">Global Day of Coderetreat in Indianapolis</title><published>2011-11-11T01:52:28Z</published><updated>2011-11-11T01:52:28Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/GPuCbv317WE/" type="text/html" /><content xml:base="http://www.aaronlerch.com/blog" type="html">&lt;p&gt;I recently came across this thing called a “&lt;a title="Coderetreat" href="http://coderetreat.com/"&gt;coderetreat&lt;/a&gt;” that &lt;a title="Tweets by Corey" href="https://twitter.com/coreyhaines"&gt;Corey Haines&lt;/a&gt; puts on. The gist is that it’s a free full-day event where a small group of dedicated-but-busy software developers can come together and work on honing the skill or art of writing software, away from the usual pressures of business.&lt;/p&gt;
&lt;p&gt;I thought it sounded awesome. I have yet to attend a developer event that was comprised primarily of the attendees coding, with the possible exception of some &lt;a title="Codemash - a fantastic conference! I&amp;#39;m going this year, are you?" href="http://codemash.org/"&gt;codemash&lt;/a&gt; sessions.&lt;/p&gt;
&lt;p&gt;Then I saw something about a “Global Day of Coderetreat” — coderetreats organized to occur all around the world on the same day: December 3rd.&lt;/p&gt;
&lt;p&gt;And I noticed that Indianapolis was &lt;strong&gt;not&lt;/strong&gt; on the list.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;That simply won’t do.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So I’m happy to announce that Indianapolis is going to participate in the Global Day of Coderetreat!&lt;/strong&gt; My employer &lt;a title="Interactive Intelligence" href="http://www.inin.com/"&gt;Interactive Intelligence&lt;/a&gt; (I contend it’s the best place to work in the midwest) has agreed to sponsor the entire event by providing a great space to meet and a &lt;em&gt;free catered lunch! &lt;/em&gt;Check out these pics of our &lt;a title="Our offices" href="https://www.facebook.com/media/set/?set=a.10150280912742721.326964.87805467720&amp;amp;type=1"&gt;offices&lt;/a&gt; and &lt;a title="Interactive Cafe" href="https://www.facebook.com/media/set/?set=a.10150280879662721.326950.87805467720&amp;amp;type=1"&gt;in-house cafe&lt;/a&gt; on facebook.&lt;/p&gt;
&lt;p&gt;You’re probably asking,&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;“Okay, so what’s a coderetreat anyway?”&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;I’ll talk about what ours is on December 3rd. I’ve opened it up to 26 people. (I said it was a small group…) You can see more information on the structure &lt;a title="Coderetreat agenda" href="http://coderetreat.com/facilitation.html"&gt;here&lt;/a&gt;, but the gist is that there is some meet &amp;amp; greet time at the start, an intro, then 5 to 6 sessions (with a long lunch in the middle) of dividing up into pairs and tackling a problem (same problem all day). After each session, we &lt;em&gt;delete&lt;/em&gt; all our code, switch pairs, and start over again, but working to grow our designs, and explore alternatives and practices like TDD. This is language agnostic, we just try to make sure each pair knows the same language (regardless of proficiency level.) Then there’s a wrap-up and whoever wants heads out for a beer. &lt;img src="http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif" alt=":)"&gt; &lt;/p&gt;
&lt;p&gt;And did I mention it’s all free?&lt;/p&gt;
&lt;p&gt;Sound good to you?&lt;/p&gt;
&lt;p&gt;Yes? Me too!&lt;/p&gt;
&lt;p&gt;See below for ticket info. I want to point out something first, though. With only 26 slots, I want to avoid it filling up quickly with people who won’t show up. So I’m charging $5 to attend. &lt;em&gt;If you attend, you will get a full refund&lt;/em&gt;, or you can opt to donate your $5 to the &lt;a title="Interactive Intelligence Foundation" href="http://www.inin.com/foundation/"&gt;Interactive Intelligence Foundation&lt;/a&gt; – a great not-for-profit that helps at-risk youth, especially with technology education.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You can get a ticket at &lt;a href="http://coderetreatindy.eventbrite.com/"&gt;http://coderetreatindy.eventbrite.com/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Any questions? Tweet to me at &lt;a title="Mah tweets." href="http://twitter.com/aaronlerch"&gt;@aaronlerch&lt;/a&gt; or email me at aaronlerch at gmail&lt;/p&gt;
&lt;p&gt;Hope to see you on the 3rd!!&lt;/p&gt;
&lt;div&gt;
&lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=SZZTLGlf6oA:7vFXiPYPmbw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=SZZTLGlf6oA:7vFXiPYPmbw:V_sGLiPBpWU" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=SZZTLGlf6oA:7vFXiPYPmbw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=SZZTLGlf6oA:7vFXiPYPmbw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=SZZTLGlf6oA:7vFXiPYPmbw:F7zBnMyn0Lo" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=SZZTLGlf6oA:7vFXiPYPmbw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=SZZTLGlf6oA:7vFXiPYPmbw:gIN9vFwOqvQ" border="0"&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/aaronlerch/~4/SZZTLGlf6oA" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/GPuCbv317WE" height="1" width="1"/&gt;</content><author><name>aaron</name></author><source gr:stream-id="feed/http://feeds.feedburner.com/aaronlerch"><id>tag:google.com,2005:reader/feed/http://feeds.feedburner.com/aaronlerch</id><title type="html">Aaron Lerch</title><link rel="alternate" href="http://www.aaronlerch.com/blog" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/aaronlerch/~3/SZZTLGlf6oA/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1314030201573"><id gr:original-id="http://ericwilleke.com/?p=268">tag:google.com,2005:reader/item/d687e73ed2d6adee</id><category term="Uncategorized" /><title type="html">What did I learn?</title><published>2011-08-22T15:57:54Z</published><updated>2011-08-22T15:57:54Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/trMTsIaofqI/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;&lt;a title="Karl&amp;#39;s blog" href="http://availagility.co.uk/"&gt;Karl Scotland&lt;/a&gt; and I have helped coordinate the organization of the bag stuffing each year for the last three years. It’s a great time because of the awesome group of volunteers showing up and the mindset of “I’m here to learn something while I help out” that’s so pervasive.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Execute!&lt;/strong&gt;&lt;br&gt;
The flow of bags was very effective at the end of the day last year and this year we simply started where we left off last year with the same design. Thanks to some great pre-work, we knew where everything was and what needed to go in each bag, so the briefing of the volunteer staff took less than 15 minutes and we were ready to go. &lt;/p&gt;
&lt;p&gt;The team got moving and each zone quickly solved any issues that arose, continually improving and adapting how they worked to the needs of their specific area. We got done a couple hours early, and everything pretty much “just worked” better than could be expected.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Retrospect?&lt;/strong&gt;&lt;br&gt;
So, when I’m asked to lead a retrospective, what do I do? Everything went so well, and learning was incorporated so rapidly, that a simple plus/delta seems utterly pointless. The plusses have been amplified, and the deltas have been changed, why should we write them down? So here’s what we did…&lt;/p&gt;
&lt;p&gt;We gathered in a standing circle, grabbed a spare piece of swag to use as a talking stick, and each answered one simple question: “What did you learn?”. After sharing, the group reflected the individual’s statement back in a simple phrase appropriate to a sticky note. [1]. As each of us answered, we sat down to bring focus to the people still wanting to speak. Best of all, the “people in charge” [2] did and said very little, and learned quite a bit.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Understand.&lt;/strong&gt;&lt;br&gt;
Why did it work? Well, as I mentioned above, many of the volunteers were there to learn. The bag stuffing has filled up in the first volunteer sign-up round (of four) each of the last two years. The process execution was well beyond “good enough”, so it seems like the right thing to do is help people take away more than just their own perspectives. With a majority of volunteers having English as a second (or more!) language, the reflection portion ensured that the individual’s perpective was conveyed clearly and helped to ensure that people were able to absorb the statements effectively. More interestingly to me, the “what did I learn” style questioning seems to have drawn out positive emotions in a way that other retrospective formats haven’t been able to do in my experience.&lt;/p&gt;
&lt;p&gt;Here’s to next year!&lt;/p&gt;
&lt;p&gt;[1] Karl captured them &lt;a href="http://availagility.co.uk/2011/08/15/lean-bag-packing-at-agile2011/"&gt;here&lt;/a&gt;.&lt;br&gt;
[2] Specifically, Karl and I as facilitators were able to keep our mouths pretty well shut.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/FazXmZ-Fdcc" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/trMTsIaofqI" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/FazXmZ-Fdcc/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1313272839847"><id gr:original-id="http://ericwilleke.com/?p=265">tag:google.com,2005:reader/item/f6d3cd637e358e24</id><category term="Meta" /><category term="Experiments" /><title type="html">Uninspired by pushing</title><published>2011-08-13T21:36:36Z</published><updated>2011-08-13T21:36:36Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/VgfjEN-Ty0k/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;I’ve not been blogging lately. I haven’t really been pushing things to twitter, either. For a while, I thought I was just lazy, and perhaps tired from travel. I’ve lately come to see that this isn’t the case. Good or bad… &lt;strong&gt;I don’t write for myself.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I write for others. I write for people who care about what I have to say, who use it to improve their own lives. I write for people that have a passion for learning, for exploring ideas, for changing the world around them. &lt;strong&gt;What do these people want?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I really have no idea. Looking back at my blog, I realize that most of my posts are the result of an amazing conversation I’ve had with somebody, or the result of reading somebody else’s work and being inspired to extend or evolve it in some way. When I hear from others which bits they find valuable, they are uniformly the cases where I write because somebody says “you should post this.” &lt;strong&gt;My inspiration is a reflection of shared passions.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So what’s this mean? It’s changed my behavior a bit. I’ve not written anything “just to write it”. I’ve focused much more on the people and ideas that are around me, especially inside of Rally. I’ve paid more attention to which trends and areas I find myself passionate about. I brainstorm with my peers around ideas before starting my writing. I’m exploring crowdsourcing initial drafts internally to Rally, and may open that beyond. I’m looking at the needs of various groups to see which ones resonate as ways of selecting topics. &lt;strong&gt;I’ve started involving others in my writing. &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Starting with this post, I’m actively inviting others in my community to pull content from me. Tell me what you feel I should write about, what ideas you’d like me to extend, what basics need better coverage. Help me to understand what’s valuable, what’s engaging, what will help you create your own reality. And I might just ask you to &lt;strong&gt;write with me.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Enter &lt;a title="User Voice web site" href="http://uservoice.com"&gt;User Voice&lt;/a&gt;. On the right bar of the blog, you’ll see a tab flagged “Suggest Topics” Throw them out there, and I’ll listen. If you wish, vote up the ideas of others. Pull the content you value, the material that inspires yourselves and others. &lt;strong&gt;Join me in my new experiment.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;…and for those who read… &lt;strong&gt;Thank you!&lt;/strong&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/EG6JXAQANkk" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/VgfjEN-Ty0k" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/EG6JXAQANkk/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1312785469245"><id gr:original-id="http://www.aaronlerch.com/blog/?p=248">tag:google.com,2005:reader/item/f4b3efd518e14b7d</id><category term="heroku" /><category term="ruby" /><title type="html">talkasaur.us – dirt simple conference calling</title><published>2011-08-08T06:35:31Z</published><updated>2011-08-08T06:35:31Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/3fid3Yxldc4/" type="text/html" /><content xml:base="http://www.aaronlerch.com/blog" type="html">&lt;p&gt;Both at work and “for fun”, I’ve used &lt;a href="http://join.me/"&gt;join.me&lt;/a&gt; for any simple screen sharing needs. I remember the first time I used it. It was simple, and it &lt;em&gt;just worked&lt;/em&gt;. You download a small app to share your screen, and everybody else visits a URL and gets instant in-browser viewing.&lt;/p&gt;
&lt;p&gt;Let me emphasize the key points in case they were missed. It was &lt;em&gt;simple&lt;/em&gt;, and it &lt;em&gt;just worked&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The 19th century French novelist George Sand once said, “Simplicity is the most difficult thing to secure in this world; it is the last limit of experience and the last effort of genius.”&lt;/p&gt;
&lt;p&gt;This is clearly a gentleman who coded against the &lt;a href="http://stackoverflow.com/questions/4952154/what-is-the-best-way-to-deal-with-kludgy-interface-hierarchies-mshtml"&gt;MSHTML library&lt;/a&gt;. &lt;img src="http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_wink.gif" alt=";)"&gt;  I would say I was kidding, except that I’m pretty sure MSHTML was around in the 1800s.&lt;/p&gt;
&lt;p&gt;When I saw that &lt;a href="http://twilio.com/"&gt;Twilio&lt;/a&gt; announced that they released an in-browser soft phone and started a 2-week contest around it, I decided to create a simple in-browser ad-hoc conference call tool. My mind immediately went to join.me’s simplicity and just-work-edness. Imitation is the sincerest form of flattery, and with &lt;a href="http://talkasaur.us/"&gt;talkasaur.us&lt;/a&gt; I am seriously flattering join.me. &lt;img src="http://www.aaronlerch.com/blog/wp-includes/images/smilies/icon_smile.gif" alt=":)"&gt; &lt;/p&gt;
&lt;p&gt;There have been a few situations in recent memory where having a tool like &lt;a href="http://talkasaur.us/"&gt;talkasaur.us&lt;/a&gt; would have been useful:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Scott Hanselman wanted to record a group conference call for an episode of his podcast. I think they went through at least 3-5 different services before settling on something, and if I recall correctly (and I probably don’t) even that service wasn’t very satisfactory.&lt;/li&gt;
&lt;li&gt;Every group video chat I’ve done (which has not been many, admittedly) has ended up requiring me to a) put on clothes, and b) create an account or sign in with an existing account like twitter or facebook. When authentication gets added to the mix, simplicity decreases. Here’s a chart to illustrate, because &lt;em&gt;data doesn’t lie&lt;/em&gt;:&lt;br&gt;
&lt;img src="https://s3.amazonaws.com/aaronlerch.com/images/talkasaurus-complexity-authentication.png" border="0" alt=""&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So thus I decided to pick a &lt;em&gt;horrible time&lt;/em&gt;, personally, to spend time on this idea of &lt;a href="http://talkasaur.us/"&gt;talkasaur.us&lt;/a&gt; – the name of which was conceived at 3AM in a state of delirium and because I’ve always been fond of any “*saur.us” domain for some reason.&lt;/p&gt;
&lt;p&gt;The result is “Iteration Zero” – enough to submit my app to the Twilio contest, and test out the waters of interest. It works like this. The homepage gives you two choices: start or join.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s3.amazonaws.com/aaronlerch.com/images/talkasaurus_home_screen.png"&gt;&lt;img src="https://s3.amazonaws.com/aaronlerch.com/images/talkasaurus_home_screen.png" border="0" alt="" width="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When you start or join a conference, you get a view that shows you a few things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The current status (“connected”, “disconnected”, etc.)&lt;/li&gt;
&lt;li&gt;Sharing options – you need to invite people to your call, otherwise you could save yourself the time and just talk to the mirror.&lt;/li&gt;
&lt;li&gt;Actions – currently only muting and leaving the conference call (watch this space, though!)&lt;/li&gt;
&lt;li&gt;Participants – a realtime list, see who’s on the call, change your name, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://s3.amazonaws.com/aaronlerch.com/images/talkasaurus_in_conference.png"&gt;&lt;img src="https://s3.amazonaws.com/aaronlerch.com/images/talkasaurus_in_conference.png" border="0" alt="" width="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When you leave the conference, you get a single call to action: start a new conference again.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s3.amazonaws.com/aaronlerch.com/images/talkasaurus_conference_over.png"&gt;&lt;img src="https://s3.amazonaws.com/aaronlerch.com/images/talkasaurus_conference_over.png" border="0" alt="" width="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bam. That’s it! Of course I can already think of features to add, and the list keeps on growing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Moderation tools: first person in gets the ability to mute others, kick them out, etc.&lt;/li&gt;
&lt;li&gt;Additional information: because the participant list is updated in realtime, we can display more information such as whether they are muted or not, and (if Twilio can implement &lt;a href="http://getsatisfaction.com/twilio/topics/additional_event_on_the_twilio_client_connection_api"&gt;my suggestion&lt;/a&gt;) even see who is currently speaking.&lt;/li&gt;
&lt;li&gt;Call recording/archiving&lt;/li&gt;
&lt;li&gt;External number integration – not excited about this, but it’s a possibility.&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The whole thing about my idea is that it isn’t &lt;strong&gt;brand new&lt;/strong&gt;, but it’s applying the discipline of keeping things simple and coming out with a better product.&lt;/p&gt;
&lt;p&gt;And, because this is my tech blog, I’ll just do a quick list of the technologies I built this site on. &lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt;, &lt;a href="http://www.sinatrarb.com/"&gt;sinatra&lt;/a&gt;, &lt;a href="http://www.heroku.com/"&gt;heroku&lt;/a&gt;, &lt;a href="http://www.mongodb.org/"&gt;mongodb&lt;/a&gt; (via &lt;a href="http://mongoid.org/"&gt;mongoid&lt;/a&gt;), &lt;a href="http://jquery.com/"&gt;jquery&lt;/a&gt;, and of course, &lt;a href="http://www.twilio.com/api/client"&gt;twilio&lt;/a&gt;. Let me just say, for a simple app like this, these tools were a &lt;em&gt;joy&lt;/em&gt; to use, even if I did spend the majority of the time fighting battles with them.&lt;/p&gt;
&lt;div&gt;
&lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=eO7Rw34Zalw:aEo5rzYxcgI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=eO7Rw34Zalw:aEo5rzYxcgI:V_sGLiPBpWU" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=eO7Rw34Zalw:aEo5rzYxcgI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=eO7Rw34Zalw:aEo5rzYxcgI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=eO7Rw34Zalw:aEo5rzYxcgI:F7zBnMyn0Lo" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=eO7Rw34Zalw:aEo5rzYxcgI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=eO7Rw34Zalw:aEo5rzYxcgI:gIN9vFwOqvQ" border="0"&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/aaronlerch/~4/eO7Rw34Zalw" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/3fid3Yxldc4" height="1" width="1"/&gt;</content><author><name>aaron</name></author><gr:likingUser>15217774922118815663</gr:likingUser><source gr:stream-id="feed/http://feeds.feedburner.com/aaronlerch"><id>tag:google.com,2005:reader/feed/http://feeds.feedburner.com/aaronlerch</id><title type="html">Aaron Lerch</title><link rel="alternate" href="http://www.aaronlerch.com/blog" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/aaronlerch/~3/eO7Rw34Zalw/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1306896587039"><id gr:original-id="http://www.aaronlerch.com/blog/?p=241">tag:google.com,2005:reader/item/0acfef27a478056b</id><category term="Uncategorized" /><title type="html">How Talentopoly is Built</title><published>2011-06-01T02:49:38Z</published><updated>2011-06-01T02:49:38Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/teuEQHiv13Y/" type="text/html" /><content xml:base="http://www.aaronlerch.com/blog" type="html">&lt;p&gt;&lt;a href="http://talentopoly.com/"&gt;&lt;img src="http://www.aaronlerch.com/blog/wp-content/uploads/2011/05/T-Icon-vector.png" alt="Talentopoly" title="Talentopoly" width="200" height="200"&gt;&lt;/a&gt;Today’s post is written by my guest and fellow Indianapolis-ite, &lt;a href="http://twitter.com/jaredbrown"&gt;Jared Brown&lt;/a&gt;. I asked Jared to guest post here because he has created an application using &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;, &lt;a href="http://www.heroku.com/"&gt;Heroku&lt;/a&gt;, and a host of other bits and services that I’ve also been using to bootstrap my new business, &lt;a href="http://beautifulsavings.com/"&gt;beautifulsavings.com&lt;/a&gt; which I’ll post more about in the near future. He’s done a fantastic job with Talentopoly, and he’s a developer I respect. Talentopoly is on my short-list when it comes to finding useful tidbits to expand my tech horizons. &lt;a href="http://talentopoly.com/users/402"&gt;Check out my profile here.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Jared Brown is the founder of &lt;a href="http://talentopoly.com/"&gt;Talentopoly.com&lt;/a&gt;, a community for programmers, designers, and IT professionals staying current by sharing the best of what they discover online.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I wanted to take a minute to give a glimpse into the platform Talentopoly is built on. A lot of this may not be familiar to non-Rails developers.&lt;/p&gt;
&lt;p&gt;The site is hosted on Heroku. I use it for staging as well as production. To say Heroku makes deployment easy would be an understatement. To deploy Talentopoly all it takes is a quick “git push heroku” or “git push heroku-staging”. To setup your project is also one command.&lt;/p&gt;
&lt;p&gt;The production server consists of two dynos (Heroku’s term for a virtual server unit) for a cost of $36/mo. This setup can handle dozens of concurrent users per minute. The site regularly peaks at 50 users and doesn’t break a sweat.&lt;/p&gt;
&lt;p&gt;Add-ons are Heroku’s way of making it easier to integrate with other services. Often times no configuration is necessary when turning on an add-on.&lt;/p&gt;
&lt;p&gt;My staging server mirrors production. It uses the same add-ons. The WebSolr folks were nice enough to setup a free staging instance. So the staging server is free. I populate staging with production data via Heroku’s handy PostgreSQL commands.&lt;/p&gt;
&lt;p&gt;Heroku uses nginx as the http server acting as a cache store and reverse proxy. nginx is written in C and super fast. Behind nginx are a load-balanced cluster of Thin servers (modified Mongrel servers) running the application stack. Heroku is constantly monitoring the health of the dynes and will spin up new ones to replace hung processes if necessary.&lt;/p&gt;
&lt;p&gt;Other than Heroku non of these things are exclusive to Ruby on Rails developers. The following services help make my life easy.&lt;/p&gt;
&lt;p&gt;Search is provided by WebSolr and the excellent Solr search engine. Search is configured on a per-model basis. Only a few lines of code are responsible for making the models searchable. It provides geospatial search as well as full text search. Unlike Sphinx Solr doesn’t rely on fragment indexes. Everything is handled transparently. When new records are added or destroyed the index is updated. WebSolr costs $20/mo. for 75k documents.&lt;/p&gt;
&lt;p&gt;The database is a shared PostgreSQL instance on Heroku. It performs well under load. There are other options such as Amazon’s RDS but for simplicity of deployment I have stuck with Heroku’s native solution.&lt;/p&gt;
&lt;p&gt;SendGrid handles all the outgoing email. It’s accomplished via a SMTP gateway, which saved time over using their API.&lt;/p&gt;
&lt;p&gt;S3 handles user uploaded image assets via the awesome paperclip gem. Paperclip re-sizes and stores the images on S3.&lt;/p&gt;
&lt;p&gt;Scribd is used to store and convert uploaded resumes. This is why Talentopoly can accept and properly display so many different file formats.&lt;/p&gt;
&lt;p&gt;New Relic is also provided as an add-on. It’s invaluable for investigating bottlenecks. It provides a breakdown of the request stack tracing it through the database.&lt;/p&gt;
&lt;p&gt;Chartbeat provides real-time analytics and alerts. I can see how many concurrent users I have on the site, which is useful if it’s seeming slow. Google Analytics gives me the full stats to analyze.&lt;/p&gt;
&lt;p&gt;I haven’t had a strong need to implement an in-memory key-value store like Mongo, Memcached, or Redis yet. Though hopefully the increasing traffic on the site makes that a priority soon.&lt;/p&gt;
&lt;p&gt;There are other great services, gems, and plug-ins I could talk about but hopefully that gives you a sense for how Talentopoly is built and what it’s like to build a Ruby on Rails app on Heroku.&lt;/p&gt;
&lt;div&gt;
&lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=cLFhGjU9zOI:FRa68xvAmnY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=cLFhGjU9zOI:FRa68xvAmnY:V_sGLiPBpWU" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=cLFhGjU9zOI:FRa68xvAmnY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=cLFhGjU9zOI:FRa68xvAmnY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=cLFhGjU9zOI:FRa68xvAmnY:F7zBnMyn0Lo" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=cLFhGjU9zOI:FRa68xvAmnY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=cLFhGjU9zOI:FRa68xvAmnY:gIN9vFwOqvQ" border="0"&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/aaronlerch/~4/cLFhGjU9zOI" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/teuEQHiv13Y" height="1" width="1"/&gt;</content><author><name>aaron</name></author><source gr:stream-id="feed/http://feeds.feedburner.com/aaronlerch"><id>tag:google.com,2005:reader/feed/http://feeds.feedburner.com/aaronlerch</id><title type="html">Aaron Lerch</title><link rel="alternate" href="http://www.aaronlerch.com/blog" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/aaronlerch/~3/cLFhGjU9zOI/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1304008333102"><id gr:original-id="http://ericwilleke.com/?p=261">tag:google.com,2005:reader/item/8899b2dbcd7c4d7d</id><category term="Uncategorized" /><title type="html">Instructional Design Applied to Agile Coaching</title><published>2011-04-28T16:32:03Z</published><updated>2011-04-28T16:32:03Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/PsW4JKKb0WA/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;[This is a cross-post from &lt;a title="Marian&amp;#39;s blog" href="http://mhwilleke.com"&gt;Marian's blog&lt;/a&gt;]&lt;/p&gt;
&lt;p&gt;Agile coaching requires observant facilitation with an ability to engage learners actively. This parallels almost identically with accelerated adult learning at the university level. “Guide on the side” instead of “sage on the stage” is a common mantra necessary for all effective facilitators to embrace when motivating adult learners. There are scores of interactive instructional strategies that not only provide relevance to the learners, but also allows for quantifiable assessment of the learning growth. However, for this post, I will focus on the instructional design that is the moving force behind effective facilitation effort.&lt;/p&gt;
&lt;p&gt;Instructional design is just putting together the course, right?&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;It is a much more holistic picture of all curriculum/courseware/module, or whatever buzz term you favour. In my experience as the instructional designer for several degree programs at a small university, a huge takeaway has been the understanding of knowing what to standardize and what to customize.&lt;/p&gt;
&lt;p&gt;Let’s look at the benefits of instructional design insight for developing multiple training programs or courses of any level.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Standardization allows focus on architectural improvements and shared collaboration across coaches.&lt;/li&gt;
&lt;li&gt;Recreating content for different client contexts is no longer necessary.&lt;/li&gt;
&lt;li&gt;The modularization of core components allows focus on tailoring courses to specific client needs at a much deeper and more effective level.&lt;/li&gt;
&lt;li&gt;Everybody shares value and baseline improvements holistically, but can also modularize for personal use. Nobody teaches the same way, and never should courseware force a specific type of instructional methodology.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any individual coach or organization that trains internally or externally wants a strong relationship with their learners. Internal coaching needs a strong relationship for better and smoother implementation efforts. External coaching needs to consistently improve relationships with their clients beyond the expectations of internal coaching. Another benefit to formalized instructional design techniques being applied to training material is that it improves relationships with the learners in the following ways.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Customization is improved for the client’s needed context before and after the course.&lt;/li&gt;
&lt;li&gt;Coaches can apply beginner’s mind more effectively.&lt;/li&gt;
&lt;li&gt;Modular pieces allow coaches to make courses more experiential.&lt;/li&gt;
&lt;li&gt;Familiarity with content and structure allows coaches to breed active learning.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, economics is always a question, even if it’s not the first one. Risk management questions need asked, including, is the cost worth the investment both financially and time-wise. Unfamiliarity with the purpose of instructional design can result in the belief that something so simple is not needed, and just one more step in the process anyway. Let’s look at the economic improvements for course development with instructional design techniques applied.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;More quality time for coaches is available.&lt;/li&gt;
&lt;li&gt;Consistent master documents represent a collection of all coach experiences for focused improvement.&lt;/li&gt;
&lt;li&gt;Course development for a new client is faster with high quality.&lt;/li&gt;
&lt;li&gt;Course development scales across personal techniques without changing the learning values.&lt;/li&gt;
&lt;li&gt;Needed improvements are easily targeted.&lt;/li&gt;
&lt;li&gt;Unnecessary re-invention is eliminated, allowing focused innovation.&lt;/li&gt;
&lt;li&gt;Easier experimentation content is enabled.&lt;/li&gt;
&lt;li&gt;Gap analysis is simplified for new course development.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While a book could be written on the value and techniques of instructional design for agile coaching, these are a few ‘down and dirty’ values that instructional design provides for training programs.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Written in collaboration with &lt;a title="Marian Willeke&amp;#39;s post" href="http://www.mhwilleke.com/instructional-design-applied-to-agile-coaching"&gt;Marian Willeke&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/5yqxccCqwFg" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/PsW4JKKb0WA" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/5yqxccCqwFg/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1303360441729"><id gr:original-id="http://ericwilleke.com/?p=258">tag:google.com,2005:reader/item/9cf9392fe897ba4d</id><category term="Uncategorized" /><title type="html">When teams work differently</title><published>2011-04-21T04:05:38Z</published><updated>2011-04-21T04:05:38Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/fm33zaRe974/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;In a few weeks at Rally’s user conference I’ll be leading a session on resolving the problems that arise when different teams have to work together, but have entirely different models for how their work gets completed. Details are posted at http://www.rallydev.com/coachingblog/?p=55.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/ZjKAvBnW-3g" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/fm33zaRe974" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/ZjKAvBnW-3g/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1302644913903"><id gr:original-id="http://www.aaronlerch.com/blog/?p=237">tag:google.com,2005:reader/item/379135b890df17fe</id><category term="Uncategorized" /><title type="html">Office Prank</title><published>2011-04-12T21:47:31Z</published><updated>2011-04-12T21:47:31Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/SQnT8Zfxafw/" type="text/html" /><content xml:base="http://www.aaronlerch.com/blog" type="html">&lt;p&gt;Every &lt;a href="http://www.aaronlerch.com/blog/2006/10/31/office-pranks/"&gt;now&lt;/a&gt; and &lt;a href="http://www.aaronlerch.com/blog/2008/01/29/office-pranks-part-deux/"&gt;then&lt;/a&gt; we like to have some fun with our boss. I’ve said it before, and I’ll say it again – he’s a fun-loving guy and we all love working together. Usually when you go on vacation for a week you can expect something to happen by the time you get back. Not too long ago I returned to find my office completely filled with black plastic. I mean it took 6 large garbage cans and a mini-dumpster, tightly packed, to remove it all.&lt;/p&gt;
&lt;p&gt;We recently played yet another prank on my boss. This one probably takes the cake, and it was a ton of fun to pull off. We actually geeked out a bit and we had two hidden cameras, which were automatically recording any motion they saw, as well as live streaming their feeds via ustream.tv. I wrote an app that monitored the filesystem and when it detected a new motion-based recording, it &lt;a href="http://twitter.com/themissingdoor"&gt;tweeted&lt;/a&gt; a frame of the motion. I just subscribed to mobile notifications and I got an SMS with a link to a JPG file every time it detected movement over the weekend. Pretty easy monitoring system!&lt;/p&gt;
&lt;p&gt;Check out the video of the prank. His reaction was priceless!&lt;br&gt;
We love to work hard and have a lot of fun at the same time. If this sounds like the kind of software company you’d like to work for, &lt;a href="http://inin.jobs/"&gt;we’re hiring&lt;/a&gt;! (Nobody asked me to post that, in case you wondered.)&lt;/p&gt;
&lt;p&gt;&lt;iframe src="http://reader.googleusercontent.com/reader/embediframe?src=http://www.youtube.com/v/qD8MhnQs588?fs%3D1%26hl%3Den_US%26rel%3D0&amp;amp;width=480&amp;amp;height=390" width="480" height="390"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;div&gt;
&lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=MymqaoVGdSA:Zwhsi9dqh1g:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=MymqaoVGdSA:Zwhsi9dqh1g:V_sGLiPBpWU" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=MymqaoVGdSA:Zwhsi9dqh1g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?d=yIl2AUoC8zA" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=MymqaoVGdSA:Zwhsi9dqh1g:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=MymqaoVGdSA:Zwhsi9dqh1g:F7zBnMyn0Lo" border="0"&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/aaronlerch?a=MymqaoVGdSA:Zwhsi9dqh1g:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/aaronlerch?i=MymqaoVGdSA:Zwhsi9dqh1g:gIN9vFwOqvQ" border="0"&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/aaronlerch/~4/MymqaoVGdSA" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/SQnT8Zfxafw" height="1" width="1"/&gt;</content><author><name>aaron</name></author><gr:likingUser>04573724387091216075</gr:likingUser><source gr:stream-id="feed/http://feeds.feedburner.com/aaronlerch"><id>tag:google.com,2005:reader/feed/http://feeds.feedburner.com/aaronlerch</id><title type="html">Aaron Lerch</title><link rel="alternate" href="http://www.aaronlerch.com/blog" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/aaronlerch/~3/MymqaoVGdSA/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1298598310123"><id gr:original-id="http://ericwilleke.com/?p=255">tag:google.com,2005:reader/item/fc64e9059ad2bce4</id><category term="Uncategorized" /><title type="html">More on expand collapse pattern</title><published>2011-02-25T01:44:38Z</published><updated>2011-02-25T01:44:38Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/l_jhBAHTwzE/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;There’s a &lt;a title="Chris Matts post on Kanbandev" href="http://finance.groups.yahoo.com/group/kanbandev/message/11327"&gt;thread&lt;/a&gt; on kanbandev today about the role of expand/collapse, and its value in helping to identify the BVI/MMF [1]. Chris’ post, linked above, talks effectively about the ability to discover work that doesn’t need done, as do a couple of Ron’s contributions in the same thread. Unfortunately, from my perspective the language there is still primarily about decomposition of scope, rather than focusing on the real nature of the work we do. The value I find in “expand / collapse” is very different. This learning and discovery is just one of several intertwining aspects important to understanding the nature of the work, but I believe that effective teams are focused on learning and discovery as a matter of course.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Focus the team&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One major benefit of expand/collapse is that it focuses more of the team on related tasks. I often joke that at Inkubook we had an MMF WIP limit of 1.1, meaning that there would be one MMF that most of the team was focusing on and one that was just being finished up or just being started. We had a different limit (four most of the time, iirc) for the tasks we broke out of the MMF, and when there weren’t enough valuable tasks left for the MMF that was about to end, people would start on the next one (with the focus being on finishing, not on starting). From what I’ve seen, type of focus scales nicely across teams and planning horizons, allowing “team” and “set of related MMF’s” to be the next unit of abstraction outward. This effectively enables WIP limiting and goal focus at that level. If taken all the way, I should be able to see how my individual activity today rolls all the way up to my company’s True North [2]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Manage Learning in Progress&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I spoke on this at the LeanSSC 2010 UK [3] and have been observing the concepts in practice since then. Teams are limited in how fast they can learn, primarily because learning takes research and conversation to achieve [4].  When you apply expand/collapse, keep an eye on the amount of stuff to “figure out” in each broken down item. The ones with lots of stuff to figure out will have the highest variability. I can’t say if you should concentrate it or balance it, or whether you should front-load it or back-load it, but be aware of it as you make your decisions and fit the breakdown to your context. If the process of breaking it out allows you a way to get a BVI without having to figure much out, then by all means defer the stuff that requires lots of figuring out.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Manage abstractions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As I mentioned above in the focus section, the levels of expand/collapse provide a very effective way of managing the abstractions inherent in the work. It’s far easier to have value and prioritization conversations about 5 large items than 50 (or 500) smaller items [5], especially if you’ve managed to effectively engage your senior management in the decision planning. On the other hand, asking a dev team to implement against a single large item taking over a month is pointless, they need the detail to effectively track and deliver against the goals. Visualization of progress against goals is also easier due to the aggregate data, enabling the use of goal-focused reports like a &lt;a title="Image of a parking lot diagram from feature driven development" href="http://www.featuredrivendevelopment.com/node/619"&gt;parking lot diagram&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Triggering conversation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The need to apply expand/collapse is also a trigger to figure a bunch of stuff out. The best way to figure things out is to have a conversation about what’s needed with the relevant people. The mere act of decomposition is a value add activity, and should not be done by a single individual. Scrum uses sprint planning and task estimation to drive these conversations, but dropping iterations doesn’t excuse you from the need to explore the meaning of work items and tasks as a group. The conversations need to happen, and the acceptance criteria need to be discovered: “Don’t start what you can’t finish” [6]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Enable Operational Languages&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One very nice side-effect of the abstractions in use is that the language used at each level of abstraction can be made appropriate to the audience, and should be. I’ve often heard about deep misunderstandings between “development” and “the business” because the two are speaking completely different languages while using the same words. This is only made more complicated when you introduce other groups as valued stakeholders, such as legal, finance, compliance and operations. With effective expand/collapse and a good goal-oriented organization, the highest levels can be written in terms of markets and the organizational vision, middle levels in terms of the desired behaviors enacted in the market and the protections the organizations require, lower levels in terms of the features that enable those behaviors, and the development level in terms of the actions that need completed to create those features. This is not a problem, this is a positive step to communicate effectively across the organization! [7]&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Finally, a perspective&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;At the lowest level, converting from the most detailed card (task/story/line item/whatever) to code (configuration/html/sql/whatever) is its own expand/collapse translation, and the conversation is one with your compiler and (hopefully) automated tests. There’s no expectation that you can clearly define what code you need when you pick up a task, you’re free to be a professional and add, remove, and modify the code until it solves the need at hand. The same logic should apply to the tasks to complete a story, the stories required to complete an epic, and any other expand/collapse relationship you may have in your particular environment. There are many effective patterns, practices, and guidelines, but the set of actual “rules” is fairly minimal. Do what makes sense, and always strive to be more effective in what you do.&lt;/p&gt;
&lt;p&gt;[1]  Business Value Increment, which Chris renamed from Minimum Marketable Feature to clarify it as different than what’s talked about in &lt;a title="Software by Numbers site." href="http://www.softwarebynumbers.org/"&gt;Software by Numbers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] Or whatever you call your organization’s guiding vision for the year/quarter/decade&lt;/p&gt;
&lt;p&gt;[3]  &lt;a title="My talk from LSSC 2010 UK at the Skillsmatter site" href="http://skillsmatter.com/podcast/agile-scrum/eric-willeke-on-value-stream-languages"&gt;http://skillsmatter.com/podcast/agile-scrum/eric-willeke-on-value-stream-languages&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[4] Dan North tasks about this as removing ignorance in the context of Deliberate Discovery.&lt;/p&gt;
&lt;p&gt;[5] I don’t think I’ve seen a Scrum training deck in years that doesn’t have a pyramid diagram for story size indicating the desired backlog composition&lt;/p&gt;
&lt;p&gt;[6] Paraphrasing from Alan S, Dean L, and Don R among many others.&lt;/p&gt;
&lt;p&gt;[7] I plan on writing shortly about the role of a BA as linguist in this exchange. The post is languishing as a half-finished draft.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/V4wgEUSVBYQ" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/l_jhBAHTwzE" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/V4wgEUSVBYQ/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1297781696327"><id gr:original-id="http://ericwilleke.com/?p=252">tag:google.com,2005:reader/item/f9fe21090059221c</id><category term="Uncategorized" /><title type="html">Away with “Active”</title><published>2011-02-15T14:46:34Z</published><updated>2011-02-15T14:46:34Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/yhd7Z0tPuU4/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;I dusted off my personal kanban about 45 days ago when I started at Rally, and it’s been a very interesting path since then. When I first rebuilt and updated the contents, the columns were Eventually, Midterm, Nowterm, Active, and Done, and they were essentially prioritization buckets so that I didn’t have to mess around sorting each of the individual items. Roughly mapped to Must Have, Should Have, and Could Have [1].&lt;/p&gt;
&lt;p&gt;Last weekend, that changed. I was getting frustrated because I kept having to prioritize things I didn’t really _care_ about, but that I needed to do. It bothered me a lot that I couldn’t get to the stuff I care about, so I updated my columns again. My columns became Options [2], Proactive, Reactive, Active, and Acted. Suddenly I felt much better about things, because I could prioritize the things in Proactive in order of how much I care about them, how engaged I would be, and how distant the payback on my investment of time would be. Reactive, I prioritize based on a combination of ease and cost of delay.&lt;/p&gt;
&lt;p&gt;It’s been working, but a pattern quickly emerged that bothered me. Either my active column was empty, or my active column contained the top item moved over my my reactive column. It didn’t tell me anything useful, it didn’t help me prioritize, it was just… there, taking up screen real estate without providing any value. So I zapped it. I don’t have an active column anymore, I just know I’m focused on the top item of one of the two columns that’s in the view. If I’m full of energy and wanting to engage, I hit the top of proactive. If I’m dragging a bit and just want to get some things done, but not pour energy in, I hit the reactive column. When they’re done, they’re dropped into Acted and left to languish with all their finished friends.&lt;/p&gt;
&lt;p&gt;[1] Why bother with Won’t have?&lt;/p&gt;
&lt;p&gt;[2] Options represents ideas that I don’t want to forget, but don’t have any desire to prioritize or work on now. Approximately weekly I skim that column to see if anything inspires me, but they’re roughly the “transient” class of service.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/5ziScCqw77c" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/yhd7Z0tPuU4" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/5ziScCqw77c/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1296531407193"><id gr:original-id="http://ericwilleke.com/?p=248">tag:google.com,2005:reader/item/eec0c55c232b9ec7</id><category term="Uncategorized" /><title type="html">Bring your ‘A’ game</title><published>2011-01-31T02:20:35Z</published><updated>2011-01-31T02:20:35Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/OgRq5v5g5uo/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;My passion is to engage. I am at my best both personally and professionally when I’m able to confront a situation and engage the people around me. I can then understand the goals they’re trying to achieve, explore the impediments they feel they’re facing, and collaboratively find solutions. Usually, these are not only acceptable to everybody, but exceed the hopes of the individuals. I’ve not only found a solution, I’ve shown people an example that more is possible, and that they shouldn’t have to settle.&lt;/p&gt;
&lt;p&gt;That’s my ‘A’ game, and I’m not talking about a grade. I’m talking about the affective learning domain, and how it’s equally important as the cognitive domain [1]. When people talk about being passionate about what they do, they’re talking about having achieved engagement at an emotional level. This engagement is what drives my effectiveness. When I’m engaged, I’m much more capable of understanding the way others are feeling, and I’m able to intuitively match the situation and their concerns against the many mental models I’ve collected over the years. Even better, the people I’m engaged with are more likely to be engaged because they can feed off my engagement. These are the experiences when the most fascinating things happen, the biggest audacious goals are defined, and the world gets changed (at least in small ways).&lt;/p&gt;
&lt;p&gt;There’s one big problem, though: It’s fragile. It’s extremely easy to knock a group out of this type of zone. All it takes is one person whining about expenses, or the waitress bringing the wrong beer, or a manager walking into the room with an “We’ve got a problem” look on her face. Please, please, don’t be that guy [2]. Team-level flow is slightly more resilient than individual flow, but it’s less able to ignore the context. As a manager, this is one of your jobs. As a team member, it’s your job too. Ditto ScrumMaster, product owner, and everybody else. Protect your environment, take care of the emotional state of your colleagues, and otherwise design the proper environment for the team to engage without distraction.&lt;/p&gt;
&lt;p&gt;[1] Referencing &lt;a title="Bloom&amp;#39;s Taxonomy of Learning Domains" href="http://www.nwlink.com/~donclark/hrd/bloom.html"&gt;Bloom’s learning domains&lt;/a&gt;. There’s also a psychomotor domain that deals with imprinting physical and repetitive behaviors, this is something I should write about after my next code retreat.&lt;/p&gt;
&lt;p&gt;[2] Although, there’s not much you can do about last call, really. Learn to stack.&lt;/p&gt;
&lt;p&gt;[edit] Forcing a feed update… playing with the blog &lt;img src="http://ericwilleke.com/wp-includes/images/smilies/icon_wink.gif" alt=";)"&gt; &lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/F9rVI-dXr98" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/OgRq5v5g5uo" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/F9rVI-dXr98/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1296531407193"><id gr:original-id="http://ericwilleke.com/?p=246">tag:google.com,2005:reader/item/4eec84cdd6256cd6</id><category term="Uncategorized" /><title type="html">Just one thing…</title><published>2011-01-28T22:21:29Z</published><updated>2011-01-28T22:21:29Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/djWM-IJO6rk/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;Yesterday, I was reminded of the power of commitment.&lt;/p&gt;
&lt;p&gt;I spent the day shadowing &lt;a title="Alan&amp;#39;s coaching page on Rally" href="http://www.rallydev.com/agileblog/about/#alan-atlas"&gt;Alan Atlas&lt;/a&gt; as he helped a room full of managers understand their role in a brave new agile world. At the end of the day I was invited to facilitate the retrospective of the day’s course and attempt to bubble up some of the individual learning to benefit the group. Last night, at the airport, I realized I’ve never written specifically about a powerful technique I’ve added to the end of every retrospective I’ve run over the last year with great effect.&lt;/p&gt;
&lt;p&gt;When I’m helping teams reflect, I tend to use a four-stage starfish to structure the thinking process. Yesterday, I tried an &lt;a title="About the ORID model" href="http://tilt.colostate.edu/guides/tilt_servicelearning/practices_reflection.cfm"&gt;ORID model&lt;/a&gt; [3] due to there being many individuals rather than a focused team. In the past, I’ve used the six thinking hats to guide the reflective paths, done standard plus/delta, and several other models. [1] Regardless of the retrospective format used, however, there is one thing I always do to close out the exercise: I ask for a commitment.&lt;/p&gt;
&lt;p&gt;This is probably the least “&lt;a title="About being a nice coach" href="http://www.coachingagileteams.com/2010/09/25/uncategorized/i-am-a-certified-scrum-coach-and-i-am-not-nice/"&gt;nice coach&lt;/a&gt;” activity I do as an agile guide. I force members of the group to make commitments. No Weasel Words, no dodges, no non-commitive commitments. I insist on real commitments. “I will set up a meeting next week with Bob, Julie, and Josh to discuss my role as an agile manager.” I don’t accept “I’ll each out to the other managers about this.” I require “I will hang up visible burndowns for each of my three teams” instead of “I’ll start increasing the amount of visual management”. I’m not a nice person. I insist on real, committed language, and I insist it’s something they’re willing to have held accountable by the entire group.&lt;/p&gt;
&lt;p&gt;Why?&lt;/p&gt;
&lt;p&gt;Because it helps. I first observed this while coaching with &lt;a title="Simon on LinkedIn" href="http://uk.linkedin.com/in/bennettsimon"&gt;Simon Bennett&lt;/a&gt; in the UK during early summer 2009, and this is where I first heard the term “&lt;a title="Weasel Words on Wikipedia" href="http://en.wikipedia.org/wiki/Weasel_word"&gt;Weasel Words&lt;/a&gt;.” I am amazed at how deeply it struck me about my own behavior, and how much it started focusing my interactions as a coach and team lead. I started doing action plans [2] with individuals and teams. It is one of the things I most appreciate here at &lt;a title="Rally&amp;#39;s home page" href="http://www.rallydev.com/"&gt;Rally&lt;/a&gt;: Following through with commitments is part of the company’s core values. Too often, it’s not. Time after time I see teams and individuals make a fuzzy statement of intent and never ever follow through, because the commitment doesn’t _mean_ anything. It doesn’t connect with affective learning, only cognitive learning, and therefore doesn’t stick very well.&lt;/p&gt;
&lt;p&gt;As a coach, I force people to connect with what they’re saying. I don’t put individuals on the spot, I put entire groups on the spot. “Stand up, tell your peers what you will _do_, and make that commitment to the group.” Starting yesterday, I even invited (didn’t insist) people to sign the written record of their commitment (i.e. the sticky on the board). It helps create focus when multiple people make very similar commitments.&lt;/p&gt;
&lt;p&gt;Just one thing, one pebble, one little piece of progress can start a landslide. It’s even more powerful when you get ten or twenty little pieces of progress. People throughout an organization see many people suddenly DO something and take notice. They instinctively recognize that something important is happening and they watch, and maybe even engage.&lt;/p&gt;
&lt;p&gt;[1] I’m more than happy to write about any of these… leave a comment or tweet at me if you’re interested.&lt;/p&gt;
&lt;p&gt;[2] Do you want another post on Action Plans?&lt;/p&gt;
&lt;p&gt;[3] Scroll down to “The ORID Model” and pay attention to the &lt;a title="Image about Kolb learning cycle" href="http://tilt.colostate.edu/guides/tilt_servicelearning/principles_whatis_kolb.cfm"&gt;Kolb Learning Cycle&lt;/a&gt; too&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/-FXOsH_ZiWM" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/djWM-IJO6rk" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/-FXOsH_ZiWM/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1296531407193"><id gr:original-id="http://ericwilleke.com/?p=235">tag:google.com,2005:reader/item/3c882a241dbd6af8</id><category term="Uncategorized" /><title type="html">Welcome to my new home!</title><published>2011-01-26T19:32:53Z</published><updated>2011-01-26T19:32:53Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/ADMZmwJXTrY/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;As many of you know from Twitter and other events, I’ve recently joined &lt;a title="Rally Software Development" href="http://rallydev.com"&gt;Rally&lt;/a&gt; as an agile coach, allowing me to engage with a much broader range of teams and contexts as I help guide people towards more effective and satisfying ways of providing meaning and value to their organizations. In the early years of my career, I was lucky in that I was exposed to a great many contexts that often were wildly different from engagement to engagement. As I progressed in my understanding, I began to recognize the value of the perspectives I gained from exploring these different environments. This knowledge allowed me to change my approach to my career, letting me seek out roles and situations that would accelerate this exposure, leading to my explorations of the product development environment as an employee of CSI and later Inkubook. Recognition that Indianapolis was not able to provide the wide exposure I desired led me to take on my role at EMC Consulting, allowing me visibility into many very large organizations over the last eighteen months.&lt;/p&gt;
&lt;p&gt;Rally is the next natural step on my path. Coaching with Rally will offer me the continued opportunity to engage with larger companies at the right level to see entire systems and how they work. I’m excited, and I look forward to the stories I will be able to tell, and the ones I won’t…&lt;/p&gt;
&lt;p&gt;To those who read this, thank you for your support and guidance over the last 167 posts! This is the new home for Rediscovering the Obvious, and it’s probably very obvious that it’s very much a work in progress. First step is a reasonable theme, then the various plugins and useful things for both myself and visitors. Only then will I start taking the time to try and clean up the older posts, with the expectation that the code blocks will take the most time; I’m hoping styles will take care of the rest of the mess in a reasonable way. Comments are lost, as are my previous view counts (a handful of posts are pushing 1800 views with most posts getting around 500). Thus ends the tale of my conversion from Community Server to WordPress.&lt;/p&gt;
&lt;p&gt;Finally, I’d like to offer a very special appreciation to two people.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Michael Ruminer&lt;/strong&gt;, owner and host of manicprogrammer.com, I appreciate you for making blogging very easy over the last few years.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bernardo Heynemann&lt;/strong&gt;, friend and fellow architect over the years, I appreciate you for getting me off my lazy ass 167 posts ago and getting me to put my thoughts on the web. I have gained far more than I ever would have expected, and I owe you.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/DM1jsuygSrE" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/ADMZmwJXTrY" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><gr:likingUser>11830179702077313278</gr:likingUser><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/DM1jsuygSrE/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1296531407192"><id gr:original-id="http://manicprogrammer.com/cs/blogs/willeke/archive/2010/12/09/forgetting-yourself-in-mef-w-prism.aspx">tag:google.com,2005:reader/item/e358c8e69990fbd7</id><category term="Uncategorized" /><title type="html">Forgetting yourself in MEF w/ Prism</title><published>2010-12-10T05:49:19Z</published><updated>2010-12-10T05:49:19Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/ckc7clnfzqE/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;Just a quick note in case anybody else runs into this issue in Prism for WPF.&lt;/p&gt;
&lt;p&gt;In the code below, the line “return Container.GetExport&amp;lt;Shell&amp;gt;().Value” was failing and telling me with the following message:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;System.ComponentModel.Composition.ChangeRejectedException was unhandled Message=The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information.&lt;/p&gt;
&lt;p&gt;1) No valid exports were found that match the constraint&lt;span style="font-family:Georgia,&amp;#39;Times New Roman&amp;#39;,&amp;#39;Bitstream Charter&amp;#39;,Times,serif;line-height:19px;white-space:normal;font-size:13px"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;‘((exportDefinition.ContractName == “ABC.DEF.MenuViewModel”)&lt;span style="font-family:Georgia,&amp;#39;Times New Roman&amp;#39;,&amp;#39;Bitstream Charter&amp;#39;,Times,serif;line-height:19px;white-space:normal;font-size:13px"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;AndAlso (exportDefinition.Metadata.ContainsKey(“ExportTypeIdentity”)&lt;span style="font-family:Georgia,&amp;#39;Times New Roman&amp;#39;,&amp;#39;Bitstream Charter&amp;#39;,Times,serif;line-height:19px;white-space:normal;font-size:13px"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;AndAlso “ABC.DEF.MenuViewModel”.Equals(exportDefinition.Metadata.get_Item(“ExportTypeIdentity”))))’&lt;/p&gt;
&lt;p&gt;, invalid exports may have been rejected.&lt;/p&gt;
&lt;p&gt;Resulting in: Cannot set import ‘ABC.DEF.Shell.ViewModel (ContractName=”ABC.DEF.MenuViewModel”)’ on part ‘ABC.DEF.Shell’.&lt;/p&gt;
&lt;p&gt;Element: ABC.DEF.Shell.ViewModel (ContractName=”ABC.DEF.MenuViewModel”) –&amp;gt;  ABC.DEF.Shell&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;It turns out, this was for a very simple reason: I’d failed to actually include the line that sets the current assembly as one of the assemblies in the AggregateCatalog. Don’t do that!&lt;/p&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#0000ff"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; Bootstrapper : MefBootstrapper&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    {&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; DependencyObject CreateShell()&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        {&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; Container.GetExport&amp;lt; Shell &amp;gt;().Value;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        }&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; InitializeShell()&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        {&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;base&lt;/span&gt;.InitializeShell();&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            App.Current.MainWindow = (Window)&lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.Shell;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        }&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff"&gt;void&lt;/span&gt; ConfigureAggregateCatalog()&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        {&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;base&lt;/span&gt;.ConfigureAggregateCatalog();&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            AggregateCatalog.Catalogs.Add(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()));&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            AggregateCatalog.Catalogs.Add(&lt;span style="color:#0000ff"&gt;new&lt;/span&gt; AssemblyCatalog(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(ABC.DEF.Module.ContactModule).Assembly));&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        }&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    }&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;img src="http://manicprogrammer.com/cs/aggbug.aspx?PostID=17828" alt="" width="1" height="1"&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/DmoRlkcETeA" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/ckc7clnfzqE" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/DmoRlkcETeA/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1296531407192"><id gr:original-id="http://manicprogrammer.com/cs/blogs/willeke/archive/2010/11/09/that-s-not-x.aspx">tag:google.com,2005:reader/item/94e4ef2e2e9ad97b</id><category term="Uncategorized" /><title type="html">That’s not X!</title><published>2010-11-09T21:00:18Z</published><updated>2010-11-09T21:00:18Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/hZ4cRsrh1Qc/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;Mark Graban has a great &lt;a href="http://www.leanblog.org/2010/11/why-nurses-should-reject-lame-and-demand-lean/"&gt;post&lt;/a&gt; [1] over at Lean Blog today. His overall premise is one we see over and over again in software: People take a good tool, apply it poorly or in the wrong context, and then blame the tool. Worse, they occasionally broadcast their blame, causing people to have a lower reputation of the tool. &lt;/p&gt;
&lt;p&gt;In software, this is most recently seen in the certification discussion and in the “Scrum vs. kanban” conversation. As a result, I very much want to call out a couple of things Mark says in the healthcare context that apply equally well in the software context:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;But the difference I draw from the Lean critics:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;They see L.A.M.E. and leap to the conclusion that Lean is inherently bad. They throw Lean under the bus and take the tone that these leaders are “idiots.” &lt;/li&gt;
&lt;li&gt;I see that Lean works well when leaders learn about and embrace the full management system. I work to try to educate healthcare leaders who are smart, but have a different viewpoint on management.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is absolutely what I see with agile, lean, scrum, and kanban quite frequently. Teams try, fail, and blame the tool. Yes, it’s quite possible the team tried the wrong tool. It’s also quite possible they didn’t actually use the tool the way it was intended. [2] It could be their context is wrong for that tool in the first place, or that they changed their labels but didn’t change anything they actually do, or that they did things right but ran into a management wall, or faced struggles scaling out to other teams, or any of the hundreds of other reasons that adoptions “fail”.&lt;/p&gt;
&lt;p&gt;We amplify this with the way our labels and language creates lines rather than identifying a body of perspectives and tools. It’s time to take a cue from BDD and define some scenarios and well-formed outcomes of the adoption. Mark presents a great list from a nursing perspective… &lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Why would nurses WANT Lean? When organizations really embrace Lean:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Nurses say, “Finally! Management is seeing the problems we face every day and we’re going to work together on fixing things.” Instead of feeling neglected, they are being properly supported and involved in process improvement. &lt;/li&gt;
&lt;li&gt;The culture changes to fix routine “Every Day” problems – instead of jumping through hoops and constantly fighting the same fires, they get to focus more time on patient care. &lt;/li&gt;
&lt;li&gt;Lean helps support save care – proven documented examples include reduced &lt;a href="http://www.healthcarevalueleaders.org/displayobject.cfm?id=1106"&gt;patient falls&lt;/a&gt;, fewer &lt;a href="http://www.leanblog.org/2010/08/great-interview-with-dr-richard-shannon-on-lean-toyota-methods/"&gt;infections&lt;/a&gt;, and fewer cases of &lt;a href="http://runningahospital.blogspot.com/2007/03/better-grades-on-vap.html"&gt;V.A.P.&lt;/a&gt; — nurses want the best for their patients. &lt;/li&gt;
&lt;li&gt;With Lean, the space is designed and sized to match the processes for nursing care, instead of nurses being forced into spaces that don’t have enough bed/equipment storage space, for example. &lt;/li&gt;
&lt;li&gt;They get to design their own standardized work and can improve it through daily huddles and kaizen boards. &lt;/li&gt;
&lt;li&gt;The nurses get to work as part of a team (such as ThedaCare’s &lt;a href="http://www.google.com/search?sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=thedacare+collaborative+care"&gt;Collaborative Care&lt;/a&gt; model, where the RN helps direct doctors and pharmacists. &lt;/li&gt;
&lt;li&gt;Nurses work less overtime because they have more time during the day to do proper charting instead of batching it at the end of the day.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;These sure feel like things I can see and validate against when they happen. What’s our list look like for software? Here’s a few that come to mind immediately:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When a stakeholder asks for a release, it’s done quickly, easily, and with a minimum of fuss.&lt;/li&gt;
&lt;li&gt;When a stakeholder identifies an opportunity related to the current application [3], it’s not painful to make it into reality.&lt;/li&gt;
&lt;li&gt;When a problem is discovered with the app, it’s professionally and quickly fixed without attacks or defensiveness.&lt;/li&gt;
&lt;li&gt;Simple and appropriate improvements are accepted and implemented with a minimum of fuss regardless of source.&lt;/li&gt;
&lt;li&gt;Teams work in ways that suit them while still respecting their organization&lt;/li&gt;
&lt;li&gt;People go home, have families, and maintain good balance despite loving their jobs&lt;/li&gt;
&lt;li&gt;People care about the end result, not just their own specific job&lt;/li&gt;
&lt;li&gt;Individuals are respectful across specializations, and attempt to use a shared language and goals rather than engaging in “legalese” or “geekspeak”.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What else?&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;[1] All quotes attributed to “Mark” are from this post, used with permission: &lt;a href="http://www.leanblog.org/2010/11/why-nurses-should-reject-lame-and-demand-lean/"&gt;http://www.leanblog.org/2010/11/why-nurses-should-reject-lame-and-demand-lean/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] Personally, this is where I stop because I feel like I’m approaching the “If it works, it’s Scrum, if it doesn’t, you did it wrong” perspective, but that’s not useful, so I’ll continue.&lt;/p&gt;
&lt;p&gt;[3] Using “application” as shorthand for “software stuff we build” including systems, services, apps, etc.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://manicprogrammer.com/cs/aggbug.aspx?PostID=16373" width="1" height="1"&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/BGh6J9hfrd4" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/hZ4cRsrh1Qc" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/BGh6J9hfrd4/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1296531407191"><id gr:original-id="http://manicprogrammer.com/cs/blogs/willeke/archive/2010/10/25/entitycommandshim-t-silverlight-mvvm-helper.aspx">tag:google.com,2005:reader/item/e01a59fc2f569c2f</id><category term="Uncategorized" /><title type="html">EntityCommandShim – Silverlight MVVM helper</title><published>2010-10-25T20:15:13Z</published><updated>2010-10-25T20:15:13Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/24afsnYO0fs/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;I received a question yesterday around the shim pattern that I used, and I thought I’d clean it up a bit and share it. Again, if you’re used to reading about agile and lean here, this isn’t one of those posts (in case the title didn’t make that clear).&lt;/p&gt;
&lt;h3&gt;Refresher&lt;/h3&gt;
&lt;p&gt;The situation I’m addressing is that I have an element in my XAML that uses an ItemsSource (e.g. ItemsControl, ListBox) and want to receive an event specific to one item. This post will assume that I’m working with an items template like this, which will be bound against a DTO or Entity that has a property descriptively named “Value” containing the content to display.&lt;/p&gt;
&lt;pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;DataTemplate&lt;/span&gt; &lt;span style="color:#ff0000"&gt;x&lt;/span&gt;:&lt;span style="color:#ff0000"&gt;Key&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;TemplateSelectionItem&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;   &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;HyperlinkButton&lt;/span&gt; &lt;span style="color:#ff0000"&gt;Content&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding Value}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;   &lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000"&gt;DataTemplate&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Now, whenever the user activates the hyperlink, the “Click” event will be raised. Without MVVM, I’d just add a handler in my code-behind that attaches to the click event and performs the logic. The testability and separation of concerns aspects of MVVM suggest this is a very bad idea. Instead, we should set up something that is called in response to the click. This leads to two options: put handling code on the bound entity, or put handling code in the ViewModel containing the ItemsControl. Since polluting the entity seems like a bad idea for a behavior local to a single view, let’s plan on putting it in in the ViewModel. And, since I like command objects for the flexibility they offer for a wide variety of scenarios, let’s target calling a Command instead of a method. Avoiding Prism-specific code, I’d write something like this:&lt;/p&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;DataTemplate&lt;/span&gt; &lt;span style="color:#ff0000"&gt;x&lt;/span&gt;:&lt;span style="color:#ff0000"&gt;Key&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;TemplateSelectionItem&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;HyperlinkButton&lt;/span&gt; &lt;span style="color:#ff0000"&gt;Content&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding Value}&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;Interaction.Triggers&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                    &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt; &lt;span style="color:#ff0000"&gt;EventName&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;Click&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;InvokeCommandAction&lt;/span&gt; &lt;span style="color:#ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding Command}&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000"&gt;CommandParameter&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding }&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                    &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;Interaction.Triggers&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000"&gt;HyperlinkButton&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000"&gt;DataTemplate&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Unfortunately, the “Command” binding will always fail, because the DataContext is currently set to my entity. Well, that’s fine, let’s just use a named source like this:&lt;/p&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;DataTemplate&lt;/span&gt; &lt;span style="color:#ff0000"&gt;x&lt;/span&gt;:&lt;span style="color:#ff0000"&gt;Key&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;TemplateSelectionItem&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;HyperlinkButton&lt;/span&gt; &lt;span style="color:#ff0000"&gt;Content&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding Value}&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;Interaction.Triggers&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                    &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt; &lt;span style="color:#ff0000"&gt;EventName&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;Click&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;InvokeCommandAction&lt;/span&gt; &lt;span style="color:#ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding DataContext.Command, ElementName=myListBox}&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000"&gt;CommandParameter&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding }&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                    &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;Interaction.Triggers&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000"&gt;HyperlinkButton&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000"&gt;DataTemplate&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Unfortunately, this is entirely too brilliant to keep working. It’ll work great as long as you don’t modify the ItemsPanel of your ListBox [1]. As soon as you do that, the binding will fail, and it took me far too long to figure out why the first time. Remembering back to my early programming education when I was taught things like “there’s no problem that can’t be solved with another level of indirection”, I decided to just put something in the middle that puts the Command where I need it. Thus the introduction of the shim, or as it’s now called, the EntityCommandShim. The comment prompted me to do some aggressive refactoring of what I was using, so thank you… here’s what it looks like now:&lt;/p&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; EntityCommandShim&amp;lt;TEntity&amp;gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    {&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; EntityCommandShim(TEntity sourceObject, DelegateCommand&amp;lt;&lt;span style="color:#0000ff"&gt;object&lt;/span&gt;&amp;gt; command)&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        {&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            Debug.Assert(command != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; sourceObject != &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;);&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.Command = command;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.Entity = sourceObject;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        }
&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; DelegateCommand&amp;lt;&lt;span style="color:#0000ff"&gt;object&lt;/span&gt;&amp;gt; Command { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;; }&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; TEntity Entity { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;; }&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    }&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;There’s not much to it. The Command and Entity references aren’t meant to change for the lifetime of the object, so no INotifyPropertyChanged implementation. The passed in Command is just a reference to one declared on the ViewModel, and doing the wrapping is quite simple with a line like this:&lt;/p&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;this&lt;/span&gt;.AvailableTemplates = service.AvailableTemplates.Select(item =&amp;gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; EntityCommandShim&amp;lt;FilterData&amp;gt;(item, TemplateItemSelectedCommand)).ToObservableCollection();&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Once this is done, I’m all set. The ItemsTemplate becomes: [2]&lt;/p&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;DataTemplate&lt;/span&gt; &lt;span style="color:#ff0000"&gt;x&lt;/span&gt;:&lt;span style="color:#ff0000"&gt;Key&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;TemplateSelectionItem&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;HyperlinkButton&lt;/span&gt; &lt;span style="color:#ff0000"&gt;Content&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding Entity.Value}&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;Interaction.Triggers&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                    &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt; &lt;span style="color:#ff0000"&gt;EventName&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;Click&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;InvokeCommandAction&lt;/span&gt; &lt;span style="color:#ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding Command}&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000"&gt;CommandParameter&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding Entity }&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                    &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;Interaction.Triggers&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000"&gt;HyperlinkButton&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000"&gt;DataTemplate&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;and the repeater can be as simple as this:&lt;/p&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;ItemsControl&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#ff0000"&gt;ItemTemplate&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{StaticResource TemplateSelectionItem}&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#ff0000"&gt;ItemsSource&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding AvailableTemplates}&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000"&gt;ItemsControl&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Or as complicated as this: [3]&lt;/p&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;input&lt;/span&gt;:&lt;span style="color:#800000"&gt;AutoCompleteBox&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#ff0000"&gt;FilterMode&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;Contains&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#ff0000"&gt;MinimumPopulateDelay&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;250&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#ff0000"&gt;ItemsSource&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding Clients}&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#ff0000"&gt;SelectedItem&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding SelectedClient, Mode=TwoWay}&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#ff0000"&gt;ItemTemplate&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{StaticResource ProviderSelectionItem}&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#ff0000"&gt;IsDropDownOpen&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding IsSelectionActive, Mode=TwoWay}&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#ff0000"&gt;ValueMemberPath&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;Entity.Value&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;Interaction.Triggers&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt; &lt;span style="color:#ff0000"&gt;EventName&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;SelectionChanged&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000"&gt;SourceName&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;autoCompleteBox&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;ic2&lt;/span&gt;:&lt;span style="color:#800000"&gt;InvokeCommandWithArgsAction&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding SelectionChangedCommand}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#ff0000"&gt;CommandParameter&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding RelativeSource={RelativeSource Self}, Path=InvokeParameter}&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt; &lt;span style="color:#ff0000"&gt;EventName&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;DropDownClosed&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000"&gt;SourceName&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;autoCompleteBox&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;ic2&lt;/span&gt;:&lt;span style="color:#800000"&gt;InvokeCommandWithArgsAction&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding SelectionConfirmedCommand}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#ff0000"&gt;CommandParameter&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding RelativeSource={RelativeSource Self}, Path=InvokeParameter}&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt; &lt;span style="color:#ff0000"&gt;EventName&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;DropDownOpened&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000"&gt;SourceName&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;autoCompleteBox&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;ic2&lt;/span&gt;:&lt;span style="color:#800000"&gt;InvokeCommandWithArgsAction&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding BeginSelectionCommand}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#ff0000"&gt;CommandParameter&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding RelativeSource={RelativeSource Self}, Path=InvokeParameter}&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;                &lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;Interaction.Triggers&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;input&lt;/span&gt;:&lt;span style="color:#800000"&gt;AutoCompleteBox&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;[1] I haven’t tried this with ItemsControl, and I don’t know where this issue comes from… any thoughts? I also haven’t tried this in SL4, maybe it’s fixed? Will check that out soon, and if it works, all of this can be removed, making it a true “shim” in the sense that it goes away when the floor’s fixed.&lt;/p&gt;
&lt;p&gt;[2] When I need to synchronize against SelectedItem in a list box, I often use CommandParameter={Binding} so I get the instance of the shim to reassign back to a property that’s Mode=TwoWay bound against SelectedItem.&lt;/p&gt;
&lt;p&gt;[3] InvokeCommandWithArgsAction is adapted from &lt;a title="http://weblogs.asp.net/alexeyzakharov/archive/2010/03/24/silverlight-commands-hacks-passing-eventargs-as-commandparameter-to-delegatecommand-triggered-by-eventtrigger.aspx" href="http://weblogs.asp.net/alexeyzakharov/archive/2010/03/24/silverlight-commands-hacks-passing-eventargs-as-commandparameter-to-delegatecommand-triggered-by-eventtrigger.aspx"&gt;http://weblogs.asp.net/alexeyzakharov/archive/2010/03/24/silverlight-commands-hacks-passing-eventargs-as-commandparameter-to-delegatecommand-triggered-by-eventtrigger.aspx&lt;/a&gt; and is a way of passing the arguments of an event as the CommandParameter. Check it out!&lt;/p&gt;
&lt;p&gt;&lt;img src="http://manicprogrammer.com/cs/aggbug.aspx?PostID=15867" width="1" height="1"&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/6vfd1tN7fbA" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/24afsnYO0fs" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/6vfd1tN7fbA/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1296531407191"><id gr:original-id="http://manicprogrammer.com/cs/blogs/willeke/archive/2010/10/24/how-does-google-know-this-stuff.aspx">tag:google.com,2005:reader/item/0a8f72e096cea5c4</id><category term="Uncategorized" /><title type="html">How does Google know this stuff?</title><published>2010-10-25T00:21:43Z</published><updated>2010-10-25T00:21:43Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/i0t44n3nBDE/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;p&gt;I get this – it’s a satellite picture of my condo building in Indy&lt;/p&gt;
&lt;p&gt;&lt;a href="http://kanbanforsoftwaredevelopment.com/HowdoesGoogleknowthisstuff_97F7/image.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://kanbanforsoftwaredevelopment.com/HowdoesGoogleknowthisstuff_97F7/image_thumb.png" width="244" height="192"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;On the other hand, how do they know where the individual units are inside? (Oh, and they’re RIGHT).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://kanbanforsoftwaredevelopment.com/HowdoesGoogleknowthisstuff_97F7/image_3.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://kanbanforsoftwaredevelopment.com/HowdoesGoogleknowthisstuff_97F7/image_thumb_3.png" width="244" height="148"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;And it’s done for the apartments nearby…&lt;/p&gt;
&lt;p&gt;&lt;a href="http://kanbanforsoftwaredevelopment.com/HowdoesGoogleknowthisstuff_97F7/image_4.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://kanbanforsoftwaredevelopment.com/HowdoesGoogleknowthisstuff_97F7/image_thumb_4.png" width="244" height="207"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;What feed is this from?&lt;/p&gt;
&lt;p&gt;&lt;img src="http://manicprogrammer.com/cs/aggbug.aspx?PostID=15846" width="1" height="1"&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/DxO26FokF4A" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/i0t44n3nBDE" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/DxO26FokF4A/</feedburner:origLink></entry><entry gr:crawl-timestamp-msec="1296531407191"><id gr:original-id="http://manicprogrammer.com/cs/blogs/willeke/archive/2010/10/24/silverlight-autocompletebox-and-mvvm.aspx">tag:google.com,2005:reader/item/db1b0f50732dc876</id><category term="Uncategorized" /><title type="html">Silverlight AutoCompleteBox and MVVM</title><published>2010-10-25T00:07:19Z</published><updated>2010-10-25T00:07:19Z</updated><link rel="alternate" href="http://feedproxy.google.com/~r/indyndabloggers/~3/njhQBKACCeQ/" type="text/html" /><content xml:base="http://ericwilleke.com/" type="html">&lt;h3&gt;First, a warning&lt;/h3&gt;
&lt;p&gt;This is not an introduction to the AutoCompleteBox. If you’re looking for a basic overview of the there’s nothing better than Jeff Wilcox’s intro at &lt;a href="http://www.jeff.wilcox.name/2008/11/autocompletebox-missing-guide/"&gt;http://www.jeff.wilcox.name/2008/11/autocompletebox-missing-guide/&lt;/a&gt;. Read that, then come back. It’s where I learned by example.&lt;/p&gt;
&lt;p&gt;There’s no direct anchor, but about half way down the page you’ll find a section titled “Building a custom search filter” and I’ll be picking up from there. His advice is “Here’s a sample item filter, set in the Loaded event of my page”, which is the first indicator that this isn’t the way to go if you’re doing MVVM… what follows is a way around that.&lt;/p&gt;
&lt;h3&gt;Next, the backstory&lt;/h3&gt;
&lt;p&gt;One pattern I’ve adopted in Silverlight development with MVVM is to introduce a helper object when I’m binding to a ListView or ItemsControl’s ItemsSource property. I call this object a “Shim” because it a slightly hackish way of solving what would otherwise be a much bigger problem creating a lot of rebuilding needs. Essentially, the Shim becomes the new DataContext that sits behind each bound item, becoming a mini-ViewModel that matches the mini-View defined by the DataTemplate/ItemTemplate. My typical need is that I need to accomplish two goals: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Bind to the data in a DTO or Domain Object in some interesting way &lt;/li&gt;
&lt;li&gt;React to a user’s operation against that item in some way specific to the data instance. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Unfortunately, markup like this doesn’t work in the ItemTemplate because the DataContext is now set to your specific DTO instance rather than to the original ViewModel instance.&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;HyperlinkButton&lt;/span&gt; &lt;span style="color:#ff0000"&gt;Content&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding Value}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;             &lt;span style="color:#ff0000"&gt;command&lt;/span&gt;:&lt;span style="color:#ff0000"&gt;Click&lt;/span&gt;.&lt;span style="color:#ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding ItemSelectedCommand}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;             &lt;span style="color:#ff0000"&gt;command&lt;/span&gt;:&lt;span style="color:#ff0000"&gt;Click&lt;/span&gt;.&lt;span style="color:#ff0000"&gt;CommandParameter&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding}&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;Instead, I introduce the Shim with an assignment something like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;this.Clients = insurer.Clients.Select(client =&amp;gt;&lt;br&gt;
    &lt;br&gt;    new ClientSelectedShim(client, SelectionChangedCommand)).ToObservableCollection();&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and then bind as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;HyperlinkButton&lt;/span&gt; &lt;span style="color:#ff0000"&gt;Content&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding Value}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;             &lt;span style="color:#ff0000"&gt;command&lt;/span&gt;:&lt;span style="color:#ff0000"&gt;Click&lt;/span&gt;.&lt;span style="color:#ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding ItemSelectedCommand}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;             &lt;span style="color:#ff0000"&gt;command&lt;/span&gt;:&lt;span style="color:#ff0000"&gt;Click&lt;/span&gt;.&lt;span style="color:#ff0000"&gt;CommandParameter&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding OriginalData}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;             &lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Shim instance simply exposes the provided DelegateCommand as a property, along with the original DTO and often an intended display value. (Thus, I bind to “Value” instead of “OriginalData.Value”). &lt;/p&gt;
&lt;p&gt;Overall, this feels like the cleanest of several different approaches I’ve tried to get around this binding issue in Silverlight. [1] I tend to do this using the Prism library, but it’s also applicable to other simple MVVM approaches. For example, the same would apply with using an EventTrigger and InvokeCommandAction to activate the command as such:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;Interaction.Triggers&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt; &lt;span style="color:#ff0000"&gt;EventName&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;Click&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;InvokeCommandAction&lt;/span&gt; &lt;span style="color:#ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding ItemSelectedCommand}&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;EventTrigger&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#c71585"&gt;i&lt;/span&gt;:&lt;span style="color:#800000"&gt;Interaction.Triggers&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Finally, the Point&lt;/h3&gt;
&lt;p&gt;All this rambling is a lead up to the challenge I hit today: I added a Shim into the list of items used to populate an AutoCompleteBox, because I needed to respond to the user with some item-specific behaviors in the popup that contains the matching values. As soon as I added the Shim, I couldn’t use the simple FilterMode=”Contains”, because it was comparing against the type of the shim rather than the much simpler string I was giving it before. Because I suddenly had a Shim involved and couldn’t dodge the complexity of having a DTO by just yielding the display value any longer, I was forced to use FilterMode=”Custom”. &lt;font color="#ff0000"&gt;{EDIT [3]}&lt;/font&gt; Problem is, MVVM strongly discourages me from writing code anywhere that looks like Jeff’s sample:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;MyAutoCompleteControl.ItemFilter = (txt, i) =&amp;gt; Stock.IsAutoCompleteSuggestion(txt, i);&lt;/pre&gt;
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;The good news is that binding is incredibly powerful, so here’s what I can do instead:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#c71585"&gt;input&lt;/span&gt;:&lt;span style="color:#800000"&gt;AutoCompleteBox&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;   &lt;span style="color:#ff0000"&gt;FilterMode&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;Custom&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;   &lt;span style="color:#ff0000"&gt;MinimumPopulateDelay&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;250&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;   &lt;span style="color:#ff0000"&gt;ItemsSource&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding Clients}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;   &lt;span style="color:#ff0000"&gt;SelectedItem&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding SelectedClient}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;   &lt;span style="color:#ff0000"&gt;ItemTemplate&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{StaticResource ClientSelectionItem}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;   &lt;span style="color:#ff0000"&gt;ItemFilter&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding ShimFilter}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;!—In Resources –&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;DataTemplate&lt;/span&gt; &lt;span style="color:#ff0000"&gt;x&lt;/span&gt;:&lt;span style="color:#ff0000"&gt;Key&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;ClientSelectionItem&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;  &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;   &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;StackPanel&lt;/span&gt; &lt;span style="color:#ff0000"&gt;Orientation&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;Horizontal&amp;quot;&lt;/span&gt; &lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;      &lt;span style="color:#0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000"&gt;HyperlinkButton&lt;/span&gt; &lt;span style="color:#ff0000"&gt;Content&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding Value}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;         &lt;span style="color:#ff0000"&gt;command&lt;/span&gt;:&lt;span style="color:#ff0000"&gt;Click&lt;/span&gt;.&lt;span style="color:#ff0000"&gt;Command&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding ItemSelectedCommand}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;         &lt;span style="color:#ff0000"&gt;command&lt;/span&gt;:&lt;span style="color:#ff0000"&gt;Click&lt;/span&gt;.&lt;span style="color:#ff0000"&gt;CommandParameter&lt;/span&gt;=&lt;span style="color:#0000ff"&gt;&amp;quot;{Binding OriginalData}&amp;quot;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;      &lt;span style="color:#0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000"&gt;DataTemplate&lt;/span&gt;&lt;span style="color:#0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;And, in the ViewModel: [2]&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;public&lt;/span&gt; AutoCompleteFilterPredicate&amp;lt;&lt;span style="color:#0000ff"&gt;object&lt;/span&gt;&amp;gt; ShimFilter &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;{ &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#0000ff"&gt;get&lt;/span&gt; &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    { &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; AutoCompleteFilterPredicate&amp;lt;&lt;span style="color:#0000ff"&gt;object&lt;/span&gt;&amp;gt;( &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;            (str, item) =&amp;gt; { &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; IsFilterMatch( str, item ); }); &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    } &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;}
&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; IsFilterMatch(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; valueToCheck, &lt;span style="color:#0000ff"&gt;object&lt;/span&gt; item) &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;{
&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;

    ClientSelectedShim shim = item &lt;span style="color:#0000ff"&gt;as&lt;/span&gt; ClientSelectedShim; 
&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (shim == &lt;span style="color:#0000ff"&gt;null&lt;/span&gt;) &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;        &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;; &lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;    &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; shim.Value.Contains(valueToCheck); &lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;}
&lt;/pre&gt;
&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;/pre&gt;
&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,&amp;#39;Courier New&amp;#39;,courier,monospace;font-size:12px"&gt;&lt;/pre&gt;
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;It wasn’t immediately obvious to me, but this definitely lets me put my comparison code in the ViewModel where it belongs while keeping the expression of the UI structure and behavior. Now I can wire the special effects!&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;[1] One of the most promising ways I’ve otherwise tried involved binding using ElementName to get “out of” the ItemTemplate and back to an element on at the parent level, typically the containing list itself. This will work as long as you don’t change the ItemsPanel to a non-default panel. Making that change hits some bug (feature?) in Silverlight I can’t properly characterize and causes lots of pain figuring out what happened. Be warned!&lt;/p&gt;
&lt;p&gt;[2] The property has to stay templated to the &amp;lt;object&amp;gt; type or there will be a binding expression error when the View is first bound against the ViewModel… covariance doesn’t apply here. More info &lt;a href="http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx"&gt;here&lt;/a&gt;. Second, it appears it must be an actual property, the binding failed when I tried to have a simple field initialized to the Predicate.&lt;/p&gt;
&lt;p&gt;[3] After figuring this all out, I did of course come across the incredibly useful ValueMemberPath property, which allowed me to revert to a simpler design for my specific case. However, if you are doing custom filters (especially if you’re checking against multiple properties, which I’ve done in the past), this technique will still be quite valuable.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://manicprogrammer.com/cs/aggbug.aspx?PostID=15845" width="1" height="1"&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/RediscoveringTheObvious/~4/CCselLtnfoQ" height="1" width="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/indyndabloggers/~4/njhQBKACCeQ" height="1" width="1"/&gt;</content><author><name>erwilleke</name></author><source gr:stream-id="feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx"><id>tag:google.com,2005:reader/feed/http://manicprogrammer.com/cs/blogs/willeke/rss.aspx</id><title type="html">Rediscovering the Obvious</title><link rel="alternate" href="http://ericwilleke.com" type="text/html" /></source><feedburner:origLink>http://feedproxy.google.com/~r/RediscoveringTheObvious/~3/CCselLtnfoQ/</feedburner:origLink></entry></feed>

