<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>IIrrelevant</title>
    <link>http://www.milkcarton.com/blog/</link>
    <description>Irrelevant musings about software development</description>
    <language>en-us</language>
    <copyright>Dan Morphis</copyright>
    <lastBuildDate>Sat, 04 Apr 2009 05:37:33 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.0.7226.0</generator>
    <managingEditor>blog@milkcarton.com</managingEditor>
    <webMaster>blog@milkcarton.com</webMaster>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/akcoder" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=bcd01da5-498e-410c-a687-acc721220457</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,bcd01da5-498e-410c-a687-acc721220457.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,bcd01da5-498e-410c-a687-acc721220457.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=bcd01da5-498e-410c-a687-acc721220457</wfw:commentRss>
      <slash:comments>3</slash:comments>
      
      <title>5 Minute Tutorial on Managed Extensibility Framework (MEF)</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,bcd01da5-498e-410c-a687-acc721220457.aspx</guid>
      <link>http://feedproxy.google.com/~r/akcoder/~3/CeYueW0Il40/5+Minute+Tutorial+On+Managed+Extensibility+Framework+MEF.aspx</link>
      <pubDate>Sat, 04 Apr 2009 05:37:33 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;h3&gt;Background&#xD;
&lt;/h3&gt;&#xD;
        &lt;p&gt;&#xD;
For a project I'm doing, I have a task model for the various pieces. In the beginning,&#xD;
I was manually creating a List&amp;lt;ITask&amp;gt;. As I kept adding tasks to run, I started&#xD;
thinking about hacking some code together to rifle through my assembly and pull back&#xD;
all the classes which implement ITask.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Then I remember hearing about Managed Extensibility Framework (MEF). I did some searching,&#xD;
found the &lt;a href="http://www.codeplex.com/MEF/" target="_blank"&gt;MEF home page&lt;/a&gt;,&#xD;
and even read the &lt;a href="http://mef.codeplex.com/Wiki/View.aspx?title=Overview&amp;amp;referringTitle=Home" target="_blank"&gt;MEF&#xD;
overview&lt;/a&gt;. But none of that told me what I really wanted to know, what's the fastest&#xD;
way to get started using MEF as a component loader?&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I did some more searching and found the &lt;a href="http://dnrtv.com/" target="_blank"&gt;dnrTV&lt;/a&gt; episode&#xD;
"&lt;a href="http://www.dnrtv.com/default.aspx?showNum=130" target="_blank"&gt;Glenn Block&#xD;
on MEF, the Managed Extensibility Framework&lt;/a&gt;" and after 20-30 minutes they finally&#xD;
got down to how to create a plugin for your app.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
But what I really wanted, and I bet a lot of others, is a quick start guide for creating&#xD;
a plugin.&#xD;
&lt;/p&gt;&#xD;
        &lt;h3&gt;Solution&#xD;
&lt;/h3&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://mef.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=22313" target="_blank"&gt;Download&#xD;
the latest version of MEF&lt;/a&gt;, as of this writing its Preview 4. Grab the System.ComponentModel.Composition.dll&#xD;
from the bin folder and stash it somewhere. Make a reference to said dll in your project.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
On your plugin class, add Export attribute:&#xD;
&lt;/p&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;[Export(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IPlugin))] &lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Foo&#xD;
: IPlugin { ... }&lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
In your plugin consumer, create a property to hold your plugins, and add the Import&#xD;
attribute:&#xD;
&lt;/p&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;[Import(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IPlugin))] &lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; IList&amp;lt;IPlugin&amp;gt;&#xD;
_myPlugins { get; set; }&lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
Now, tell MEF where to get the plugins at (line 2), and where you want MEF to fulfill&#xD;
any plugins (line 5):&#xD;
&lt;/p&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&#xD;
            &lt;p&gt;&#xD;
              &lt;span style="color: #0000ff"&gt;private&lt;/span&gt;&#xD;
              &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LoadPlugins()&#xD;
{ var catalog = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AssemblyCatalog(Assembly.GetExecutingAssembly());&#xD;
var container = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CompositionContainer(catalog);&#xD;
var batch = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CompositionBatch(); batch.AddPart(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);&#xD;
container.Compose(batch); } &#xD;
&lt;/p&gt;&#xD;
            &lt;p&gt;&#xD;
 &#xD;
&lt;/p&gt;&#xD;
          &lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
I put my call to the LoadPlugins method in the constructor.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Now, spin through your plugins and do the work:&#xD;
&lt;/p&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;Console.WriteLine(&lt;span style="color: #006080"&gt;"Found&#xD;
{0} plugins"&lt;/span&gt;, _myPlugins.Count); &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var&#xD;
plugin &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; _myPlugins) { Console.WriteLine(plugin.Name);&#xD;
}&lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
 &#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="/blog/content/binary/5_Minute_MEF_Tutorial.zip" target="_blank"&gt;Download&#xD;
the complete source&lt;/a&gt; to this (really, only about 10 extra lines to glue things&#xD;
together) and have fun!&#xD;
&lt;/p&gt;&#xD;
        &lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.milkcarton.com%2fblog%2f2009%2f04%2f04%2f5%2bMinute%2bTutorial%2bOn%2bManaged%2bExtensibility%2bFramework%2bMEF.aspx"&gt;&#xD;
          &lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.milkcarton.com%2fblog%2f2009%2f04%2f04%2f5%2bMinute%2bTutorial%2bOn%2bManaged%2bExtensibility%2bFramework%2bMEF.aspx" border="0" alt="kick it on DotNetKicks.com"&gt;&lt;/img&gt;&#xD;
        &lt;/a&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=bcd01da5-498e-410c-a687-acc721220457"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=CeYueW0Il40:q7DWaw-uwHI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=CeYueW0Il40:q7DWaw-uwHI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/akcoder/~4/CeYueW0Il40" height="1" width="1"/&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,bcd01da5-498e-410c-a687-acc721220457.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>HowTo</category>
      <category>MEF</category>
    <feedburner:origLink>http://www.milkcarton.com/blog/2009/04/04/5+Minute+Tutorial+On+Managed+Extensibility+Framework+MEF.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a</wfw:commentRss>
      
      <title>Does your Cruise Control.NET server Twitter?</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a.aspx</guid>
      <link>http://feedproxy.google.com/~r/akcoder/~3/c1LR20G-e7o/Does+Your+Cruise+ControlNET+Server+Twitter.aspx</link>
      <pubDate>Mon, 16 Mar 2009 04:59:22 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
