Commits

Anonymous committed 61116ed

Moved the solution into a C# folder. I will now port the solution to Ruby.

  • Participants
  • Parent commits 6a2254d

Comments (0)

Files changed (48)

File CSharpSolution/README

+Hello Justin.tv :)
+My name is Charlie Guse and this is my solution for the spellcheck problem.
+http://www.justin.tv/problems/spellcheck
+
+
+Non-explaining list version of instructions:
+
+Compiling the source:
+    Open up source/spellcheck/spellcheck.sln
+    Compile it.
+    Open up source/spellcheck/spellcheck/bin/Debug(and Release) and put american-english
+    Rename american-english words for the program.
+
+    Follow the same instructions for unspeller to compile and use that.
+
+Using NUnit:
+    Install from http://www.nunit.org/
+    Run NUnit 2.5.10\bin\net-2.0\nunit-x86.exe (NOT nunit.exe)
+    File > Open Project... and open source/nunit_spellcheck/spellcheck.nunit (give an error if the source isn't compiled)
+    
+    Same for source/nunit_unspeller/unspeller.nunit
+
+
+Explaining paragraph version of instructions:  
+
+    If you compile the source code, you will have to manually put the american-english
+dictionary in the Debug/Release folder and rename it words. I didn't make a post-
+build step for that because I only had to do it once. I deleted all of the pre-
+compiled stuff before sending it to you though. Since you know... space is an issue. ;)
+I just wanted to put the source code in it's most basic form as if you were pulling it
+down from source control.
+
+    I used NUnit 2.5.10.11092 for unit testing. If you use the default executable
+(nunit.exe) you will get a BadImageFormat exception. There is a second executable
+named nunit-x86.exe that you need to use instead. If you are unfamiliar with NUnit,
+to use it, open up nunit-x86.exe, File > Open Project... and then go to
+source/nunit_spellcheck/spellcheck.nunit to load the unit test project. If you get
+an error saying Assembly Not Loaded, you will have to compile the Spellcheck project
+once first so it can find the Release version of the dlls.
+
+    This was created in .net 4.0. If this is an issue. Please let me know.
+    

File CSharpSolution/nunit_spellcheck/TestResult.xml

+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--This file represents the results of running a test suite-->
+<test-results name="C:\sandbox\spellchecker\CSharpSolution\nunit_spellcheck\spellcheck.nunit" total="17" errors="0" failures="0" not-run="0" inconclusive="0" ignored="0" skipped="0" invalid="0" date="2012-01-08" time="14:02:27">
+  <environment nunit-version="2.5.10.11092" clr-version="2.0.50727.5448" os-version="Microsoft Windows NT 6.1.7601 Service Pack 1" platform="Win32NT" cwd="C:\Program Files (x86)\NUnit 2.5.10\bin\net-2.0" machine-name="ANIMUS" user="Charles" user-domain="Animus" />
+  <culture-info current-culture="en-US" current-uiculture="en-US" />
+  <test-suite type="Test Project" name="C:\sandbox\spellchecker\CSharpSolution\nunit_spellcheck\spellcheck.nunit" executed="True" result="Success" success="True" time="0.859" asserts="0">
+    <results>
+      <test-suite type="Assembly" name="C:\sandbox\spellchecker\CSharpSolution\nunit_spellcheck\..\spellcheck\spellcheckUnitTests\bin\Release\spellcheckUnitTests.dll" executed="True" result="Success" success="True" time="0.137" asserts="0">
+        <results>
+          <test-suite type="Namespace" name="spellCheckUnitTests" executed="True" result="Success" success="True" time="0.130" asserts="0">
+            <results>
+              <test-suite type="TestFixture" name="LetterTreePopulationTests" executed="True" result="Success" success="True" time="0.097" asserts="0">
+                <results>
+                  <test-case name="spellCheckUnitTests.LetterTreePopulationTests.PopulateNonOverlappingWordsInTree" executed="True" result="Success" success="True" time="0.074" asserts="9" />
+                  <test-case name="spellCheckUnitTests.LetterTreePopulationTests.PopulateNoWordInTree" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="spellCheckUnitTests.LetterTreePopulationTests.PopulateOverlappingWordsInTree" executed="True" result="Success" success="True" time="0.001" asserts="8" />
+                  <test-case name="spellCheckUnitTests.LetterTreePopulationTests.PopulateSameWordInTreeTwice" executed="True" result="Success" success="True" time="0.001" asserts="1" />
+                  <test-case name="spellCheckUnitTests.LetterTreePopulationTests.PopulateSingleWordIsInTree" executed="True" result="Success" success="True" time="0.002" asserts="8" />
+                  <test-case name="spellCheckUnitTests.LetterTreePopulationTests.PopulateSmallerWordUsingSameCharactersAsBiggerWord" executed="True" result="Success" success="True" time="0.002" asserts="15" />
+                </results>
+              </test-suite>
+              <test-suite type="TestFixture" name="LetterTreeSpellCheckTests" executed="True" result="Success" success="True" time="0.030" asserts="0">
+                <results>
+                  <test-case name="spellCheckUnitTests.LetterTreeSpellCheckTests.SpellcheckExampleOnWebsite" executed="True" result="Success" success="True" time="0.007" asserts="6" />
+                  <test-case name="spellCheckUnitTests.LetterTreeSpellCheckTests.SpellcheckIncorrectVowel" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="spellCheckUnitTests.LetterTreeSpellCheckTests.SpellcheckMismatchedCase" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="spellCheckUnitTests.LetterTreeSpellCheckTests.SpellcheckNoSuggestionWord" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="spellCheckUnitTests.LetterTreeSpellCheckTests.SpellcheckProperlySpelled" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="spellCheckUnitTests.LetterTreeSpellCheckTests.SpellcheckProperlySpelledOneLetterWord" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="spellCheckUnitTests.LetterTreeSpellCheckTests.SpellcheckRepeatedLetters" executed="True" result="Success" success="True" time="0.001" asserts="1" />
+                  <test-case name="spellCheckUnitTests.LetterTreeSpellCheckTests.SpellcheckWordsThatHaveMultipleCasings" executed="True" result="Success" success="True" time="0.000" asserts="2" />
+                  <test-case name="spellCheckUnitTests.LetterTreeSpellCheckTests.SpellcheckWordsThatHaveRepeatingCharactersWithMultipleCasings" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="spellCheckUnitTests.LetterTreeSpellCheckTests.SpellcheckWordsThatHaveRepeatingVowelsNextToOtherVowels" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="spellCheckUnitTests.LetterTreeSpellCheckTests.SpellcheckWordsThatNeedBacktrackingToFind" executed="True" result="Success" success="True" time="0.001" asserts="1" />
+                </results>
+              </test-suite>
+            </results>
+          </test-suite>
+        </results>
+      </test-suite>
+    </results>
+  </test-suite>
+</test-results>

File CSharpSolution/nunit_spellcheck/spellcheck.VisualState.xml

