public void Read()
        {
            const string product = "product";
            const string productVersion = "2.0";
            const string testPurpose = "client";

            const string operatingSystemName = "Os";
            const string operatingSystemServicePack = "SP300";
            const string operatingSystemCulture = "en-US";
            const string operatingSystemPointerSize = "32";

            const string applicationName = "application";
            const string applicationVersion = "1.0";

            const string environmentName = "environment_a";
            const string notificationPath = @"c:\a\b\c\d";

            // Note that the order of the elements is purposefully out of document order to
            // test the ordering of the test steps
            var files = new Dictionary<string, string>();
            var console = BuildConsoleExecuteTestStepFunctions(3, environmentName, files);
            var msi = BuildMsiDeployTestStepFunctions(1, environmentName, files);
            var script = BuildScriptExecuteTestStepFunctions(2, environmentName, files);
            var xcopy = BuildXCopyDeployTestStepFunctions(0, environmentName, files);

            // Load the config file string
            var text = EmbeddedResourceExtracter.LoadEmbeddedTextFile(
               Assembly.GetExecutingAssembly(),
               "Sherlock.Console.Sherlock.Configuration.v12.xml");
            string configText;
            {
                var builder = new StringBuilder(text);
                builder.Replace("${NAME_OF_PRODUCT_UNDER_TEST}$", product);
                builder.Replace("${VERSION_OF_PRODUCT_UNDER_TEST}$", productVersion);
                builder.Replace("${PURPOSE_OF_TEST}$", testPurpose);

                builder.Replace("${OPERATING_SYSTEM_NAME}$", operatingSystemName);
                builder.Replace("${OPERATING_SYSTEM_SERVICE_PACK}$", operatingSystemServicePack);
                builder.Replace("${OPERATING_SYSTEM_CULTURE}$", operatingSystemCulture);
                builder.Replace("${OPERATING_SYSTEM_POINTER_SIZE}$", operatingSystemPointerSize);

                builder.Replace("${APPLICATION_NAME}$", applicationName);
                builder.Replace("${APPLICATION_VERSION}$", applicationVersion);

                console.Item1(builder);
                msi.Item1(builder);
                script.Item1(builder);
                xcopy.Item1(builder);

                builder.Replace("${NOTIFICATION_DIRECTORY_FULL_PATH_GOES_HERE}$", notificationPath);

                configText = builder.ToString();
            }

            var doc = XDocument.Parse(configText, LoadOptions.None);

            var file = new MockFile(files);
            var directory = new MockDirectory(xcopy.Item4);
            var fileSystem = new Mock<IFileSystem>();
            {
                fileSystem.Setup(f => f.File)
                    .Returns(file);
                fileSystem.Setup(f => f.Directory)
                    .Returns(directory);
            }

            StoreFileDataForEnvironment storage =
                (environment, step, name, data) =>
                {
                    switch (step)
                    {
                        case 0:
                            xcopy.Item2(environment, step, name, data);
                            break;
                        case 1:
                            msi.Item2(environment, step, name, data);
                            break;
                        case 2:
                            script.Item2(environment, step, name, data);
                            break;
                        case 3:
                            console.Item2(environment, step, name, data);
                            break;
                        default:
                            Assert.Fail();
                            break;
                    }
                };

            var reader = new ConfigurationReaderVersion12(fileSystem.Object, storage);
            var config = reader.Read(doc);
            Assert.IsNotNull(config);

            Assert.AreEqual(product, config.Test.ProductUnderTest);
            Assert.AreEqual(productVersion, config.Test.VersionOfProductUnderTest);
            Assert.AreEqual(testPurpose, config.Test.Description);

            Assert.AreEqual(1, config.Test.Environments.Count());

            var testSteps = config.Test.TestSteps.ToList();
            console.Item3(testSteps[0] as ConsoleExecuteTestStepDescription);
            msi.Item3(testSteps[1] as MsiInstallTestStepDescription);
            script.Item3(testSteps[2] as ScriptExecuteTestStepDescription);
            xcopy.Item3(testSteps[3] as XCopyTestStepDescription);

            Assert.AreEqual(notificationPath, config.Test.ReportPath);
        }
        public void ReadWithIncorrectVersionNumber()
        {
            // Load the config file string
            var configText = EmbeddedResourceExtracter.LoadEmbeddedTextFile(
               Assembly.GetExecutingAssembly(),
               "Sherlock.Console.Sherlock.Configuration.v11.xml");

            // Replace the version place holder
            configText = configText.Replace("${VERSION}$", new Version(2, 1).ToString());
            var doc = XDocument.Parse(configText, LoadOptions.None);

            var fileSystem = new Mock<IFileSystem>();
            StoreFileDataForEnvironment storage = (environment, step, name, data) => { };

            var reader = new ConfigurationReaderVersion12(fileSystem.Object, storage);
            Assert.Throws<NonMatchingVersionFoundException>(() => reader.Read(doc));
        }