A long time, and many many moons ago I took wrote some code to interface our build&#xD;
server with a &lt;a href="http://www.epowerswitch.com/uk/p-4g_guard.htm" target="_blank" rel="nofollow"&gt;network&#xD;
power switch&lt;/a&gt; we had laying around the office. We used this to turn on and off&#xD;
lava lamps to indicate the status of the build. Some might ask why we didn't use the&#xD;
X10 support that is already in CCNET, and the answer mostly is cost, and the fact&#xD;
that X10 wouldn't work in our environment.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
That was 2.5 years ago. Since then, our team has become more distributed. We have&#xD;
one guy working in Ann Arbor, MI, and occasionally have others telecommuting. So not&#xD;
everyone can see the status of the lamps. Also in the 2.5 years since that code was&#xD;
written, a little thing called &lt;a href="http://twitter.com/" target="_blank"&gt;Twitter&lt;/a&gt; has&#xD;
become very popular. I did some research, and found &lt;a href="http://techblog.tomfanning.eu/2008/03/twitter-task-for-nant-sms-notification.html" target="_blank"&gt;Tom&#xD;
Fannings nAnt Twitter task&lt;/a&gt; and briefly considered using it.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
But in the end, I just couldn't resist adding my own &lt;a href="http://www.codinghorror.com/blog/archives/000150.html" target="_blank"&gt;developer&#xD;
gold plating&lt;/a&gt; and thought it would be neat if we could also issue commands to the&#xD;
build server via tweets. So with that feature in mind, I had to write it myself.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
To start out with, I used &lt;a href="http://devblog.yedda.com/index.php/2007/05/16/twitter-c-library/" target="_blank"&gt;Yedda's&#xD;
C# Twitter library&lt;/a&gt;. The Yedda library is a pleasure to work with, it makes sending&#xD;
a tweet as simple as&#xD;
&lt;/p&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&#xD;
            &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Twitter().UpdateAsXML(_username,&#xD;
password, messsage);&lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
One thing the Yedda library didn't have, was the ability to query for your Twitter&#xD;
replies. A quick look through the source, and the &lt;a href="http://apiwiki.twitter.com/" target="_blank"&gt;Twitter&#xD;
API&lt;/a&gt; docs and I realized this would be trivial. The details of how I did it aren't&#xD;
important to this post, but if your curious, you can look at lines 567 - 627 of the&#xD;
Yedda source included with this post.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I'm not going to dive to much into how the whole project works, but here is a high&#xD;
level. The software runs as a Windows Service, leverages the CCTrayLib assembly for&#xD;
Cruise Control.NET to do all the heavy lifting. It polls the Cruise Control.NET server&#xD;
every 5 seconds, and fires events when things happen. The two events we want are the&#xD;
Polled and BuildOccurred events.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
These events allow us to intern kick off our own events based on the state of the&#xD;
build. Based on the state, we grab the appropriate actions to run as defined in the&#xD;
BuildActions.xml file. This maps a build state to a set of actions. In the case of&#xD;
a "Building" action, we send a Twitter, with a message template of "{PROJECT} is building",&#xD;
and turn ports 1 on, and 2 off on our ePower switch. Easy enough.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
But how do we take in commands? I pondered this for a minute than realized it would&#xD;
be trivial to leverage the Twitter replies API for this. But what about security,&#xD;
we can't have just anyone sending commands to our build server. This is where the&#xD;
Twitter friends API comes in handy. In order to issue commands to our build server,&#xD;
the account our build server uses has to have you as a friend, not just a follower.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The first action I implemented was the force build command. The idea for the grammar&#xD;
came from a &lt;a href="http://twitter.com/orand/status/1319154695" target="_blank"&gt;joke&#xD;
reply&lt;/a&gt;&lt;a href="http://twitter.com/orand" target="_blank"&gt;@orand&lt;/a&gt; sent our Twitter&#xD;
bot. After that, I thought it might be nice to be able to get the list of projects,&#xD;
get a projects status, and ask for help. So that leaves us with a total of 4 commands.&#xD;
&lt;/p&gt;&#xD;
        &lt;h3&gt;A small bunny trail&#xD;
&lt;/h3&gt;&#xD;
        &lt;p&gt;&#xD;