+<?xml version="1.0" encoding="utf-8"?>
+<VisualState xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ShowCheckBoxes="false">
+  <TopNode>[0-1000]C:\sandbox\spellchecker\CSharpSolution\nunit_spellcheck\spellcheck.nunit</TopNode>
+  <SelectedNode>[0-1000]C:\sandbox\spellchecker\CSharpSolution\nunit_spellcheck\spellcheck.nunit</SelectedNode>
+  <ExcludeCategories>false</ExcludeCategories>
+  <Nodes>
+    <Node UniqueName="[0-1000]C:\sandbox\spellchecker\CSharpSolution\nunit_spellcheck\spellcheck.nunit" Expanded="true" />
+    <Node UniqueName="[0-1019]C:\sandbox\spellchecker\CSharpSolution\nunit_spellcheck\..\spellcheck\spellcheckUnitTests\bin\Release\spellcheckUnitTests.dll" Expanded="true" />
+    <Node UniqueName="[0-1020]spellCheckUnitTests" Expanded="true" />
+    <Node UniqueName="[0-1000]spellCheckUnitTests.LetterTreePopulationTests" Expanded="true" />
+    <Node UniqueName="[0-1007]spellCheckUnitTests.LetterTreeSpellCheckTests" Expanded="true" />
+  </Nodes>
+</VisualState>

File CSharpSolution/nunit_spellcheck/spellcheck.nunit

+<NUnitProject>
+  <Settings activeconfig="Debug" />
+  <Config name="Debug" binpathtype="Auto">
+    <assembly path="..\spellcheck\spellcheckUnitTests\bin\Release\spellcheckUnitTests.dll" />
+  </Config>
+  <Config name="Release" binpathtype="Auto" />
+</NUnitProject>

File CSharpSolution/nunit_unspeller/TestResult.xml

+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!--This file represents the results of running a test suite-->
+<test-results name="C:\sandbox\spellchecker\CSharpSolution\nunit_unspeller\unspeller.nunit" total="11" errors="0" failures="0" not-run="0" inconclusive="0" ignored="0" skipped="0" invalid="0" date="2012-01-08" time="14:02:36">
+  <environment nunit-version="2.5.10.11092" clr-version="2.0.50727.5448" os-version="Microsoft Windows NT 6.1.7601 Service Pack 1" platform="Win32NT" cwd="C:\Program Files (x86)\NUnit 2.5.10\bin\net-2.0" machine-name="ANIMUS" user="Charles" user-domain="Animus" />
+  <culture-info current-culture="en-US" current-uiculture="en-US" />
+  <test-suite type="Test Project" name="C:\sandbox\spellchecker\CSharpSolution\nunit_unspeller\unspeller.nunit" executed="True" result="Success" success="True" time="0.196" asserts="0">
+    <results>
+      <test-suite type="Assembly" name="C:\sandbox\spellchecker\CSharpSolution\nunit_unspeller\..\unspeller\unspellerUnitTests\bin\Release\unspellerUnitTests.dll" executed="True" result="Success" success="True" time="0.058" asserts="0">
+        <results>
+          <test-suite type="Namespace" name="unspellerUnitTests" executed="True" result="Success" success="True" time="0.054" asserts="0">
+            <results>
+              <test-suite type="TestFixture" name="unspellerTests" executed="True" result="Success" success="True" time="0.054" asserts="0">
+                <results>
+                  <test-case name="unspellerUnitTests.unspellerTests.ChangeAllVowels" executed="True" result="Success" success="True" time="0.025" asserts="1" />
+                  <test-case name="unspellerUnitTests.unspellerTests.ChangeCapatalizeationOnWord" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="unspellerUnitTests.unspellerTests.ChangeCapitalVowel" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="unspellerUnitTests.unspellerTests.ChangeCaseFromLowerToUpper" executed="True" result="Success" success="True" time="0.002" asserts="1" />
+                  <test-case name="unspellerUnitTests.unspellerTests.ChangeCaseFromUpperToLower" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="unspellerUnitTests.unspellerTests.ChangeCharacter" executed="True" result="Success" success="True" time="0.001" asserts="1" />
+                  <test-case name="unspellerUnitTests.unspellerTests.ChangeNoVowelWord" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="unspellerUnitTests.unspellerTests.ChangeWord" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="unspellerUnitTests.unspellerTests.DontChangeCaseOfDifferentCulture" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="unspellerUnitTests.unspellerTests.GetRepeatingCharData" executed="True" result="Success" success="True" time="0.000" asserts="1" />
+                  <test-case name="unspellerUnitTests.unspellerTests.UnspellWord" executed="True" result="Success" success="True" time="0.001" asserts="1" />
+                </results>
+              </test-suite>
+            </results>
+          </test-suite>
+        </results>
+      </test-suite>
+    </results>
+  </test-suite>
+</test-results>

File CSharpSolution/nunit_unspeller/unspeller.VisualState.xml

+<?xml version="1.0" encoding="utf-8"?>
+<VisualState xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ShowCheckBoxes="false">
+  <TopNode>[0-1000]C:\sandbox\spellchecker\CSharpSolution\nunit_unspeller\unspeller.nunit</TopNode>
+  <SelectedNode>[0-1000]C:\sandbox\spellchecker\CSharpSolution\nunit_unspeller\unspeller.nunit</SelectedNode>
+  <ExcludeCategories>false</ExcludeCategories>
+  <Nodes>
+    <Node UniqueName="[0-1000]C:\sandbox\spellchecker\CSharpSolution\nunit_unspeller\unspeller.nunit" Expanded="true" />
+    <Node UniqueName="[0-1012]C:\sandbox\spellchecker\CSharpSolution\nunit_unspeller\..\unspeller\unspellerUnitTests\bin\Release\unspellerUnitTests.dll" Expanded="true" />
+    <Node UniqueName="[0-1013]unspellerUnitTests" Expanded="true" />
+    <Node UniqueName="[0-1000]unspellerUnitTests.unspellerTests" Expanded="true" />
+  </Nodes>
+</VisualState>

File CSharpSolution/nunit_unspeller/unspeller.nunit

+<NUnitProject>
+  <Settings activeconfig="Debug" />
+  <Config name="Debug" binpathtype="Auto">
+    <assembly path="..\unspeller\unspellerUnitTests\bin\Release\unspellerUnitTests.dll" />
+  </Config>
+  <Config name="Release" binpathtype="Auto" />
+</NUnitProject>

File CSharpSolution/spellcheck/spellcheck.sln

