<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" 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/"><channel><title>.Net</title><link>http://www.agileprogrammer.com/oneagilecoder/category/112.aspx</link><description>.Net specific content, including comments on Microsoft tools and languages</description><managingEditor>Brian Button</managingEditor><dc:language>en-US</dc:language><generator>.Text Version 0.95.2005.109</generator><item><dc:creator>Brian Button</dc:creator><title>What do you think of this code?</title><link>http://www.agileprogrammer.com/oneagilecoder/archive/2008/01/13/23995.aspx</link><pubDate>Sun, 13 Jan 2008 21:15:00 GMT</pubDate><guid>http://www.agileprogrammer.com/oneagilecoder/archive/2008/01/13/23995.aspx</guid><description>&lt;p&gt;I recently finished 6 weeks of coding for a client, and it was heaven! I actually got a chance to code every day, for 6 solid weeks. It was a chance for me to learn C# 3.0, and a chance to work on testing things that are hard to test. It was great!&lt;/p&gt; &lt;p&gt;Out of the work, came several interesting observations and coding techniques, all rooted in C# 3.0. Since no one at work has any experience with these new idioms I "invented", "discovered", or just "copied", I'd love to get some reader feedback. I'll start with this one trick I tried, and follow on with more as the mood strikes me over time.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Trick 1: Using extension methods and a marker interface in place of implementation inheritance&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I had an instance of code duplication in two parallel hierarchies of classes, and I wanted to find a way to share the code. One option would be to use inheritance, factoring out another base class above BaseResponse and BaseRequest. This is where methods common to requests and responses could both live. Using inheritance as a way to reuse code in a single inheritance language is a pretty heavyweight thing to do. I'd rather find a way to use delegation, since that preserves the SRP in my class hierarchy. Instead, I decided to try an extension method, and just use that method where I needed it. To avoid polluting Object with unnecessary methods, however, I came up with the idea of using a marker interface on the classes I wanted to have these extension methods, limiting the scope where these extra methods were visible. (No idea if anyone else has done this yet or not)&lt;/p&gt; &lt;p&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="296" alt="ClassDiagram1" src="http://www.agilestl.com/BlogImages/ClassDiagram1.jpg" width="647" border="0"&gt; &lt;/p&gt; &lt;p&gt;For each request and response class, in the two parallel&amp;nbsp; hierarchies, my client requirements made it necessary to add an XmlRoot attribute to tell the XmlSerializer that this object was the root of an XML document and to specify the runtime name of this element. To let me get the runtime name of each request and response object, for auditing and logging purposes, both hierarchies had a CommandName property, containing the exact same code. This was the code in question that I was trying to share.&lt;/p&gt; &lt;p&gt;As a simple exercise, I created an extension method to deal with this:&lt;/p&gt;&lt;pre&gt;    &lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SssMessageExtensionMethods
    {
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GetCommandNameFromXmlRootAttribute(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; object message)
        {
            &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;[] attributes = message.GetType().GetCustomAttributes(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(XmlRootAttribute), &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (attributes.Length == 0) &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; message.GetType().Name;

            XmlRootAttribute xmlRootAttribute = attributes[0] &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; XmlRootAttribute;

            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; xmlRootAttribute.ElementName;
        }
    }&lt;/pre&gt;
&lt;p&gt;This solution worked just fine, and the code ran correctly, but I still wasn't happy with my solution. The problem I was sensing was that I was adding yet another extension method to Object, and Object's neighborhood was already pretty crowded with all the Linq methods in there. I wanted my extension methods to show up only on those classes to which I wanted to apply them. &lt;/p&gt;
&lt;p&gt;The solution that I came up with was to use a marker interface whose sole purpose is to limit the visibility of the extension methods to classes that I intend to apply them to. In this case, I made BaseRequest and BaseResponse each implement IMessageMarker, an interface with no methods. And I changed the extension method to be:&lt;/p&gt;&lt;pre&gt;    &lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SssMessageExtensionMethods
    {
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; GetCommandNameFromXmlRootAttribute(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt; ISssMessageMarker message)
        {
            &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;[] attributes = message.GetType().GetCustomAttributes(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(XmlRootAttribute), &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (attributes.Length == 0) &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; message.GetType().Name;

            XmlRootAttribute xmlRootAttribute = attributes[0] &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; XmlRootAttribute;

            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; xmlRootAttribute.ElementName;
        }
    }&lt;/pre&gt;
&lt;p&gt;Now I have the same extension method defined, but it only appears on those classes that implement the marker. &lt;/p&gt;
&lt;p&gt;What do you think of this technique? In a more powerful language, like Ruby or C++ (ducking and running for cover!), this kind of trickery wouldn't be needed. But C# can only get you so far, so I felt this was a good tradeoff between adding the methods for needed functionality and making the most minimal change in my classes to hide these methods so that only those places that needed them could see them.&lt;/p&gt;
&lt;p&gt;-- bab&lt;/p&gt;&lt;img src ="http://www.agileprogrammer.com/oneagilecoder/aggbug/23995.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Brian Button</dc:creator><title>Slides from my powershell talk</title><link>http://www.agileprogrammer.com/oneagilecoder/archive/2007/10/31/23675.aspx</link><pubDate>Wed, 31 Oct 2007 20:30:00 GMT</pubDate><guid>http://www.agileprogrammer.com/oneagilecoder/archive/2007/10/31/23675.aspx</guid><description>&lt;p&gt;
I gave an introduction to Powershell talk at the St. Louis .Net UG meeting on Monday, October 29th to about 70-80 people or so. I introduced basic concepts of powershell, talked about a few problems I had solved with it, and showed some simple scripts.
&lt;/p&gt;
&lt;p&gt;
At the end of the presentation, I promised to post &lt;a href="http://www.agilestl.com/downloads/IntroductionToPowershell.ppt"&gt;the slides&lt;/a&gt; by the end of this week, and I'm making it Wednesday night. Believe me when I say that me getting something finished early is a minor miracle :)&lt;/p&gt;

-- bab&lt;img src ="http://www.agileprogrammer.com/oneagilecoder/aggbug/23675.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Brian Button</dc:creator><title>Episode 2 - The InputReader and the start of the Processor</title><link>http://www.agileprogrammer.com/oneagilecoder/archive/2007/09/17/23374.aspx</link><pubDate>Mon, 17 Sep 2007 09:42:00 GMT</pubDate><guid>http://www.agileprogrammer.com/oneagilecoder/archive/2007/09/17/23374.aspx</guid><description>&lt;p&gt;OK, so this stuff is different. Really different. So different that i feel like a TDD rookie all over again. I find myself questioning everything that I do, and wondering if I&amp;#8217;m going in the right direction. But it&amp;#8217;s fun learning something new&amp;#8230;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When I last left you&amp;#8230;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When we finished episode 1, we had created a couple of customer tests and had used Interaction Based Testing to drive out the basics of our architecture. In looking back at what we drove out, I  wonder about some of those classes. I can see that I have an input side, and processing middle, and an output side, but I see an awful lot of generalization having happened already. I&amp;#8217;m going to watch out for this throughout the rest of this exercise. It is possible that this style of writing tests drives you towards early generalization, but I&amp;#8217;m pretty sure it is just my unfamiliarity with how to drive code through these tests that is making this happen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Input Side&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;According to the first test I wrote, this is the interface that the input side needs to have:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public interface IInputReader
{
    List&amp;lt;BatchInput&amp;gt; ReadAllInputs();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I don&amp;#8217;t know anything about a &lt;em&gt;BatchInput&lt;/em&gt; yet, or how to read the input lines, but I think I may be about to find out.&lt;/p&gt;

&lt;p&gt;So my job now is to drive out how the &lt;em&gt;IInputReader&lt;/em&gt; will be implemented by some class. As it turns out, this is really not very interesting. The interaction-based testing that we&amp;#8217;ve been doing has been very useful at driving out interactions, but the &lt;em&gt;InputReader&lt;/em&gt; seems to stand alone. It is at the very end of the call chain, which means that it doesn&amp;#8217;t interact with anything else. This means that state-based tests will do just fine to test this piece of the system. &lt;/p&gt;

&lt;p&gt;Here is the first test I wrote for this class:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[Test]
public void InputReaderImplementsIInputReader()
{
    Assert.IsInstanceOfType(typeof(IInputReader), new InputReader(null));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I&amp;#8217;ve started writing tests like these to force me to make the class I&amp;#8217;m writing implement a specific interface. I started doing this because I&amp;#8217;ve found myself going along writing a class, knowing full well that it has to implement some interface, but forgetting to actually do it. I end up writing the whole class to the wrong API, and I have to go back and refactor the API to match what it should be. Hence, I write this test now to enforce me implementing the right interface.&lt;/p&gt;

&lt;p&gt;Here are the rest of the tests:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[Test]
public void EmptyInputStreamGeneratesEmptyOutputList()
{
    StringReader reader = new StringReader(String.Empty);
    InputReader inputReader = new InputReader(reader);

    List&amp;lt;BatchInput&amp;gt; input = inputReader.ReadAllInputs();

    Assert.AreEqual(0, input.Count);
}

[Test]
public void SingleCommandInputStringGeneratesSingleElementOutputList()
{
    StringReader reader = new StringReader("a|b" + System.Environment.NewLine);
    InputReader inputReader = new InputReader(reader);

    List&amp;lt;BatchInput&amp;gt; input = inputReader.ReadAllInputs();

    Assert.AreEqual(1, input.Count);
    Assert.AreEqual("a|b", input[0].ToString());
}

[Test]
public void MultipleCommandInputStringGeneratesMultipleElementsInOutputList()
{
    StringReader reader = new StringReader("a|b" + System.Environment.NewLine + "b|c" + Environment.NewLine);
    InputReader inputReader = new InputReader(reader);

    List&amp;lt;BatchInput&amp;gt; input = inputReader.ReadAllInputs();

    Assert.AreEqual(2, input.Count);
    Assert.AreEqual("a|b", input[0].ToString());
    Assert.AreEqual("b|c", input[1].ToString());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These tests follow the usual &lt;em&gt;0, 1, many&lt;/em&gt; pattern for implementing functionality. Make sure something works  for 0 elements, which fleshes out the API, then make sure it works for a single element, which puts the business logic in, and then make it work for multiple elements, which adds the looping logic. Here is the oh, so complicated code to implement these tests:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class InputReader : IInputReader
{
    private readonly TextReader reader;

    public InputReader(TextReader reader)
    {
        this.reader = reader;
    }

    public List&amp;lt;BatchInput&amp;gt; ReadAllInputs()
    {
        List&amp;lt;BatchInput&amp;gt; inputData = new List&amp;lt;BatchInput&amp;gt;();
        ReadAllLines().ForEach(delegate(string newLine) 
            { inputData.Add(new BatchInput(newLine)); });
        return inputData;
    }

    private List&amp;lt;string&amp;gt; ReadAllLines()
    {
        List&amp;lt;string&amp;gt; inputLines = new List&amp;lt;string&amp;gt;();
        while (reader.Peek() != -1)
        {
            inputLines.Add(reader.ReadLine());
        }

        return inputLines;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And that should pretty well handle the input side of this system. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On to the &lt;em&gt;Processor&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;Processor&lt;/em&gt; class takes the input &lt;em&gt;BatchInput&lt;/em&gt; list and converts it into &lt;em&gt;ProcessOutput&lt;/em&gt; objects, which are then written to the output section of the program. Here is the interface again that rules this section of code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public interface IProcessor
{
    List&amp;lt;ProcessOutput&amp;gt; Process(List&amp;lt;BatchInput&amp;gt; inputs);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;First of all, let&amp;#8217;s make sure that my class is going to implement the correct interface:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[Test]
public void ProcessorImplementsIProcessor()
{
    Assert.IsInstanceOfType(typeof(IProcessor), new Processor(null, null));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, the responsibilities that seem to have to happen here are that each &lt;em&gt;BatchInput&lt;/em&gt; object needs to be turned into something representing a payroll input line, and that new object needs to be executed in some way. Those thought processes lead me to this test:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[Test]
public void SingleBatchInputCausesStuffToHappenOnce()
{
    MockRepository mocks = new MockRepository();

    IPayrollProcessorFactory factory = mocks.CreateMock&amp;lt;IPayrollProcessorFactory&amp;gt;();
    IPayrollExecutor executor = mocks.CreateMock&amp;lt;IPayrollExecutor&amp;gt;();
    Processor processor = new Processor(factory, executor);
    PayrollCommand commonPayrollCommand = new PayrollCommand();

    List&amp;lt;BatchInput&amp;gt; batches = TestDataFactory.CreateBatchInput();

    using (mocks.Record())
    {
        Expect.Call(factory.Create(batches[0])).Return(commonPayrollCommand).Repeat.Once();
        executor.Execute(commonPayrollCommand);
        LastCall.Constraints(Is.Equal(commonPayrollCommand)).Repeat.Once();
    }

    using (mocks.Playback())
    {
        processor.Process(batches);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There is tons of stuff to see in this test method now. Immediately after I create my &lt;em&gt;MockRepository&lt;/em&gt;, I create my system. This consists of three objects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;IPayrollProcessorFactory&lt;/em&gt;&lt;/strong&gt; &amp;#8212; responsible for converting the &lt;em&gt;BatchInput&lt;/em&gt; object into a &lt;em&gt;PayrollCommand&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;IPayrollExecutor&lt;/em&gt;&lt;/strong&gt; &amp;#8212; responsible for executing the &lt;em&gt;PayrollCommand&lt;/em&gt; after it is created&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Processor&lt;/em&gt;&lt;/strong&gt; &amp;#8212; the driver of the system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, these three classes make up this portion of our system. If I were doing SBT (state-based testing), I&amp;#8217;m not entirely sure at all that I would have these two embedded objects yet. I would probably have written code and then refactored to get to where I am now. But, with IBT, you have to &lt;em&gt;think&lt;/em&gt; in terms of who the collaborators are that the method under test is going to use, and jump to having those collaborators now rather than later. In fact, the whole &lt;em&gt;IPayrollExecutor&lt;/em&gt; seems kind of contrived at this point to me, but I need to have something there to interact with, so I can write an IBT for this.&lt;/p&gt;

&lt;p&gt;On the next line, I create an instance of my &lt;em&gt;PayrollCommand&lt;/em&gt;. I specifically use this instance as the returned value from the &lt;em&gt;factory.Create&lt;/em&gt; call in the first expectation and as a constraint to the &lt;em&gt;executor.Execute&lt;/em&gt; in the second expectation. This was something I was struggling with earlier in my experimentation with IBT. What I want to have happen is that I want to force my code to take the object that is returned from the &lt;em&gt;Create&lt;/em&gt; call and pass it to the &lt;em&gt;Execute&lt;/em&gt; call. By having a common object that I use in the expectations, and having the &lt;em&gt;Is.Equal&lt;/em&gt; constraint in the second expectation, I can actually force that to happen. It took me a while to figure this out, and I&amp;#8217;m pretty sure that this is a Rhino Mocks thing, rather than a generic IBT thing, but I found this to be helpful.&lt;/p&gt;

&lt;p&gt;Then I drop into the record section, where I set some expectations on the objects I&amp;#8217;m collaborating with. The first expectation says that I expect an instance of a &lt;em&gt;BatchInput&lt;/em&gt; to be provided to this &lt;em&gt;Execute&lt;/em&gt; method when called. Please note, and it took me a while to intellectually really grasp this, the batches[0] that I&amp;#8217;m passing to the Create method is really just a place holder. This is the weird part here &amp;#8212; I&amp;#8217;m not actually calling the factory.Create method here, I&amp;#8217;m signaling the mocking framework that this is a method I&amp;#8217;m about to set some expectations on. I could have just as easily, in this case, passed in null in place of the argument, but I thought null didn&amp;#8217;t communicate very clearly. What I do mean is that I expect some instance of a &lt;em&gt;BatchInput&lt;/em&gt; to be provided to this method. Maybe I would have done better by new&amp;#8217;ing one up in place of using batches[0]???? It is not the value or identity of the object that matters here at all, it is the type, and only because a) the compiler needs it and b) it communicates test intent. The rest of that expectation states that I&amp;#8217;m only going to expect this method to be called once, and is allowing me to specify what object will be returned when this method is called. This last part is one of the hardest parts for me to have initially grasped. I was unsure whether this framework was asserting that the mocked method would return the value I passed it, or whether it was allowing me to set up the value that would be returned when it was called. In looking back, the second option is the only one that makes any sense at all, since these expectations are being set on methods that are 100% mocked out and have no ability to return anything without me specifying it in some way. Doh!&lt;/p&gt;

&lt;p&gt;The second expectation is where I set up the fact that I expect the same object that was returned from the Create call to be the object passed to this call. Again, I do this through the Constraint, not through the value actually passed to the executor.Execute() method. I could just as easily passed in null there, but it wouldn&amp;#8217;t have communicated as clearly. &lt;/p&gt;

&lt;p&gt;Finally, I get to the playback section, call my method, and the test is over.&lt;/p&gt;

&lt;p&gt;This is the code that I wrote to make this test pass:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public List&amp;lt;ProcessOutput&amp;gt; Process(List&amp;lt;BatchInput&amp;gt; batches)
{
    List&amp;lt;ProcessOutput&amp;gt; results = new List&amp;lt;ProcessOutput&amp;gt;();

    PayrollCommand command = factory.Create(batches[0]);
    executor.Execute(command);

    return results;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I know I&amp;#8217;m not handling the results at all yet, but I&amp;#8217;m pretty sure I can flesh out what will happen with those at some point soon.&lt;/p&gt;

&lt;p&gt;In my second test, I&amp;#8217;ll worry about how to handle multiple &lt;em&gt;BatchInput&lt;/em&gt; objects. Again, this is a very common pattern for me, starting with one of something to get the logic right, and then moving on to multiple, to put in any looping logic I need. Here is the second test:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[Test]
public void MultipleBatchInputsCausesStuffToHappenMultipleTimes()
{
    MockRepository mocks = new MockRepository();

    IPayrollProcessorFactory factory = mocks.CreateMock&amp;lt;IPayrollProcessorFactory&amp;gt;();
    IPayrollExecutor executor = mocks.CreateMock&amp;lt;IPayrollExecutor&amp;gt;();
    Processor processor = new Processor(factory, executor);
    PayrollCommand commonPayrollCommand = new PayrollCommand();

    List&amp;lt;BatchInput&amp;gt; batches = TestDataFactory.CreateMultipleBatches(2);

    using (mocks.Record())
    {
        Expect.Call(factory.Create(batches[0])).
                Constraints(List.OneOf(batches)).Return(commonPayrollCommand).Repeat.Twice();
        executor.Execute(commonPayrollCommand);
        LastCall.Constraints(Is.Equal(commonPayrollCommand)).Repeat.Twice();
    }

    using (mocks.Playback())
    {
        processor.Process(batches);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Almost all of this test is exactly the same, except I add two &lt;em&gt;BatchInput&lt;/em&gt; objects to my list. The only other thing I need to enforce is that the object that is passed to the &lt;em&gt;factory.Create&lt;/em&gt; method is a &lt;em&gt;BatchInput&lt;/em&gt; object that is a member of the list I passed in, which I do with the List Constraint to the first expectation.  &lt;/p&gt;

&lt;p&gt;Here is the modified &lt;em&gt;Processor&lt;/em&gt; code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public List&amp;lt;ProcessOutput&amp;gt; Process(List&amp;lt;BatchInput&amp;gt; batches)
{
    List&amp;lt;ProcessOutput&amp;gt; results = new List&amp;lt;ProcessOutput&amp;gt;();

    foreach (BatchInput batch in batches)
    {
        PayrollCommand command = factory.Create(batch);
        executor.Execute(command);
    }

    return results;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Object Mother&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In both of these tests, you&amp;#8217;ll see a reference to &lt;em&gt;TestDataFactory&lt;/em&gt;. This is a class whose responsibility it is to create test data for me when asked. I use it to remove irrelevant details about test data from my tests and move it someplace else. This is called the Object Mother pattern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In the next episode&amp;#8230;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s about enough for now. If any of this wasn&amp;#8217;t clear, please let me know, and I&amp;#8217;ll update the text to be better. In the next episode, I&amp;#8217;ll go ahead and build the factory using SBT, since it isn&amp;#8217;t going to interact with anything and then dive into the &lt;em&gt;Processor&lt;/em&gt; code, which should prove interesting.&lt;/p&gt;

&lt;p&gt;Overall, I&amp;#8217;m pretty happy with how IBT is allowing me to focus on interactions between objects and ignore details like the contents of my domain classes entirely until I get to a class who manipulates the contents of those domain classes. &lt;/p&gt;

&lt;p&gt;My biggest question lies in the area of premature generalization. Am I thinking too much and ignoring YAGNI? Do these tests reflect the simplest thing that can possibly work? I&amp;#8217;m truly not sure. I tried to do better in this episode to focus on just payroll stuff and not make generic classes, like the &lt;em&gt;IInputReader&lt;/em&gt;. I have a &lt;em&gt;PayrollProcessorFactory&lt;/em&gt;, for example, instead of a &lt;em&gt;ProcessorFactory&lt;/em&gt;. Those refactorings will come, and I want to wait for the code to tell me about them. IBT, I think, makes it easier to see those abstractions ahead of time, but I need to resist!&lt;/p&gt;

&lt;p&gt;Please write with questions and comments. This continues to be an interesting journey for me, and I&amp;#8217;m not at all sure where I&amp;#8217;m going yet! But it is fun!&lt;/p&gt;

&lt;p&gt;&amp;#8212; bab&lt;/p&gt;&lt;img src ="http://www.agileprogrammer.com/oneagilecoder/aggbug/23374.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Brian Button</dc:creator><title>Interesting difference using nested test suites in JUnit versus NUnit</title><link>http://www.agileprogrammer.com/oneagilecoder/archive/2007/09/10/23341.aspx</link><pubDate>Mon, 10 Sep 2007 10:58:00 GMT</pubDate><guid>http://www.agileprogrammer.com/oneagilecoder/archive/2007/09/10/23341.aspx</guid><description>&lt;p&gt;My friend, &lt;a href="http://blogs.msdn.com/jamesnewkirk/"&gt;Jim Newkirk&lt;/a&gt;, introduced me to a very nice way of partitioning programmer tests for a class as you write them. Most developers write a single test class for a single application class, and just dump all tests for that class in the same place. This is not as correct as it could be (that&amp;#8217;s Consultant-Speak for &amp;#8220;that&amp;#8217;s just plain wrong&amp;#8221;). &lt;/p&gt;

&lt;p&gt;The accepted best practice is to group together tests that have the same setup/teardown logic into the same test fixtures, which can lead to having multiple fixtures for a single class. For example, when I build a Stack class, I generally have different fixtures for each of the different states that my Stack class can have, and I put a test into the correct fixture representing its starting state. For example, I  might have states corresponding to &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an empty stack&lt;/li&gt;
&lt;li&gt;stack with a single element&lt;/li&gt;
&lt;li&gt;stack with multiple elements&lt;/li&gt;
&lt;li&gt;stack that is full&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and so on. I would create a new fixture for each of these states, and use setup and teardown to push my system into the given state for that fixture. I know that this is a departure from my previous advice about &lt;a href="http://www.agileprogrammer.com/oneagilecoder/archive/2005/07/23/6261.aspx"&gt;Assiduously Avoid Setup and Teardown&lt;/a&gt;, but I think I like where this leads me. I promise to post an example of writing tests like this over the next few days, but that example is not part of what I&amp;#8217;m talking about here.&lt;/p&gt;

&lt;p&gt;What I am talking about is an arrangement like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[TestFixture]
public class StackFixture
{
    [TestFixture]
    public class EmptyFixture
    {
        [Test]
        public void ATest() {}
    }

    [TestFixture]
    public class SingleElementFixture
    {
        [Test]
        public void AnotherTest() {}
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and so on. The main reason I like this arrangement of using nested fixtures is that it allows for me to separate out tests for different behaviors of my class into different fixtures, which lets me find them more easily and makes it easier to decide where to put new tests, and it lets me run all the tests for a particular class together at the same time. If I were to have several independent test fixtures, I would have no automated way of ensuring that I ran all of them together. The closest I could come would be to use categories, which is rather manual and error prone.&lt;/p&gt;

&lt;p&gt;Now, what I just tried to do was to replicate this arrangement in Java, and it was harder to make it work. Using JUnit 3.8.1, I tried this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class StackFixture extends TestCase {
    public static class EmptyFixture extends TestCase {
        public void testATest() {}
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This gave me two tests run, one failing, so it found the test in the inner class, but found an error about no test being found in the outer fixture, StackFixture, so my tests could never all pass. I tried removing static from the class declaration, and then JUnit didn&amp;#8217;t find the test in the inner fixture, and I still had the failure for no tests found. Clearly, not possible here.&lt;/p&gt;

&lt;p&gt;Then I tried JUnit 4, which, like NUnit 2 and beyond, uses attributes to identify tests. In Java, they call them annotations, but they seem to be the same thing. Here is what I wrote:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class JUnitFourFixture {
    public  class StackEmptyFixture {
        @Test
        public void EmptyAtCreation() {
            Stack stack = new Stack();

            assertTrue(stack.isEmpty());
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When I ran this, I got an error popup saying that there were no tests found. Not a winner :( But when I added static to the class declaration for the inner class, things did finally work beautifully. Here is the code that worked, with an extra fixture added just to be sure, and the inner classes made static. (BTW, for those of you who don&amp;#8217;t know, there are two kinds of inner classes in Java. Inner classes without the static prefix belong to a particular instance of the enclosing class, so when you instantiate the outer class, you&amp;#8217;re instantiating the inner class as well, and it has access to stuff in the outer object. If you have the static prefix, then the inner class is entirely independent of the outer class, just like inner classes in C#.)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class JUnitFourFixture {
    public static class StackEmptyFixture {
        @Test
        public void EmptyAtCreation() {
            Stack stack = new Stack();

            assertTrue(stack.isEmpty());
        }
    }

    public static class SingleElementFixture {
        @Test
        public void AnotherTest() {
            assertTrue(true);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I don&amp;#8217;t know how many of you didn&amp;#8217;t know this, or never had a reason to care about this, but I am teaching a Java TDD course this week. Before I taught this, I wanted to make sure it worked!&lt;/p&gt;

&lt;p&gt;&amp;#8212; bab&lt;/p&gt;&lt;img src ="http://www.agileprogrammer.com/oneagilecoder/aggbug/23341.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Brian Button</dc:creator><title>Another powershell quickie - removing all bin and obj directories beneath VS.Net projects</title><link>http://www.agileprogrammer.com/oneagilecoder/archive/2007/06/23/22919.aspx</link><pubDate>Sat, 23 Jun 2007 10:32:00 GMT</pubDate><guid>http://www.agileprogrammer.com/oneagilecoder/archive/2007/06/23/22919.aspx</guid><description>&lt;p&gt;&lt;font face="Courier New"&gt;gci -recurse -include bin,obj . | ri -recurse&lt;/font&gt;&lt;/p&gt; &lt;p&gt;I was playing around with how to get this to work, and I couldn't seem to figure out why these commands didn't find the same locations to delete:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;font face="courier new"&gt;gci -recurse -include bin,obj .&lt;/font&gt;&lt;/li&gt; &lt;li&gt;&lt;font face="courier new"&gt;ri -recurse -force -include bin,obj -whatif .&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I finally got so baffled that I RTFMed remove-item, and there was my answer. In the fine print, nestled away in an example that did what I was looking for, and in the documentation for the recurse parameter was my answer...&lt;/p&gt; &lt;p&gt;&lt;em&gt;-recurse &amp;lt;SwitchParameter&amp;gt;&lt;br&gt;Deletes the items in the specified locations and in all child items of the locations. &lt;/em&gt; &lt;p&gt;&lt;em&gt;&lt;strong&gt;The Recurse parameter in this cmdlet does not work properly.&lt;/strong&gt;&lt;/em&gt;  &lt;p&gt;Ah ha! That's when I went to the format that I finally settled on, and everything worked. &lt;p&gt;Another blog posting mostly written to help me remember how I solved this problem the next time I encounter it! &lt;p&gt;-- bab&lt;img src ="http://www.agileprogrammer.com/oneagilecoder/aggbug/22919.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Brian Button</dc:creator><title>Asynchrony Solutions is hiring!</title><link>http://www.agileprogrammer.com/oneagilecoder/archive/2007/01/13/22029.aspx</link><pubDate>Sat, 13 Jan 2007 15:43:00 GMT</pubDate><guid>http://www.agileprogrammer.com/oneagilecoder/archive/2007/01/13/22029.aspx</guid><description>&lt;p&gt;Asynchrony Solutions is looking for&amp;nbsp;several developers to join our company. Our immediate requirements are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C/C++/Unix/realtime/embedded developer &amp;mdash; This is for an exciting, very long-term project where you would have the opportunity to write code in C, Java, and C++&lt;/li&gt;
&lt;li&gt;Java or C#/.Net/ASP.Net developer for any one of a number of projects&lt;/li&gt;
&lt;li&gt;Agile mentors and trainers&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;In addition to technical skills, agile experience is a definite plus. Even if you haven&amp;rsquo;t ever worked in an agile environment, you should be very opening to learning agile skills and working in such an environment.&lt;/p&gt;
&lt;p&gt;I joined the company in May of this year, and I have been very happy there. I&amp;rsquo;m the VP of Engineering, and the thing that convinced me to join was the company&amp;rsquo;s committment to an agile way of thinking. There are 4 principal owners, and each of them understands, appreciates, and values agility, and this shows in how the company markets is services, how projects are run, and how people are valued. Our project teams are generally 5&amp;ndash;10 people who work together in a warroom atmosphere. We actively encourage the agile management and development practices, and, more importantly, an agile belief system. I could go on, but it is just a great place to work. If you have questions about the company or the working environment, just let me know &amp;mdash; I&amp;rsquo;ll be happy to answer.&lt;/p&gt;
&lt;p&gt;For more information about our company, please see our &lt;a href="http://www.asolutions.com/"&gt;web site&lt;/a&gt;. If you&amp;rsquo;d like to learn more about these opportunities, please contact me directly through this blog.&lt;/p&gt;
&lt;p&gt;Thanks!&lt;/p&gt;
&lt;p&gt;&amp;mdash; bab&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src ="http://www.agileprogrammer.com/oneagilecoder/aggbug/22029.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Brian Button</dc:creator><title>A Real World Example of Refactoring</title><link>http://www.agileprogrammer.com/oneagilecoder/archive/2007/01/07/21984.aspx</link><pubDate>Sun, 07 Jan 2007 12:41:00 GMT</pubDate><guid>http://www.agileprogrammer.com/oneagilecoder/archive/2007/01/07/21984.aspx</guid><description>&lt;p&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20     [\cf10 TestFixture\cf0 ]\par ??    \cf2 public\cf0  \cf2 class\cf0  \cf10 ImageWriterFixture\par ??\cf0     \{\par ??        \cf2 private\cf0  \cf10 Image\cf0  fullSizeLandscapeImage;\par ??        \cf2 private\cf0  \cf10 Image\cf0  fullSizePortraitImage;\par ??        \cf2 private\cf0  \cf10 MemoryStream\cf0  imageInStream;\par ??\par ??        [\cf10 SetUp\cf0 ]\par ??        \cf2 public\cf0  \cf2 void\cf0  SetUp()\par ??        \{\par ??            fullSizeLandscapeImage = \cf2 new\cf0  \cf10 Bitmap\cf0 (800, 600);\par ??            fullSizePortraitImage = \cf2 new\cf0  \cf10 Bitmap\cf0 (600, 800);\par ??            imageInStream = \cf2 new\cf0  \cf10 MemoryStream\cf0 ();\par ??        \}\par ??\par ??        [\cf10 TearDown\cf0 ]\par ??        \cf2 public\cf0  \cf2 void\cf0  ReleaseResources()\par ??        \{\par ??            imageInStream.Dispose();\par ??            fullSizeLandscapeImage.Dispose();\par ??        \}\par ??\par ??        [\cf10 Test\cf0 ]\par ??        \cf2 public\cf0  \cf2 void\cf0  ImageWriteWillWriteFullSizeLandscapeImages()\par ??        \{\par ??            \cf10 ImageWriter\cf0  writer = \cf10 ImageWriter\cf0 .GetFullSizeWriter(imageInStream);\par ??            writer.Write(fullSizeLandscapeImage);\par ??\par ??            \cf10 Image\cf0  rereadImage = ResizeImageFromStream();\par ??\par ??            \cf10 Assert\cf0 .AreEqual(fullSizeLandscapeImage.Height, rereadImage.Height);\par ??            \cf10 Assert\cf0 .AreEqual(fullSizeLandscapeImage.Width, rereadImage.Width);\par ??        \}\par ??\par ??        \cf2 private\cf0  \cf10 Image\cf0  ResizeImageFromStream()\par ??        \{\par ??            imageInStream.Seek(0, \cf10 SeekOrigin\cf0 .Begin);\par ??            \cf2 return\cf0  \cf10 Image\cf0 .FromStream(imageInStream);\par ??        \}\par ??\par ??        [\cf10 Test\cf0 ]\par ??        \cf2 public\cf0  \cf2 void\cf0  ImageWriterWillWriteDetailsLandscapeImages()\par ??        \{\par ??            \cf10 ImageWriter\cf0  writer = \cf10 ImageWriter\cf0 .GetDetailsSizeWriter(imageInStream);\par ??            writer.Write(fullSizeLandscapeImage);\par ??\par ??            \cf10 Image\cf0  rereadImage = ResizeImageFromStream();\par ??\par ??            \cf10 Assert\cf0 .AreEqual(306, rereadImage.Height);\par ??            \cf10 Assert\cf0 .AreEqual(408, rereadImage.Width);\par ??        \}\par ??\par ??        [\cf10 Test\cf0 ]\par ??        \cf2 public\cf0  \cf2 void\cf0  ImageWriterWillWriteThumbnailLandscapeImages()\par ??        \{\par ??            \cf10 ImageWriter\cf0  writer = \cf10 ImageWriter\cf0 .GetThumbnailSizeWriter(imageInStream);\par ??            writer.Write(fullSizeLandscapeImage);\par ??\par ??            \cf10 Image\cf0  rereadImage = ResizeImageFromStream();\par ??\par ??            \cf10 Assert\cf0 .AreEqual(105, rereadImage.Height);\par ??            \cf10 Assert\cf0 .AreEqual(140, rereadImage.Width);\par ??        \}\par ??\par ??        [\cf10 Test\cf0 ]\par ??        \cf2 public\cf0  \cf2 void\cf0  ImageWriterWillWriteFullSizePortraitImages()\par ??        \{\par ??            \cf10 ImageWriter\cf0  writer = \cf10 ImageWriter\cf0 .GetFullSizeWriter(imageInStream);\par ??            writer.Write(fullSizePortraitImage);\par ??\par ??            \cf10 Image\cf0  rereadImage = ResizeImageFromStream();\par ??\par ??            \cf10 Assert\cf0 .AreEqual(800, rereadImage.Height);\par ??            \cf10 Assert\cf0 .AreEqual(600, rereadImage.Width);\par ??        \}\par ??\par ??        [\cf10 Test\cf0 ]\par ??        \cf2 public\cf0  \cf2 void\cf0  ImageWriterWillWriteDetailsSizePortraitImages()\par ??        \{\par ??            \cf10 ImageWriter\cf0  writer = \cf10 ImageWriter\cf0 .GetDetailsSizeWriter(imageInStream);\par ??            writer.Write(fullSizePortraitImage);\par ??\par ??            \cf10 Image\cf0  rereadImage = ResizeImageFromStream();\par ??\par ??            \cf10 Assert\cf0 .AreEqual(306, rereadImage.Height);\par ??            \cf10 Assert\cf0 .AreEqual(230, rereadImage.Width);            \par ??        \}\par ??\par ??        [\cf10 Test\cf0 ]\par ??        \cf2 public\cf0  \cf2 void\cf0  ImageWriterWillWriteThumbnailSizePortraitImages()\par ??        \{\par ??            \cf10 ImageWriter\cf0  writer = \cf10 ImageWriter\cf0 .GetThumbnailSizeWriter(imageInStream);\par ??            writer.Write(fullSizePortraitImage);\par ??\par ??            \cf10 Image\cf0  rereadImage = ResizeImageFromStream();\par ??\par ??            \cf10 Assert\cf0 .AreEqual(105, rereadImage.Height);\par ??            \cf10 Assert\cf0 .AreEqual(79, rereadImage.Width);\par ??        \}\par ??\par ??    \}\par ??}
--&gt;I'm leading an agile team through developing a web site. This means that I spend most of my time managing, but on this one occasion I had the opportunity to write some code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We had an image stored in a database that was always either 800x600 (portrait) or 600x800 (landscape). We had a need to render that image on the site either as-is or reduced to one of two other sizes. You can think of this as a thumbnail, a details image, and a full-size image. We were (of course) writing the code test first, and the tests were focusing on getting the sizes right and not so much on checking the generated images. We ended up getting it working, but we were thoroughly disgusted with the code that we produced :) At least we &lt;em&gt;knew&lt;/em&gt; the code was bad, and resolved to fix it when we had a chance.&lt;br /&gt;&lt;br /&gt;Before we get into the application code, let's look at the tests we wrote, and I'll explain the evolution of the code and what the classes involved are.&lt;/p&gt;
&lt;p&gt;As you can see, the class under test is called ImageWriter. It came into being because we were being careful about resource management, so we didn't want to resize an image and expose it to the world, where it might not get disposed. So, our concept was to create this class, whose purpose in life is to write a properly sized image to a Stream. It would ensure that the image was sized correctly, it was put into the stream properly, and the resources were reclaimed. Sounds pretty simple, and it was, other than some ugly switch logic.&lt;/p&gt;
&lt;p&gt;We wrote the first three tests you see below first, starting with just taking in the full-sized landscape image and writing that to the stream. This wasn't a hard test to get working, as you might expect. We followed that up with writing the detail-sized image, which forced us to write a conditional statement to choose between the two sizes. And then we wrote the third test, which caused us to write another else to allow us to choose thumbnail-sized images. At the fourth test, it started to get really ugly when we had to decide if the image was portrait or landscape, which added a totally different conditional statement. Very rapidly this code was becoming unwieldy. We quickly wrote the fifth and sixth tests, just to get the functionality working, since we were just following an already existing pattern, ugly though it was. Once we were finished, though, we knew we needed to refactor this beast before checking it in.&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    7&lt;/span&gt; [&lt;span style="color: teal;"&gt;TestFixture&lt;/span&gt;]&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    8&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriterFixture&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    9&lt;/span&gt; {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   10&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: teal;"&gt;Image&lt;/span&gt; fullSizeLandscapeImage;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   11&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: teal;"&gt;Image&lt;/span&gt; fullSizePortraitImage;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   12&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: teal;"&gt;MemoryStream&lt;/span&gt; imageInStream;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   13&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   14&lt;/span&gt;     [&lt;span style="color: teal;"&gt;SetUp&lt;/span&gt;]&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   15&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; SetUp()&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   16&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   17&lt;/span&gt;         fullSizeLandscapeImage = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Bitmap&lt;/span&gt;(800, 600);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   18&lt;/span&gt;         fullSizePortraitImage = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Bitmap&lt;/span&gt;(600, 800);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   19&lt;/span&gt;         imageInStream = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;MemoryStream&lt;/span&gt;();&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   20&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   21&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   22&lt;/span&gt;     [&lt;span style="color: teal;"&gt;TearDown&lt;/span&gt;]&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   23&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ReleaseResources()&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   24&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   25&lt;/span&gt;         imageInStream.Dispose();&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   26&lt;/span&gt;         fullSizeLandscapeImage.Dispose();&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   27&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   28&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   29&lt;/span&gt;     [&lt;span style="color: teal;"&gt;Test&lt;/span&gt;]&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   30&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ImageWriteWillWriteFullSizeLandscapeImages()&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   31&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   32&lt;/span&gt;         &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; writer = &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt;.GetFullSizeWriter(imageInStream);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   33&lt;/span&gt;         writer.Write(fullSizeLandscapeImage);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   34&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   35&lt;/span&gt;         &lt;span style="color: teal;"&gt;Image&lt;/span&gt; rereadImage = ResizeImageFromStream();&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   36&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   37&lt;/span&gt;         &lt;span style="color: teal;"&gt;Assert&lt;/span&gt;.AreEqual(fullSizeLandscapeImage.Height, rereadImage.Height);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   38&lt;/span&gt;         &lt;span style="color: teal;"&gt;Assert&lt;/span&gt;.AreEqual(fullSizeLandscapeImage.Width, rereadImage.Width);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   39&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   40&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   41&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: teal;"&gt;Image&lt;/span&gt; ResizeImageFromStream()&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   42&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   43&lt;/span&gt;         imageInStream.Seek(0, &lt;span style="color: teal;"&gt;SeekOrigin&lt;/span&gt;.Begin);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   44&lt;/span&gt;         &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: teal;"&gt;Image&lt;/span&gt;.FromStream(imageInStream);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   45&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   46&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   47&lt;/span&gt;     [&lt;span style="color: teal;"&gt;Test&lt;/span&gt;]&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   48&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ImageWriterWillWriteDetailsLandscapeImages()&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   49&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   50&lt;/span&gt;         &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; writer = &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt;.GetDetailsSizeWriter(imageInStream);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   51&lt;/span&gt;         writer.Write(fullSizeLandscapeImage);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   52&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   53&lt;/span&gt;         &lt;span style="color: teal;"&gt;Image&lt;/span&gt; rereadImage = ResizeImageFromStream();&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   54&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   55&lt;/span&gt;         &lt;span style="color: teal;"&gt;Assert&lt;/span&gt;.AreEqual(306, rereadImage.Height);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   56&lt;/span&gt;         &lt;span style="color: teal;"&gt;Assert&lt;/span&gt;.AreEqual(408, rereadImage.Width);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   57&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   58&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   59&lt;/span&gt;     [&lt;span style="color: teal;"&gt;Test&lt;/span&gt;]&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   60&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ImageWriterWillWriteThumbnailLandscapeImages()&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   61&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   62&lt;/span&gt;         &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; writer = &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt;.GetThumbnailSizeWriter(imageInStream);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   63&lt;/span&gt;         writer.Write(fullSizeLandscapeImage);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   64&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   65&lt;/span&gt;         &lt;span style="color: teal;"&gt;Image&lt;/span&gt; rereadImage = ResizeImageFromStream();&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   66&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   67&lt;/span&gt;         &lt;span style="color: teal;"&gt;Assert&lt;/span&gt;.AreEqual(105, rereadImage.Height);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   68&lt;/span&gt;         &lt;span style="color: teal;"&gt;Assert&lt;/span&gt;.AreEqual(140, rereadImage.Width);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   69&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   70&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   71&lt;/span&gt;     [&lt;span style="color: teal;"&gt;Test&lt;/span&gt;]&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   72&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ImageWriterWillWriteFullSizePortraitImages()&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   73&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   74&lt;/span&gt;         &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; writer = &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt;.GetFullSizeWriter(imageInStream);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   75&lt;/span&gt;         writer.Write(fullSizePortraitImage);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   76&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   77&lt;/span&gt;         &lt;span style="color: teal;"&gt;Image&lt;/span&gt; rereadImage = ResizeImageFromStream();&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   78&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   79&lt;/span&gt;         &lt;span style="color: teal;"&gt;Assert&lt;/span&gt;.AreEqual(800, rereadImage.Height);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   80&lt;/span&gt;         &lt;span style="color: teal;"&gt;Assert&lt;/span&gt;.AreEqual(600, rereadImage.Width);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   81&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   82&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   83&lt;/span&gt;     [&lt;span style="color: teal;"&gt;Test&lt;/span&gt;]&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   84&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ImageWriterWillWriteDetailsSizePortraitImages()&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   85&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   86&lt;/span&gt;         &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; writer = &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt;.GetDetailsSizeWriter(imageInStream);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   87&lt;/span&gt;         writer.Write(fullSizePortraitImage);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   88&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   89&lt;/span&gt;         &lt;span style="color: teal;"&gt;Image&lt;/span&gt; rereadImage = ResizeImageFromStream();&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   90&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   91&lt;/span&gt;         &lt;span style="color: teal;"&gt;Assert&lt;/span&gt;.AreEqual(306, rereadImage.Height);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   92&lt;/span&gt;         &lt;span style="color: teal;"&gt;Assert&lt;/span&gt;.AreEqual(230, rereadImage.Width);           &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   93&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   94&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   95&lt;/span&gt;     [&lt;span style="color: teal;"&gt;Test&lt;/span&gt;]&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   96&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; ImageWriterWillWriteThumbnailSizePortraitImages()&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   97&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   98&lt;/span&gt;         &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; writer = &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt;.GetThumbnailSizeWriter(imageInStream);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   99&lt;/span&gt;         writer.Write(fullSizePortraitImage);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;  100&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;  101&lt;/span&gt;         &lt;span style="color: teal;"&gt;Image&lt;/span&gt; rereadImage = ResizeImageFromStream();&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;  102&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;  103&lt;/span&gt;         &lt;span style="color: teal;"&gt;Assert&lt;/span&gt;.AreEqual(105, rereadImage.Height);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;  104&lt;/span&gt;         &lt;span style="color: teal;"&gt;Assert&lt;/span&gt;.AreEqual(79, rereadImage.Width);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;  105&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;  106&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;  107&lt;/span&gt; }&lt;/p&gt;
    &lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now here is the finished, but mostly unrefactored, source code. During the process of writing the tests, we did do some refactoring to clean up the code a bit, make things a bit more readable, etc, but we held off on the Replace Conditional with Polymorphism refactoring that we could both see coming. And that refactoring is what I want to eventually share here. So, here is our ugly code:&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    1&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; : &lt;span style="color: teal;"&gt;IImageWriter&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    2&lt;/span&gt; {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    3&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: teal;"&gt;Stream&lt;/span&gt; stream;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    4&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt; desiredImageSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    5&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; desiredHeight;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    6&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;int&lt;/span&gt; desiredWidth;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    7&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    8&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;enum&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    9&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   10&lt;/span&gt;         THUMBNAIL,&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   11&lt;/span&gt;         DETAILS,&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   12&lt;/span&gt;         FULLSIZE&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   13&lt;/span&gt;     } ;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   14&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   15&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; LandscapeFullSize = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;(0, 0, 800, 600);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   16&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; LandscapeDetailsSize = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;(0, 0, 408, 306);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   17&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; LandscapeThumbnailSize = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;(0, 0, 140, 105);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   18&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; PortraitFullSize = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;(0, 0, 600, 800);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   19&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; PortraitDetailsSize = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;(0,0, 230, 306);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   20&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; PortraitThumbnailSize = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;(0, 0, 79, 105);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   21&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   22&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; GetFullSizeWriter(&lt;span style="color: teal;"&gt;Stream&lt;/span&gt; imageInStream)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   23&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   24&lt;/span&gt;         &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt;(imageInStream, &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.FULLSIZE);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   25&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   26&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   27&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; GetDetailsSizeWriter(&lt;span style="color: teal;"&gt;Stream&lt;/span&gt; imageInStream)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   28&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   29&lt;/span&gt;         &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt;(imageInStream, &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.DETAILS);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   30&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   31&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   32&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; GetThumbnailSizeWriter(&lt;span style="color: teal;"&gt;Stream&lt;/span&gt; imageInStream)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   33&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   34&lt;/span&gt;         &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt;(imageInStream, &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.THUMBNAIL);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   35&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   36&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   37&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; ImageWriter(&lt;span style="color: teal;"&gt;Stream&lt;/span&gt; stream, &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt; imageSize)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   38&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   39&lt;/span&gt;         &lt;span style="color: blue;"&gt;this&lt;/span&gt;.stream = stream;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   40&lt;/span&gt;         desiredImageSize = imageSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   41&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   42&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   43&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Write(&lt;span style="color: teal;"&gt;Image&lt;/span&gt; image)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   44&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   45&lt;/span&gt;         &lt;span style="color: blue;"&gt;int&lt;/span&gt; width = image.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   46&lt;/span&gt;         &lt;span style="color: blue;"&gt;int&lt;/span&gt; height = image.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   47&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   48&lt;/span&gt;         &lt;span style="color: blue;"&gt;if&lt;/span&gt; (width &amp;lt; height) &lt;span style="color: green;"&gt;// isPortrait&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   49&lt;/span&gt;         {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   50&lt;/span&gt;             &lt;span style="color: blue;"&gt;switch&lt;/span&gt;(desiredImageSize)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   51&lt;/span&gt;             {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   52&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.FULLSIZE:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   53&lt;/span&gt;                     desiredHeight = PortraitFullSize.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   54&lt;/span&gt;                     desiredWidth = PortraitFullSize.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   55&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   56&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   57&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.DETAILS:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   58&lt;/span&gt;                     desiredHeight = PortraitDetailsSize.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   59&lt;/span&gt;                     desiredWidth = PortraitDetailsSize.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   60&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   61&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   62&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.THUMBNAIL:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   63&lt;/span&gt;                     desiredHeight = PortraitThumbnailSize.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   64&lt;/span&gt;                     desiredWidth = PortraitThumbnailSize.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   65&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   66&lt;/span&gt;             }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   67&lt;/span&gt;         }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   68&lt;/span&gt;         &lt;span style="color: blue;"&gt;else&lt;/span&gt; &lt;span style="color: green;"&gt;// isLandscape&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   69&lt;/span&gt;         {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   70&lt;/span&gt;             &lt;span style="color: blue;"&gt;switch&lt;/span&gt;(desiredImageSize)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   71&lt;/span&gt;             {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   72&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.FULLSIZE:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   73&lt;/span&gt;                     desiredHeight = LandscapeFullSize.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   74&lt;/span&gt;                     desiredWidth = LandscapeFullSize.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   75&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   76&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   77&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.DETAILS:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   78&lt;/span&gt;                     desiredHeight = LandscapeDetailsSize.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   79&lt;/span&gt;                     desiredWidth = LandscapeDetailsSize.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   80&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   81&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   82&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.THUMBNAIL:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   83&lt;/span&gt;                     desiredHeight = LandscapeThumbnailSize.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   84&lt;/span&gt;                     desiredWidth = LandscapeThumbnailSize.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   85&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   86&lt;/span&gt;             }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   87&lt;/span&gt;         }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   88&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   89&lt;/span&gt;         &lt;span style="color: blue;"&gt;using&lt;/span&gt; (&lt;span style="color: teal;"&gt;Image&lt;/span&gt; resized = image.GetThumbnailImage(desiredWidth, desiredHeight, &lt;span style="color: blue;"&gt;null&lt;/span&gt;, &lt;span style="color: teal;"&gt;IntPtr&lt;/span&gt;.Zero))&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   90&lt;/span&gt;         {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   91&lt;/span&gt;             resized.Save(stream, &lt;span style="color: teal;"&gt;ImageFormat&lt;/span&gt;.Jpeg);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   92&lt;/span&gt;         }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   93&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   94&lt;/span&gt; }&lt;/p&gt;
    &lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The bright idea we had while we were writing it was that we would use the Rectangles to hold the dimensions of an image of the proper size, to make it easier to identify what the magic numbers for height and width meant. This also made it easier for us to write the body of each leg of the case statements. Clearly, however, this was only a short term workaround for a more proper solution later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Beginning the refactoring&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;OK, so we're about to start this. I truly have never attempted the refactoring that we're going to try here on this code, so I'm going to be doing it essentially live for you. I'll try to share with you any mistakes I make, what thoughts are going through my semi-sentient head, and what I'm feeling about the code as it progresses. Our goal is to end up in a situation where any conditional behavior is moved out of a procedural if/then/else block and into some sort of polymorphic dispatch, but to do that in small, orderly steps, such that we're always pretty close to having working code.&lt;/p&gt;
&lt;p&gt;To begin, I'm planning on opening up my refactoring book to the section on Replace Conditional with Polymorphism. As I tell my students in every TDD course I teach, &lt;em&gt;please&lt;/em&gt; open your Fowler Refactoring books and follow the steps, as Martin makes these things easy once you figure out which refactoring to use. So, to follow my own advice, I'm going to open the book and use it as I go.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;First step -- Are the responsibilities in the right place?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The first thing I notice when I look at the ImageWriter's Write method is that I see policy and details happening in the same place. The policy in that class can be summed up as, &amp;quot;Determine the dimensions of the final image, resize the image, and then write the image to the stream&amp;quot;, and the details in that method are concerned with how those dimensions are determined. In order for us to do anything at all to simplify this system, we're going to have to pull the dimension calculations out into another method at least, and into another class possibly after that. So lets start with an ExtractMethod refactoring to get those dimension calculations out of there.&lt;/p&gt;
&lt;p&gt;As my first step in doing this, I noticed that the member variables desiredHeight and desiredWidth weren't really doing anything good for me, and I could get rid of them by using height and width, the local variables declared in the Write method, in their place, as such:&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    1&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Write(&lt;span style="color: teal;"&gt;Image&lt;/span&gt; image)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    2&lt;/span&gt; {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    3&lt;/span&gt;     &lt;span style="color: blue;"&gt;int&lt;/span&gt; width = image.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    4&lt;/span&gt;     &lt;span style="color: blue;"&gt;int&lt;/span&gt; height = image.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    5&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    6&lt;/span&gt;     &lt;span style="color: blue;"&gt;if&lt;/span&gt; (width &amp;lt; height) &lt;span style="color: green;"&gt;// isPortrait&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    7&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    8&lt;/span&gt;         &lt;span style="color: blue;"&gt;switch&lt;/span&gt;(desiredImageSize)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    9&lt;/span&gt;         {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   10&lt;/span&gt;             &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.FULLSIZE:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   11&lt;/span&gt;                 height = PortraitFullSize.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   12&lt;/span&gt;                 width = PortraitFullSize.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   13&lt;/span&gt;                 &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   14&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   15&lt;/span&gt;             &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.DETAILS:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   16&lt;/span&gt;                 height = PortraitDetailsSize.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   17&lt;/span&gt;                 width = PortraitDetailsSize.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   18&lt;/span&gt;                 &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   19&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   20&lt;/span&gt;             &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.THUMBNAIL:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   21&lt;/span&gt;                 height = PortraitThumbnailSize.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   22&lt;/span&gt;                 width = PortraitThumbnailSize.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   23&lt;/span&gt;                 &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   24&lt;/span&gt;         }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   25&lt;/span&gt;     }&lt;/p&gt;
    &lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;and so on. I think this sets me up very nicely to get rid of the individual width and height variables and replacing them with a Rectangle object. I'm going to try that in the code and see where that takes me. I'm not going to make this whole change all at once, because that's too large of a change. Instead, I'm going to find a way to refactor each leg of the switch to contain the assignment to the desiredRectangle reference and then take advantage of that rectangle to set the height and width repeatedly.&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   48&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Write(&lt;span style="color: teal;"&gt;Image&lt;/span&gt; image)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   49&lt;/span&gt; {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   50&lt;/span&gt;     &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; desiredRectangle;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   51&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   52&lt;/span&gt;     &lt;span style="color: blue;"&gt;int&lt;/span&gt; width = image.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   53&lt;/span&gt;     &lt;span style="color: blue;"&gt;int&lt;/span&gt; height = image.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   54&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   55&lt;/span&gt;     &lt;span style="color: blue;"&gt;if&lt;/span&gt; (width &amp;lt; height) &lt;span style="color: green;"&gt;// isPortrait&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   56&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   57&lt;/span&gt;         &lt;span style="color: blue;"&gt;switch&lt;/span&gt;(desiredImageSize)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   58&lt;/span&gt;         {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   59&lt;/span&gt;             &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.FULLSIZE:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   60&lt;/span&gt;                 desiredRectangle = PortraitFullSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   61&lt;/span&gt;                 height = desiredRectangle.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   62&lt;/span&gt;                 width = desiredRectangle.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   63&lt;/span&gt;                 &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;As you can see, I added a new Rectangle reference on line 50 which is going to hold the rectangle with the desired dimensions. And the smallest change I could make to start making use of this was to rewrite the body of the case statement starting on line 60 as you can see. For those of you new to refactoring, this is one of the most important pieces of the process -- take steps that are as small as possible. By doing this, you keep your risk down as low as possible while you're changing your code. If you take big steps and mess something up, it could take you a lot of time to get back to having something working. If you take a small step and mess something up, you can just back up a bit to where things worked. I'm taking a small step here, and just changing this leg of the switch. And after doing this, I ran my tests, and they worked. I'm going to change the rest of the legs now, running my tests between each change. I'll do this privately, as it doesn't seem very interesting to show you each step along this way.&lt;/p&gt;
&lt;p&gt;&amp;lt;time passes&amp;gt;&lt;/p&gt;
&lt;p&gt;OK, I did that, and all my tests worked, and each of the legs of the switches looks just like the sample code above, except for a different equivalent of line 60 for each case. Now that I've done this, I believe I can factor out the setting of the height and width in each leg and do that at the bottom of the method, right before actually doing the resizing. That will leave the code looking like this:&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   48&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Write(&lt;span style="color: teal;"&gt;Image&lt;/span&gt; image)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   49&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   50&lt;/span&gt;         &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; desiredRectangle = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;();&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   51&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   52&lt;/span&gt;         &lt;span style="color: blue;"&gt;if&lt;/span&gt; (image.Width &amp;lt; image.Height) &lt;span style="color: green;"&gt;// isPortrait&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   53&lt;/span&gt;         {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   54&lt;/span&gt;             &lt;span style="color: blue;"&gt;switch&lt;/span&gt;(desiredImageSize)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   55&lt;/span&gt;             {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   56&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.FULLSIZE:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   57&lt;/span&gt;                     desiredRectangle = PortraitFullSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   58&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   59&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   60&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.DETAILS:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   61&lt;/span&gt;                     desiredRectangle = PortraitDetailsSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   62&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   63&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   64&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.THUMBNAIL:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   65&lt;/span&gt;                     desiredRectangle = PortraitThumbnailSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   66&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   67&lt;/span&gt;             }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   68&lt;/span&gt;         }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   69&lt;/span&gt;         &lt;span style="color: blue;"&gt;else&lt;/span&gt; &lt;span style="color: green;"&gt;// isLandscape&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   70&lt;/span&gt;         {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   71            // extra stuff elided&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   85&lt;/span&gt;         }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   86&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   87&lt;/span&gt;         &lt;span style="color: blue;"&gt;int&lt;/span&gt; height = desiredRectangle.Height;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   88&lt;/span&gt;         &lt;span style="color: blue;"&gt;int&lt;/span&gt; width = desiredRectangle.Width;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   89&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   90&lt;/span&gt;         &lt;span style="color: blue;"&gt;using&lt;/span&gt; (&lt;span style="color: teal;"&gt;Image&lt;/span&gt; resized = image.GetThumbnailImage(width, height, &lt;span style="color: blue;"&gt;null&lt;/span&gt;, &lt;span style="color: teal;"&gt;IntPtr&lt;/span&gt;.Zero))&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   91&lt;/span&gt;         {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   92&lt;/span&gt;             resized.Save(stream, &lt;span style="color: teal;"&gt;ImageFormat&lt;/span&gt;.Jpeg);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   93&lt;/span&gt;         }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   94&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   95&lt;/span&gt; }&lt;/p&gt;
    &lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;So each leg of the switches has become more simple and we're breaking out the height and width individually now only at the end. During the next refactoring, I'll probably do an Inline refactoring on height and width, as they're really not helping much, which would shrink this method down even more.&lt;/p&gt;
&lt;p&gt;Now that we're at this point, I think I can do the ExtractMethod I talked about previously on the switch stuff and move that out into another method, so we can  make the Write method only concerned with the higher level, more abstract steps of how this process works, and get the details of how the dimensions are calculated into its own method. After this refactoring, another ExtractMethod to take the mechanics of the writing to the stream out, and a couple of renamings to clarify what the rectangle dimension calculations actually &lt;em&gt;mean&lt;/em&gt;, Write looks like this, which is just about right :)&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   48&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Write(&lt;span style="color: teal;"&gt;Image&lt;/span&gt; image)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   49&lt;/span&gt; {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   50&lt;/span&gt;     &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; imageDimensions = CalculateScaledImageDimensions(image);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   51&lt;/span&gt;     WriteScaledImage(image, imageDimensions);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   52&lt;/span&gt; }&lt;/p&gt;
    &lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;A decision needs to be made&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I'm at somewhat of a crossroads here. In looking back at the Write method, I've decided I really don't like it. Something just seems strange to me about it. I know I need to do something with scaled images, but instead I'm working with the dimensions of that scaled image. To me, the calculations of the dimensions of the scaled images and storing those dimensions into a rectangle seems like an implementation detail of &lt;em&gt;how&lt;/em&gt; I did this. What the code really needs to be using, and written in terms of, are the scaled images themselves. In doing this, I think the method will now read better, since both lines of code in it will be using the same abstraction. Instead of using a Rectangle to represent something &lt;em&gt;about&lt;/em&gt; the scaled image, now I can deal with the scaled image throughout the method. I like this better. This leads us to this code:&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   48&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Write(&lt;span style="color: teal;"&gt;Image&lt;/span&gt; image)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   49&lt;/span&gt; {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   50&lt;/span&gt;     &lt;span style="color: blue;"&gt;using&lt;/span&gt; (&lt;span style="color: teal;"&gt;Image&lt;/span&gt; scaledImage = GenerateScaledImage(image))&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   51&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   52&lt;/span&gt;         WriteScaledImage(scaledImage);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   53&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   54&lt;/span&gt; }&lt;/p&gt;
    &lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I like this a lot better, as it seems like both of the lines of this method are dealing with the same abstraction now, a ScaledImage. This leads me to think that there is a ScaledImage class or hierarchy of classes trying to find its way out, which was our goal when we started this -- we were looking for the right place to put our polymorphic logic, and this ScaledImage class seems like the right place. The final code for this class looks like this:&lt;/p&gt;
&lt;p&gt;&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20     \cf2 public\cf0  \cf2 class\cf0  \cf10 ImageWriter\cf0  : \cf10 IImageWriter\par ??\cf0     \{\par ??        \cf2 private\cf0  \cf10 Stream\cf0  stream;\par ??        \cf2 private\cf0  \cf2 readonly\cf0  \cf10 ImageSize\cf0  desiredImageSize;\par ??\par ??        \cf2 private\cf0  \cf2 enum\cf0  \cf10 ImageSize\par ??\cf0         \{\par ??            THUMBNAIL,\par ??            DETAILS,\par ??            FULLSIZE\par ??        \} ;\par ??\par ??        \cf2 private\cf0  \cf2 readonly\cf0  \cf10 Rectangle\cf0  LandscapeFullSize = \cf2 new\cf0  \cf10 Rectangle\cf0 (0, 0, 800, 600);\par ??        \cf2 private\cf0  \cf2 readonly\cf0  \cf10 Rectangle\cf0  LandscapeDetailsSize = \cf2 new\cf0  \cf10 Rectangle\cf0 (0, 0, 408, 306);\par ??        \cf2 private\cf0  \cf2 readonly\cf0  \cf10 Rectangle\cf0  LandscapeThumbnailSize = \cf2 new\cf0  \cf10 Rectangle\cf0 (0, 0, 140, 105);\par ??        \cf2 private\cf0  \cf2 readonly\cf0  \cf10 Rectangle\cf0  PortraitFullSize = \cf2 new\cf0  \cf10 Rectangle\cf0 (0, 0, 600, 800);\par ??        \cf2 private\cf0  \cf2 readonly\cf0  \cf10 Rectangle\cf0  PortraitDetailsSize = \cf2 new\cf0  \cf10 Rectangle\cf0 (0,0, 230, 306);\par ??        \cf2 private\cf0  \cf2 readonly\cf0  \cf10 Rectangle\cf0  PortraitThumbnailSize = \cf2 new\cf0  \cf10 Rectangle\cf0 (0, 0, 79, 105);\par ??\par ??        \cf2 public\cf0  \cf2 static\cf0  \cf10 ImageWriter\cf0  GetFullSizeWriter(\cf10 Stream\cf0  imageInStream)\par ??        \{\par ??            \cf2 return\cf0  \cf2 new\cf0  \cf10 ImageWriter\cf0 (imageInStream, \cf10 ImageSize\cf0 .FULLSIZE);\par ??        \}\par ??\par ??        \cf2 public\cf0  \cf2 static\cf0  \cf10 ImageWriter\cf0  GetDetailsSizeWriter(\cf10 Stream\cf0  imageInStream)\par ??        \{\par ??            \cf2 return\cf0  \cf2 new\cf0  \cf10 ImageWriter\cf0 (imageInStream, \cf10 ImageSize\cf0 .DETAILS);\par ??        \}\par ??\par ??        \cf2 public\cf0  \cf2 static\cf0  \cf10 ImageWriter\cf0  GetThumbnailSizeWriter(\cf10 Stream\cf0  imageInStream)\par ??        \{\par ??            \cf2 return\cf0  \cf2 new\cf0  \cf10 ImageWriter\cf0 (imageInStream, \cf10 ImageSize\cf0 .THUMBNAIL);\par ??        \}\par ??\par ??        \cf2 private\cf0  ImageWriter(\cf10 Stream\cf0  stream, \cf10 ImageSize\cf0  imageSize)\par ??        \{\par ??            \cf2 this\cf0 .stream = stream;\par ??            desiredImageSize = imageSize;\par ??        \}\par ??\par ??        \cf2 public\cf0  \cf2 void\cf0  Write(\cf10 Image\cf0  image)\par ??        \{\par ??            \cf2 using\cf0  (\cf10 Image\cf0  scaledImage = GenerateScaledImage(image))\par ??            \{\par ??                WriteScaledImage(scaledImage);\par ??            \}\par ??        \}\par ??\par ??        \cf2 private\cf0  \cf2 void\cf0  WriteScaledImage(\cf10 Image\cf0  scaledImage)\par ??        \{\par ??            scaledImage.Save(stream, \cf10 ImageFormat\cf0 .Jpeg);\par ??        \}\par ??\par ??        \cf2 private\cf0  \cf10 Image\cf0  GenerateScaledImage(\cf10 Image\cf0  image)\par ??        \{\par ??            \cf10 Rectangle\cf0  imageDimensions = \cf2 new\cf0  \cf10 Rectangle\cf0 ();\par ??\par ??            \cf2 if\cf0  (image.Width &amp;lt; image.Height) \cf11 // isPortrait\par ??\cf0             \{\par ??                \cf2 switch\cf0 (desiredImageSize)\par ??                \{\par ??                    \cf2 case\cf0  \cf10 ImageSize\cf0 .FULLSIZE:\par ??                        imageDimensions = PortraitFullSize;\par ??                        \cf2 break\cf0 ;\par ??                        \par ??                    \cf2 case\cf0  \cf10 ImageSize\cf0 .DETAILS:\par ??                        imageDimensions = PortraitDetailsSize;\par ??                        \cf2 break\cf0 ;\par ??\par ??                    \cf2 case\cf0  \cf10 ImageSize\cf0 .THUMBNAIL:\par ??                        imageDimensions = PortraitThumbnailSize;\par ??                        \cf2 break\cf0 ;\par ??                \}\par ??            \}\par ??            \cf2 else\cf0  \cf11 // isLandscape\par ??\cf0             \{\par ??                \cf2 switch\cf0 (desiredImageSize)\par ??                \{\par ??                    \cf2 case\cf0  \cf10 ImageSize\cf0 .FULLSIZE:\par ??                        imageDimensions = LandscapeFullSize;\par ??                        \cf2 break\cf0 ;\par ??\par ??                    \cf2 case\cf0  \cf10 ImageSize\cf0 .DETAILS:\par ??                        imageDimensions = LandscapeDetailsSize;\par ??                        \cf2 break\cf0 ;\par ??\par ??                    \cf2 case\cf0  \cf10 ImageSize\cf0 .THUMBNAIL:\par ??                        imageDimensions = LandscapeThumbnailSize;\par ??                        \cf2 break\cf0 ;\par ??                \}\par ??            \}\par ??\par ??            \cf2 return\cf0  image.GetThumbnailImage(imageDimensions.Width, imageDimensions.Height, \cf2 null\cf0 , \cf10 IntPtr\cf0 .Zero);;\par ??        \}\par ??    \}\par ??}
--&gt;&lt;/p&gt;
&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    8&lt;/span&gt; &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;class&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; : &lt;span style="color: teal;"&gt;IImageWriter&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;    9&lt;/span&gt; {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   10&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: teal;"&gt;Stream&lt;/span&gt; stream;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   11&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt; desiredImageSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   12&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   13&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;enum&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   14&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   15&lt;/span&gt;         THUMBNAIL,&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   16&lt;/span&gt;         DETAILS,&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   17&lt;/span&gt;         FULLSIZE&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   18&lt;/span&gt;     } ;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   19&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   20&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; LandscapeFullSize = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;(0, 0, 800, 600);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   21&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; LandscapeDetailsSize = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;(0, 0, 408, 306);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   22&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; LandscapeThumbnailSize = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;(0, 0, 140, 105);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   23&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; PortraitFullSize = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;(0, 0, 600, 800);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   24&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; PortraitDetailsSize = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;(0,0, 230, 306);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   25&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;readonly&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; PortraitThumbnailSize = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;(0, 0, 79, 105);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   26&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   27&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; GetFullSizeWriter(&lt;span style="color: teal;"&gt;Stream&lt;/span&gt; imageInStream)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   28&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   29&lt;/span&gt;         &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt;(imageInStream, &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.FULLSIZE);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   30&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   31&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   32&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; GetDetailsSizeWriter(&lt;span style="color: teal;"&gt;Stream&lt;/span&gt; imageInStream)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   33&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   34&lt;/span&gt;         &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt;(imageInStream, &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.DETAILS);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   35&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   36&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   37&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;static&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt; GetThumbnailSizeWriter(&lt;span style="color: teal;"&gt;Stream&lt;/span&gt; imageInStream)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   38&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   39&lt;/span&gt;         &lt;span style="color: blue;"&gt;return&lt;/span&gt; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageWriter&lt;/span&gt;(imageInStream, &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.THUMBNAIL);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   40&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   41&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   42&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; ImageWriter(&lt;span style="color: teal;"&gt;Stream&lt;/span&gt; stream, &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt; imageSize)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   43&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   44&lt;/span&gt;         &lt;span style="color: blue;"&gt;this&lt;/span&gt;.stream = stream;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   45&lt;/span&gt;         desiredImageSize = imageSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   46&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   47&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   48&lt;/span&gt;     &lt;span style="color: blue;"&gt;public&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; Write(&lt;span style="color: teal;"&gt;Image&lt;/span&gt; image)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   49&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   50&lt;/span&gt;         &lt;span style="color: blue;"&gt;using&lt;/span&gt; (&lt;span style="color: teal;"&gt;Image&lt;/span&gt; scaledImage = GenerateScaledImage(image))&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   51&lt;/span&gt;         {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   52&lt;/span&gt;             WriteScaledImage(scaledImage);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   53&lt;/span&gt;         }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   54&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   55&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   56&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: blue;"&gt;void&lt;/span&gt; WriteScaledImage(&lt;span style="color: teal;"&gt;Image&lt;/span&gt; scaledImage)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   57&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   58&lt;/span&gt;         scaledImage.Save(stream, &lt;span style="color: teal;"&gt;ImageFormat&lt;/span&gt;.Jpeg);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   59&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   60&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   61&lt;/span&gt;     &lt;span style="color: blue;"&gt;private&lt;/span&gt; &lt;span style="color: teal;"&gt;Image&lt;/span&gt; GenerateScaledImage(&lt;span style="color: teal;"&gt;Image&lt;/span&gt; image)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   62&lt;/span&gt;     {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   63&lt;/span&gt;         &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt; imageDimensions = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Rectangle&lt;/span&gt;();&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   64&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   65&lt;/span&gt;         &lt;span style="color: blue;"&gt;if&lt;/span&gt; (image.Width &amp;lt; image.Height) &lt;span style="color: green;"&gt;// isPortrait&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   66&lt;/span&gt;         {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   67&lt;/span&gt;             &lt;span style="color: blue;"&gt;switch&lt;/span&gt;(desiredImageSize)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   68&lt;/span&gt;             {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   69&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.FULLSIZE:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   70&lt;/span&gt;                     imageDimensions = PortraitFullSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   71&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   72&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   73&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.DETAILS:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   74&lt;/span&gt;                     imageDimensions = PortraitDetailsSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   75&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   76&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   77&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.THUMBNAIL:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   78&lt;/span&gt;                     imageDimensions = PortraitThumbnailSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   79&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   80&lt;/span&gt;             }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   81&lt;/span&gt;         }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   82&lt;/span&gt;         &lt;span style="color: blue;"&gt;else&lt;/span&gt; &lt;span style="color: green;"&gt;// isLandscape&lt;/span&gt;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   83&lt;/span&gt;         {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   84&lt;/span&gt;             &lt;span style="color: blue;"&gt;switch&lt;/span&gt;(desiredImageSize)&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   85&lt;/span&gt;             {&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   86&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.FULLSIZE:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   87&lt;/span&gt;                     imageDimensions = LandscapeFullSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   88&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   89&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   90&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.DETAILS:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   91&lt;/span&gt;                     imageDimensions = LandscapeDetailsSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   92&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   93&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   94&lt;/span&gt;                 &lt;span style="color: blue;"&gt;case&lt;/span&gt; &lt;span style="color: teal;"&gt;ImageSize&lt;/span&gt;.THUMBNAIL:&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   95&lt;/span&gt;                     imageDimensions = LandscapeThumbnailSize;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   96&lt;/span&gt;                     &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   97&lt;/span&gt;             }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   98&lt;/span&gt;         }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;   99&lt;/span&gt; &lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;  100&lt;/span&gt;         &lt;span style="color: blue;"&gt;return&lt;/span&gt; image.GetThumbnailImage(imageDimensions.Width, imageDimensions.Height, &lt;span style="color: blue;"&gt;null&lt;/span&gt;, &lt;span style="color: teal;"&gt;IntPtr&lt;/span&gt;.Zero);&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;  101&lt;/span&gt;     }&lt;/p&gt;
    &lt;p style="margin: 0px;"&gt;&lt;span style="color: #2b91af;"&gt;  102&lt;/span&gt; }&lt;/p&gt;
    &lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Next time&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This entry is getting pretty long, so I'm going to end it here. When I pick it up again next time, I'll do the refactoring to pull the conditional logic out into the ScaledImage hierarchy we're going to create and see where the code takes us after that. I suspect that the WriteScaledImage method is going to find its way into there as well, given its name. One big hint that methods want to be grouped together is when you discover that they have a common abstraction as part of their name. Generate&lt;em&gt;ScaledImage&lt;/em&gt; and Write&lt;em&gt;ScaledImage&lt;/em&gt; seem to both be crying out to be in a ScaledImage class to me, but we'll have to see.&lt;/p&gt;
&lt;p&gt;I'm so sorry that I haven't posted any worthwhile content in a long time, but I was tied up managing a huge waterfall-ish project all fall. That project is over, and I'm working with several different agile teams now with varying levels of involvement, which should give me more time to blog. I'm also working on 4 different proposals for Agile 2007 and one for the PMI National Congress. More on those as they get more fully formed.&lt;/p&gt;
&lt;p&gt;As always, if you've made it this far, thanks for reading, and please let me know if you have any comments. I've had to disable comments on the blog as the spammers have taken over the comment logs, so send the emails to me directly. I'll post a summary of the best questions and my answers in my next post.&lt;/p&gt;
&lt;p&gt;-- bab&lt;/p&gt;&lt;img src ="http://www.agileprogrammer.com/oneagilecoder/aggbug/21984.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Brian Button</dc:creator><title>Brian's Handy Dandy Rules of Framework Development</title><link>http://www.agileprogrammer.com/oneagilecoder/archive/2006/06/09/15841.aspx</link><pubDate>Fri, 09 Jun 2006 14:00:00 GMT</pubDate><guid>http://www.agileprogrammer.com/oneagilecoder/archive/2006/06/09/15841.aspx</guid><description>&lt;p&gt;The whole basis of my talk at TechEd is that there are some non-technical rules around which creating good frameworks should revolve. Since I mined those rules from my earlier poll on this blog, I thought I should share my results with you. I give you&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Brian&amp;rsquo;s Handy Dandy Rules for Framework Development&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clients come before frameworks&lt;/li&gt;
&lt;li&gt;Ease of use trumps ease of implementation&lt;/li&gt;
&lt;li&gt;Quality, Quality, Quality&lt;/li&gt;
&lt;li&gt;Be an enabler&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s a people problem&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Clients come before frameworks&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This was easily the most commonly heard bit of advice my poll revealed, and it matches up very nicely with my own experiences. The best frameworks are not created, they are mined out of existing code. The worst frameworks seem to have sprung from the twisted imagination of a rogue architect somewhere&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Ease of use trumps ease of implementation&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As the author of a framework, you need to keep your eye on the ball of making others&amp;rsquo; jobs easier. If you ever have to make a tradeoff between changing something to make it easier to implement and changing something to make it easier for your framework clients to use, always choose the latter. Write good documentation, ship your unit tests, and test out your APIs through writing lots of in-house client code. Lots of eyes on the API helps as well&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Quality, Quality, Quality&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Use Test Driven Development on your framework code, and enable framework users to use it on theirs. This means to avoid things like &lt;em&gt;sealed&lt;/em&gt; and overzealous use of CAS. &amp;lsquo;Nuff said.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Be an enabler&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You can&amp;rsquo;t read people&amp;rsquo;s minds, so don&amp;rsquo;t presume to know what their key uses of your framework will be. Allow people to embrace and extend your framework through extension points. Document these extension points, give lots of examples, and create automation to help users with these tasks.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;It&amp;rsquo;s a people problem&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Building a framework is decidedly not a difficult technical problem. We&amp;rsquo;ve built these things before, we&amp;rsquo;ll build them again. It is primarily an issue of balancing people and their conflicting interests. Good architects know this and are adept at balancing these concerns.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In a nutshell, that&amp;rsquo;s my talk. I have&amp;nbsp;a lot more detail, a lot more stories, and a lot more to say. If you want to hear it, come see me Friday morning, from 9&amp;ndash;10:30 at TechEd :)&lt;/p&gt;
&lt;p&gt;See you there,&lt;/p&gt;
&lt;p&gt;bab&lt;/p&gt;&lt;img src ="http://www.agileprogrammer.com/oneagilecoder/aggbug/15841.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Brian Button</dc:creator><title>I'll be speaking at Tech Ed!</title><link>http://www.agileprogrammer.com/oneagilecoder/archive/2006/05/11/14588.aspx</link><pubDate>Thu, 11 May 2006 15:26:00 GMT</pubDate><guid>http://www.agileprogrammer.com/oneagilecoder/archive/2006/05/11/14588.aspx</guid><description>&lt;p&gt;I&amp;rsquo;ve been meaning to post this for a while, but I&amp;rsquo;m finally making myself do it now&amp;hellip;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll be giving a presentation on &amp;ldquo;Creating Your Own Enterprise Application Framework&amp;rdquo; at Tech Ed in Boston, on Friday, June 16 at 9:00 AM in Grand Ballroom A. My talk is based on experiences in my 2&amp;ndash;1/2 years in patterns &amp;amp; practices and how I believe we most successfully build our libraries and frameworks. I set out to build a technical talk on this subject but quickly came to the realization that framework and library building is just as much about the softer skills of team building, politics, and negotiation.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re going to be in the area, look me up!&lt;/p&gt;
&lt;p&gt;&amp;mdash; bab&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now playing:&lt;/strong&gt; Rush - Force Ten&lt;/p&gt;&lt;img src ="http://www.agileprogrammer.com/oneagilecoder/aggbug/14588.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Brian Button</dc:creator><title>Chock full of bloglets</title><link>http://www.agileprogrammer.com/onea