When I first wrote the command parser, it looked something like this:&#xD;
&lt;/p&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&#xD;
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (msg.StartsWith(&lt;span style="color: #006080"&gt;"force&#xD;
build "&lt;/span&gt;)) ProcessForceBuildCommand(msg, user); &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (msg.StartsWith(&lt;span style="color: #006080"&gt;"get&#xD;
projects"&lt;/span&gt;)) ProcessProjectListsCommand(msg, user); ...&lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
I thought about it for a while, and thought there had to be an easier way. We are&#xD;
using .NET 3.5 after all, with all its lamba, LINQ and new and improved delegate goodness.&#xD;
I did some research and came upon the Action&amp;lt;T&amp;gt; (and Func&amp;lt;T&amp;gt;) delegate&#xD;
type. And came up with this implementation for registering commands&#xD;
&lt;/p&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;var commands = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;,&#xD;
Action&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;&amp;gt;&#xD;
{ {&lt;span style="color: #006080"&gt;"force build "&lt;/span&gt;, ProcessForceBuildCommand},&#xD;
{&lt;span style="color: #006080"&gt;"get projects"&lt;/span&gt;, ProcessProjectListsCommand},&#xD;
{&lt;span style="color: #006080"&gt;"get project status "&lt;/span&gt;, ProcessProjectStatusCommand},&#xD;
{&lt;span style="color: #006080"&gt;"help"&lt;/span&gt;, ProcessHelpCommand} };&lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
Once we have all the commands registered, we can use some lambda and LINQ magic to&#xD;
act upon the commands issued&#xD;
&lt;/p&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;var key = _commands.Keys.Where(msg.StartsWith).First();&#xD;
&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(key))&#xD;
_commands[key].Invoke(msg, user); &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; SendTweet(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;"@{0}&#xD;
I'm sorry, I don't understand you. Maybe you should ask for help"&lt;/span&gt;, user)); &lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;h3&gt;Get to the point, I want to see the source code&#xD;
&lt;/h3&gt;&#xD;
        &lt;p&gt;&#xD;
The code overall is fairly well structured (if I do say so myself), although there&#xD;
is one area where I did violate the separation of concerns rule, the TwitterManager&#xD;
class knows more about Cruise Control.NET than it should. But, given that this is&#xD;
a very simple internal project, and not for public consumption, I'm mostly OK with&#xD;
that :)&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I've included the source to our entire build monitor, I hope you find it useful. &#xD;
We are using a very old version (1.1) of Cruise Control.NET in our environment. If&#xD;
your using a more recent version, you will probably need to swap out the Cruise Control&#xD;
CCTrayLib and Remote assemblies for something more recent, and invert some of the&#xD;
commented out code in the SetupCruiseControl method of BuildServerMonitor.cs&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If you have any questions, or find/fix any bugs, please feel free to leave a comment,&#xD;
or send me a tweet, my username on Twitter is &lt;a href="http://twitter.com/akcoder" target="_blank"&gt;akcoder&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
          &lt;a href="http://files.milkcarton.com/Afhcan.BuildMonitor.zip" target="_blank"&gt;Download&#xD;
the Afhcan.BuildMonitor&lt;/a&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=c1LR20G-e7o:m8srHJuwavE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=c1LR20G-e7o:m8srHJuwavE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/akcoder/~4/c1LR20G-e7o" height="1" width="1"/&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>HowTo</category>
    <feedburner:origLink>http://www.milkcarton.com/blog/2009/03/16/Does+Your+Cruise+ControlNET+Server+Twitter.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=8396d43e-d21d-44fd-b279-b9e8940a3304</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,8396d43e-d21d-44fd-b279-b9e8940a3304.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,8396d43e-d21d-44fd-b279-b9e8940a3304.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=8396d43e-d21d-44fd-b279-b9e8940a3304</wfw:commentRss>
      
      <title>Building a log4net appender</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,8396d43e-d21d-44fd-b279-b9e8940a3304.aspx</guid>
      <link>http://feedproxy.google.com/~r/akcoder/~3/1bHESpUuiJ0/Building+A+Log4net+Appender.aspx</link>
      <pubDate>Sat, 21 Feb 2009 07:18:15 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
One of our applications has a Windows service in it. To make debugging and running&#xD;
this service easy,we have a winform in the service which can be activated by passing&#xD;
a command line switch. Simple enough. Our service does all its logging with log4net.&#xD;
I wanted to be able to put the output of the logging on our development form, but&#xD;
how?&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
After looking at various things, I realized what I needed to do was create a log4net&#xD;
appender, and add the appender to the log4net logger and at regular intervals, grab&#xD;
the contents of the logger.&#xD;
&lt;/p&gt;&#xD;
        &lt;h3&gt;Solution&#xD;
&lt;/h3&gt;&#xD;
        &lt;p&gt;&#xD;
I created the below appender which uses a StringBuilder as the backing store. It takes&#xD;
in one bool param in the contructor which allows you to specify if you want the log&#xD;
to be built up in reverse.  This is useful if you want to display the most recent&#xD;
event at the top.&#xD;
&lt;/p&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&#xD;
            &lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&#xD;
            &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; StringBuilderAppender&#xD;
: log4net.Appender.AppenderSkeleton { &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; System.Text.StringBuilder&#xD;
_builder = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; System.Text.StringBuilder(); &lt;span style="color: #0000ff"&gt;private&lt;/span&gt;&lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; _invert; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; StringBuilderAppender(&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; invert)&#xD;
{ _invert = invert; } &lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Text&#xD;
{ get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _builder.ToString(); } } &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; Append(log4net.Core.LoggingEvent&#xD;
loggingEvent) { var msg = loggingEvent.RenderedMessage; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (_invert)&#xD;
_builder = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; System.Text.StringBuilder().AppendLine(msg).Append(_builder); &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; _builder.AppendLine(msg);&#xD;
} }&lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
Now we need to add our new appender to the logger. I found this helper method someone&#xD;
wrote.&#xD;
&lt;/p&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&#xD;
            &lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&#xD;
            &lt;span style="color: #0000ff"&gt;static&lt;/span&gt;&#xD;
            &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddAppender(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; loggerName,&#xD;
IAppender appender) { log4net.ILog log = log4net.LogManager.GetLogger(loggerName);&#xD;
log4net.Repository.Hierarchy.Logger l = (log4net.Repository.Hierarchy.Logger)log.Logger;&#xD;
l.AddAppender(appender); }&lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;p&gt;&#xD;
Finally, lets put it all together:&#xD;
&lt;/p&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;StringBuilderAppender appender = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StringBuilderAppender(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&#xD;
AddAppender(&lt;span style="color: #006080"&gt;"MyLogger"&lt;/span&gt;, appender); &lt;span style="color: #0000ff"&gt;while&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)&#xD;
{ System.Threading.Thread.Sleep(5000); someControl.Text = appender.Text; }&lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=8396d43e-d21d-44fd-b279-b9e8940a3304"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=1bHESpUuiJ0:yGx3C3aF8cM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=1bHESpUuiJ0:yGx3C3aF8cM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/akcoder/~4/1bHESpUuiJ0" height="1" width="1"/&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,8396d43e-d21d-44fd-b279-b9e8940a3304.aspx</comments>
      <category>.NET</category>
      <category>HowTo</category>
      <category>Logging</category>
    <feedburner:origLink>http://www.milkcarton.com/blog/2009/02/21/Building+A+Log4net+Appender.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=dc6fd10c-b67e-4771-a7dc-9ee2444d02e5</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,dc6fd10c-b67e-4771-a7dc-9ee2444d02e5.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,dc6fd10c-b67e-4771-a7dc-9ee2444d02e5.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=dc6fd10c-b67e-4771-a7dc-9ee2444d02e5</wfw:commentRss>
      <slash:comments>4</slash:comments>
      
      <title>A better, easier way to make sure you've globalized everything</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,dc6fd10c-b67e-4771-a7dc-9ee2444d02e5.aspx</guid>
      <link>http://feedproxy.google.com/~r/akcoder/~3/wOWuyD5cUI8/A+Better+Easier+Way+To+Make+Sure+Youve+Globalized+Everything.aspx</link>
      <pubDate>Tue, 10 Feb 2009 23:11:48 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