+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual C# Express 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "spellcheck", "spellcheck\spellcheck.csproj", "{65AAB598-8045-4B84-8B11-91CE51A799B3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "spellcheckUnitTests", "spellcheckUnitTests\spellcheckUnitTests.csproj", "{267220FB-6CB6-4F6F-9967-9D55F58EE98C}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|Mixed Platforms = Debug|Mixed Platforms
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|Mixed Platforms = Release|Mixed Platforms
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{65AAB598-8045-4B84-8B11-91CE51A799B3}.Debug|Any CPU.ActiveCfg = Debug|x86
+		{65AAB598-8045-4B84-8B11-91CE51A799B3}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+		{65AAB598-8045-4B84-8B11-91CE51A799B3}.Debug|Mixed Platforms.Build.0 = Debug|x86
+		{65AAB598-8045-4B84-8B11-91CE51A799B3}.Debug|x86.ActiveCfg = Debug|x86
+		{65AAB598-8045-4B84-8B11-91CE51A799B3}.Debug|x86.Build.0 = Debug|x86
+		{65AAB598-8045-4B84-8B11-91CE51A799B3}.Release|Any CPU.ActiveCfg = Release|x86
+		{65AAB598-8045-4B84-8B11-91CE51A799B3}.Release|Mixed Platforms.ActiveCfg = Release|x86
+		{65AAB598-8045-4B84-8B11-91CE51A799B3}.Release|Mixed Platforms.Build.0 = Release|x86
+		{65AAB598-8045-4B84-8B11-91CE51A799B3}.Release|x86.ActiveCfg = Release|x86
+		{65AAB598-8045-4B84-8B11-91CE51A799B3}.Release|x86.Build.0 = Release|x86
+		{267220FB-6CB6-4F6F-9967-9D55F58EE98C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{267220FB-6CB6-4F6F-9967-9D55F58EE98C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{267220FB-6CB6-4F6F-9967-9D55F58EE98C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{267220FB-6CB6-4F6F-9967-9D55F58EE98C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{267220FB-6CB6-4F6F-9967-9D55F58EE98C}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{267220FB-6CB6-4F6F-9967-9D55F58EE98C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{267220FB-6CB6-4F6F-9967-9D55F58EE98C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{267220FB-6CB6-4F6F-9967-9D55F58EE98C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{267220FB-6CB6-4F6F-9967-9D55F58EE98C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{267220FB-6CB6-4F6F-9967-9D55F58EE98C}.Release|x86.ActiveCfg = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

File CSharpSolution/spellcheck/spellcheck/LetterNode.cs

+using System.Collections.Generic;
+using System.Text;
+
+namespace spellcheck
+{
+    public class LetterNode
+    {
+        public char Letter;
+        public LetterNode Parent;
+        public Dictionary<char, LetterNode> Nodes;
+        public bool End;
+
+        public LetterNode()
+        {
+            Nodes = new Dictionary<char, LetterNode>();
+        }
+
+        public string GetWord()
+        {
+            StringBuilder word = new StringBuilder();
+            var traverser = this;
+
+            do
+            {
+                word.Insert(0, traverser.Letter);
+                traverser = traverser.Parent;
+            }
+            while (traverser != null);
+
+            return word.ToString();
+        }
+    }
+}

File CSharpSolution/spellcheck/spellcheck/LetterTree.cs

+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+
+namespace spellcheck
+{
+    public struct TraversalData
+    {
+        public int Depth;
+        public LetterNode CurrentNode;
+        public Dictionary<char,LetterNode> Nodes;
+    }
+
+    public class LetterTree
+    {
+        private const string NO_SUGGESTION_TEXT = "NO SUGGESTION";
+
+        public Dictionary<char, LetterNode> Tree { get; private set; }
+        public Dictionary<string, HashSet<int>> BadWord { get; private set; }
+
+        public LetterTree()
+        {
+            Tree = new Dictionary<char,LetterNode>();
+            BadWord = new Dictionary<string, HashSet<int>>();
+        }
+
+        public TraversalData GetRoot()
+        {
+            TraversalData treeData = new TraversalData();
+            treeData.Depth = -1;
+            treeData.CurrentNode = null;
+            treeData.Nodes = Tree;
+
+            return treeData;
+        }
+
+        public void Add(string word)
+        {
+            var traversal = Traverse(word, GetRoot());
+            AddAtLocation(word, traversal);
+        }
+
+        private void AddAtLocation(string word, TraversalData traversal)
+        {
+            LetterNode node;
+
+            if (traversal.Depth < word.Length - 1)
+            {
+                node = new LetterNode();
+                node.Parent = traversal.CurrentNode;
+                node.Letter = word[++traversal.Depth];
+                traversal.Nodes.Add(node.Letter,node);
+
+                if (traversal.Depth + 1 < word.Length)
+                {
+                    traversal.CurrentNode = node;
+                    traversal.Nodes = node.Nodes;
+                    AddAtLocation(word, traversal);
+                }
+                else
+                    node.End = true;
+            }
+            else
+                traversal.CurrentNode.End = true;
+        }
+
+        // Travels as far as it can before it either comes to the wrong letter
+        // or comes to the end of the tree
+        private TraversalData Traverse(string word, TraversalData traversal)
+        {
+            TraversalData oldSpot;
+            TraversalData newSpot = traversal;
+
+            do
+            {
+                oldSpot = newSpot;
+                newSpot = TraverseOneStep(word, oldSpot);
+
+            } while (oldSpot.Depth != newSpot.Depth);
+
+            return newSpot;
+        }
+
+        private TraversalData TraverseOneStep(string word, TraversalData traversal)
+        {
+            var currentNode = TraverseNode(word, traversal);
+
+            if (currentNode != null)
+            {
+                traversal.CurrentNode = currentNode;
+                traversal.Nodes = currentNode.Nodes;
+                traversal.Depth++;
+            }
+
+            return traversal;
+        }
+
+
+        private LetterNode TraverseNode(string word, TraversalData traversal)
+        {
+            if (word.Length > 0 && traversal.Depth < word.Length - 1)
+            {
+                var potentialKey = word[traversal.Depth + 1];
+
+                // Check TraversalData.Nodes instead of TraversalData.CurrentNode
+                // because there is not a single tree structure containing all of
+                // the nodes. Instead it is a hash of nodes based on the first letter
+                if (traversal.Nodes.ContainsKey(potentialKey))
+                    return traversal.Nodes[potentialKey];
+            }
+            
+            return null;
+        }
+
+        public string Spellcheck(string word)
+        {
+            var root = GetRoot();
+            var newWord = Spellcheck(word, root);
+            BadWord.Clear();
+            return newWord;
+        }
+
+        // This function is called recursively from within itself and from within
+        // each letter changing case (including case change)
+        // The order is as follows:
+        //   Go to the next letter in the word.
+        //   If you can traverse to it, recursively call spellcheck at the next node in the tree
+        //   Then if that returns no suggestion, check repeating letters, vowels, and improper casing.
+        //   If any function returns a word that fits the requirements, stop immediately and return it
+        //   If all options are exhausted, return no suggestion.
+        public string Spellcheck(string word, TraversalData traversal,
+                                 bool changingVowel = false, bool changingCase = false)
+        {
+            // If a word has been checked from this depth, don't check it again.
+            if (!(BadWord.ContainsKey(word) && BadWord[word].Contains(traversal.Depth)))
+            {
+                if (traversal.CurrentNode != null)
+                {
+                    var currentWord = traversal.CurrentNode.GetWord();
+
+                    if (traversal.CurrentNode.End == true && currentWord == word)
+                        return currentWord;
+                }
+
+                var nextLocation = TraverseOneStep(word, traversal);
+                if (traversal.Depth != nextLocation.Depth)
+                {
+                    var returnedWord = Spellcheck(word, nextLocation);
+
+                    if (returnedWord != NO_SUGGESTION_TEXT)
+                        return returnedWord;
+                }
+
+                // If a vowel was changed to cause the repeating character,
+                // don't remove the repeated character.
+                if ((traversal.Depth + 1 < word.Length && !IsVowel(word[traversal.Depth + 1]))
+                    || !changingVowel)
+                {
+                    var processedWord = ProcessRepeatedLetter(word, traversal);
+
+                    if (processedWord != NO_SUGGESTION_TEXT)
+                        return processedWord;
+                }
+
+                // If you are still checking vowels, so don't try checking them again.
+                if (!changingVowel)
+                {
+                    var changedVowel = CheckForIncorrectVowel(word, traversal, changingCase);
+
+                    if (changedVowel != NO_SUGGESTION_TEXT)
+                        return changedVowel;
+                }
+
+                // If you already changed the case, don't try checking it again.
+                if (!changingCase)
+                {
+                    var changedCasing = CheckForImproperCasing(word, traversal, changingVowel);
+
+                    if (changedCasing != NO_SUGGESTION_TEXT)
+                        return changedCasing;
+                }
+
+                if (!BadWord.ContainsKey(word))
+                    BadWord.Add(word, new HashSet<int>());
+                BadWord[word].Add(traversal.Depth);
+            }
+            return NO_SUGGESTION_TEXT;
+        }
+
+        private string CheckForImproperCasing(string word, TraversalData traversal,
+                                               bool changingVowel)
+        {
+            if (0 <= traversal.Depth + 1 && traversal.Depth + 1 < word.Length)
+            {
+                StringBuilder newWord = new StringBuilder(word);
+
+                if (char.IsLower(word[traversal.Depth + 1]))
+                    newWord[traversal.Depth + 1] = char.ToUpper(newWord[traversal.Depth + 1]);
+                else
+                    newWord[traversal.Depth + 1] = char.ToLower(newWord[traversal.Depth + 1]);
+
+                return Spellcheck(newWord.ToString(), traversal, changingVowel, true);
+            }
+            return NO_SUGGESTION_TEXT;
+        }
+
+        private string CheckForIncorrectVowel(string word, TraversalData traversal,
+                                              bool changingCase)
+        {
+            if (0 <= traversal.Depth + 1
+                && traversal.Depth + 1 < word.Length
+                && IsVowel(word[traversal.Depth + 1]))
+            {
+                StringBuilder newWord = new StringBuilder(word);
+
+                foreach (char vowel in GetVowel())
+                {
+                    if (vowel != char.ToLower(word[traversal.Depth + 1]))
+                    {
+                        if (char.IsUpper(word[traversal.Depth + 1]))
+                            newWord[traversal.Depth + 1] = char.ToUpper(vowel);
+                        else
+                            newWord[traversal.Depth + 1] = vowel;
+
+                        var spellcheckReturn = Spellcheck(newWord.ToString(), traversal, true, changingCase);
+
+                        if (spellcheckReturn != NO_SUGGESTION_TEXT)
+                            return spellcheckReturn;
+                    }
+                }
+            }
+            return NO_SUGGESTION_TEXT;
+        }
+
+        private string ProcessRepeatedLetter(string word, TraversalData traversal)
+        {
+            // Strip off the repeating letter and run it through spellcheck again
+            StringBuilder newWordBuilder = new StringBuilder(word);
+
+            while (traversal.Depth + 2 < newWordBuilder.Length
+                && newWordBuilder[traversal.Depth + 1] == newWordBuilder[traversal.Depth + 2])
+            {
+                newWordBuilder = newWordBuilder.Remove(traversal.Depth + 1, 1);
+
+                string newWord = newWordBuilder.ToString();
+
+                if (traversal.CurrentNode != null)
+                {
+                    var newTraversal = traversal;
+                    newTraversal = TraverseOneStep(newWord, newTraversal);
+                    newTraversal = TraverseOneStep(newWord, newTraversal);
+
+                    if (traversal.Depth + 2 == newTraversal.Depth && newTraversal.CurrentNode.End
+                        && newTraversal.CurrentNode.GetWord() == newWord)
+                        return newTraversal.CurrentNode.GetWord();
+                }
+                var spellcheckReturn = Spellcheck(newWord, traversal);
+
+                if (spellcheckReturn != NO_SUGGESTION_TEXT)
+                    return spellcheckReturn;
+            }
+            return NO_SUGGESTION_TEXT;
+        }
+
+        private bool IsVowel(char character)
+        {
+            foreach (char vowel in GetVowel())
+            {
+                if (char.ToLower(character) == vowel)
+                    return true;
+            }
+            return false;
+        }
+
+        // I used an array in the unspeller because I needed vowels
+        // in a different way there. I could have used an array here
+        // but I thought it would be fun trying the yield keyword
+        // since I haven't really found a good use for yield yet.
+        private IEnumerable GetVowel()
+        {
+            yield return 'a';
+            yield return 'e';
+            yield return 'i';
+            yield return 'o';
+            yield return 'u';
+            yield return 'y';
+        }
+    }
+}

File CSharpSolution/spellcheck/spellcheck/Program.cs

+using System;
+using System.IO;
+
+namespace spellcheck
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            LetterTree words = new LetterTree();
+
+            string path = "words";
+            if (args.Length != 0)
+            {
+                if (args[0].Trim() == "help" || args[0].Trim() == "/?"
+                    || args[0].Trim() == "?")
+                {
+                    PrintUsage();
+                    return;
+                }
+                else
+                    path = args[0];
+            }
+
+            if (PopulateWords(words, path))
+            {
+                string line = string.Empty;
+                while (true)
+                {
+                    Console.Write("> ");
+
+                    do
+                    {
+                        line = Console.ReadLine();
+
+
+                        if (line != null)
+                        {
+                            line = line.Trim();
+                            Console.WriteLine(words.Spellcheck(line));
+                        }
+                    } while (line == null);
+                }
+            }
+        }
+
+        static bool PopulateWords(LetterTree Words, string filePath)
+        {
+            string line;
+            try
+            {
+                using (StreamReader sr = new StreamReader(Path.GetFullPath(filePath)))
+                {
+                    while (sr.Peek() >= 0)
+                    {
+                        line = sr.ReadLine();
+                        if (line != string.Empty)
+                            Words.Add(line);
+                    }
+                }
+
+                return true;
+            }
+            catch (FileNotFoundException)
+            {
+                Console.WriteLine("\nNo file found at: \"{0}\"\n", filePath);
+                PrintUsage();
+                return false;
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.ToString());
+                return false;
+            }
+        }
+
+        private static void PrintUsage()
+        {
+            Console.WriteLine("Welcome to Charlie's Amazing Spellchecker!!");
+            Console.WriteLine("");
+            Console.WriteLine("Usage:");
+            Console.WriteLine("");
+            Console.WriteLine("spellcheck <optional file name>");
+            Console.WriteLine("If you want to call it without a filename, put the dictionary");
+            Console.WriteLine("file in this directory ({0}) and name it words", Environment.CurrentDirectory);
+        }
+    }
+}

File CSharpSolution/spellcheck/spellcheck/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("spellcheck")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("spellcheck")]
+[assembly: AssemblyCopyright("Copyright ©  2011")]
+[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("2ecc933a-229d-470e-b480-2cd58d17df86")]
+
+// 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")]

File CSharpSolution/spellcheck/spellcheck/spellcheck.csproj

+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{65AAB598-8045-4B84-8B11-91CE51A799B3}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>spellcheck</RootNamespace>
+    <AssemblyName>spellcheck</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <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|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="LetterNode.cs" />
+    <Compile Include="LetterTree.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.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>

File CSharpSolution/spellcheck/spellcheckUnitTests/LetterTreeTests.cs

+using NUnit.Framework;
+using spellcheck;
+
+namespace spellCheckUnitTests
+{
+    [TestFixture]
+    public class LetterTreePopulationTests
+    {
+        LetterTree Words;
+        
+        [SetUp]
+        public void SetUp()
+        {
+            Words = new LetterTree();
+        }
+
+        [Test]
+        public void PopulateNoWordInTree()
+        {
+            Assert.IsEmpty(Words.Tree);
+        }
+
+        [Test]
+        public void PopulateSingleWordIsInTree()
+        {
+            Words.Add("hi");
+            Assert.AreEqual(1, Words.Tree.Count);
+            Assert.AreEqual(1, Words.Tree['h'].Nodes.Count);
+            Assert.AreEqual(0, Words.Tree['h'].Nodes['i'].Nodes.Count);
+
+            Assert.AreEqual('h', Words.Tree['h'].Letter);
+            Assert.AreEqual('i', Words.Tree['h'].Nodes['i'].Letter);
+
+            Assert.IsFalse(Words.Tree['h'].End);
+            Assert.IsTrue(Words.Tree['h'].Nodes['i'].End);
+
+            Assert.AreEqual("hi", Words.Tree['h'].Nodes['i'].GetWord());
+        }
+
+        [Test]
+        public void PopulateNonOverlappingWordsInTree()
+        {
+            Words.Add("hi");
+            Words.Add("a");
+
+            Assert.AreEqual(2, Words.Tree.Count);
+            Assert.AreEqual(1, Words.Tree['h'].Nodes.Count);
+            Assert.AreEqual(0, Words.Tree['a'].Nodes.Count);
+
+            Assert.AreEqual('h', Words.Tree['h'].Letter);
+            Assert.AreEqual('i', Words.Tree['h'].Nodes['i'].Letter);
+
+            Assert.AreEqual('a', Words.Tree['a'].Letter);
+
+            Assert.IsFalse(Words.Tree['h'].End);
+            Assert.IsTrue(Words.Tree['h'].Nodes['i'].End);
+
+            Assert.IsTrue(Words.Tree['a'].End);
+        }
+
+        [Test]
+        public void PopulateSameWordInTreeTwice()
+        {
+            Words.Add("a");
+            Words.Add("a");
+
+            Assert.AreEqual(1, Words.Tree.Count);
+        }
+
+        [Test]
+        public void PopulateOverlappingWordsInTree()
+        {
+            Words.Add("hi");
+            Words.Add("ha");
+
+            Assert.AreEqual(1, Words.Tree.Count);
+            Assert.AreEqual(2, Words.Tree['h'].Nodes.Count);
+
+            Assert.AreEqual('h', Words.Tree['h'].Letter);
+            Assert.AreEqual('i', Words.Tree['h'].Nodes['i'].Letter);
+            Assert.AreEqual('a', Words.Tree['h'].Nodes['a'].Letter);
+
+            Assert.IsFalse(Words.Tree['h'].End);
+            Assert.IsTrue(Words.Tree['h'].Nodes['i'].End);
+            Assert.IsTrue(Words.Tree['h'].Nodes['a'].End);
+        }
+
+        [Test]
+        public void PopulateSmallerWordUsingSameCharactersAsBiggerWord()
+        {
+            Words.Add("high");
+            Words.Add("hi");
+            Assert.AreEqual(1, Words.Tree.Count);
+            Assert.AreEqual(1, Words.Tree['h'].Nodes.Count);
+            Assert.AreEqual(1, Words.Tree['h'].Nodes['i'].Nodes.Count);
+            Assert.AreEqual(1, Words.Tree['h'].Nodes['i'].Nodes['g'].Nodes.Count);
+            Assert.AreEqual(0, Words.Tree['h'].Nodes['i'].Nodes['g'].Nodes['h'].Nodes.Count);
+
+            Assert.AreEqual('h', Words.Tree['h'].Letter);
+            Assert.AreEqual('i', Words.Tree['h'].Nodes['i'].Letter);
+            Assert.AreEqual('g', Words.Tree['h'].Nodes['i'].Nodes['g'].Letter);
+            Assert.AreEqual('h', Words.Tree['h'].Nodes['i'].Nodes['g'].Nodes['h'].Letter);
+
+            Assert.IsFalse(Words.Tree['h'].End);
+            Assert.IsTrue(Words.Tree['h'].Nodes['i'].End);
+            Assert.IsFalse(Words.Tree['h'].Nodes['i'].Nodes['g'].End);
+            Assert.IsTrue(Words.Tree['h'].Nodes['i'].Nodes['g'].Nodes['h'].End);
+
+            Assert.AreEqual("hi", Words.Tree['h'].Nodes['i'].GetWord());
+            Assert.AreEqual("high", Words.Tree['h'].Nodes['i'].Nodes['g'].Nodes['h'].GetWord());
+        }
+    }
+
+    [TestFixture]
+    public class LetterTreeSpellCheckTests
+    {
+        LetterTree Words;
+
+        [SetUp]
+        public void SetUp()
+        {
+            Words = new LetterTree();
+        }
+
+        [Test]
+        public void SpellcheckNoSuggestionWord()
+        {
+            var actual = Words.Spellcheck("ohaithar");
+
+            Assert.AreEqual("NO SUGGESTION", actual);
+        }
+
+        [Test]
+        public void SpellcheckProperlySpelled()
+        {
+            var expected = "hi";
+
+            Words.Add(expected);
+            Words.Add("noise");
+            Words.Add("morenoise");
+            Words.Add("even more noise");
+            Words.Add("hihihihihi");
+
+            var actual = Words.Spellcheck(expected);
+
+            Assert.AreEqual(expected, actual);
+        }
+
+        [Test]
+        public void SpellcheckProperlySpelledOneLetterWord()
+        {
+            var expected = "a";
+
+            Words.Add(expected);
+            Words.Add("noise");
+            Words.Add("morenoise");
+            Words.Add("even more noise");
+            Words.Add("hihihihihi");
+
+            var actual = Words.Spellcheck(expected);
+
+            Assert.AreEqual(expected, actual);
+        }
+
+
+        [Test]
+        public void SpellcheckMismatchedCase()
+        {
+            Words.Add("inside");
+
+            var actual = Words.Spellcheck("inSIDE");
+
+            Assert.AreEqual("inside", actual);
+        }
+
+        [Test]
+        public void SpellcheckIncorrectVowel()
+        {
+            Words.Add("wake");
+
+            var actual = Words.Spellcheck("weke");
+
+            Assert.AreEqual("wake", actual);
+        }
+
+        [Test]
+        public void SpellcheckRepeatedLetters()
+        {
+            Words.Add("job");
+
+            var actual = Words.Spellcheck("jjoobbb");
+
+            Assert.AreEqual("job", actual);
+        }
+
+        [Test]
+        public void SpellcheckExampleOnWebsite()
+        {
+            Words.Add("sheep");
+            Words.Add("people");
+            Words.Add("inside");
+            Words.Add("job");
+            Words.Add("wake");
+            Words.Add("conspiracy");
+
+            Assert.AreEqual("sheep", Words.Spellcheck("sheeeeep"));
+            Assert.AreEqual("people", Words.Spellcheck("peepple"));
+            Assert.AreEqual("NO SUGGESTION", Words.Spellcheck("sheeple"));
+            Assert.AreEqual("inside", Words.Spellcheck("inSIDE"));
+            Assert.AreEqual("job", Words.Spellcheck("jjoobbb"));
+            Assert.AreEqual("conspiracy", Words.Spellcheck("CUNsperrICY"));
+        }
+
+        [Test]
+        public void SpellcheckWordsThatNeedBacktrackingToFind()
+        {
+            Words.Add("wake");
+            Words.Add("west");
+
+            var actual = Words.Spellcheck("weke");
+
+            Assert.AreEqual("wake", actual);
+        }
+
+        [Test]
+        public void SpellcheckWordsThatHaveMultipleCasings()
+        {
+            // Actual example from my word list.
+            // That is what made me realize that this is not handled properly.
+            Words.Add("Wake");
+            Words.Add("wake");
+
+            var actual = Words.Spellcheck("Wake");
+            Assert.AreEqual("Wake", actual);
+
+            actual = Words.Spellcheck("wake");
+            Assert.AreEqual("wake", actual);
+        }
+
+        [Test]
+        public void SpellcheckWordsThatHaveRepeatingCharactersWithMultipleCasings()
+        {
+            Words.Add("Azov's");
+
+            var actual = Words.Spellcheck("OozZAavv''S");
+            Assert.AreEqual("Azov's", actual);
+        }
+
+        [Test]
+        public void SpellcheckWordsThatHaveRepeatingVowelsNextToOtherVowels()
+        {
+            Words.Add("Beaumont");
+
+            var actual = Words.Spellcheck("bOoaaOOMuUnTt");
+            Assert.AreEqual("Beaumont", actual);
+        }
+    }
+}

File CSharpSolution/spellcheck/spellcheckUnitTests/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("NUnit")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("NUnit")]
+[assembly: AssemblyCopyright("Copyright ©  2011")]
+[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("37c3a485-fd07-439a-83fb-6c537201a92e")]
+
+// 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")]

File CSharpSolution/spellcheck/spellcheckUnitTests/spellcheckUnitTests.csproj

+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{267220FB-6CB6-4F6F-9967-9D55F58EE98C}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>spellcheckUnitTests</RootNamespace>
+    <AssemblyName>spellcheckUnitTests</AssemblyName>
+    <TargetFrameworkVersion>v4.0</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.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="LetterTreeTests.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\spellcheck\spellcheck.csproj">
+      <Project>{65AAB598-8045-4B84-8B11-91CE51A799B3}</Project>
+      <Name>spellcheck</Name>
+    </ProjectReference>
+  </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>

File CSharpSolution/unspeller/unspeller.sln

+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual C# Express 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "unspeller", "unspeller\unspeller.csproj", "{A1DE99EF-1600-4619-A5A3-231298E6C378}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "unspellerUnitTests", "unspellerUnitTests\unspellerUnitTests.csproj", "{F6FDAFC4-9C82-4781-A85E-6E952D94DB15}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|Mixed Platforms = Debug|Mixed Platforms
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|Mixed Platforms = Release|Mixed Platforms
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{A1DE99EF-1600-4619-A5A3-231298E6C378}.Debug|Any CPU.ActiveCfg = Debug|x86
+		{A1DE99EF-1600-4619-A5A3-231298E6C378}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+		{A1DE99EF-1600-4619-A5A3-231298E6C378}.Debug|Mixed Platforms.Build.0 = Debug|x86
+		{A1DE99EF-1600-4619-A5A3-231298E6C378}.Debug|x86.ActiveCfg = Debug|x86
+		{A1DE99EF-1600-4619-A5A3-231298E6C378}.Debug|x86.Build.0 = Debug|x86
+		{A1DE99EF-1600-4619-A5A3-231298E6C378}.Release|Any CPU.ActiveCfg = Release|x86
+		{A1DE99EF-1600-4619-A5A3-231298E6C378}.Release|Mixed Platforms.ActiveCfg = Release|x86
+		{A1DE99EF-1600-4619-A5A3-231298E6C378}.Release|Mixed Platforms.Build.0 = Release|x86
+		{A1DE99EF-1600-4619-A5A3-231298E6C378}.Release|x86.ActiveCfg = Release|x86
+		{A1DE99EF-1600-4619-A5A3-231298E6C378}.Release|x86.Build.0 = Release|x86
+		{F6FDAFC4-9C82-4781-A85E-6E952D94DB15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F6FDAFC4-9C82-4781-A85E-6E952D94DB15}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F6FDAFC4-9C82-4781-A85E-6E952D94DB15}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{F6FDAFC4-9C82-4781-A85E-6E952D94DB15}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{F6FDAFC4-9C82-4781-A85E-6E952D94DB15}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{F6FDAFC4-9C82-4781-A85E-6E952D94DB15}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F6FDAFC4-9C82-4781-A85E-6E952D94DB15}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F6FDAFC4-9C82-4781-A85E-6E952D94DB15}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{F6FDAFC4-9C82-4781-A85E-6E952D94DB15}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{F6FDAFC4-9C82-4781-A85E-6E952D94DB15}.Release|x86.ActiveCfg = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

