Commits

Reshef Mann committed 9860bba

Initial commit

Comments (0)

Files changed (44)

+syntax: glob
+
+ďťż
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfigReader", "src\app\ConfigReader\ConfigReader.csproj", "{49334784-9B6B-479F-9DCD-3B33D0AA8B8E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfigReader.Tests", "src\tests\ConfigReader.Tests\ConfigReader.Tests.csproj", "{623A59F3-4D70-4A39-B60A-C727622C0F74}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{49334784-9B6B-479F-9DCD-3B33D0AA8B8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{49334784-9B6B-479F-9DCD-3B33D0AA8B8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{49334784-9B6B-479F-9DCD-3B33D0AA8B8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{49334784-9B6B-479F-9DCD-3B33D0AA8B8E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{623A59F3-4D70-4A39-B60A-C727622C0F74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{623A59F3-4D70-4A39-B60A-C727622C0F74}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{623A59F3-4D70-4A39-B60A-C727622C0F74}.Release|Any CPU.ActiveCfg = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
+<?xml version="1.0" encoding="utf-8" ?>
+
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <Target Name="build_release">
+    <MSBuild Projects="src\app\ConfigReader\ConfigReader.csproj" Properties="Configuration=Release;"/>
+    <RemoveDir Directories="Output"/>
+    <MakeDir Directories="Output"/>
+    <Exec Command="tools\ILMerge\ILMerge.exe /log /lib:src\app\ConfigReader\bin\Release /internalize /out:Output\ConfigReader.dll ConfigReader.dll Castle.Components.DictionaryAdapter.dll" />
+  </Target>
+
+
+</Project>

build_release.bat

+%WinDir%\Microsoft.NET\Framework\v3.5\msbuild.exe build.msbuild /target:build_release

lib/.DS_Store

Binary file added.

lib/Castle.DictionaryAdapter/Castle.Components.DictionaryAdapter.dll

Binary file added.

src/app/ConfigReader/ConfigConverter.cs

+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+
+namespace ConfigReader
+{
+    internal class ConfigConverter
+    {
+        private readonly Type type;
+        private readonly Dictionary<Type, Func<string, object>> customConversions;
+        private readonly Dictionary<string, PropertyInfo> propertiesOfType;
+
+        public ConfigConverter(Type type, Dictionary<Type, Func<string, object>> customConversions)
+        {
+            if (type == null) 
+                throw new ArgumentNullException("type");
+            
+            this.type = type;
+            this.customConversions = customConversions;
+            propertiesOfType = type.GetProperties().ToDictionary(prop=>prop.Name);
+        }
+
+        public IDictionary ConvertConfigProperties(IDictionary<string, object> configurationForT)
+        {
+            var result = new Dictionary<string, object>(configurationForT.Count);
+
+            foreach(var pair in configurationForT)
+            {
+                var name = pair.Key;
+
+                var propertyInfo = propertiesOfType[name];
+
+                var value = ConvertValue(pair, name, propertyInfo);
+
+                result.Add(name, value);
+            }
+            return result;
+        }
+
+        private object ConvertValue(KeyValuePair<string, object> pair, string name, PropertyInfo propertyInfo)
+        {
+            object value;
+
+            if (customConversions != null && customConversions.ContainsKey(propertyInfo.PropertyType) && pair.Value is string)
+            {
+                try
+                {
+                    value = customConversions[propertyInfo.PropertyType](pair.Value as string);
+                }
+                catch (Exception ex)
+                {
+                    throw new ConfigurationException(
+                        String.Format("The property '{0}.{1}' could not be converted correctly.", type.Name, name),
+                        ex);
+                }
+            }
+            else if (pair.Value == null || propertyInfo.PropertyType.IsAssignableFrom(pair.Value.GetType()))
+            {
+                value = pair.Value;
+            }
+            else
+            {
+                var converter = TypeDescriptor.GetConverter(propertyInfo.PropertyType);
+
+                try
+                {
+                    value = converter.ConvertFrom(pair.Value);
+                }
+                catch (Exception ex)
+                {
+                    throw new ConfigurationException(
+                        String.Format("The property '{0}.{1}' could not be converted correctly.", type.Name, name),
+                        ex);
+                }
+            }
+            return value;
+        }
+    }
+}

src/app/ConfigReader/ConfigNameParts/ConfigProperty.cs

+ďťżusing System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace ConfigReader.ConfigNameParts
+{
+    public class ConfigProperty
+    {
+        public string Name { get; internal set; }
+        public object Value { get; internal set; }
+    }
+
+    public class ConfigPropertyCollection : KeyedCollection<string, ConfigProperty>
+    {
+        protected override string GetKeyForItem(ConfigProperty item)
+        {
+            return item.Name;
+        }
+
+        public Dictionary<string, object> GetValuesDictionary()
+        {
+            var result = new Dictionary<string, object>(this.Count);
+
+            foreach (var item in this.Items)
+            {
+                result.Add(item.Name, item.Value);
+            }
+
+            return result;
+        }
+    }
+}

src/app/ConfigReader/ConfigNameParts/ConfigType.cs

+ďťżusing System.Collections.ObjectModel;
+
+namespace ConfigReader.ConfigNameParts
+{
+    public class ConfigType
+    {
+        public ConfigType(string name)
+        {
+            this.Name = name;
+            this.Properties = new ConfigPropertyCollection();
+        }
+
+        public string Name { get; private set; }
+        public ConfigPropertyCollection Properties { get; private set; }
+
+        public void Add(string name, string value)
+        {
+            this.Properties.Add(new ConfigProperty {Name = name, Value = value});
+        }
+    }
+
+    public class ConfigTypesCollection : KeyedCollection<string, ConfigType>
+    {
+        public new ConfigType this[string name]
+        {
+            get
+            {
+                if (this.Contains(name))
+                    return base[name];
+                
+                if (this.Contains(name.TrimStart('I')))
+                    return base[name.TrimStart('I')];
+
+                return null;
+            }
+        }
+
+        protected override string GetKeyForItem(ConfigType item)
+        {
+            return item.Name;
+        }
+    }
+}

src/app/ConfigReader/ConfigReader.csproj

+ďťż<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{49334784-9B6B-479F-9DCD-3B33D0AA8B8E}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>ConfigReader</RootNamespace>
+    <AssemblyName>ConfigReader</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Castle.Components.DictionaryAdapter, Version=1.0.3.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\lib\Castle.DictionaryAdapter\Castle.Components.DictionaryAdapter.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.configuration" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ConfigConverter.cs" />
+    <Compile Include="ConfigTransformer.cs" />
+    <Compile Include="ConfigurationException.cs" />
+    <Compile Include="ConfigurationReader.cs" />
+    <Compile Include="ConfigurationSources\AppConfigSource.cs" />
+    <Compile Include="ConfigurationSources\MappedAppConfigSource.cs" />
+    <Compile Include="DefaultConfigurationBrowser.cs" />
+    <Compile Include="ConfigNameParts\ConfigProperty.cs" />
+    <Compile Include="ConfigNameParts\ConfigType.cs" />
+    <Compile Include="Interfaces\IConfigurationBrowser.cs" />
+    <Compile Include="Interfaces\IConfigurationSource.cs" />
+    <Compile Include="NameSplitter.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SplittedName.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

src/app/ConfigReader/ConfigTransformer.cs

+using System;
+using System.Collections.Generic;
+using ConfigReader.ConfigNameParts;
+
+namespace ConfigReader
+{
+    internal class ConfigTransformer
+    {
+		#region Fields (3) 
+
+        private ConfigTypesCollection configurationEntriesCollection = null;
+        private readonly IDictionary<string, string> inputConfiguration;
+        private static readonly NameSplitter nameSplitter = new NameSplitter();
+
+		#endregion Fields 
+
+		#region Constructors (1) 
+
+        private ConfigTransformer(IDictionary<string, string> inputConfiguration)
+        {
+            if (inputConfiguration == null) 
+                throw new ArgumentNullException("inputConfiguration");
+
+            this.inputConfiguration = inputConfiguration;
+        }
+
+		#endregion Constructors 
+
+		#region Methods (8) 
+
+		// Private Methods (6) 
+
+        private void AddTheConfigurationValue(SplittedName splittedName, KeyValuePair<string, string> entry)
+        {
+            configurationEntriesCollection[splittedName.TypeName].Add(splittedName.Key, entry.Value);
+        }
+
+        private void CreateTheTransformedDictionary()
+        {
+            configurationEntriesCollection = new ConfigTypesCollection();
+        }
+
+        private void EnsureTransformedDictionaryHasKey(SplittedName splittedName)
+        {
+            if (!configurationEntriesCollection.Contains(splittedName.TypeName))
+                configurationEntriesCollection.Add(new ConfigType(splittedName.TypeName));
+        }
+
+        private void SetupTheTransformedDictionary()
+        {
+            CreateTheTransformedDictionary();
+            foreach(var entry in inputConfiguration)
+            {
+                var splittedName = SplitTheFlatKey(entry);
+                
+                if (!TheNameIsValid(splittedName)) 
+                    continue;
+
+                EnsureTransformedDictionaryHasKey(splittedName);
+                AddTheConfigurationValue(splittedName, entry);
+            }
+        }
+
+        private static SplittedName SplitTheFlatKey(KeyValuePair<string, string> entry)
+        {
+            return nameSplitter.Split(entry.Key);
+        }
+
+        private static bool TheNameIsValid(SplittedName splittedName)
+        {
+            return splittedName != null;
+        }
+		// Internal Methods (2) 
+
+        internal static ConfigTransformer ForConfigSource(IDictionary<string, string> inputConfiguration)
+        {
+            return new ConfigTransformer(inputConfiguration);
+        }
+
+        internal ConfigTypesCollection Transform()
+        {
+            if (configurationEntriesCollection == null)
+            {
+                SetupTheTransformedDictionary();
+            }
+            return configurationEntriesCollection;
+        }
+
+		#endregion Methods 
+    }
+}

src/app/ConfigReader/ConfigurationException.cs

+using System;
+using System.Runtime.Serialization;
+
+namespace ConfigReader
+{
+    public class ConfigurationException : Exception
+    {
+        public ConfigurationException()
+        {
+        }
+
+        public ConfigurationException(string message) : base(message)
+        {
+        }
+
+        public ConfigurationException(string message, Exception innerException) : base(message, innerException)
+        {
+        }
+
+        protected ConfigurationException(SerializationInfo info, StreamingContext context) : base(info, context)
+        {
+        }
+    }
+}

src/app/ConfigReader/ConfigurationReader.cs

+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Castle.Components.DictionaryAdapter;
+using ConfigReader.ConfigNameParts;
+using ConfigReader.ConfigurationSources;
+using ConfigReader.Interfaces;
+
+namespace ConfigReader
+{
+    public class ConfigurationReader
+    {
+        private readonly IConfigurationSource configurationSource;
+        private readonly DictionaryAdapterFactory dictionaryAdapterFactory = new DictionaryAdapterFactory();
+        private readonly DefaultConfigurationBrowser configBrowser = new DefaultConfigurationBrowser();
+        private ConfigTypesCollection configTypes;
+        private Dictionary<Type, Func<string, object>> customConversions;
+
+        /// <summary>
+        /// Creates the ConfigurationReader based on the Application Configuration file.
+        /// </summary>
+        public ConfigurationReader()
+            :this(new AppConfigSource())
+        {
+        }
+
+
+        public ConfigurationReader(IConfigurationSource configurationSource)
+        {
+            if (configurationSource == null) 
+                throw new ArgumentNullException("configurationSource");
+
+            this.configurationSource = configurationSource;
+            Initialize();
+        }
+
+        private void Initialize()
+        {
+            configTypes = ConfigTransformer.
+                ForConfigSource(configurationSource.GetConfigDictionary()).
+                Transform();
+        }
+
+        public ConfigurationReader SetupConfigOf<T>()
+        {
+            var cnfg = typeof (T);
+
+            var config = configTypes[cnfg.Name];
+
+            var configurationForT = config.Properties.GetValuesDictionary();
+
+            var configConverter = new ConfigConverter(typeof (T), CustomConversions);
+
+            var convertedConfiguration = configConverter.ConvertConfigProperties(configurationForT);
+            
+            configBrowser.AddConfigAdapter(
+                typeof(T),
+                dictionaryAdapterFactory.GetAdapter<T>(convertedConfiguration));
+
+            return this;
+        }
+
+        public ConfigurationReader SetupConfigOf<T>(object defaultValues)
+        {
+            FillConfigTypesWithDefaultValues<T>(defaultValues);
+            return SetupConfigOf<T>();
+        }
+
+        private void FillConfigTypesWithDefaultValues<T>(object defaultValues)
+        {
+            var configType = typeof (T);
+
+            var typePublicProperties = configType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);
+            
+            var config = configTypes[configType.Name];
+            
+            if(config == null)
+                configTypes.Add(config = new ConfigType(configType.Name));
+
+            var configurationForT = config.Properties;
+
+            foreach (var propertyInfo in typePublicProperties)
+            {
+                var propertyName = propertyInfo.Name;
+
+                if (!configurationForT.Contains(propertyName))
+                {
+                    ConfigProperty configProperty;
+                    try
+                    {
+                        configProperty = new ConfigProperty
+                                             {
+                                                 Name = propertyName,
+                                                 Value =
+                                                     defaultValues.GetType().GetProperty(propertyName).GetValue(
+                                                     defaultValues, null)
+                                             };
+                    }
+                    catch (NullReferenceException)
+                    {
+                        throw new ConfigurationException(
+                            String.Format("The default values object misses the property named '{0}' of type '{1}'.",
+                                          propertyName, propertyInfo.PropertyType.FullName));
+                    }
+
+                    if (configProperty.Value != null &&
+                        !propertyInfo.PropertyType.IsAssignableFrom(configProperty.Value.GetType()))
+                        throw new ConfigurationException(
+                            String.Format("The default values object misses the property named '{0}' of type '{1}'.",
+                                          propertyName, propertyInfo.PropertyType.FullName));
+
+
+                    configurationForT.Add(configProperty);
+                }
+            }
+        }
+
+        private void ValidateConfiguration()
+        {
+            
+        }
+
+        public IConfigurationBrowser ConfigBrowser
+        {
+            get
+            {
+                return configBrowser;
+            }
+        }
+
+        public ConfigurationReader SetupCustomConverter<T>(Func<string, T> conversion)
+        {
+            CustomConversions.Add(typeof (T), source => conversion(source) as object);
+            return this;
+        }
+
+        private Dictionary<Type, Func<string, object>> CustomConversions
+        {
+            get
+            {
+                if(customConversions == null)
+                    customConversions = new Dictionary<Type, Func<string, object>>();
+
+                return customConversions;
+            }
+        }
+    }
+}

src/app/ConfigReader/ConfigurationSources/AppConfigSource.cs

+using System.Collections.Generic;
+using ConfigReader.Interfaces;
+using System.Configuration;
+
+namespace ConfigReader.ConfigurationSources
+{
+    public class AppConfigSource : IConfigurationSource
+    {
+        public IDictionary<string, string> GetConfigDictionary()
+        {
+            var appSettings = ConfigurationManager.AppSettings;
+            var result = new Dictionary<string, string>(appSettings.Count);
+
+            foreach (var key in appSettings.AllKeys)
+            {
+                result.Add(key, appSettings[key]);    
+            }
+            return result;
+        }
+    }
+}

src/app/ConfigReader/ConfigurationSources/MappedAppConfigSource.cs

+using System.Collections.Generic;
+using System.Configuration;
+using ConfigReader.Interfaces;
+
+namespace ConfigReader.ConfigurationSources
+{
+    public class MappedAppConfigSource : IConfigurationSource
+    {
+        private readonly Dictionary<string, string> configDictionary;
+
+        public MappedAppConfigSource(string mappedConfig)
+        {
+            var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = mappedConfig };
+            var config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
+
+            this.configDictionary = new Dictionary<string, string>(config.AppSettings.Settings.Count);
+
+            foreach (var key in config.AppSettings.Settings.AllKeys)
+            {
+                this.configDictionary.Add(key, config.AppSettings.Settings[key].Value);
+            }
+        }
+
+        public IDictionary<string, string> GetConfigDictionary()
+        {
+            return configDictionary;
+        }
+    }
+}

src/app/ConfigReader/DefaultConfigurationBrowser.cs

+ďťżusing System;
+using System.Collections.Generic;
+using ConfigReader.Interfaces;
+
+namespace ConfigReader
+{
+    internal class DefaultConfigurationBrowser : IConfigurationBrowser
+    {
+        private readonly Dictionary<Type, object> configurations = new Dictionary<Type,object>();
+
+        internal void AddConfigAdapter(Type type, object instance)
+        {
+            configurations.Add(type, instance);
+        }
+
+        #region IConfigurationBrowser Members
+
+        public T Get<T>()
+        {
+            return (T)configurations[typeof (T)];
+        }
+
+        #endregion
+    }
+}

src/app/ConfigReader/Interfaces/IConfigurationBrowser.cs

+namespace ConfigReader.Interfaces
+{
+    public interface IConfigurationBrowser
+    {
+        T Get<T>();
+    }
+}

src/app/ConfigReader/Interfaces/IConfigurationSource.cs

+using System.Collections.Generic;
+
+namespace ConfigReader.Interfaces
+{
+    public interface IConfigurationSource
+    {
+        IDictionary<string, string> GetConfigDictionary();
+    }
+}

src/app/ConfigReader/NameSplitter.cs

+using System;
+using System.Text.RegularExpressions;
+
+namespace ConfigReader
+{
+    public class NameSplitter
+    {
+        private const string typeCapture = "Type";
+        private const string keyCapture = "Key";
+        private static readonly Regex splitter = new Regex(String.Format(@"(?<{0}>\w+)\.(?<{1}>\w+)", typeCapture, keyCapture), RegexOptions.Compiled);
+
+        public SplittedName Split(string name)
+        {
+            if (name == null || !splitter.IsMatch(name))
+                return null;
+
+            var groups = splitter.Match(name).Groups;
+           
+            string typeName = groups[typeCapture].Captures[0].Value;
+            string keyName = groups[keyCapture].Captures[0].Value;
+
+            return new SplittedName(typeName, keyName);
+        }
+    }
+}

src/app/ConfigReader/Properties/AssemblyInfo.cs

+ďťżusing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ConfigReader")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyProduct("ConfigReader")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("4622b561-de80-4f3f-9869-50647c33d779")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+
+#if DEBUG
+[assembly: InternalsVisibleTo("ConfigReader.Tests")]
+#endif
+

src/app/ConfigReader/SplittedName.cs

+namespace ConfigReader
+{
+    public class SplittedName
+    {
+        public readonly string TypeName;
+        public readonly string Key;
+
+        public SplittedName(string typeName, string key)
+        {
+            TypeName = typeName;
+            Key = key;
+        }
+    }
+}

src/tests/ConfigReader.Tests/ConfigReader.Tests.csproj

+ďťż<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{623A59F3-4D70-4A39-B60A-C727622C0F74}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>ConfigReader.Tests</RootNamespace>
+    <AssemblyName>ConfigReader.Tests</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="nunit.framework, Version=2.4.6.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\tools\NUnit\nunit.framework.dll</HintPath>
+    </Reference>
+    <Reference Include="Rhino.Mocks, Version=3.4.0.0, Culture=neutral, PublicKeyToken=0b3305902db7183f, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\tools\RhinoMocks\Rhino.Mocks.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="ConfigTransformerFixture.cs" />
+    <Compile Include="ConfigurationReaderSpecificationBase.cs" />
+    <Compile Include="IConfigurationAdapter1.cs" />
+    <Compile Include="IConfigurationAdapter2.cs" />
+    <Compile Include="when_a_custom_conversion_strategy_is_set_for_a_type.cs" />
+    <Compile Include="when_config_reader_does_not_have_a_complete_config_in_the_source.cs" />
+    <Compile Include="when_config_reader_reads_a_values_that_cant_be_casted_to_the_interface_datatype.cs" />
+    <Compile Include="when_config_reader_reads_configuration_with_different_data_types.cs" />
+    <Compile Include="NameSplitterFixture.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="when_config_reader_reads_maps_to_two_interfaces_that_has_property_with_the_same_name.cs" />
+    <Compile Include="when_one_adapter_is_from_config_and_one_from_default_config.cs" />
+    <Compile Include="when_the_config_reader_get_default_vaules.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\app\ConfigReader\ConfigReader.csproj">
+      <Project>{49334784-9B6B-479F-9DCD-3B33D0AA8B8E}</Project>
+      <Name>ConfigReader</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="mappedConfig.xml">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

src/tests/ConfigReader.Tests/ConfigTransformerFixture.cs

+using System.Collections.Generic;
+using ConfigReader;
+using NUnit.Framework;
+
+namespace ConfigReader.Tests
+{
+    [TestFixture]
+    public class ConfigTransformerFixture
+    {
+        [Test]
+        public void Parse_GetsAFlatDictionaryOfConfiguration_ShouldReturnAnHierarchicalStructure()
+        {
+            var inputConfiguration =
+                new Dictionary<string, string>
+                    {
+                        {"StubInterface.StrProp", "the value"},
+                        {"StubInterface.IntProp", "1"}
+                    };
+
+
+            var transformer = ConfigTransformer.ForConfigSource(inputConfiguration);
+
+            var transformedDictionary = transformer.Transform();
+
+            Assert.AreEqual(1, transformedDictionary.Count);
+            Assert.IsTrue(transformedDictionary.Contains("StubInterface"));
+            Assert.AreEqual(2, transformedDictionary["StubInterface"].Properties.Count);
+        }
+    }
+
+    public interface IStubInterface
+    {
+        string StrProp { get; }
+        string IntProp { get; }
+    }
+}

src/tests/ConfigReader.Tests/ConfigurationReaderSpecificationBase.cs

+using ConfigReader.Interfaces;
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace ConfigReader.Tests
+{
+    public abstract class ConfigurationReaderSpecificationBase
+    {
+        protected MockRepository mocks;
+        protected IConfigurationSource configSource;
+
+        [SetUp]
+        protected virtual void Context()
+        {
+            mocks = new MockRepository();
+            configSource = this.mocks.DynamicMock<IConfigurationSource>();
+        }
+    }
+}

src/tests/ConfigReader.Tests/IConfigurationAdapter1.cs

+using System;
+using System.Drawing;
+
+namespace ConfigReader.Tests
+{
+    public interface IConfigurationAdapter1
+    {
+        string StringProperty { get; }
+        int IntegerProperty { get; }
+        Color ColorProperty { get; }
+        Uri AddressProperty { get; }
+    }
+}

src/tests/ConfigReader.Tests/IConfigurationAdapter2.cs

+namespace ConfigReader.Tests
+{
+    public interface IConfigurationAdapter2
+    {
+        string StringProperty { get; }
+        bool BoolProperty { get; }
+    }
+}

src/tests/ConfigReader.Tests/NameSplitterFixture.cs

+using NUnit.Framework;
+
+namespace ConfigReader.Tests
+{
+    [TestFixture]
+    public class NameSplitterFixture
+    {
+        private NameSplitter splitter;
+
+        [SetUp]
+        public void Setup()
+        {
+            splitter = new NameSplitter();
+        }
+
+        [Test]
+        public void Split_ValidNameConsistsOfTwoPartsSeparatedByDot_ReturnsTheFirstPartAndScondPart()
+        {
+            var name = "TheTypeName.TheKey";
+
+            SplittedName splitted = splitter.Split(name);
+
+            Assert.IsNotNull(splitted);
+            Assert.AreEqual("TheTypeName", splitted.TypeName);
+            Assert.AreEqual("TheKey", splitted.Key);
+        }
+
+        [Test]
+        public void Split_NameThatHasNoDot_ShouldReturnNull()
+        {
+            var name = "NonValidName";
+
+            SplittedName splitted = splitter.Split(name);
+
+            Assert.IsNull(splitted);
+        }
+
+        [Test]
+        public void Split_NameIsNull_ShouldReturnNull()
+        {
+            SplittedName splitted = splitter.Split(null);
+
+            Assert.IsNull(splitted);
+        }
+    }
+}

src/tests/ConfigReader.Tests/Properties/AssemblyInfo.cs

+ďťżusing System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ConfigReader.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyProduct("ConfigReader.Tests")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("291504f4-2ed9-41ca-93ad-5e7331bb44ab")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

src/tests/ConfigReader.Tests/mappedConfig.xml

+ďťż<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+  <appSettings>
+    <add key="ConfigurationAdapter1.IntegerProperty" value="99"/>
+  </appSettings>
+</configuration>

src/tests/ConfigReader.Tests/when_a_custom_conversion_strategy_is_set_for_a_type.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace ConfigReader.Tests
+{
+    [TestFixture]
+    public class when_a_custom_conversion_strategy_is_set_for_a_type  : ConfigurationReaderSpecificationBase
+    {
+        protected override void Context()
+        {
+            base.Context();
+
+            var configDictionaryToReturn =
+                new Dictionary<string, string>
+                    {
+                        {"CustomConversion.Address", "111.111.111.2"},
+                        {"CustomConversion.StringArray", "value1;value2;value3"}
+                    };
+
+            SetupResult.For(this.configSource.GetConfigDictionary()).Return(configDictionaryToReturn);
+
+            mocks.ReplayAll();
+        }
+
+
+        [Test]
+        public void it_should_use_it_to_convert_type_that_have_no_type_converter()
+        {
+            var configReader = new ConfigurationReader(this.configSource);
+
+            configReader.
+                SetupCustomConverter(source => source.Split(';')).
+                SetupCustomConverter((string source) => IPAddress.Parse(source)).
+                SetupConfigOf<ICustomConversion>();
+
+
+            var array = configReader.ConfigBrowser.Get<ICustomConversion>().StringArray;
+            Assert.AreEqual(3, array.Count());
+            Assert.AreEqual("value3", array.ElementAt(2));
+
+            var ipAddress = configReader.ConfigBrowser.Get<ICustomConversion>().Address;
+            Assert.IsNotNull(ipAddress);
+            Assert.AreEqual("111.111.111.2", ipAddress.ToString());
+        }
+
+        public interface ICustomConversion
+        {
+            IPAddress Address { get; }
+            string[] StringArray { get; }
+        }
+
+    }
+}

src/tests/ConfigReader.Tests/when_config_reader_does_not_have_a_complete_config_in_the_source.cs

+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace ConfigReader.Tests
+{
+    [TestFixture]
+    public class when_config_reader_does_not_have_a_complete_config_in_the_source : ConfigurationReaderSpecificationBase
+    {
+        protected override void Context()
+        {
+            base.Context();
+
+            var configDictionaryToReturn =
+                new Dictionary<string, string>
+                    {
+                        {"ConfigurationAdapter1.StringProperty", "1prop1"}
+                    };
+
+            SetupResult.For(this.configSource.GetConfigDictionary()).Return(configDictionaryToReturn);
+
+            this.mocks.ReplayAll();
+        }
+
+        [Test]
+        public void it_should_return_the_default_value_for_the_type()
+        {
+            var configReader = new ConfigurationReader(this.configSource).SetupConfigOf<IConfigurationAdapter1>();
+            
+            Assert.AreEqual(0, configReader.ConfigBrowser.Get<IConfigurationAdapter1>().IntegerProperty);
+            Assert.AreEqual(Color.Empty, configReader.ConfigBrowser.Get<IConfigurationAdapter1>().ColorProperty);
+        }
+    }
+}

src/tests/ConfigReader.Tests/when_config_reader_reads_a_values_that_cant_be_casted_to_the_interface_datatype.cs

+using System.Collections.Generic;
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace ConfigReader.Tests
+{
+    [TestFixture]
+    public class when_config_reader_reads_a_values_that_cant_be_casted_to_the_interface_datatype : ConfigurationReaderSpecificationBase
+    {
+        protected override void Context()
+        {
+            base.Context();
+
+            var configDictionaryToReturn =
+                new Dictionary<string, string>
+                    {
+                        {"ConfigurationAdapter1.IntegerProperty", 2.ToString()},
+                        {"ConfigurationAdapter1.StringProperty", "1prop1"},
+                        {"ConfigurationAdapter1.ColorProperty", "WrongValue"}
+                    };
+
+            SetupResult.For(this.configSource.GetConfigDictionary()).Return(configDictionaryToReturn);
+
+            mocks.ReplayAll();
+        }
+
+
+        [Test]
+        [ExpectedException(typeof(ConfigurationException), ExpectedMessage = "The property 'IConfigurationAdapter1.ColorProperty' could not be converted correctly.")]
+        public void it_should_throw_an_exception_stating_the_property_name()
+        {
+            var configReader = new ConfigurationReader(configSource);
+
+            configReader.SetupConfigOf<IConfigurationAdapter1>();
+        }
+    }
+}

src/tests/ConfigReader.Tests/when_config_reader_reads_configuration_with_different_data_types.cs

+ďťżusing System;
+using System.Collections.Generic;
+using System.Drawing;
+using ConfigReader.Interfaces;
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace ConfigReader.Tests
+{
+    [TestFixture]
+    public class when_config_reader_reads_configuration_with_different_data_types : ConfigurationReaderSpecificationBase
+    {
+        [SetUp]
+        protected override void Context()
+        {
+            base.Context();
+
+            var configDictionaryToReturn =
+                new Dictionary<string, string>
+                    {
+                        {"ConfigurationAdapter2.BoolProperty", true.ToString()},
+                        {"ConfigurationAdapter2.StringProperty", "2prop1"},
+                        {"ConfigurationAdapter1.IntegerProperty", 2.ToString()},
+                        {"ConfigurationAdapter1.StringProperty", "1prop1"},
+                        {"ConfigurationAdapter1.ColorProperty", "#FFFFFF"},
+                        {"ConfigurationAdapter1.AddressProperty", "http://localhost"}
+                    };
+
+            SetupResult.For(this.configSource.GetConfigDictionary()).Return(configDictionaryToReturn);
+
+            this.mocks.ReplayAll();
+        }
+
+        [Test]
+        public void it_should_convert_the_string_values_to_the_data_types()
+        {
+            var configReader = new ConfigurationReader(this.configSource);
+
+            configReader.
+                SetupConfigOf<IConfigurationAdapter1>().
+                SetupConfigOf<IConfigurationAdapter2>();
+
+            IConfigurationBrowser configurations = configReader.ConfigBrowser;
+
+            var configurationAdapter1 = configurations.Get<IConfigurationAdapter1>();
+
+            Assert.IsNotNull(configurationAdapter1);
+            Assert.IsNotNull(configurations.Get<IConfigurationAdapter2>());
+
+            Assert.AreEqual("1prop1", configurationAdapter1.StringProperty);
+            Assert.AreEqual(2, configurationAdapter1.IntegerProperty);
+            Assert.AreEqual(Color.White, configurationAdapter1.ColorProperty);
+            Assert.AreEqual(new Uri("http://localhost"), configurationAdapter1.AddressProperty);
+        }
+    }
+}

src/tests/ConfigReader.Tests/when_config_reader_reads_maps_to_two_interfaces_that_has_property_with_the_same_name.cs

+using System.Collections.Generic;
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace ConfigReader.Tests
+{
+    [TestFixture]
+    public class when_config_reader_reads_maps_to_two_interfaces_that_has_property_with_the_same_name : ConfigurationReaderSpecificationBase
+    {
+        [SetUp]
+        protected override void Context()
+        {
+            base.Context();
+
+            var configDictionaryToReturn =
+                new Dictionary<string, string>
+                    {
+                        {"ConfigurationAdapter2.BoolProperty", true.ToString()},
+                        {"ConfigurationAdapter2.StringProperty", "2prop1"},
+                        {"ConfigurationAdapter1.IntegerProperty", 2.ToString()},
+                        {"ConfigurationAdapter1.StringProperty", "1prop1"},
+                        {"ConfigurationAdapter1.ColorProperty", "#FFFFFF"},
+                        {"ConfigurationAdapter1.AddressProperty", "http://localhost"}
+                    };
+
+            SetupResult.For(this.configSource.GetConfigDictionary()).Return(configDictionaryToReturn);
+
+            this.mocks.ReplayAll();
+        }
+
+        [Test]
+        public void it_should_map_the_correct_value_to_per_interface()
+        {
+            var configReader = new ConfigurationReader(configSource);
+
+            var browser = configReader.SetupConfigOf<IConfigurationAdapter1>().SetupConfigOf<IConfigurationAdapter2>().ConfigBrowser;
+
+            Assert.AreEqual("1prop1", browser.Get<IConfigurationAdapter1>().StringProperty);
+            Assert.AreEqual("2prop1", browser.Get<IConfigurationAdapter2>().StringProperty);
+        }
+    }
+}

src/tests/ConfigReader.Tests/when_one_adapter_is_from_config_and_one_from_default_config.cs

+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace ConfigReader.Tests
+{
+    [TestFixture]
+    public class when_one_adapter_is_from_config_and_one_from_default_config : ConfigurationReaderSpecificationBase
+    {
+        [Test]
+        public void it_should_read_the_default_values_of_the_second_adapter()
+        {
+            var configDictionaryToReturn =
+                new Dictionary<string, string>
+                    {
+                        {"ConfigurationAdapter1.IntegerProperty", 2.ToString()},
+                        {"ConfigurationAdapter1.StringProperty", "1prop1"},
+                        {"ConfigurationAdapter1.ColorProperty", "#FFFFFF"},
+                        {"ConfigurationAdapter1.AddressProperty", "http://localhost"}
+                    };
+
+            SetupResult.For(this.configSource.GetConfigDictionary()).Return(configDictionaryToReturn);
+
+            this.mocks.ReplayAll();
+
+            var configReader = new ConfigurationReader(configSource);
+
+            configReader.SetupConfigOf<IConfigurationAdapter1>(new DefaultAdapter1Values());
+            configReader.SetupConfigOf<IConfigurationAdapter2>(new DefaultAdapter2Values());
+
+            Assert.AreEqual(true, configReader.ConfigBrowser.Get<IConfigurationAdapter2>().BoolProperty);
+        }
+    }
+
+    public class DefaultAdapter1Values : IConfigurationAdapter1
+    {
+        public string StringProperty
+        {
+            get { return "default"; }
+        }
+
+        public int IntegerProperty
+        {
+            get { return -1; }
+        }
+
+        public Color ColorProperty
+        {
+            get { return Color.DodgerBlue; }
+        }
+
+        public Uri AddressProperty
+        {
+            get { return new Uri("http://localhost"); }
+        }
+    }
+
+    public class DefaultAdapter2Values : IConfigurationAdapter2
+    {
+        public string StringProperty
+        {
+            get { return "adapter 2 default"; }
+        }
+
+        public bool BoolProperty
+        {
+            get { return true; }
+        }
+    }
+}

src/tests/ConfigReader.Tests/when_the_config_reader_get_default_vaules.cs

+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Reflection;
+using NUnit.Framework;
+using Rhino.Mocks;
+
+namespace ConfigReader.Tests
+{
+    [TestFixture]
+    public class when_the_config_reader_get_default_vaules : ConfigurationReaderSpecificationBase
+    {
+        [SetUp]
+        protected override void Context()
+        {
+            base.Context();
+
+            var configDictionaryToReturn =
+                new Dictionary<string, string>
+                    {
+                        {"ConfigurationAdapter1.StringProperty", "1prop1"},
+                    };
+
+            SetupResult.For(this.configSource.GetConfigDictionary()).Return(configDictionaryToReturn);
+
+            this.mocks.ReplayAll();
+        }
+
+        [Test]
+        public void it_will_use_the_default_values_when_no_value_was_specified_in_the_configuration()
+        {
+            var configReader = new ConfigurationReader(this.configSource).SetupConfigOf<IConfigurationAdapter1>(new ConfigurationAdapter1DefaultValues());
+
+            var browser = configReader.ConfigBrowser.Get<IConfigurationAdapter1>();
+
+            Assert.AreEqual("1prop1", browser.StringProperty);
+            Assert.AreEqual(12, browser.IntegerProperty);
+            Assert.AreEqual(Color.DimGray, browser.ColorProperty);
+        }
+
+        [Test]
+        public void it_will_use_default_values_from_an_anonymous_object_when_no_value_was_specified_in_the_configuration()
+        {
+            var configReader = new ConfigurationReader(this.configSource).
+                SetupConfigOf<IConfigurationAdapter1>(
+                new
+                    {
+                        StringProperty = "Default",
+                        IntegerProperty = 12,
+                        ColorProperty = Color.DimGray,
+                        AddressProperty = (Uri) null
+                    });
+
+            var browser = configReader.ConfigBrowser.Get<IConfigurationAdapter1>();
+
+            Assert.AreEqual("1prop1", browser.StringProperty);
+            Assert.AreEqual(12, browser.IntegerProperty);
+            Assert.AreEqual(Color.DimGray, browser.ColorProperty);
+        }
+
+        [Test]
+        [ExpectedException(ExceptionType = typeof(ConfigurationException), ExpectedMessage = "The default values object misses the property named 'AddressProperty' of type 'System.Uri'.")]
+        public void it_will_throw_an_exception_when_an_anonymous_object_is_missing_a_property_defined_in_the_configuration_adapter_interface()
+        {
+            var configReader = new ConfigurationReader(this.configSource).
+                SetupConfigOf<IConfigurationAdapter1>(
+                new
+                    {
+                        StringProperty = "Default",
+                        IntegerProperty = 12,
+                        ColorProperty = Color.DimGray,
+                    });
+        }
+
+        [Test]
+        [ExpectedException(ExceptionType = typeof(ConfigurationException), ExpectedMessage = "The default values object misses the property named 'AddressProperty' of type 'System.Uri'.")]
+        public void it_will_throw_an_exception_when_an_anonymous_object_has_a_property_with_the_wrong_type()
+        {
+            var configReader = new ConfigurationReader(this.configSource).
+                SetupConfigOf<IConfigurationAdapter1>(
+                new
+                    {
+                        StringProperty = "Default",
+                        IntegerProperty = 12,
+                        ColorProperty = Color.DimGray,
+                        AddressProperty = Assembly.GetExecutingAssembly()  // Arbitrary choise. Just for the test's sake...
+                    });
+        }
+
+        public class ConfigurationAdapter1DefaultValues : IConfigurationAdapter1
+        {
+            public string StringProperty
+            {
+                get { return "Default"; }
+            }
+
+            public int IntegerProperty
+            {
+                get { return 12; }
+            }
+
+            public Color ColorProperty
+            {
+                get { return Color.DimGray; }
+            }
+
+            public Uri AddressProperty
+            {
+                get { return null; }
+            }
+        }
+    }
+}

tools/ILMerge/ILMerge License.rtf

Binary file added.
+{\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f37\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}
+{\f39\froman\fcharset0\fprq2{\*\panose 02040602050305030304}Book Antiqua;}{\f40\fswiss\fcharset0\fprq2{\*\panose 020b0706030402020204}Franklin Gothic Demi Cond;}{\f41\fswiss\fcharset0\fprq2{\*\panose 020b0503020102020204}Franklin Gothic Book;}
+{\f42\froman\fcharset238\fprq2 Times New Roman CE;}{\f43\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f45\froman\fcharset161\fprq2 Times New Roman Greek;}{\f46\froman\fcharset162\fprq2 Times New Roman Tur;}
+{\f47\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f48\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f49\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f50\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
+{\f412\fswiss\fcharset238\fprq2 Tahoma CE;}{\f413\fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f415\fswiss\fcharset161\fprq2 Tahoma Greek;}{\f416\fswiss\fcharset162\fprq2 Tahoma Tur;}{\f417\fswiss\fcharset177\fprq2 Tahoma (Hebrew);}
+{\f418\fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f419\fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f420\fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f421\fswiss\fcharset222\fprq2 Tahoma (Thai);}{\f432\froman\fcharset238\fprq2 Book Antiqua CE;}
+{\f433\froman\fcharset204\fprq2 Book Antiqua Cyr;}{\f435\froman\fcharset161\fprq2 Book Antiqua Greek;}{\f436\froman\fcharset162\fprq2 Book Antiqua Tur;}{\f439\froman\fcharset186\fprq2 Book Antiqua Baltic;}
+{\f442\fswiss\fcharset238\fprq2 Franklin Gothic Demi Cond CE;}{\f443\fswiss\fcharset204\fprq2 Franklin Gothic Demi Cond Cyr;}{\f445\fswiss\fcharset161\fprq2 Franklin Gothic Demi Cond Greek;}{\f446\fswiss\fcharset162\fprq2 Franklin Gothic Demi Cond Tur;}
+{\f449\fswiss\fcharset186\fprq2 Franklin Gothic Demi Cond Baltic;}{\f452\fswiss\fcharset238\fprq2 Franklin Gothic Book CE;}{\f453\fswiss\fcharset204\fprq2 Franklin Gothic Book Cyr;}{\f455\fswiss\fcharset161\fprq2 Franklin Gothic Book Greek;}
+{\f456\fswiss\fcharset162\fprq2 Franklin Gothic Book Tur;}{\f459\fswiss\fcharset186\fprq2 Franklin Gothic Book Baltic;}}{\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;}
+{\stylesheet{\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\*
+\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv 
+\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\s15\ql \fi-274\li274\ri0\sb120\sl460\slmult0
+\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin274\itap0 \f40\fs44\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext15 \styrsid9786739 1sectionhead;}{\s16\ql \li0\ri0\sb120\sl200\slmult0
+\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \caps\f40\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext16 \styrsid9786739 4laparahead;}{\s17\ql \li0\ri-18\sb120\sl240\slmult0
+\widctlpar\aspalpha\aspnum\faauto\adjustright\rin-18\lin0\itap0 \f40\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext17 \styrsid9786739 2lasubhead;}{\s18\ql \fi-187\li187\ri0\sb60\sl180\slmult0
+\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin187\itap0 \f41\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext18 \styrsid9786739 3cnumbered;}{\s19\ql \fi-340\li624\ri0\sb60\sl160\slmult0
+\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin624\itap0 \f41\fs14\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext19 \styrsid9786739 3inumbered2ndlevel;}{\s20\ql \li0\ri0\sb240\sl240\slmult0
+\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \f40\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext20 \styrsid9786739 2afrenchsubhead;}{\s21\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 
+\cbpat9 \f37\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext21 \ssemihidden \styrsid7154712 Document Map;}}{\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\pgptbl {\pgp\ipgp2\itap0\li0\ri0\sb0\sa0\brdrt\brdrs\brdrw20 }{\pgp\ipgp0
+\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid2099452\rsid4207571\rsid5465292\rsid5510097\rsid5510644\rsid7154712\rsid7241305\rsid7672529\rsid7735936\rsid9179139\rsid9786739\rsid10440675\rsid11303133\rsid13130884\rsid14028235\rsid14100361\rsid14113652
+\rsid15276140\rsid16213514}{\*\generator Microsoft Word 11.0.6359;}{\info{\title ILMerge EULA}{\author Ken Leppert}{\operator mbarnett}{\creatim\yr2005\mo3\dy16\hr15\min43}{\revtim\yr2005\mo3\dy16\hr15\min43}{\printim\yr2004\mo4\dy30\hr13\min9}{\version2}
+{\edmins0}{\nofpages3}{\nofwords1188}{\nofchars6775}{\*\company Microsoft Corporation}{\nofcharsws7948}{\vern24703}}\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180
+\dghorigin1800\dgvorigin1440\dghshow1\dgvshow1\jexpand\viewkind1\viewscale68\viewzk2\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel
+\wrppunct\asianbrkrule\rsidroot9786739\newtblstyruls\nogrowautofit \fet0\sectd \linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang 
+{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang 
+{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain 
+\s15\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\outlinelevel0\adjustright\rin0\lin0\itap0\pararsid7154712 \f40\fs44\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\f39\fs28\insrsid9786739 MICROSOFT }{
+\b\f39\fs28\insrsid5465292 ILMerge}{\insrsid9786739 
+\par }{\b\f39\fs22\insrsid9786739 END-USER LICENSE AGREEMENT FOR MICROSOFT SOFTWARE}{\insrsid9786739 
+\par }\pard\plain \s17\qj \li0\ri-17\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin-17\lin0\itap0\pararsid14100361 \f40\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\f39\insrsid9786739 IMPORTANT\emdash 
+READ CAREFULLY: }{\f39\insrsid9786739 This End-User License Agreement (\'93EULA\'94) is a legal agreement between you (either an individual or a single entity) and Microsoft Corporation (\'93Microsoft\'94) for th
+e Microsoft software that accompanies this EULA, which includes computer software and may include associated media, printed materials, \'93online\'94 or electronic documentation, and Internet-based services (\'93Software\'94).\~
+ An amendment or addendum to this EULA may accompany the Software.\~ }{\b\f39\insrsid9786739 
+YOU AGREE TO BE BOUND BY THE TERMS OF THIS EULA BY INSTALLING, COPYING, OR OTHERWISE USING THE SOFTWARE. IF YOU DO NOT AGREE, DO NOT INSTALL, COPY, OR USE THE SOFTWARE.}{\insrsid9786739 
+\par }\pard\plain \qj \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\insrsid9786739 1.\~\~\~\~\~\~\~\~ }{
+\b\f39\fs22\insrsid9786739 GRANTS OF LICENSE}{\f39\fs22\insrsid9786739 . Microsoft grants you the rights described in this EULA provided that you comply with all terms and conditions of this EULA.\~ }{\insrsid9786739 
+\par }\pard\plain \s19\qj \fi720\li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs14\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\cf0\insrsid9786739 1.1\~\~\~\~\~\~ }{
+\b\i\f39\fs22\cf0\insrsid9786739 License Grant}{\f39\fs22\cf0\insrsid9786739 . Microsoft grants to you a personal, nonexclusive, nontransferable, limited license to }{\f39\fs22\insrsid9786739 install and use a reasonable number of copies of 
+the Software on computers residing on your premises }{\f39\fs22\cf0\insrsid9786739 for the purposes of designing, developing, and testing, your software product(s), provided that you are the only individual using the Software.\~ }{\insrsid9786739 
+\par }\pard\plain \s18\qj \fi720\li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\insrsid9786739 1.2\~\~\~\~\~\~ }{
+\b\i\f39\fs22\insrsid9786739 Documentation}{\f39\fs22\insrsid9786739 .}{\b\f39\fs22\insrsid9786739 \~ }{\f39\fs22\insrsid9786739 You may make and use a reasonabl
+e number of copies of any documentation, provided that such copies shall be used only for your personal purposes and are not to be republished or distributed (either in hard copy or electronic form) beyond your premises.}{\insrsid9786739 
+\par }\pard \s18\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 {\f39\fs22\insrsid9786739 2.\~\~\~\~\~\~\~\~ }{\b\f39\fs22\insrsid9786739 RESERVATION OF RIGHTS AND OWNERSHIP.\~ }{
+\f39\fs22\insrsid9786739 The Software is licensed as a single product.\~ Its component parts may not be separated. Microsoft reserves all rights not expressly granted to you in this EULA.\~
+ The Software is protected by copyright and other intellectual property laws and treaties}{\f39\fs22\insrsid14028235 , and}{\f39\fs22\insrsid9786739  Microsoft }{\f39\fs22\insrsid14028235 (}{\f39\fs22\insrsid9786739 or its suppliers}{
+\f39\fs22\insrsid14028235 , where applicable)}{\f39\fs22\insrsid9786739  own }{\f39\fs22\insrsid14028235 all right, }{\f39\fs22\insrsid9786739 title, }{\f39\fs22\insrsid14028235 and interest in all }{\f39\fs22\insrsid9786739 
+intellectual property rights in the Software.\~ }{\b\f39\fs22\insrsid9786739 The Software is licensed, not sold.}{\insrsid9786739 
+\par }\pard\plain \s19\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs14\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\cf0\insrsid9786739 3.\~\~\~\~\~\~\~\~ }{
+\b\f39\fs22\cf0\insrsid9786739 LIMITATIONS ON REVERSE ENGINEERING, DECOMPILATION, AND DISASSEMBLY}{\b\i\f39\fs22\cf0\insrsid9786739 .}{\f39\fs22\cf0\insrsid9786739 \~
+ You may not reverse engineer, decompile, or disassemble the Software, except and only to the extent that such activity is expressly permitted by applicable law notwithstanding this limitation.}{\insrsid9786739 
+\par }\pard\plain \s18\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\sl220\slmult0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\insrsid9786739 4.\~\~\~\~\~\~\~\~ 
+}{\b\f39\fs22\insrsid9786739 NO RENTAL/COMMERCIAL HOSTING.}{\b\i\f39\fs22\insrsid9786739  }{\f39\fs22\insrsid9786739 You may not rent, lease, lend or provide commercial hosting services with the Software.}{\insrsid9786739 
+\par }\pard\plain \s19\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs14\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\cf0\insrsid9786739 5.\~\~\~\~\~\~\~\~ }{
+\b\f39\fs22\cf0\insrsid9786739 NO SOFTWARE TRANSFER.\~ }{\f39\fs22\cf0\insrsid9786739 You may not assign or otherwise transfer the SOFTWARE or any of your rights hereunder to any third party.}{\insrsid9786739 
+\par }{\f39\fs22\cf0\insrsid9786739 6.\~\~\~\~\~\~\~\~ }{\b\f39\fs22\cf0\insrsid9786739 CONSENT TO USE OF DATA.\~ }{\f39\fs22\cf0\insrsid9786739 You
+ agree that Microsoft and its affiliates may collect and use technical information gathered as part of the product support services provided to you, if any, related to the Software.\~
+ Microsoft may use this information solely to improve our products or to provide customized services or technologies to you and will not disclose this information in a form that personally identifies you.\~\~ }{\insrsid9786739 
+\par }{\f39\fs22\cf0\insrsid5510644 7}{\f39\fs22\cf0\insrsid9786739 .\~\~\~\~\~\~\~\~ }{\b\f39\fs22\cf0\insrsid9786739 ADDITIONAL SOFTWARE/SERVICES.\~ }{\f39\fs22\insrsid9786739 Microsoft is not obligated to provide maintenance, technical supplements}{
+\f39\fs22\insrsid14028235 , updates,}{\f39\fs22\insrsid9786739  or other support to you for the Software licensed under this EULA. }{\f39\fs22\insrsid7241305  }{\f39\fs22\insrsid9786739 In the event that Microsoft does provide such supplements or updates}
+{\b\f39\fs22\insrsid9786739 , }{\f39\fs22\insrsid9786739 this EULA applies to such updates, supplements, or add-on components of the Software that Microsoft may provide to 
+you or make available to you after the date you obtain your initial copy of the Software, unless we provide other terms along with the update, supplement, or add-on component}{\f39\fs22\cf0\insrsid9786739 .\~
+ Microsoft reserves the right to discontinue any Internet-based services provided to you or made available to you through the use of the Software.\~ }{\insrsid9786739 
+\par }\pard\plain \s18\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\sl220\slmult0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\insrsid5510644 8}{
+\f39\fs22\insrsid9786739 .\~\~\~\~\~\~\~\~ }{\b\f39\fs22\insrsid9786739 EXPORT RESTRICTIONS}{\f39\fs22\insrsid9786739 .\~ }{\f39\fs22\cgrid0\insrsid9786739 You acknowledge that the Software is subject to U.S. export jurisdiction.\~
+ You agree to comply with all applicable international and national laws that apply to the Software, including the U.S. Export Administration Regulations, as well as end-user, end-use, and destination restrictions issued by U.S. and other governments.\~\~
+ For additional information see }{\f39\fs22\ul\cgrid0\insrsid9786739 http://www.microsoft.com/exporting/}{\f39\fs22\cgrid0\insrsid9786739 .}{\insrsid9786739 
+\par }\pard\plain \s19\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs14\cf1\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\cf0\insrsid14113652 9}{
+\f39\fs22\cf0\insrsid9786739 .\~\~\~\~\~\~ }{\b\f39\fs22\cf0\insrsid9786739 TERMINATION.}{\f39\fs22\cf0\insrsid9786739 \~ Without prejudice to any other rights, Microsoft may terminate this EULA if you fail to comply with }{\f39\fs22\cf0\insrsid7241305 
+any }{\f39\fs22\cf0\insrsid9786739 term}{\f39\fs22\cf0\insrsid7241305  or}{\f39\fs22\cf0\insrsid9786739  condition of this EULA. }{\f39\fs22\cf0\insrsid7241305  }{\f39\fs22\cf0\insrsid9786739 
+In such event, you must destroy all copies of the Software and all of its component parts.}{\insrsid9786739 
+\par }\pard\plain \s18\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\sl220\slmult0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f41\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\fs22\insrsid9786739 1}{
+\f39\fs22\insrsid14113652 0}{\f39\fs22\insrsid9786739 .\~\~\~\~\~\~ }{\b\f39\fs22\ul\insrsid9786739 DISCLAIMER OF WARRANTIES}{\b\f39\fs22\insrsid9786739 .\~
+ TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, MICROSOFT AND ITS SUPPLIERS PROVIDE THE SOFTWARE}{\f39\fs22\insrsid9786739  }{\b\f39\fs22\insrsid9786739 AND SUPPORT SERVICES (IF ANY) }{\b\i\f39\fs22\insrsid9786739 AS IS AND WITH ALL FAULTS}{
+\b\f39\fs22\insrsid9786739 , AND HEREBY DISCLAIM ALL OTHER WARRANTIES AND CONDITIONS, WHETHER EXPRESS, IMPLIED
+ OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY (IF ANY) IMPLIED WARRANTIES, DUTIES OR CONDITIONS OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE, OF RELIABILITY OR AVAILABILITY, OF ACCURACY OR COMPLETENESS OF RESPONSES, OF RESULTS, OF WORKMANLI
+K
+E EFFORT, OF LACK OF VIRUSES, AND OF LACK OF NEGLIGENCE, ALL WITH REGARD TO THE SOFTWARE, AND THE PROVISION OF OR FAILURE TO PROVIDE SUPPORT OR OTHER SERVICES, INFORMATION, SOFTWARE, AND RELATED CONTENT THROUGH THE SOFTWARE OR OTHERWISE ARISING OUT OF THE
+ USE OF THE SOFTWARE.\~ ALSO, THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT, QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR NON-INFRINGEMENT WITH REGARD TO THE SOFTWARE.}{\insrsid9786739 
+\par }{\f39\fs22\insrsid9786739 1}{\f39\fs22\insrsid14113652 1}{\f39\fs22\insrsid9786739 .}{\b\f39\fs22\insrsid9786739 \~\~\~\~\~\~ }{\b\f39\fs22\ul\insrsid9786739 EXCLUSION OF INCIDENTAL, CONSEQUENTIAL AND CERTAIN OTHER DAMAGES}{\b\f39\fs22\insrsid9786739 .\~
+ }{\b\caps\f39\fs22\insrsid9786739 
+To the maximum extent permitted by applicable law, in no event shall Microsoft or its suppliers be liable for any special, incidental, punitive, indirect, or consequential damages whatsoever (including, but not limited to, damages for loss of profit
+s, LOSS OF DATA, or confidential or other information}{\b\f39\fs22\insrsid9786739 , }{\b\caps\f39\fs22\insrsid9786739 
+for business interruption, for personal injury, for loss of privacy, for failure to meet any duty including of good faith or of reasonable care, for negligence, and}{\b\f39\fs22\insrsid9786739  }{\b\caps\f39\fs22\insrsid9786739 
+for any other pecuniary or other los
+s whatsoever) arising out of or in any way related to the use of or inability to use the SOFTWARE, the provision of or failure to provide Support OR OTHER Services, informatIon, software, and related CONTENT through the software or otherwise arising out o
+f
+ the use of the software, or otherwise under or in connection with any provision of this EULA, even in the event of the fault, tort (including negligence), misrepresentation, strict liability, breach of contract or breach of warranty of Microsoft or any s
+upplier, and even if Microsoft or any supplier has been advised of the possibility of such damages. }{\insrsid9786739 
+\par }{\f39\fs22\insrsid9786739 1}{\f39\fs22\insrsid14113652 2}{\f39\fs22\insrsid9786739 .}{\b\f39\fs22\insrsid9786739 \~\~\~\~\~\~ }{\b\f39\fs22\ul\insrsid9786739 LIMITATION OF LIABILITY AND REMEDIES}{\b\f39\fs22\insrsid9786739 
+. NOTWITHSTANDING ANY DAMAGES THAT YOU MIGHT INCUR FOR ANY REASON WHATSOEVER (INCLUDING, WITHOUT LIMITATION, A
+LL DAMAGES REFERENCED HEREIN AND ALL DIRECT OR GENERAL DAMAGES IN CONTRACT OR ANYTHING ELSE), THE ENTIRE LIABILITY OF MICROSOFT AND ANY OF ITS SUPPLIERS UNDER ANY PROVISION OF THIS EULA AND YOUR EXCLUSIVE REMEDY HEREUNDER SHALL BE LIMITED TO THE GREATER O
+F THE ACTUAL DAMAGES YOU INCUR IN REASONABLE RELIANCE ON THE SOFTWARE UP TO THE AMOUNT ACTUALLY PAID BY YOU FOR THE SOFTWARE}{\f39\fs22\insrsid9786739  }{\b\f39\fs22\insrsid9786739 OR US$5.00.\~
+ THE FOREGOING LIMITATIONS, EXCLUSIONS AND DISCLAIMERS SHALL APPLY TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, EVEN IF ANY REMEDY FAILS ITS ESSENTIAL PURPOSE.}{\insrsid9786739 
+\par }{\f39\fs22\insrsid9786739 1}{\f39\fs22\insrsid14113652 3}{\f39\fs22\insrsid9786739 .\~\~\~\~\~\~ }{\b\f39\fs22\insrsid9786739 APPLICABLE LAW.\~ }{\f39\fs22\insrsid7735936 T}{\f39\fs22\insrsid9786739 his EULA }{\f39\fs22\insrsid7735936 
+shall be construed under and }{\f39\fs22\insrsid9786739 governed by the laws of the State of Washington}{\f39\fs22\insrsid7735936 , without regard to conflicts of law principles}{\f39\fs22\insrsid9786739 .\~ }{\insrsid9786739 
+\par }\pard\plain \s20\qj \li0\ri0\sb100\sa100\sbauto1\saauto1\sl240\slmult0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \f40\fs22\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\f39\insrsid9786739 1}{\f39\insrsid14113652 
+4}{\f39\insrsid9786739 .\~\~\~\~ }{\b\f39\insrsid9786739 ENTIRE AGREEMENT; SEVERABILITY.\~ }{\f39\insrsid9786739 This 
+EULA (including any addendum or amendment to this EULA which is included with the Software) are the entire agreement between you and Microsoft relating to the Software and the support services (if any) and they supersede all prior or contemporaneous oral 
+or written communications,\~proposals and representations with respect to the Software or any other subject matter covered by this EULA.\~
+ If any provision of this EULA is held to be void, invalid, unenforceable or illegal, the other provisions shall continue in full force and effect}{\insrsid9786739 
+\par }\pard\plain \qj \li0\ri0\sb100\sa100\sbauto1\saauto1\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14100361 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\insrsid10440675 
+\par }}