At our organization, we have to globalize our software. Making sure you've gotten&#xD;
all the strings globalized can be a real pain. You have to create a new language resource&#xD;
that looks nothing like your native language, then set the Thread.CurrentThread.CurrentUICulture&#xD;
to the culture of the new language resource you created.  Such a pain.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
While pondering that this afternoon, I came upon something better. The .NET CultureManger&#xD;
looks for the most specific resource file, then works its way back to the least specific.&#xD;
For example, given the following resource files:&#xD;
&lt;/p&gt;&#xD;
        &lt;ul&gt;&#xD;
          &lt;li&gt;&#xD;
i18n &#xD;
&lt;/li&gt;&#xD;
          &lt;li&gt;&#xD;
i18n.en &#xD;
&lt;/li&gt;&#xD;
          &lt;li&gt;&#xD;
i18n.en-US&lt;/li&gt;&#xD;
        &lt;/ul&gt;&#xD;
        &lt;p&gt;&#xD;
If your current culture was en-GB, the CultureManger would use the resource file for&#xD;
i18n.en, since there is no i18n.en-GB. But, if your current culture was da-DK, it&#xD;
would use i18n.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
In our software, we have i18n, and i18n.da-DK resource files, plus i18n.fr-FR which&#xD;
is a special, internal resource file. What's so special about the fr-FR resource file&#xD;
you ask? The fr-FR resource file is really the i18n resource file which as been transformed&#xD;
to replace all the localized text with dashes.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Why did we do this? Because with all the English text replaced with dashes, it makes&#xD;
it very easy to see which text in the application hasn't been globalized. The down&#xD;
side to this, is we have to change the CurrentUICulture (and CurrentCulture) to fr-FR&#xD;
in order to test this.&#xD;
&lt;/p&gt;&#xD;
        &lt;h3&gt;Solution&#xD;
&lt;/h3&gt;&#xD;
        &lt;p&gt;&#xD;
The solution is actually quite simple, rename the fr-FR resource file to i18n.en-US&#xD;
(or what ever the ISO code for your culture is).  Now when your testing, the&#xD;
CultureManager will pick the most specific resource file, and use that. But, don't&#xD;
forget to remove en-US folder from the final build folder before you deploy your application,&#xD;
lest users get your debug language resource.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.milkcarton.com%2fblog%2f2009%2f02%2f10%2fA%2bBetter%2bEasier%2bWay%2bTo%2bMake%2bSure%2bYouve%2bGlobalized%2bEverything.aspx"&gt;&#xD;
          &lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.milkcarton.com%2fblog%2f2009%2f02%2f10%2fA%2bBetter%2bEasier%2bWay%2bTo%2bMake%2bSure%2bYouve%2bGlobalized%2bEverything.aspx" border="0" alt="kick it on DotNetKicks.com"&gt;&lt;/img&gt;&#xD;
        &lt;/a&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=dc6fd10c-b67e-4771-a7dc-9ee2444d02e5"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=wOWuyD5cUI8:CwVTYn4vnRQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=wOWuyD5cUI8:CwVTYn4vnRQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/akcoder/~4/wOWuyD5cUI8" height="1" width="1"/&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,dc6fd10c-b67e-4771-a7dc-9ee2444d02e5.aspx</comments>
      <category>.NET</category>
      <category>Globalization</category>
      <category>HowTo</category>
    <feedburner:origLink>http://www.milkcarton.com/blog/2009/02/10/A+Better+Easier+Way+To+Make+Sure+Youve+Globalized+Everything.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=6c15c80c-974b-4f73-b3c5-a8406f582566</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,6c15c80c-974b-4f73-b3c5-a8406f582566.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,6c15c80c-974b-4f73-b3c5-a8406f582566.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=6c15c80c-974b-4f73-b3c5-a8406f582566</wfw:commentRss>
      
      <title>Update on Mac blogging software</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,6c15c80c-974b-4f73-b3c5-a8406f582566.aspx</guid>
      <link>http://feedproxy.google.com/~r/akcoder/~3/VFClG9MsNqo/Update+On+Mac+Blogging+Software.aspx</link>
      <pubDate>Sun, 08 Feb 2009 21:11:01 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p style="clear: both"&gt;&#xD;