File CSharpSolution/unspeller/unspeller/Program.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+
+namespace unspeller
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            if (!ArgsAreCorrect(args))
+                return;
+
+            int timesToRun;
+            timesToRun = int.Parse(args[0]);
+
+            string path = "words";
+            if (args.Length == 2)
+                path = args[1];
+
+            string[] words;
+            words = PopulateWords(path);
+
+            if (words.Length > 0)
+            {
+                Random rand = new Random();
+                string wordToUnspell;
+
+                while (timesToRun > 0)
+                {
+                    wordToUnspell = words[rand.Next(words.Length)];
+
+                    Console.WriteLine(unspell.UnspellWord(wordToUnspell));
+                    timesToRun--;
+                }
+            }
+        }
+
+        static bool ArgsAreCorrect(string[] args)
+        {
+            // Make sure there is only one or two args passed in
+            if (args.Length != 1 && args.Length != 2)
+            {
+                PrintUsage();
+                return false;
+            }
+
+            if (args[0].Trim() == "help" || args[0].Trim() == "/?"
+                || args[0].Trim() == "?")
+            {
+                PrintUsage();
+                return false;
+            }
+
+            // First arg needs to be the number of times the app is run.
+            try
+            {
+                int.Parse(args[0]);
+            }
+            catch
+            {
+                PrintUsage();
+                return false;
+            }
+
+            return true;
+        }
+
+        static string[] PopulateWords(string filePath)
+        {
+            List<string> words = new List<string>();
+            string line;
+            try
+            {
+                using (StreamReader sr = new StreamReader(Path.GetFullPath(filePath)))
+                {
+                    while (sr.Peek() >= 0)
+                    {
+                        line = sr.ReadLine();
+                        if (line != string.Empty)
+                            words.Add(line);
+                    }
+                }
+            }
+            catch (FileNotFoundException)
+            {
+                Console.WriteLine("\nNo file found at: \"{0}\"\n", filePath);
+                PrintUsage();
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.ToString());
+            }
+
+            return words.ToArray();
+        }
+
+        private static void PrintUsage()
+        {
+            Console.WriteLine("Welcome to Charlie's Amazing Unspeller!!");
+            Console.WriteLine("");
+            Console.WriteLine("Usage:");
+            Console.WriteLine("");
+            Console.WriteLine("unspell <# of times to run> <optional file name>");
+            Console.WriteLine("If you want to call it without a filename, put the dictionary");
+            Console.WriteLine("file in this directory ({0}) and name it words", Environment.CurrentDirectory);
+        }
+    }
+}