tools/ILMerge/ILMerge.doc

Binary file added.

tools/ILMerge/ILMerge.exe

Binary file added.

tools/ILMerge/ILMerge.txt

+Get latest version from http://msdn2.microsoft.com/en-us/netframework/aa569269.aspx

tools/ILMerge/mscorsn.dll

Binary file added.

tools/NUnit/nunit.framework.dll

Binary file added.

tools/RhinoMocks/Rhino.Mocks.dll

Binary file added.

tools/RhinoMocks/Rhino.Mocks.xml

+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<doc>
+  <assembly>
+    <name>Rhino.Mocks</name>
+  </assembly>
+  <members>
+    <member name="T:Rhino.Mocks.BackToRecordOptions">
+      <summary>
+            What should BackToRecord clear
+            </summary>
+    </member>
+    <member name="F:Rhino.Mocks.BackToRecordOptions.None">
+      <summary>
+            Nothing
+            </summary>
+    </member>
+    <member name="F:Rhino.Mocks.BackToRecordOptions.EventSubscribers">
+      <summary>
+            Event subscribers for this instance
+            </summary>
+    </member>
+    <member name="F:Rhino.Mocks.BackToRecordOptions.OriginalMethodsToCall">
+      <summary>
+            Methods that should be forwarded to the base class implementation
+            </summary>
+    </member>
+    <member name="F:Rhino.Mocks.BackToRecordOptions.PropertyBehavior">
+      <summary>
+            Properties that should behave like properties
+            </summary>
+    </member>
+    <member name="F:Rhino.Mocks.BackToRecordOptions.All">
+      <summary>
+            Remove al the behavior of the object
+            </summary>
+    </member>
+    <member name="T:Rhino.Mocks.Constraints.AbstractConstraint">
+      <summary>
+            Interface for constraints
+            </summary>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.AbstractConstraint.Eval(System.Object)">
+      <summary>
+            determains if the object pass the constraints
+            </summary>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.AbstractConstraint.op_BitwiseAnd(Rhino.Mocks.Constraints.AbstractConstraint,Rhino.Mocks.Constraints.AbstractConstraint)">
+      <summary>
+            And operator for constraints
+            </summary>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.AbstractConstraint.op_LogicalNot(Rhino.Mocks.Constraints.AbstractConstraint)">
+      <summary>
+            Not operator for constraints
+            </summary>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.AbstractConstraint.op_BitwiseOr(Rhino.Mocks.Constraints.AbstractConstraint,Rhino.Mocks.Constraints.AbstractConstraint)">
+      <summary>
+            Or operator for constraints
+            </summary>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.AbstractConstraint.op_False(Rhino.Mocks.Constraints.AbstractConstraint)">
+      <summary>
+            Allow overriding of || or &amp;&amp;
+            </summary>
+      <param name="c">
+      </param>
+      <returns>
+      </returns>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.AbstractConstraint.op_True(Rhino.Mocks.Constraints.AbstractConstraint)">
+      <summary>
+            Allow overriding of || or &amp;&amp;
+            </summary>
+      <param name="c">
+      </param>
+      <returns>
+      </returns>
+    </member>
+    <member name="P:Rhino.Mocks.Constraints.AbstractConstraint.Message">
+      <summary>
+            Gets the message for this constraint
+            </summary>
+      <value>
+      </value>
+    </member>
+    <member name="T:Rhino.Mocks.Constraints.PublicFieldConstraint">
+      <summary>
+            Constrain that the public field matches another constraint.
+            </summary>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.PublicFieldConstraint.#ctor(System.String,Rhino.Mocks.Constraints.AbstractConstraint)">
+      <summary>
+            Creates a new <see cref="T:Rhino.Mocks.Constraints.PublicFieldConstraint" /> instance.
+            </summary>
+      <param name="publicFieldName">Name of the public field.</param>
+      <param name="constraint">Constraint to place on the public field value.</param>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.PublicFieldConstraint.#ctor(System.Type,System.String,Rhino.Mocks.Constraints.AbstractConstraint)">
+      <summary>
+            Creates a new <see cref="T:Rhino.Mocks.Constraints.PublicFieldConstraint" /> instance, specifying a disambiguating
+            <paramref name="declaringType" /> for the public field.
+            </summary>
+      <param name="declaringType">The type that declares the public field, used to disambiguate between public fields.</param>
+      <param name="publicFieldName">Name of the public field.</param>
+      <param name="constraint">Constraint to place on the public field value.</param>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.PublicFieldConstraint.Eval(System.Object)">
+      <summary>
+            Determines if the object passes the constraint.
+            </summary>
+    </member>
+    <member name="P:Rhino.Mocks.Constraints.PublicFieldConstraint.Message">
+      <summary>
+            Gets the message for this constraint
+            </summary>
+      <value>
+      </value>
+    </member>
+    <member name="T:Rhino.Mocks.Constraints.PublicFieldIs">
+      <summary>
+            Constrain that the public field has a specified value
+            </summary>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.PublicFieldIs.#ctor(System.String,System.Object)">
+      <summary>
+            Creates a new <see cref="T:Rhino.Mocks.Constraints.PublicFieldIs" /> instance.
+            </summary>
+      <param name="publicFieldName">Name of the public field.</param>
+      <param name="expectedValue">Expected value.</param>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.PublicFieldIs.#ctor(System.Type,System.String,System.Object)">
+      <summary>
+            Creates a new <see cref="T:Rhino.Mocks.Constraints.PublicFieldIs" /> instance, specifying a disambiguating
+            <paramref name="declaringType" /> for the public field.
+            </summary>
+      <param name="declaringType">The type that declares the public field, used to disambiguate between public fields.</param>
+      <param name="publicFieldName">Name of the public field.</param>
+      <param name="expectedValue">Expected value.</param>
+    </member>
+    <member name="T:Rhino.Mocks.Constraints.PropertyConstraint">
+      <summary>
+            Constrain that the property matches another constraint.
+            </summary>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.PropertyConstraint.#ctor(System.String,Rhino.Mocks.Constraints.AbstractConstraint)">
+      <summary>
+            Creates a new <see cref="T:Rhino.Mocks.Constraints.PropertyConstraint" /> instance.
+            </summary>
+      <param name="propertyName">Name of the property.</param>
+      <param name="constraint">Constraint to place on the property value.</param>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.PropertyConstraint.#ctor(System.Type,System.String,Rhino.Mocks.Constraints.AbstractConstraint)">
+      <summary>
+            Creates a new <see cref="T:Rhino.Mocks.Constraints.PropertyConstraint" /> instance, specifying a disambiguating
+            <paramref name="declaringType" /> for the property.
+            </summary>
+      <param name="declaringType">The type that declares the property, used to disambiguate between properties.</param>
+      <param name="propertyName">Name of the property.</param>
+      <param name="constraint">Constraint to place on the property value.</param>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.PropertyConstraint.Eval(System.Object)">
+      <summary>
+            Determines if the object passes the constraint.
+            </summary>
+    </member>
+    <member name="P:Rhino.Mocks.Constraints.PropertyConstraint.Message">
+      <summary>
+            Gets the message for this constraint
+            </summary>
+      <value>
+      </value>
+    </member>
+    <member name="T:Rhino.Mocks.Constraints.PropertyIs">
+      <summary>
+            Constrain that the property has a specified value
+            </summary>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.PropertyIs.#ctor(System.String,System.Object)">
+      <summary>
+            Creates a new <see cref="T:Rhino.Mocks.Constraints.PropertyIs" /> instance.
+            </summary>
+      <param name="propertyName">Name of the property.</param>
+      <param name="expectedValue">Expected value.</param>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.PropertyIs.#ctor(System.Type,System.String,System.Object)">
+      <summary>
+            Creates a new <see cref="T:Rhino.Mocks.Constraints.PropertyIs" /> instance, specifying a disambiguating
+            <paramref name="declaringType" /> for the property.
+            </summary>
+      <param name="declaringType">The type that declares the property, used to disambiguate between properties.</param>
+      <param name="propertyName">Name of the property.</param>
+      <param name="expectedValue">Expected value.</param>
+    </member>
+    <member name="T:Rhino.Mocks.Constraints.TypeOf">
+      <summary>
+            Constrain that the parameter must be of the specified type
+            </summary>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.TypeOf.#ctor(System.Type)">
+      <summary>
+            Creates a new <see cref="T:Rhino.Mocks.Constraints.TypeOf" /> instance.
+            </summary>
+      <param name="type">Type.</param>
+    </member>
+    <member name="M:Rhino.Mocks.Constraints.TypeOf.Eval(System.Object)">
+      <summary>
+            determains if the object pass the constraints
+            </summary>
+    </member>
+    <member name="P:Rhino.Mocks.Constraints.TypeOf.Message">
+      <summary>
+            Gets the message for this constraint
+            </summary>