A few weeks back, &lt;a href="http://www.milkcarton.com/blog/2009/01/22/Mac+Blogging+Software.aspx" target="_blank"&gt;I&#xD;
wrote about Mac blogging software&lt;/a&gt;. Since then, I've removed Ecto. It was way to&#xD;
clunky, and not a joy to use at all. I've downloaded &lt;a href="http://www.drinkbrainjuice.com/blogo" target="_blank"&gt;Blogo&lt;/a&gt; and&#xD;
figured I'd give it a whirl. So far, its pretty good. But none of these are like Windows&#xD;
Live Writer, which is really what I want. Oh well, can't have it all unless you write&#xD;
it yourself.&#xD;
&lt;/p&gt;&#xD;
        &lt;br class="final-break" style="clear: both"&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=6c15c80c-974b-4f73-b3c5-a8406f582566"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=VFClG9MsNqo:FQn6T0LRN4s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=VFClG9MsNqo:FQn6T0LRN4s:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/akcoder/~4/VFClG9MsNqo" height="1" width="1"/&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,6c15c80c-974b-4f73-b3c5-a8406f582566.aspx</comments>
      <category>Mac OS X</category>
      <category>Non-Tech</category>
    <feedburner:origLink>http://www.milkcarton.com/blog/2009/02/08/Update+On+Mac+Blogging+Software.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=74895ca2-de31-4c92-aa9c-d5da390a7700</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,74895ca2-de31-4c92-aa9c-d5da390a7700.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,74895ca2-de31-4c92-aa9c-d5da390a7700.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=74895ca2-de31-4c92-aa9c-d5da390a7700</wfw:commentRss>
      
      <title>Have you re-indexed your database lately?</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,74895ca2-de31-4c92-aa9c-d5da390a7700.aspx</guid>
      <link>http://feedproxy.google.com/~r/akcoder/~3/Ea9Regg_eLM/Have+You+Reindexed+Your+Database+Lately.aspx</link>
      <pubDate>Thu, 29 Jan 2009 19:04:54 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
As our production database gets more and more data in it, we noticed that things were&#xD;
slowing down. I ran SQL Profiler trying to figure out if we needed to ad more indexes,&#xD;
better arrange the data, or anything we could do to improve the performance. After&#xD;
about an hour of running queries, creating indexes, profiling, and looking at execution&#xD;
plans; I had gotten barely anything for performance gains.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I then decided to take a different track and wondered if our indexes needed to be&#xD;
rebuilt.  A quick Google later, and I came across an article on &lt;a title="Tips for Rebuilding Indexes" href="http://www.sql-server-performance.com/tips/rebuilding_indexes_p1.aspx" target="_blank"&gt;Tips&#xD;
for Rebuilding Indexes&lt;/a&gt; over at &lt;a href="http://www.sql-server-performance.com/" target="_blank"&gt;SQL&#xD;
Server Performance&lt;/a&gt;.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
The gist of the article is your indexes get fragmented and need to be rebuilt. I ran&#xD;
the script present in the article and noticed a substantial improvement in performance. &#xD;
I failed to capture metrics to quantify the performance improvements, but the users&#xD;
definitely noticed.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Without further ado, here is the script from the article:&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
If your using MS SQL Server 2000:&#xD;
&lt;/p&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&#xD;
            &lt;span style="color: #0000ff"&gt;USE&lt;/span&gt; DatabaseName&#xD;