File CSharpSolution/unspeller/unspeller/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("unspeller")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("unspeller")]
+[assembly: AssemblyCopyright("Copyright ©  2011")]
+[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("99827e34-3ad8-4b83-9684-62f0028459a4")]
+
+// 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")]

File CSharpSolution/unspeller/unspeller/unspell.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Collections;
+
+namespace unspeller
+{
+    public struct CharacterChangeData
+    {
+        public int LetterIndex;
+        public char NewCharacter;
+    }
+
+    public struct CharacterRepeatData
+    {
+        public int LetterIndex;
+        public int TimesToRepeat;
+    }
+
+    public class unspell
+    {
+        static Random rand = new Random();
+        public static char[] Vowels = { 'a', 'e', 'i', 'o', 'u', 'y' };
+
+        public static int MAX_TIMES_TO_REPEAT_CHAR = 2;
+
+        public static char ChangeCase(char letter)
+        {
+            if (('a' <= letter && letter <= 'z') || ('A' <= letter && letter <= 'Z'))
+            {
+                if (char.IsLower(letter))
+                    letter = char.ToUpper(letter);
+                else
+                    letter = char.ToLower(letter);
+            }
+            return letter;
+
+        }
+
+        public static string ChangeCharacter(string word, int letterIndex, char newCharacter)
+        {
+            StringBuilder newWord = new StringBuilder(word);
+            newWord[letterIndex] = newCharacter;
+            return newWord.ToString();
+        }
+
+        public static string ChangeVowels(string word, bool testMode = false)
+        {
+            StringBuilder newWord = new StringBuilder(word);
+            int vowelToUse = -1;
+            bool changeVowel = false;
+
+            for (int i = 0; i < word.Length; i++)
+            {
+                if (IsVowel(word[i]))
+                {
+                    if (testMode)
+                    {
+                        vowelToUse += 1;
+                        vowelToUse %= Vowels.Length;
+                        changeVowel = true;
+                    }
+                    else
+                    {
+                        // Make it so it doesn't always change vowels
+                        if (rand.Next(2) == 0)
+                            changeVowel = false;
+                        else
+                        {
+                            vowelToUse = rand.Next(Vowels.Length);
+                            changeVowel = true;
+                        }
+                    }
+
+                    if (changeVowel)
+                    {
+                        if (Char.IsUpper(newWord[i]))
+                            newWord[i] = Char.ToUpper(Vowels[vowelToUse]);
+                        else
+                            newWord[i] = Vowels[vowelToUse];
+                    }
+                }
+            }
+            return newWord.ToString();
+        }
+
+        public static string RepeatCharacters(string word, bool testMode = false)
+        {
+            StringBuilder newWord = new StringBuilder(word);
+            int timesToRepeat = word.Length;
+            char charToRepeat;
+
+            for (int i = word.Length - 1; i >= 0; i--)
+            {
+                if (testMode)
+                    timesToRepeat -= 1;
+                else
+                    timesToRepeat = rand.Next(MAX_TIMES_TO_REPEAT_CHAR);
+                
+                charToRepeat = newWord[i];
+                String repeatedChars = new String(charToRepeat, timesToRepeat);
+                newWord.Insert(i, repeatedChars);
+            }
+            return newWord.ToString();
+        }
+
+        public static string ChangeCapatlizationOnWord(string word, bool testMode = false)
+        {
+            StringBuilder newWord = new StringBuilder(word);
+            bool changeCase;
+
+            for (int i = 0; i < newWord.Length; i++)
+            {
+                if (testMode)
+                    changeCase = true;
+                else
+                {
+                    if (rand.Next(2) == 0)
+                        changeCase = false;
+                    else
+                        changeCase = true;
+                }
+                if (changeCase)
+                    newWord[i] = ChangeCase(newWord[i]);
+            }
+            return newWord.ToString();
+        }
+
+        public static string UnspellWord(string word, bool testMode = false)
+        {
+            word = ChangeVowels(word, testMode);
+            word = RepeatCharacters(word, testMode);
+            word = ChangeCapatlizationOnWord(word, testMode);
+            return word;
+        }
+
+        // The vowel related stuff is close to identical in both applications.
+        // Normally I wouldn't copy and paste code from one spot to another.
+        // However, since these are seperate applications, I didn't want to
+        // have them linked together and I didn't want to create a library
+        // of one to two functions.
+        private static bool IsVowel(char character)
+        {
+            foreach (char vowel in Vowels)
+            {
+                if (char.ToLower(character) == vowel)
+                    return true;
+            }
+            return false;
+        }
+    }
+}

File CSharpSolution/unspeller/unspeller/unspeller.csproj

+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{A1DE99EF-1600-4619-A5A3-231298E6C378}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>unspeller</RootNamespace>
+    <AssemblyName>unspeller</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <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|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="unspell.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>

File CSharpSolution/unspeller/unspellerUnitTests/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("unspellerUnitTests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("unspellerUnitTests")]
+[assembly: AssemblyCopyright("Copyright ©  2011")]
+[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("4f8c3643-785e-452e-87cb-3c0cc8528ba5")]
+
+// 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")]

File CSharpSolution/unspeller/unspellerUnitTests/unspellerTests.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using unspeller;
+
+namespace unspellerUnitTests
+{
+    [TestFixture]
+    public class unspellerTests
+    {
+        [Test]
+        public void ChangeCaseFromLowerToUpper()
+        {
+
+            Assert.AreEqual('I', unspell.ChangeCase('i'));
+        }
+
+        [Test]
+        public void ChangeCaseFromUpperToLower()
+        {
+            Assert.AreEqual('i', unspell.ChangeCase('I'));
+        }
+
+        [Test]
+        public void DontChangeCaseOfDifferentCulture() 
+        {
+            // DOS window can't handle all culture's letters
+            // like Á specifically. It will become a regular A
+            // and make the unspeller not realize the cultural
+            // difference.
+            Assert.AreEqual('Á', unspell.ChangeCase('Á'));
+        }
+
+        [Test]
+        public void ChangeCharacter()
+        {
+            Assert.AreEqual("weke", unspell.ChangeCharacter("wake", 1, 'e'));
+        }
+
+        [Test]
+        public void ChangeNoVowelWord()
+        {
+            var actual = unspell.ChangeVowels("blrg");
+
+            Assert.AreEqual("blrg", actual);
+        }
+
+        [Test]
+        public void ChangeAllVowels()
+        {
+            // Not a practical example, but gets the job done
+            var actual = unspell.ChangeVowels("eiouya", true);
+
+            Assert.AreEqual("aeiouy", actual);
+        }
+
+        [Test]
+        public void ChangeCapitalVowel()
+        {
+            // Not a practical example, but gets the job done
+            var actual = unspell.ChangeVowels("E", true);
+
+            Assert.AreEqual("A", actual);
+        }
+
+        [Test]
+        public void ChangeWord()
+        {
+            var actual = unspell.ChangeVowels("sheep", true);
+
+            Assert.AreEqual("shaep", actual);
+        }
+
+        [Test]
+        public void GetRepeatingCharData()
+        {
+            var actual = unspell.RepeatCharacters("job", true);
+
+            Assert.AreEqual("joobbb", actual);
+        }
+
+        [Test]
+        public void ChangeCapatalizeationOnWord()
+        {
+            var actual = unspell.ChangeCapatlizationOnWord("yUp", true);
+
+            Assert.AreEqual("YuP", actual);
+        }
+
+        [Test]
+        public void UnspellWord()
+        {
+            var actual = unspell.UnspellWord("yUp", true);
+
+            Assert.AreEqual("AeePPP", actual);
+        }
+    }
+}

File CSharpSolution/unspeller/unspellerUnitTests/unspellerUnitTests.csproj

+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{F6FDAFC4-9C82-4781-A85E-6E952D94DB15}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>unspellerUnitTests</RootNamespace>
+    <AssemblyName>unspellerUnitTests</AssemblyName>
+    <TargetFrameworkVersion>v4.0</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.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
+    <Reference Include="nunit.mocks, Version=2.5.10.11092, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="unspellerTests.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\unspeller\unspeller.csproj">
+      <Project>{A1DE99EF-1600-4619-A5A3-231298E6C378}</Project>
+      <Name>unspeller</Name>
+    </ProjectReference>
+  </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>

File README

-Hello Justin.tv :)
-My name is Charlie Guse and this is my solution for the spellcheck problem.
-http://www.justin.tv/problems/spellcheck
-
-
-Non-explaining list version of instructions:
-
-Compiling the source:
-    Open up source/spellcheck/spellcheck.sln
-    Compile it.
-    Open up source/spellcheck/spellcheck/bin/Debug(and Release) and put american-english
-    Rename american-english words for the program.
-
-    Follow the same instructions for unspeller to compile and use that.
-
-Using NUnit:
-    Install from http://www.nunit.org/
-    Run NUnit 2.5.10\bin\net-2.0\nunit-x86.exe (NOT nunit.exe)
-    File > Open Project... and open source/nunit_spellcheck/spellcheck.nunit (give an error if the source isn't compiled)
-    
-    Same for source/nunit_unspeller/unspeller.nunit
-
-
-Explaining paragraph version of instructions:  
-
-    If you compile the source code, you will have to manually put the american-english
-dictionary in the Debug/Release folder and rename it words. I didn't make a post-
-build step for that because I only had to do it once. I deleted all of the pre-
-compiled stuff before sending it to you though. Since you know... space is an issue. ;)
-I just wanted to put the source code in it's most basic form as if you were pulling it
-down from source control.
-
-    I used NUnit 2.5.10.11092 for unit testing. If you use the default executable
-(nunit.exe) you will get a BadImageFormat exception. There is a second executable
-named nunit-x86.exe that you need to use instead. If you are unfamiliar with NUnit,
-to use it, open up nunit-x86.exe, File > Open Project... and then go to
-source/nunit_spellcheck/spellcheck.nunit to load the unit test project. If you get
-an error saying Assembly Not Loaded, you will have to compile the Spellcheck project
-once first so it can find the Release version of the dlls.
-
-    This was created in .net 4.0. If this is an issue. Please let me know.
-    