--Enter the name &lt;span style="color: #0000ff"&gt;of&lt;/span&gt; the &lt;span style="color: #0000ff"&gt;database&lt;/span&gt; you&#xD;
want &lt;span style="color: #0000ff"&gt;to&lt;/span&gt; reindex &lt;span style="color: #0000ff"&gt;DECLARE&lt;/span&gt; @TableName &lt;span style="color: #0000ff"&gt;varchar&lt;/span&gt;(255) &lt;span style="color: #0000ff"&gt;DECLARE&lt;/span&gt; TableCursor &lt;span style="color: #0000ff"&gt;CURSOR&lt;/span&gt;&lt;span style="color: #0000ff"&gt;FOR&lt;/span&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; table_name &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; information_schema.tables &lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; table_type&#xD;
= &lt;span style="color: #006080"&gt;'base table'&lt;/span&gt;&lt;span style="color: #0000ff"&gt;OPEN&lt;/span&gt; TableCursor &lt;span style="color: #0000ff"&gt;FETCH&lt;/span&gt;&lt;span style="color: #0000ff"&gt;NEXT&lt;/span&gt;&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; TableCursor &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; @TableName &lt;span style="color: #0000ff"&gt;WHILE&lt;/span&gt;&lt;span style="color: #cc6633"&gt;@@FETCH_STATUS&lt;/span&gt; =&#xD;
0 &lt;span style="color: #0000ff"&gt;BEGIN&lt;/span&gt;&lt;span style="color: #0000ff"&gt;DBCC&lt;/span&gt; DBREINDEX(@TableName,&lt;span style="color: #006080"&gt;'&#xD;
'&lt;/span&gt;,90) &lt;span style="color: #0000ff"&gt;FETCH&lt;/span&gt;&lt;span style="color: #0000ff"&gt;NEXT&lt;/span&gt;&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; TableCursor &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; @TableName &lt;span style="color: #0000ff"&gt;END&lt;/span&gt;&lt;span style="color: #0000ff"&gt;CLOSE&lt;/span&gt; TableCursor &lt;span style="color: #0000ff"&gt;DEALLOCATE&lt;/span&gt; TableCursor&lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;div&gt; &#xD;
&lt;/div&gt;&#xD;
        &lt;div&gt;If your using MS SQL Server 2005:&#xD;
&lt;/div&gt;&#xD;
        &lt;div&gt;&#xD;
          &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&#xD;
            &lt;span style="color: #0000ff"&gt;USE&lt;/span&gt; DatabaseName&#xD;
--Enter the name &lt;span style="color: #0000ff"&gt;of&lt;/span&gt; the &lt;span style="color: #0000ff"&gt;database&lt;/span&gt; you&#xD;
want &lt;span style="color: #0000ff"&gt;to&lt;/span&gt; reindex &lt;span style="color: #0000ff"&gt;DECLARE&lt;/span&gt; @TableName &lt;span style="color: #0000ff"&gt;varchar&lt;/span&gt;(255) &lt;span style="color: #0000ff"&gt;DECLARE&lt;/span&gt; TableCursor &lt;span style="color: #0000ff"&gt;CURSOR&lt;/span&gt;&lt;span style="color: #0000ff"&gt;FOR&lt;/span&gt;&lt;span style="color: #0000ff"&gt;SELECT&lt;/span&gt; table_name &lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; information_schema.tables &lt;span style="color: #0000ff"&gt;WHERE&lt;/span&gt; table_type&#xD;
= &lt;span style="color: #006080"&gt;'base table'&lt;/span&gt;&lt;span style="color: #0000ff"&gt;OPEN&lt;/span&gt; TableCursor &lt;span style="color: #0000ff"&gt;FETCH&lt;/span&gt;&lt;span style="color: #0000ff"&gt;NEXT&lt;/span&gt;&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; TableCursor &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; @TableName &lt;span style="color: #0000ff"&gt;WHILE&lt;/span&gt;&lt;span style="color: #cc6633"&gt;@@FETCH_STATUS&lt;/span&gt; =&#xD;
0 &lt;span style="color: #0000ff"&gt;BEGIN&lt;/span&gt;&lt;span style="color: #0000ff"&gt;ALTER&lt;/span&gt;&lt;span style="color: #0000ff"&gt;INDEX&lt;/span&gt;&lt;span style="color: #0000ff"&gt;ON&lt;/span&gt;&lt;span style="color: #0000ff"&gt;schema&lt;/span&gt;.&lt;span style="color: #0000ff"&gt;table&lt;/span&gt; REBUILD/REORGANIZE &lt;span style="color: #0000ff"&gt;FETCH&lt;/span&gt;&lt;span style="color: #0000ff"&gt;NEXT&lt;/span&gt;&lt;span style="color: #0000ff"&gt;FROM&lt;/span&gt; TableCursor &lt;span style="color: #0000ff"&gt;INTO&lt;/span&gt; @TableName &lt;span style="color: #0000ff"&gt;END&lt;/span&gt;&lt;span style="color: #0000ff"&gt;CLOSE&lt;/span&gt; TableCursor &lt;span style="color: #0000ff"&gt;DEALLOCATE&lt;/span&gt; TableCursor&lt;/pre&gt;&#xD;
        &lt;/div&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=74895ca2-de31-4c92-aa9c-d5da390a7700"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=Ea9Regg_eLM:QuJ5ZJ7Tqdc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=Ea9Regg_eLM:QuJ5ZJ7Tqdc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/akcoder/~4/Ea9Regg_eLM" height="1" width="1"/&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,74895ca2-de31-4c92-aa9c-d5da390a7700.aspx</comments>
      <category>HowTo</category>
      <category>SQL</category>
    <feedburner:origLink>http://www.milkcarton.com/blog/2009/01/29/Have+You+Reindexed+Your+Database+Lately.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=11135e07-6332-4c64-a883-61810d48b80c</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,11135e07-6332-4c64-a883-61810d48b80c.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,11135e07-6332-4c64-a883-61810d48b80c.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=11135e07-6332-4c64-a883-61810d48b80c</wfw:commentRss>
      
      <title>How to make the OS X Volumes folder visible</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,11135e07-6332-4c64-a883-61810d48b80c.aspx</guid>
      <link>http://feedproxy.google.com/~r/akcoder/~3/sSjevRXLcPc/How+To+Make+The+OS+X+Volumes+Folder+Visible.aspx</link>
      <pubDate>Sun, 25 Jan 2009 05:59:00 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;h3&gt;Background&#xD;
&lt;/h3&gt;&#xD;
        &lt;p&gt;&#xD;
Call me a control freak, but I like to see all the shared volumes on my Mac. I could&#xD;
open Terminal and cd to the Volumes folder, or I could use Finder and Go -&amp;gt; Go&#xD;
to Folder to see everything that OS X has mounted in my Volumes folder. But thats&#xD;
kind of a pain.&#xD;
&lt;/p&gt;&#xD;
        &lt;h3&gt;Solution&#xD;
&lt;/h3&gt;&#xD;
        &lt;p&gt;&#xD;
After a little bit of digging around, I found out about SetFile. SetFile is a command&#xD;
line utility that allows you to set the file attributes on files in an HFS+ directory.&#xD;
After figuring out the parameters for it, I came up with this little ditty to make&#xD;
the Volumes folder show up under "Macintosh HD." Run this in Terminal:&#xD;
&lt;/p&gt;&#xD;
        &lt;blockquote&gt;sudo SetFile -a v /Volumes&lt;/blockquote&gt;&#xD;
        &lt;p&gt;&#xD;
With this command, you are setting the visibility attribute on the Volumes folder&#xD;
to visible. To reverse the process, change -a v to -a &lt;strong&gt;V&lt;/strong&gt;. Now open&#xD;
up "Macintosh HD" and you should now see all the volumes mounted on your Mac!&#xD;
&lt;/p&gt;&#xD;
        &lt;img src="http://www.milkcarton.com/blog/content/binary/VolumesScreenShot.png" height="111" width="192" border="1" hspace="4" vspace="4" alt="Screenshot" title="Screenshot"&gt;&lt;/img&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=11135e07-6332-4c64-a883-61810d48b80c"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=sSjevRXLcPc:tLavG6RhHfo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=sSjevRXLcPc:tLavG6RhHfo:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/akcoder/~4/sSjevRXLcPc" height="1" width="1"/&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,11135e07-6332-4c64-a883-61810d48b80c.aspx</comments>
      <category>HowTo</category>
      <category>Mac OS X</category>
    <feedburner:origLink>http://www.milkcarton.com/blog/2009/01/25/How+To+Make+The+OS+X+Volumes+Folder+Visible.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=9ca26879-f4aa-4bd9-ae5a-c083bb91cf3b</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,9ca26879-f4aa-4bd9-ae5a-c083bb91cf3b.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,9ca26879-f4aa-4bd9-ae5a-c083bb91cf3b.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=9ca26879-f4aa-4bd9-ae5a-c083bb91cf3b</wfw:commentRss>
      
      <title>Getting Time Machine to backup to a network volume</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,9ca26879-f4aa-4bd9-ae5a-c083bb91cf3b.aspx</guid>
      <link>http://feedproxy.google.com/~r/akcoder/~3/OOdU-oRN94Q/Getting+Time+Machine+To+Backup+To+A+Network+Volume.aspx</link>
      <pubDate>Sat, 24 Jan 2009 07:42:58 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;h3&gt;Background&#xD;
&lt;/h3&gt;&#xD;
        &lt;p&gt;&#xD;
When I originally got Mac Mini, Mac OS X 10.5.1 was out. I did a quick google search&#xD;
and found simple steps to follow to get Time Machine to backup to a network volume&#xD;
on my Linux server. Everything worked great!&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
When Mac OS X 10.5.2 was released a few weeks later, Time Machine would no longer&#xD;
backup to my file server. I did a lot of googling and found I wasn't the only one&#xD;
with the problem, but couldn't find any solutions. I've given it the old collage try&#xD;
a few times since then trying to get it working again, as recently as mid December&#xD;
2008, but to no avail.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I don't know what possessed me to try and get it working again this time, but I did.&#xD;
And I won! It wasn't an easy battle, nor was it an epic battle. But it was a battle&#xD;
none the less.&#xD;
&lt;/p&gt;&#xD;
        &lt;h3&gt;Problem&#xD;
&lt;/h3&gt;&#xD;
        &lt;p&gt;&#xD;
I found the various postings on the net about how to everything working, including &lt;a href="http://hupio.wordpress.com/2008/04/27/osx-timemachine-and-sambawindows-share/"&gt;Hupio's&#xD;
OSX Timemachine and Samba/Windows share&lt;/a&gt;. But nothing really worked. I kept getting&#xD;
the error message "the backup disk image could not be mounted."&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I almost gave up again, but decided to google the error message. And came across a&#xD;
few more sites, but they didn't have anything of interest. I don't know why, but I&#xD;
tried to create my sparse bundle on the network share itself, instead of on the Mini&#xD;
and moving it to the network share. That got me the error message "hdiutil: create&#xD;
failed - Operation not supported".&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Googling that error message led me to &lt;a href="http://www.viraj.org/b2evolution/blogs/index.php/2008/05/26/"&gt;Viraj's&#xD;
post about Time machine + AFP + Ubuntu - Samba.&lt;/a&gt; Viraj got everything working by&#xD;
installing the AFP service on his Linux (Ubuntu) server. He linked to &lt;a href="http://blog.damontimm.com/how-to-install-netatalk-afp-on-ubuntu-with-encrypted-authentication/"&gt;How&#xD;
to: Install Netatalk (AFP) on Ubuntu with Encrypted Authentication&lt;/a&gt; which was perfect&#xD;
because I happen to be running an Ubuntu server.&#xD;
&lt;/p&gt;&#xD;
        &lt;h3&gt;Solution&#xD;
&lt;/h3&gt;&#xD;
        &lt;p&gt;&#xD;
If your using a Linux file server like I am, and want to backup your Mac using Time&#xD;
Machine to your file server, follow these steps:&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
1. &lt;a href="http://blog.damontimm.com/how-to-install-netatalk-afp-on-ubuntu-with-encrypted-authentication/"&gt;Install&#xD;
AFP on your Linux server&lt;/a&gt;&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
2. Figure out where you are going to store the backups on your file server. I stored&#xD;
mine in /media/backup/TimeMachine. You will need to edit your /etc/netatalk/AppleVolumes.default&#xD;
file and point it to the directory: &#xD;
&lt;/p&gt;&#xD;
        &lt;blockquote&gt; sudo echo "/media/backup/TimeMachine \"Time Machines\"" &amp;gt;&amp;gt;&#xD;
/etc/netatalk/AppleVolumes.default &lt;/blockquote&gt;&#xD;
        &lt;p&gt;&#xD;
3. Restart netatalk &#xD;
&lt;/p&gt;&#xD;
        &lt;blockquote&gt; sudo /etc/init.d/netatalk restart &lt;/blockquote&gt;&#xD;
        &lt;p&gt;&#xD;
4. Mount your "Time Machines" volume. Finder -&amp;gt; Go -&amp;gt; Connect to Server and enter&#xD;
afp://IPADDRESS/Time Machines&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
5. &lt;a href="http://hupio.wordpress.com/2008/04/27/osx-timemachine-and-sambawindows-share/"&gt;Create&#xD;
a sparse bundle&lt;/a&gt;. If your OS volume is case-sensitive like mine, run this in terminal: &#xD;
&lt;/p&gt;&#xD;
        &lt;blockquote&gt; hdiutil create -library SPUD -size 50g -fs "Case-sensitive Journaled&#xD;
HFS+" -type SPARSEBUNDLE -volname "TimeMachine for YOURNAME" "YOURMACSNAME_MACADDRESS.sparsebundle" &lt;/blockquote&gt; this&#xD;
will create a 50 GB sparse bundle for Time Machine. If your OS volume is &lt;strong&gt;not&lt;/strong&gt; case-sensitive&#xD;
(the default) use this command: &lt;blockquote&gt; hdiutil create -library SPUD -size 50g&#xD;
-fs "Journaled HFS+" -type SPARSEBUNDLE -volname "TimeMachine for YOURNAME" "YOURMACSNAME_MACADDRESS.sparsebundle" &lt;/blockquote&gt;&lt;p&gt;&#xD;
I'm not going to go into the details about the command line, the link above goes into&#xD;
greater detail. You will need to read the article so you can plug the correct values&#xD;
in.&#xD;
&lt;/p&gt;&lt;p&gt;&#xD;
6. Move your newly created sparsebundle to your "Time Machines" share: &#xD;
&lt;/p&gt;&lt;blockquote&gt; mv mini_MACADDRESS.sparsebundle /Volumes/Time\ Machines/ &lt;/blockquote&gt;&lt;p&gt;&#xD;
7. Configure your Mac to allow backing up to a network share: &#xD;
&lt;/p&gt;&lt;blockquote&gt; defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes&#xD;
1 &lt;/blockquote&gt;&lt;p&gt;&#xD;
8. Finally, open Time Machine, click "Change Disk" and point to your "Time Machines"&#xD;
volume. In 2 minutes, Time Machine will start to backup your data to your Linux network&#xD;
file system!&#xD;
&lt;/p&gt;&lt;p&gt;&#xD;
A quick note about the conventions used above &#xD;
&lt;/p&gt;&lt;blockquote&gt;all commands blockquote are supposed to be run in Terminal. All commands&#xD;
that start with a sudo (items 2 and 3) are supposed to be run on your Linux server &lt;/blockquote&gt;&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=9ca26879-f4aa-4bd9-ae5a-c083bb91cf3b"&gt;&lt;/img&gt;&lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=OOdU-oRN94Q:PMY7nvymit8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=OOdU-oRN94Q:PMY7nvymit8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/akcoder/~4/OOdU-oRN94Q" height="1" width="1"/&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,9ca26879-f4aa-4bd9-ae5a-c083bb91cf3b.aspx</comments>
      <category>HowTo</category>
      <category>Mac OS X</category>
    <feedburner:origLink>http://www.milkcarton.com/blog/2009/01/24/Getting+Time+Machine+To+Backup+To+A+Network+Volume.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=34258c92-aca4-4bba-b783-62705037f74f</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,34258c92-aca4-4bba-b783-62705037f74f.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,34258c92-aca4-4bba-b783-62705037f74f.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=34258c92-aca4-4bba-b783-62705037f74f</wfw:commentRss>
      
      <title>Reflections on becoming a more grounded developer</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,34258c92-aca4-4bba-b783-62705037f74f.aspx</guid>
      <link>http://feedproxy.google.com/~r/akcoder/~3/xRz-MNAXCuY/Reflections+On+Becoming+A+More+Grounded+Developer.aspx</link>
      <pubDate>Fri, 23 Jan 2009 16:32:19 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p&gt;&#xD;
Wednesday, I posted &lt;a href="/blog/2009/01/22/Becoming+More+Grounded+As+A+Developer.aspx"&gt;my&#xD;
musing on becoming more grounded as a developer&lt;/a&gt;. Yesterday, I tried in ernest&#xD;
to put my reflections into action.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
I exercised my code from every angle I could think of, and found a bunch of minor&#xD;
nits. I fixed and refactored the code until I had something I was truly proud of.&#xD;
The problem is, I became so focused on the details that I forgot about a main scenario.&#xD;
&lt;/p&gt;&#xD;
        &lt;p&gt;&#xD;
Given the state of my laptop, it would have been a pain, but not painful to test this&#xD;
scenario. All and all, I can say that I'm pleased with my performance yesterday, and&#xD;
will try in earnest to keep this up going forward.&#xD;
&lt;/p&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=34258c92-aca4-4bba-b783-62705037f74f"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=xRz-MNAXCuY:CIBmXyVdNfI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=xRz-MNAXCuY:CIBmXyVdNfI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/akcoder/~4/xRz-MNAXCuY" height="1" width="1"/&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,34258c92-aca4-4bba-b783-62705037f74f.aspx</comments>
      <category>Personal Growth</category>
    <feedburner:origLink>http://www.milkcarton.com/blog/2009/01/23/Reflections+On+Becoming+A+More+Grounded+Developer.aspx</feedburner:origLink></item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=09297991-285a-4510-84d4-5f2323be7350</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,09297991-285a-4510-84d4-5f2323be7350.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,09297991-285a-4510-84d4-5f2323be7350.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=09297991-285a-4510-84d4-5f2323be7350</wfw:commentRss>
      
      <title>Mac blogging software</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,09297991-285a-4510-84d4-5f2323be7350.aspx</guid>
      <link>http://feedproxy.google.com/~r/akcoder/~3/D3jOZ-if5fs/Mac+Blogging+Software.aspx</link>
      <pubDate>Thu, 22 Jan 2009 06:48:12 GMT</pubDate>
      <description>&lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;&#xD;
        &lt;p style="clear: both"&gt;&#xD;
I'm trying out blog editing software on my Mac Mini. So far, I've used &lt;a href="http://www.red-sweater.com/marsedit/"&gt;MarsEdit&lt;/a&gt; and &lt;a href="http://illuminex.com/ecto/"&gt;Ecto&lt;/a&gt;.&#xD;
I'm honestly not very impressed with either of them. MarsEdit doesn't support (that&#xD;
I've found) rich text editing from within its editor. It only supports raw HTML editing,&#xD;
but will shell out to other editors to do the rich text editing.&#xD;
&lt;/p&gt;&#xD;
        &lt;p style="clear: both"&gt;&#xD;
Ecto, took me quite a few tries to find a good link to download it. When I finally&#xD;
got it downloaded, isn't to terrible. The UI isn't very clean IMHO. Its interface&#xD;
for adding links is sub-par, and NOT discoverable. At least it supports a rich text&#xD;
editor out of the box.&#xD;
&lt;/p&gt;&#xD;
        &lt;p style="clear: both"&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p style="clear: both"&gt;&#xD;
I wish Microsoft would make a version of Windows Live Writer for the Mac :) &#xD;
&lt;!-- technorati tags start --&gt;&lt;/p&gt;&#xD;
        &lt;p style="clear: both; text-align:right;"&gt;&#xD;
Technorati Tags: &lt;a href="http://www.technorati.com/tag/Non-tech" rel="tag"&gt;Non-tech&lt;/a&gt;&lt;/p&gt;&#xD;
        &lt;p style="clear: both"&gt;&#xD;
          &lt;!-- technorati tags end --&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;p style="clear: both"&gt;&#xD;
        &lt;/p&gt;&#xD;
        &lt;br class="final-break" style="clear: both"&gt;&#xD;
        &lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=09297991-285a-4510-84d4-5f2323be7350"&gt;&lt;/img&gt;&#xD;
      &lt;/body&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=D3jOZ-if5fs:sUqDrSk7Sys:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/akcoder?a=D3jOZ-if5fs:sUqDrSk7Sys:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/akcoder?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/akcoder/~4/D3jOZ-if5fs" height="1" width="1"/&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,09297991-285a-4510-84d4-5f2323be7350.aspx</comments>
      <category>Mac OS X</category>
      <category>Non-Tech</category>
    <feedburner:origLink>http://www.milkcarton.com/blog/2009/01/22/Mac+Blogging+Software.aspx</feedburner:origLink></item>
  </channel>
</rss>