File nunit_spellcheck/TestResult.xml

-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!--This file represents the results of running a test suite-->
-<test-results name="C:\sandbox\spellchecker\nunit_spellcheck\spellcheck.nunit" total="17" errors="0" failures="0" not-run="0" inconclusive="0" ignored="0" skipped="0" invalid="0" date="2012-01-03" time="17:33:15">
-  <environment nunit-version="2.5.10.11092" clr-version="2.0.50727.5448" os-version="Microsoft Windows NT 6.1.7601 Service Pack 1" platform="Win32NT" cwd="C:\Program Files (x86)\NUnit 2.5.10\bin\net-2.0" machine-name="ANIMUS" user="Charles" user-domain="Animus" />
-  <culture-info current-culture="en-US" current-uiculture="en-US" />
-  <test-suite type="Test Project" name="C:\sandbox\spellchecker\nunit_spellcheck\spellcheck.nunit" executed="True" result="Success" success="True" time="0.240" asserts="0">
-    <results>
-      <test-suite type="Assembly" name="C:\sandbox\spellchecker\nunit_spellcheck\..\spellcheck\spellcheckUnitTests\bin\Release\spellcheckUnitTests.dll" executed="True" result="Success" success="True" time="0.096" asserts="0">
-        <results>
-          <test-suite type="Namespace" name="spellCheckUnitTests" executed="True" result="Success" success="True" time="0.092" asserts="0">
-            <results>
-              <test-suite type="TestFixture" name="LetterTreePopulationTests" executed="True" result="Success" success="True" time="0.057" asserts="0">
-                <results>