Commits

aarondandy  committed 936fbc7

Some refactoring and installer tweaks.

  • Participants
  • Parent commits be461eb

Comments (0)

Files changed (37)

File build/YouCantSpell.Installer.v61/YouCantSpell.Installer.v61.wixproj

     <OutputPath>bin\$(Configuration)\</OutputPath>
     <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
     <DefineConstants>Debug;</DefineConstants>
+    <LinkerAdditionalOptions>
+    </LinkerAdditionalOptions>
+    <CompilerAdditionalOptions>
+    </CompilerAdditionalOptions>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
     <OutputPath>bin\$(Configuration)\</OutputPath>
       <Using Namespace="System" />
       <Using Namespace="System.IO" />
       <Using Namespace="System.Reflection" />
-      <Code Type="Fragment" Language="cs"><![CDATA[
+      <Code Type="Fragment" Language="cs">
+<![CDATA[
 var filePath = Path.GetFullPath(@"..\..\bin\Debug\YouCantSpell.Core.dll");
-var asm = Assembly.LoadFile(filePath);
-CoreAsmVersion = asm.GetName().Version.ToString();
-]]></Code>
+CoreAsmVersion = AssemblyName.GetAssemblyName(filePath).Version.ToString();
+]]>
+      </Code>
     </Task>
   </UsingTask>
   <ItemGroup>
     </GetCoreVersion>
     <PropertyGroup>
       <DefineConstants>$(DefineConstants);CoreAsmVersion=$(CoreAsmVersion)</DefineConstants>
+      <TargetName>$(ProjectName).$(CoreAsmVersion)</TargetName>
+      <TargetFileName>$(TargetName).msi</TargetFileName>
+      <TargetPath>$(TargetDir)$(TargetFileName)</TargetPath>
     </PropertyGroup>
   </Target>
   <Target Name="AfterBuild">
   </Target>
+  <PropertyGroup>
+    <PreBuildEvent />
+  </PropertyGroup>
 </Project>

File build/YouCantSpell.Installer.v70/YouCantSpell.Installer.v70.wixproj

       <Using Namespace="System" />
       <Using Namespace="System.IO" />
       <Using Namespace="System.Reflection" />
-      <Code Type="Fragment" Language="cs"><![CDATA[
+      <Code Type="Fragment" Language="cs">
+<![CDATA[
 var filePath = Path.GetFullPath(@"..\..\bin\Debug\YouCantSpell.Core.dll");
-var asm = Assembly.LoadFile(filePath);
-CoreAsmVersion = asm.GetName().Version.ToString();
-]]></Code>
+CoreAsmVersion = AssemblyName.GetAssemblyName(filePath).Version.ToString();
+]]>
+      </Code>
     </Task>
   </UsingTask>
   <ItemGroup>
     </GetCoreVersion>
     <PropertyGroup>
       <DefineConstants>$(DefineConstants);CoreAsmVersion=$(CoreAsmVersion)</DefineConstants>
+      <TargetName>$(ProjectName).$(CoreAsmVersion)</TargetName>
+      <TargetFileName>$(TargetName).msi</TargetFileName>
+      <TargetPath>$(TargetDir)$(TargetFileName)</TargetPath>
     </PropertyGroup>
   </Target>
   <Target Name="AfterBuild">

File src/YouCantSpell.Core/TextSubString.cs

 namespace YouCantSpell
 {
-	public struct TextSubString : ITextSubString
+	/// <summary>
+	/// A sub-string of text derrived from a larger string of text.
+	/// </summary>
+	public class TextSubString : ITextSubString
 	{
-
+		/// <summary>
+		/// The source text that this sub-string is based on.
+		/// </summary>
 		public readonly string Source;
+		/// <summary>
+		/// The offset within the source string where the sub-string begins.
+		/// </summary>
 		public readonly int Offset;
+		/// <summary>
+		/// The number of characters from the offset that make up the sub-string.
+		/// </summary>
 		public readonly int Length;
 
+		private string _subStringCache;
+
+		/// <summary>
+		/// Creates a sub-string which is the same as the source string.
+		/// </summary>
+		/// <param name="source"></param>
 		public TextSubString(string source)
 			: this(source, 0, source.Length) { }
 
+		/// <summary>
+		/// Creates a sub-string from the 
+		/// </summary>
+		/// <param name="source">The source text.</param>
+		/// <param name="offset">The offset where the sub-string starts.</param>
+		/// <param name="length">The length of the sub-string.</param>
 		public TextSubString(string source, int offset, int length)
 		{
 			Source = source;
 			Offset = offset;
 			Length = length;
+			_subStringCache = null;
 		}
 
+		/// <summary>
+		/// The sub-text derrived from the source text.
+		/// </summary>
 		public string SubText {
-			get { return Source.Substring(Offset, Length); }
+			get { return _subStringCache ?? (_subStringCache = Source.Substring(Offset, Length)); }
 		}
 
+		/// <summary>
+		/// The location one past the last character in the sub-string within the source string.
+		/// </summary>
 		public int EndOffset {
 			get { return Offset + Length; }
 		}

File src/YouCantSpell.Core/Utility/StringUtil.cs

 using System;
 using System.Collections.Generic;
-using System.IO;
-using System.Reflection;
 using System.Text.RegularExpressions;
 
 namespace YouCantSpell.Utility

File src/YouCantSpell.ReSharper.Core/ResourceAccessor.cs

+using System.Globalization;
+using System.Resources;
+
+namespace YouCantSpell.ReSharper
+{
+	public static class ResourceAccessor
+	{
+		private static readonly ResourceManager TextResourceManager = new ResourceManager("YouCantSpell.ReSharper.Text", typeof(ResourceAccessor).Assembly);
+
+		public static string GetString(string name) {
+			return TextResourceManager.GetString(name);
+		}
+
+		public static string GetString(string name, CultureInfo culture) {
+			return TextResourceManager.GetString(name, culture);
+		}
+
+	}
+}

File src/YouCantSpell.ReSharper.Core/Text.Designer.cs

+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.269
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace YouCantSpell.ReSharper {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Text {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Text() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("YouCantSpell.ReSharper.Text", typeof(Text).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Add &quot;{0}&quot; to dictionary.
+        /// </summary>
+        internal static string RS_AddToDictionaryText {
+            get {
+                return ResourceManager.GetString("RS_AddToDictionaryText", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Ignore spelling for &quot;{0}&quot;.
+        /// </summary>
+        internal static string RS_AddToIgnoreList {
+            get {
+                return ResourceManager.GetString("RS_AddToIgnoreList", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Replace with: {0}.
+        /// </summary>
+        internal static string RS_ReplaceWith {
+            get {
+                return ResourceManager.GetString("RS_ReplaceWith", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Spelling error: {0}.
+        /// </summary>
+        internal static string RS_SpellingErrorTip {
+            get {
+                return ResourceManager.GetString("RS_SpellingErrorTip", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Spelling Fixes.
+        /// </summary>
+        internal static string RS_SpellingFixesCategoryName {
+            get {
+                return ResourceManager.GetString("RS_SpellingFixesCategoryName", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Ignored Words.
+        /// </summary>
+        internal static string UI_IgnoredWordListTitle {
+            get {
+                return ResourceManager.GetString("UI_IgnoredWordListTitle", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to User Dictionary.
+        /// </summary>
+        internal static string UI_UserDictionaryListTitle {
+            get {
+                return ResourceManager.GetString("UI_UserDictionaryListTitle", resourceCulture);
+            }
+        }
+    }
+}

File src/YouCantSpell.ReSharper.Core/Text.resx

+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="RS_AddToDictionaryText" xml:space="preserve">
+    <value>Add "{0}" to dictionary</value>
+    <comment>The quick fix text for a spelling fix.</comment>
+  </data>
+  <data name="RS_AddToIgnoreList" xml:space="preserve">
+    <value>Ignore spelling for "{0}"</value>
+    <comment>The ignore bulb item text.</comment>
+  </data>
+  <data name="RS_ReplaceWith" xml:space="preserve">
+    <value>Replace with: {0}</value>
+    <comment>Used in the spelling replace bulb item.</comment>
+  </data>
+  <data name="RS_SpellingErrorTip" xml:space="preserve">
+    <value>Spelling error: {0}</value>
+    <comment>The highlight tool-tip text.</comment>
+  </data>
+  <data name="RS_SpellingFixesCategoryName" xml:space="preserve">
+    <value>Spelling Fixes</value>
+    <comment>A category name for spelling fixes.</comment>
+  </data>
+  <data name="UI_IgnoredWordListTitle" xml:space="preserve">
+    <value>Ignored Words</value>
+    <comment>Displayed above the list of user ignored words.</comment>
+  </data>
+  <data name="UI_UserDictionaryListTitle" xml:space="preserve">
+    <value>User Dictionary</value>
+    <comment>Displayed above the list of user dictionary words.</comment>
+  </data>
+</root>

File src/YouCantSpell.ReSharper.Core/YouCantSpell.ReSharper.Core.csproj

       <Link>Properties\YouCantSpellAssemblyInfo.cs</Link>
     </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ResourceAccessor.cs" />
     <Compile Include="StringListBox.cs">
       <SubType>UserControl</SubType>
     </Compile>
     <Compile Include="StringListBox.designer.cs">
       <DependentUpon>StringListBox.cs</DependentUpon>
     </Compile>
+    <Compile Include="Text.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Text.resx</DependentUpon>
+    </Compile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\YouCantSpell.Core\YouCantSpell.Core.csproj">
     <EmbeddedResource Include="StringListBox.resx">
       <DependentUpon>StringListBox.cs</DependentUpon>
     </EmbeddedResource>
+    <EmbeddedResource Include="Text.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Text.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\dic\en_US.aff">

File src/YouCantSpell.ReSharper.Shared/CSharp/CSharpFreeTextSpellingHighlightFinder.cs

 		) {
 			var parser = new CStyleFreeTextParser();
 			var xmlTextParts = parser.ParseXmlTextParts(new TextSubString(text));
-			var wordParts = xmlTextParts.SelectMany(x => parser.ParseSentenceWordsForSpellCheck(x));
+			var wordParts = xmlTextParts.SelectMany(parser.ParseSentenceWordsForSpellCheck);
 			foreach(var wordPart in wordParts)
 			{
 				var word = wordPart.SubText;

File src/YouCantSpell.ReSharper.Shared/CSharp/CSharpSpellCheckDaemonStageProcess.cs

 	public class CSharpSpellCheckDaemonStageProcess : CSharpDaemonStageProcessBase
 	{
 
+		private const int MinWordSize = 2;
+		private static readonly int MaxSuggestions = 10;
+
 		/// <summary>
 		/// Determines if a node is and acceptable identifier for spell checking.
 		/// </summary>
 		private readonly ShellSpellCheckResources _spellCheckResources;
 		private readonly NamingManager _namingManager;
 		private readonly INamingPolicyProvider _namingPolicyProvider;
-		private readonly int _minWordSize = 2;
-		private readonly int _maxSuggestions = 10;
 		private readonly IPsiSourceFile _sourceFile;
+		private readonly ICSharpFile _cSharpFile;
 
-		public CSharpSpellCheckDaemonStageProcess(IDaemonProcess process, IContextBoundSettingsStore settingsStore) :
+		public CSharpSpellCheckDaemonStageProcess(IDaemonProcess process, IContextBoundSettingsStore settingsStore, ICSharpFile cSharpFile) :
 #if RSHARP6
 			base(process)
 #else
-			base(process, process.SourceFile.GetPsiFiles<CSharpLanguage>().OfType<ICSharpFile>().First())
+			base(process, cSharpFile)
 #endif
 		{
+			if (null == cSharpFile)
+				throw new ArgumentNullException("cSharpFile");
+			if (null == CSharpLanguage.Instance)
+				throw new InvalidOperationException("C# language instance not loaded.");
+
+			_cSharpFile = cSharpFile;
+
 			_spellCheckResources = Shell.Instance.GetComponent<ShellSpellCheckResources>();
 			_sourceFile = process.SourceFile;
 			var psiServices = _sourceFile.PsiModule.GetPsiServices();
 			get { return SpellCheckResources.Primary; }
 		}
 
-		private ICSharpFile GetPsiFile() {
-#if RSHARP6
-			return DaemonProcess.SourceFile.GetPsiFile(CSharpLanguage.Instance) as ICSharpFile;
-#else
-			return DaemonProcess.SourceFile.GetPsiFiles<CSharpLanguage>().OfType<ICSharpFile>().Single();
-#endif
-		}
-
 		private Name ParseName(string name) {
 			return _namingManager.Parsing.Parse(name, NamingRule.Default, _namingPolicyProvider);
 		}
 					.Matches(namePart.SubText)
 					.Cast<Match>()
 					.SingleOrDefault(x => x.Success);
-				if(null == wordPart || wordPart.Length <= _minWordSize)
+				if(null == wordPart || wordPart.Length <= MinWordSize)
 					continue;
 
 				var wordPartText = wordPart.Value;
 					.GetRecommendations(wordPartText)
 					.Select(x => formatter.FormatSuggestion(x, i))
 					.Distinct()
-					.Take(_maxSuggestions)
+					.Take(MaxSuggestions)
 					.ToArray();
 
 				if (suggestions.Contains(wordPartText))
 		}
 
 		public override void Execute(Action<DaemonStageResult> commiter) {
-			/*if(!DaemonProcess.FullRehighlightingRequired)
-				return;*/
-
-			var file = GetPsiFile();
-			if(file == null)
-				return;
-
 			var localIdentifierNames = new HashSet<string>(StringComparer.CurrentCultureIgnoreCase);
 			var highlightings = new List<HighlightingInfo>();
 
-			file.ProcessChildren<IIdentifier>(
+			_cSharpFile.ProcessChildren<IIdentifier>(
 				node => {
 					localIdentifierNames.Add(node.Name);
 					localIdentifierNames.Add(RemovePrefixAndSuffix(node));
 				}
 			);
 
-			var declarationsCache = file.GetPsiServices().CacheManager.GetDeclarationsCache(file.GetPsiModule(), true, true);
+			var declarationsCache = _cSharpFile.GetPsiServices().CacheManager.GetDeclarationsCache(_cSharpFile.GetPsiModule(), true, true);
 
-			file.ProcessChildren<ITreeNode>(
+			_cSharpFile.ProcessChildren<ITreeNode>(
 				node => {
 					if(node is ICSharpLiteralExpression && (node as ICSharpLiteralExpression).ConstantValue.IsString()) {
 						highlightings.AddRange(FindStringHighlightings(node as IExpression, localIdentifierNames, declarationsCache));

File src/YouCantSpell.ReSharper.Shared/Html/HtmlFreeTextSpellingHighlightFinder.cs

 {
 	public class HtmlFreeTextSpellingHighlightFinder
 	{
+		private const int MinWordSize = 2;
 
 		private readonly ShellSpellCheckResources _shellSpellCheckResources;
 		private readonly IDocument _document;
-		private readonly int _minWordSize = 2;
-
+		
 		public HtmlFreeTextSpellingHighlightFinder(
 			ShellSpellCheckResources shellSpellCheckResources,
 			IDocument document
 
 		private bool WordIsIgnored(string word) {
 			return String.IsNullOrEmpty(word)
-				|| word.Length < _minWordSize
+				|| word.Length < MinWordSize
 				|| _shellSpellCheckResources.IsIgnoredInsensitive(word)
 				|| CStyleFreeTextParser.LooksLikeCodeWord(word);
 		}

File src/YouCantSpell.ReSharper.Shared/Html/HtmlSpellCheckDaemonStageProcess.cs

 				.SingleOrDefault(x => x.Document == _sourceFile.Document);
 		}
 
-		private IEnumerable<HighlightingInfo> FindWordHighlightings(TreeElement node)
+		private IEnumerable<HighlightingInfo> FindWordHighlightings(ITreeNode node)
 		{
 			var validRange = FindTrueDocumentRange(node.GetTreeTextRange());
 			if (!validRange.HasValue) return Enumerable.Empty<HighlightingInfo>();
 
-			return _freeTextSpellingHighlightFinder.FindWordHighlightings(node, node.GetText(), validRange.Value);
+			return _freeTextSpellingHighlightFinder
+				.FindWordHighlightings(node, node.GetText(), validRange.Value);
 		}
 
 		private IEnumerable<HighlightingInfo> FindHighlightings(HtmlTag node) {
 				var validRange = FindTrueDocumentRange(valueElement.GetUnquotedTreeTextRange());
 				if (!validRange.HasValue) continue;
 
-				results.AddRange(_freeTextSpellingHighlightFinder.FindWordHighlightings(
-					valueElement,
-					valueElement.UnquotedValue,
-					validRange.Value
-				));
+				results.AddRange(_freeTextSpellingHighlightFinder
+					.FindWordHighlightings(valueElement,valueElement.UnquotedValue,validRange.Value));
 			}
 			return results;
 		}

File src/YouCantSpell.ReSharper.Shared/Html/HtmlUtil.cs

-using System;
-
-namespace YouCantSpell.ReSharper.Html
-{
-	[Obsolete]
-	class HtmlUtil
-	{
-	}
-}

File src/YouCantSpell.ReSharper.Shared/JavaScript/JavaScriptSpellCheckDaemonStageProcess.cs

 using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
 using System.Text.RegularExpressions;
 using JetBrains.Application;
 using JetBrains.Application.Settings;
 using JetBrains.ReSharper.Daemon.JavaScript.Impl;
 using JetBrains.ReSharper.Psi;
 using JetBrains.ReSharper.Psi.Caches;
-using JetBrains.ReSharper.Psi.ExtensionsAPI.Tree;
 using JetBrains.ReSharper.Psi.JavaScript.Impl.Tree;
 using JetBrains.ReSharper.Psi.JavaScript.LanguageImpl;
 using JetBrains.ReSharper.Psi.JavaScript.Parsing;
 using JetBrains.ReSharper.Psi.JavaScript.Tree;
 using JetBrains.ReSharper.Psi.Naming;
+using JetBrains.ReSharper.Psi.Naming.Impl;
 using JetBrains.ReSharper.Psi.Naming.Interfaces;
-
-using JetBrains.ReSharper.Psi.Naming.Impl;
 using JetBrains.ReSharper.Psi.Naming.Settings;
 using JetBrains.ReSharper.Psi.Tree;
 using JetBrains.Util;
 
 namespace YouCantSpell.ReSharper.JavaScript
 {
-	public class JavaScriptSpellCheckDaemonStageProcess : JavaScriptDaemonStageProcessBase, IDaemonStageProcess
+	public class JavaScriptSpellCheckDaemonStageProcess : JavaScriptDaemonStageProcessBase
 	{
 
+		private const int MinWordSize = 2;
+
 		/// <summary>
 		/// Finds text that is only letters.
 		/// </summary>
 		private readonly ShellSpellCheckResources _spellCheckResources;
 		private readonly NamingManager _namingManager;
 		private readonly INamingPolicyProvider _namingPolicyProvider;
-		private readonly int _minWordSize = 2;
 		private readonly IPsiSourceFile _sourceFile;
+		private readonly IJavaScriptFile _javaScriptFile;
 
-		public JavaScriptSpellCheckDaemonStageProcess(IDaemonProcess process, IContextBoundSettingsStore settingsStore)
+		public JavaScriptSpellCheckDaemonStageProcess(IDaemonProcess process, IContextBoundSettingsStore settingsStore, IJavaScriptFile javaScriptFile)
 #if RSHARP6
 			: base(process, settingsStore)
 #else
-			: base(process, settingsStore, process.SourceFile.GetPsiFiles<JavaScriptLanguage>().OfType<IJavaScriptFile>().First())
+			: base(process, settingsStore, javaScriptFile)
 #endif
-		{
+ {
+			if(null == JavaScriptLanguage.Instance)
+				throw new InvalidOperationException("JavaScript languange instance not supported.");
+			if (null == javaScriptFile)
+				throw new ArgumentNullException("javaScriptFile");
+
+			_javaScriptFile = javaScriptFile;
 			_spellCheckResources = Shell.Instance.GetComponent<ShellSpellCheckResources>();
 			_sourceFile = process.SourceFile;
 			var psiServices = _sourceFile.PsiModule.GetPsiServices();
 			if(parsedName.InnerElements == null || parsedName.InnerElements.Count == 0)
 				yield break;
 
-			int identifierNamePartIndex = null != parsedName.NamePrefix
-				? parsedName.NamePrefix.Text.Length
-				: 0;
+			int identifierNamePartIndex = null != parsedName.NamePrefix ? parsedName.NamePrefix.Text.Length : 0;
 
 			foreach(var identifierNamePart in parsedName.InnerElements) {
 				if(!identifierNamePart.IsSeparator) {
 				if(
 					null == wordPart
 					|| String.IsNullOrEmpty(wordPart.Value)
-					|| wordPart.Length <= _minWordSize
+					|| wordPart.Length <= MinWordSize
 					|| localIgnoredWords.Contains(wordPart.Value)
 					|| JavaScriptUtil.IsKeyword(wordPart.Value)
 					|| SpellCheckResources.IsIgnoredInsensitive(wordPart.Value)
 			if(!coreMatch.Success)
 				return Enumerable.Empty<HighlightingInfo>();
 
-			//var textRange = node.GetDocumentRange();
 			var validRange = FindTrueDocumentRange(node.GetTreeTextRange());
 			if (!validRange.HasValue)
 				return Enumerable.Empty<HighlightingInfo>();
 		}
 
 		public override void Execute(Action<DaemonStageResult> commiter) {
-			var file = GetPsiFile();
-			if(file == null)
-				return;
-
 			var localIdentifierNames = new HashSet<string>(StringComparer.CurrentCultureIgnoreCase);
 			var highlightings = new List<HighlightingInfo>();
 
-			file.ProcessChildren<IIdentifier>(
+			_javaScriptFile.ProcessChildren<IIdentifier>(
 				node => {
 					localIdentifierNames.Add(node.Name);
 					if(IsValidSpellCheckIdentifierNode(node)) {
 				}
 			);
 
-			var declarationsCache = file.GetPsiServices().CacheManager.GetDeclarationsCache(file.GetPsiModule(), true, true);
+			var declarationsCache = _javaScriptFile.GetPsiServices().CacheManager.GetDeclarationsCache(_javaScriptFile.GetPsiModule(), true, true);
 
-			file.ProcessChildren<ITreeNode>(
+			_javaScriptFile.ProcessChildren<ITreeNode>(
 				node => {
 #if RSHARP6
 					if (node is JavaScriptGenericToken && (node as JavaScriptGenericToken).NodeType == JavaScriptTokenType.STRING_LITERAL) {

File src/YouCantSpell.ReSharper.Shared/JavaScript/JavaScriptSpellingFixBulbItem.cs

 		}
 
 		private static ITreeNode CreateNode(ITreeNode basedOn, string text) {
-			var languageService = PsiLanguageTypeExtensions.LanguageService(basedOn.Language);
+			var languageService = basedOn.Language.LanguageService();
+			if(null == languageService)
+				return null;
 			var parser = languageService.CreateParser(
 				languageService.GetPrimaryLexerFactory().CreateLexer(new StringBuffer(text)),
 				basedOn.GetPsiModule(),
 				basedOn.GetSourceFile()
 			) as IJavaScriptParser;
-			return parser.ParseFile().LastChild;
+			if (null != parser) {
+				var newNodes = parser.ParseFile();
+				if(null != newNodes)
+					return newNodes.LastChild;
+			}
+			return null;
 		}
 
 	}

File src/YouCantSpell.ReSharper.Shared/JavaScript/JavaScriptSpellingQuickFix.cs

-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
 using JetBrains.ReSharper.Feature.Services.Bulbs;
 
 namespace YouCantSpell.ReSharper.JavaScript

File src/YouCantSpell.ReSharper.Shared/JavaScript/JavaScriptSpellingSuggestionFormatter.cs

 using System;
-using System.Collections.Generic;
 using System.Linq;
-using System.Text;
 using System.Text.RegularExpressions;
 using JetBrains.ReSharper.Psi;
 using JetBrains.ReSharper.Psi.Naming;

File src/YouCantSpell.ReSharper.Shared/PrimaryOptionsControl.Designer.cs

 		/// </summary>
 		private void InitializeComponent() {
 			this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
-			this.groupBox1 = new System.Windows.Forms.GroupBox();
-			this.groupBox2 = new System.Windows.Forms.GroupBox();
+			this.groupBoxUserDictionary = new System.Windows.Forms.GroupBox();
 			this.stringListBoxUserDictionary = new YouCantSpell.ReSharper.StringListBox();
+			this.groupBoxIgnoredWords = new System.Windows.Forms.GroupBox();
 			this.stringListBoxIgnoredWords = new YouCantSpell.ReSharper.StringListBox();
 			this.tableLayoutPanel1.SuspendLayout();
-			this.groupBox1.SuspendLayout();
-			this.groupBox2.SuspendLayout();
+			this.groupBoxUserDictionary.SuspendLayout();
+			this.groupBoxIgnoredWords.SuspendLayout();
 			this.SuspendLayout();
 			// 
 			// tableLayoutPanel1
 			this.tableLayoutPanel1.ColumnCount = 2;
 			this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
 			this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
-			this.tableLayoutPanel1.Controls.Add(this.groupBox1, 0, 0);
-			this.tableLayoutPanel1.Controls.Add(this.groupBox2, 1, 0);
+			this.tableLayoutPanel1.Controls.Add(this.groupBoxUserDictionary, 0, 0);
+			this.tableLayoutPanel1.Controls.Add(this.groupBoxIgnoredWords, 1, 0);
 			this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
 			this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
 			this.tableLayoutPanel1.Name = "tableLayoutPanel1";
 			this.tableLayoutPanel1.Size = new System.Drawing.Size(582, 366);
 			this.tableLayoutPanel1.TabIndex = 0;
 			// 
-			// groupBox1
+			// groupBoxUserDictionary
 			// 
-			this.groupBox1.Controls.Add(this.stringListBoxUserDictionary);
-			this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill;
-			this.groupBox1.Location = new System.Drawing.Point(3, 3);
-			this.groupBox1.Name = "groupBox1";
-			this.groupBox1.Size = new System.Drawing.Size(285, 330);
-			this.groupBox1.TabIndex = 0;
-			this.groupBox1.TabStop = false;
-			this.groupBox1.Text = "User Dictionary";
-			// 
-			// groupBox2
-			// 
-			this.groupBox2.Controls.Add(this.stringListBoxIgnoredWords);
-			this.groupBox2.Dock = System.Windows.Forms.DockStyle.Fill;
-			this.groupBox2.Location = new System.Drawing.Point(294, 3);
-			this.groupBox2.Name = "groupBox2";
-			this.groupBox2.Size = new System.Drawing.Size(285, 330);
-			this.groupBox2.TabIndex = 1;
-			this.groupBox2.TabStop = false;
-			this.groupBox2.Text = "Ignored Words";
+			this.groupBoxUserDictionary.Controls.Add(this.stringListBoxUserDictionary);
+			this.groupBoxUserDictionary.Dock = System.Windows.Forms.DockStyle.Fill;
+			this.groupBoxUserDictionary.Location = new System.Drawing.Point(3, 3);
+			this.groupBoxUserDictionary.Name = "groupBoxUserDictionary";
+			this.groupBoxUserDictionary.Size = new System.Drawing.Size(285, 330);
+			this.groupBoxUserDictionary.TabIndex = 0;
+			this.groupBoxUserDictionary.TabStop = false;
+			this.groupBoxUserDictionary.Text = "User Dictionary";
 			// 
 			// stringListBoxUserDictionary
 			// 
+			this.stringListBoxUserDictionary.CurrentItems = new string[0];
 			this.stringListBoxUserDictionary.Dock = System.Windows.Forms.DockStyle.Fill;
 			this.stringListBoxUserDictionary.Location = new System.Drawing.Point(3, 16);
 			this.stringListBoxUserDictionary.Name = "stringListBoxUserDictionary";
 			this.stringListBoxUserDictionary.Size = new System.Drawing.Size(279, 311);
 			this.stringListBoxUserDictionary.TabIndex = 0;
 			// 
+			// groupBoxIgnoredWords
+			// 
+			this.groupBoxIgnoredWords.Controls.Add(this.stringListBoxIgnoredWords);
+			this.groupBoxIgnoredWords.Dock = System.Windows.Forms.DockStyle.Fill;
+			this.groupBoxIgnoredWords.Location = new System.Drawing.Point(294, 3);
+			this.groupBoxIgnoredWords.Name = "groupBoxIgnoredWords";
+			this.groupBoxIgnoredWords.Size = new System.Drawing.Size(285, 330);
+			this.groupBoxIgnoredWords.TabIndex = 1;
+			this.groupBoxIgnoredWords.TabStop = false;
+			this.groupBoxIgnoredWords.Text = "Ignored Words";
+			// 
 			// stringListBoxIgnoredWords
 			// 
+			this.stringListBoxIgnoredWords.CurrentItems = new string[0];
 			this.stringListBoxIgnoredWords.Dock = System.Windows.Forms.DockStyle.Fill;
 			this.stringListBoxIgnoredWords.Location = new System.Drawing.Point(3, 16);
 			this.stringListBoxIgnoredWords.Name = "stringListBoxIgnoredWords";
 			this.stringListBoxIgnoredWords.Size = new System.Drawing.Size(279, 311);
 			this.stringListBoxIgnoredWords.TabIndex = 0;
 			// 
-			// PrimaryOptionsPage
+			// PrimaryOptionsControl
 			// 
 			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
 			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
 			this.Controls.Add(this.tableLayoutPanel1);
-			this.Name = "PrimaryOptionsPage";
+			this.Name = "PrimaryOptionsControl";
 			this.Size = new System.Drawing.Size(582, 366);
 			this.tableLayoutPanel1.ResumeLayout(false);
-			this.groupBox1.ResumeLayout(false);
-			this.groupBox2.ResumeLayout(false);
+			this.groupBoxUserDictionary.ResumeLayout(false);
+			this.groupBoxIgnoredWords.ResumeLayout(false);
 			this.ResumeLayout(false);
 
 		}
 		#endregion
 
 		private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
-		private System.Windows.Forms.GroupBox groupBox1;
-		private System.Windows.Forms.GroupBox groupBox2;
+		private System.Windows.Forms.GroupBox groupBoxUserDictionary;
+		private System.Windows.Forms.GroupBox groupBoxIgnoredWords;
 		private StringListBox stringListBoxUserDictionary;
 		private StringListBox stringListBoxIgnoredWords;
 

File src/YouCantSpell.ReSharper.Shared/PrimaryOptionsControl.cs

 using System;
 using System.Linq;
 using System.Linq.Expressions;
+using System.Resources;
 using System.Windows.Forms;
 using JetBrains.Annotations;
 using JetBrains.Application;
 		public PrimaryOptionsControl([NotNull] Lifetime lifetime, OptionsSettingsSmartContext settings) {
 			InitializeComponent();
 
+			groupBoxUserDictionary.Text = ResourceAccessor.GetString("UI_UserDictionaryListTitle")
+				?? "User Dictionary";
+			groupBoxIgnoredWords.Text = ResourceAccessor.GetString("UI_IgnoredWordListTitle")
+				?? "Ignored Words";
 
 			// Extact the string keys from the settings and apply them to the UI list boxes.
 			UserWords.Initialize(

File src/YouCantSpell.ReSharper.Shared/ReSharperUtil.cs

 		/// This method walks up the parent nodes to find a declared element.
 		/// </remarks>
 		public static IDeclaredElement GetDeclaredElement(ITreeNode node) {
-			/*if (null == node)
-				return null;
-			if (node is IDeclaration)
-				return (node as IDeclaration).DeclaredElement;
-			if (node.Parent != null) {
-				if (node.Parent is IDeclaration) {
-					return (node.Parent as IDeclaration).DeclaredElement;
-				}
-				if (node.Parent.Parent != null) {
-					if (node.Parent.Parent is IDeclaration)
-						return (node.Parent.Parent as IDeclaration).DeclaredElement;
-				}
-			}*/
 			while(null != node) {
 				if (node is IDeclaration)
 					return (node as IDeclaration).DeclaredElement;

File src/YouCantSpell.ReSharper.Shared/RenameRefactoringExecutor.cs

 	[SolutionComponent]
 	public class RenameRefactoringExecutor
 	{
+		private const string RootRuleName = "ManualChangeNameFix";
+
 		private readonly ActionManager _actionManager;
 		private readonly ISolution _solution;
 		private readonly RenameRefactoringService _renameRefactoringService;
 				_actionManager.DataContexts.CreateWithDataRules(
 					lifetime,
 					DataRules
-						// I think these rules are some kind of free fform parameters for the refactor tool to use
-						.AddRule("ManualChangeNameFix", JetBrains.ReSharper.Psi.Services.DataConstants.DECLARED_ELEMENTS, new[] { declaredElement })
-						.AddRule("ManualChangeNameFix", JetBrains.TextControl.DataContext.DataConstants.TEXT_CONTROL, textControl)
-						.AddRule("ManualChangeNameFix", JetBrains.ProjectModel.DataContext.DataConstants.SOLUTION, _solution)
-						.AddRule("ManualChangeNameFix", RenameWorkflow.RenameDataProvider, new SimpleRenameDataProvider(newText))
+						// I think these rules are some kind of free form parameters for the refactor tool to use but ... ?
+						.AddRule(RootRuleName, JetBrains.ReSharper.Psi.Services.DataConstants.DECLARED_ELEMENTS, new[] { declaredElement })
+						.AddRule(RootRuleName, JetBrains.TextControl.DataContext.DataConstants.TEXT_CONTROL, textControl)
+						.AddRule(RootRuleName, JetBrains.ProjectModel.DataContext.DataConstants.SOLUTION, _solution)
+						.AddRule(RootRuleName, RenameWorkflow.RenameDataProvider, new SimpleRenameDataProvider(newText))
 				)
 			));
 		}

File src/YouCantSpell.ReSharper.Shared/ShellSpellCheckResources.cs

 
 		private HashSet<string> _ignored;
 		private HashSet<string> _ignoredInsensitive; 
-		private object _ignoredSync = new object();
+		private readonly object _ignoredSync = new object();
 
 		public ShellSpellCheckResources(ISettingsStore settingsStore)
 		{

File src/YouCantSpell.ReSharper.Shared/SpellCheckDaemonStage.cs

 using System.Collections.Generic;
+// ReSharper disable RedundantUsingDirective
 using System.Linq;
+// ReSharper restore RedundantUsingDirective
 using JetBrains.Application.Settings;
 using JetBrains.ReSharper.Daemon;
 using JetBrains.ReSharper.Psi;
 using JetBrains.ReSharper.Psi.CSharp;
+using JetBrains.ReSharper.Psi.CSharp.Tree;
 using JetBrains.ReSharper.Psi.Html;
 using JetBrains.ReSharper.Psi.Html.Tree;
+using JetBrains.ReSharper.Psi.JavaScript.LanguageImpl;
+using JetBrains.ReSharper.Psi.JavaScript.Tree;
+using JetBrains.ReSharper.Psi.Xml;
 using JetBrains.ReSharper.Psi.Xml.Tree;
 using YouCantSpell.ReSharper.CSharp;
-using JetBrains.ReSharper.Psi.JavaScript.LanguageImpl;
 using YouCantSpell.ReSharper.Html;
 using YouCantSpell.ReSharper.JavaScript;
-using JetBrains.ReSharper.Psi.Xml;
 using YouCantSpell.ReSharper.Xml;
 
 namespace YouCantSpell.ReSharper
 #endif
 
 
-		private bool HasAnyCSharp(IDaemonProcess process) {
+		private ICSharpFile GetCSharpFile(IPsiSourceFile sourceFile) {
 #if RSHARP6
-			return process.SourceFile.GetPsiFile(CSharpLanguage.Instance) != null;
+			return sourceFile.GetPsiFile(CSharpLanguage.Instance) as ICSharpFile;
 #else
-			return process.SourceFile.GetPsiFiles<CSharpLanguage>().Any();
+			return sourceFile.GetPsiFiles<CSharpLanguage>().OfType<ICSharpFile>().SingleOrDefault();
 #endif
 		}
 
-		private bool HasAnyJavaScript(IDaemonProcess process) {
+		private IJavaScriptFile GetJavaScriptFile(IPsiSourceFile sourceFile) {
 #if RSHARP6
-			return process.SourceFile.GetPsiFile(JavaScriptLanguage.Instance) != null;
+			return sourceFile.GetPsiFile(JavaScriptLanguage.Instance) as IJavaScriptFile;
 #else
-			return process.SourceFile.GetPsiFiles<JavaScriptLanguage>().Any();
+			return sourceFile.GetPsiFiles<JavaScriptLanguage>().OfType<IJavaScriptFile>().SingleOrDefault();
 #endif
 		}
 
 		private List<IDaemonStageProcess> CreateProcessesCore(IDaemonProcess process, IContextBoundSettingsStore settings, DaemonProcessKind processKind) {
 			var sourceFile = process.SourceFile;
 			var stageProcesses = new List<IDaemonStageProcess>();
-			if (HasAnyCSharp(process))
-				stageProcesses.Add(new CSharpSpellCheckDaemonStageProcess(process, settings));
-			if (HasAnyJavaScript(process))
-				stageProcesses.Add(new JavaScriptSpellCheckDaemonStageProcess(process, settings));
+
+			var csFile = GetCSharpFile(sourceFile);
+			if(null != csFile)
+				stageProcesses.Add(new CSharpSpellCheckDaemonStageProcess(process, settings, csFile));
+
+			var jsFile = GetJavaScriptFile(sourceFile);
+			if(null != jsFile)
+				stageProcesses.Add(new JavaScriptSpellCheckDaemonStageProcess(process, settings, jsFile));
 
 			var xmlFile = GetXmlFile(sourceFile);
 			if(null != xmlFile)

File src/YouCantSpell.ReSharper.Shared/SpellingAddToDictionaryBulbItem.cs

 using JetBrains.Application;
 using JetBrains.Application.Settings;
 using JetBrains.ProjectModel;
-using JetBrains.ReSharper.Feature.Services.Bulbs;
 using JetBrains.ReSharper.Daemon;
 using JetBrains.TextControl;
 
 		JetBrains.ReSharper.Intentions.Extensibility.IBulbAction
 #endif
 	{
+
 		private readonly SpellingErrorHighlightingBase _highlight;
 		private readonly string _word;
 
 		/// <summary>
 		/// Creates a new add to dictionary bulb item.
 		/// </summary>
-		/// <param name="word">The word that could be added to the dictionary.</param>
+		/// <param name="highlight">The highlight that the bulb item is bound to.</param>
 		public SpellingAddToDictionaryBulbItem(SpellingErrorHighlightingBase highlight) {
 			if(null == highlight) throw new ArgumentNullException();
 			_highlight = highlight;
 
 		/// <inheritdoc/>
 		public string Text {
-			get { return String.Format("Add \"{0}\" to dictionary", _word); }
+			get {
+				return String.Format(
+					ResourceAccessor.GetString("RS_AddToDictionaryText")
+						?? @"Add ""{0}"" to dictionary",
+					_word
+				);
+			}
 		}
 	}
 }

File src/YouCantSpell.ReSharper.Shared/SpellingErrorHighlightingBase.cs

 		/// The tool-tip text that appears when the mouse hovers over the highlight.
 		/// </summary>
 		public string ToolTip {
-			get { return "Spelling error: \"" + _wordInError + '\"'; }
+			get {
+				return String.Format(
+					ResourceAccessor.GetString("RS_SpellingErrorTip")
+						?? @"Spelling error: {0}",
+					_wordInError
+				);
+			}
 		}
 
 		/// <inheritdoc/>

File src/YouCantSpell.ReSharper.Shared/SpellingFixBulbItemBase.cs

 		public override string Text {
 			get {
 				if(String.IsNullOrEmpty(_suggestion))
-					return "ERROR: No spelling suggestion.";
-				return String.Format("Replace with \"{0}\"", _suggestion);
+					return "ERROR";
+				return String.Format(
+					ResourceAccessor.GetString("RS_ReplaceWith")
+						?? "Replace with: {0}",
+					_suggestion
+				);
 			}
 		}
 

File src/YouCantSpell.ReSharper.Shared/SpellingIgnoreWordBulbItem.cs

 		/// <summary>
 		/// Creats a new ignore bulb item that adds the word to the ignore list when executed.
 		/// </summary>
-		/// <param name="word">The word that may be ignored.</param>
+		/// <param name="highlight">The highlight that the bulb item is bound to.</param>
 		public SpellingIgnoreWordBulbItem(SpellingErrorHighlightingBase highlight)
 		{
-			if (null == highlight) throw new ArgumentNullException();
+			if (null == highlight) throw new ArgumentNullException("highlight");
 			_highlight = highlight;
 
 			var word = highlight.WordInError;
 			var boundSettings = settingsStore.BindToContextTransient(ContextRange.Smart((lifetime, contexts) => contexts.Empty));
 			boundSettings.SetIndexedValue<SpellCheckSettings, string, byte>(x => x.IgnoreEntries, _word, 0);
 			Shell.Instance.GetComponent<ShellSpellCheckResources>().NotifyNewIgnoreWord(_word); // we must also notify the active spell checker of the new ignored word
-			Daemon.GetInstance(solution).ForceReHighlight(textControl.Document); // without changing the document this is a way to request a re-processing of the document
+			Daemon.GetInstance(solution).ForceReHighlight(_highlight.Range.Document); // without changing the document this is a way to request a re-processing of the document
 		}
 
 		/// <inheritdoc/>
 		public string Text {
-			get { return String.Format("Ignore spelling for \"{0}\"", _word); }
+			get {
+				return String.Format(
+					ResourceAccessor.GetString("RS_AddToIgnoreList")
+						?? "Ignore spelling for \"{0}\"",
+					_word
+				);
+			}
 		}
 	}
 }

File src/YouCantSpell.ReSharper.Shared/SpellingQuickFixBase.cs

 			var subMenu = defaultGroup.GetOrCreateSubmenu(new BulbMenuItemViewDescription(
 				new Anchor("SpellingFixes", new AnchorRelation[0]),
 				UnnamedThemedIcons.SpellCheckOptionsIcon.Id,
-				"Spelling Fixes"
+				ResourceAccessor.GetString("RS_SpellingFixesCategoryName") ?? "Spelling Fixes"
 			));
 			subMenu.Submenu.ArrangeQuickFixes(Items.Select(x => new Pair<IBulbAction, Severity>(x,severity)));
 

File src/YouCantSpell.ReSharper.Shared/Xml/XmlFreeTextSpellingHighlightFinder.cs

 {
 	public class XmlFreeTextSpellingHighlightFinder
 	{
+		private const int MinWordSize = 2;
 
 		private readonly ShellSpellCheckResources _shellSpellCheckResources;
 		private readonly IDocument _document;
-		private readonly int _minWordSize = 2;
 
 		public XmlFreeTextSpellingHighlightFinder(
 			ShellSpellCheckResources shellSpellCheckResources,
 
 		private bool WordIsIgnored(string word) {
 			return String.IsNullOrEmpty(word)
-				|| word.Length < _minWordSize
+				|| word.Length < MinWordSize
 				|| _shellSpellCheckResources.IsIgnoredInsensitive(word)
 				|| CStyleFreeTextParser.LooksLikeCodeWord(word);
 		}

File src/YouCantSpell.ReSharper.Shared/Xml/XmlSpellCheckDaemonStageProcess.cs

 using JetBrains.ReSharper.Daemon;
 using JetBrains.ReSharper.Psi;
 using JetBrains.ReSharper.Psi.Tree;
-using JetBrains.ReSharper.Psi.Xml;
 using JetBrains.ReSharper.Psi.Xml.Impl.Tree;
 using JetBrains.ReSharper.Psi.Xml.Tree;
 
 				.SingleOrDefault(x => x.Document == _sourceFile.Document);
 		}
 
-		private IEnumerable<HighlightingInfo> FindWordHighlightings(IXmlFloatingTextTokenNode node) {
+		private IEnumerable<HighlightingInfo> FindWordHighlightings(ITreeNode node) {
 			var validRange = FindTrueDocumentRange(node.GetTreeTextRange());
 			if (!validRange.HasValue) return Enumerable.Empty<HighlightingInfo>();
 
 		public void Execute(Action<DaemonStageResult> commiter) {
 			var highlightings = new List<HighlightingInfo>(0);
 
-			var allNodes = new List<ITreeNode>();
-			_xmlFile.ProcessChildren<ITreeNode>(allNodes.Add);
-
 			_xmlFile.ProcessChildren<XmlFloatingTextToken>(node => {
 				if(!node.IsIdentifier() && !node.IsWhitespaceToken())
 					highlightings.AddRange(FindWordHighlightings(node));
 			});
 
-			_xmlFile.ProcessChildren<XmlValueToken>(node => {
-				highlightings.AddRange(FindWordHighlightings(node));
+			_xmlFile.ProcessChildren<XmlValueToken>(node => highlightings.AddRange(FindWordHighlightings(node)));
+
+			_xmlFile.ProcessChildren<XmlToken>(node => {
+				if (node.XmlTokenTypes.COMMENT_BODY.Equals(node.NodeType))
+					highlightings.AddRange(FindWordHighlightings(node));
 			});
 
 			commiter(new DaemonStageResult(highlightings));

File src/YouCantSpell.ReSharper.Shared/Xml/XmlSpellingFixBulbItem.cs

 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using JetBrains.Application.Progress;
+using JetBrains.ProjectModel;
 using JetBrains.ReSharper.Psi;
 using JetBrains.ReSharper.Psi.ExtensionsAPI.Tree;
 using JetBrains.ReSharper.Psi.Tree;
 using JetBrains.ReSharper.Psi.Xml.Impl.Tree;
-using JetBrains.ReSharper.Psi.Xml.Parsing;
 using JetBrains.Text;
+using JetBrains.TextControl;
 using YouCantSpell.Utility;
 
 namespace YouCantSpell.ReSharper.Xml
 		public XmlSpellingFixBulbItem(XmlSpellingErrorHighlighting highlighting, string suggestion)
 			: base(highlighting, suggestion) { }
 
-		protected override Action<JetBrains.TextControl.ITextControl> ExecutePsiTransaction(JetBrains.ProjectModel.ISolution solution, JetBrains.Application.Progress.IProgressIndicator progress) {
+		protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress) {
 			if (!Highlighting.IsValid())
 				return null;
 
 				ModificationUtil.ReplaceChild(node, newElm);
 				return null;
 			}
+			if (node is XmlToken) {
+				var newElm = new XmlToken(
+					(node as XmlToken).GetTokenType(),
+					new StringBuffer(newText),
+					new TreeOffset(0),
+					new TreeOffset(newText.Length)
+				);
+				ModificationUtil.ReplaceChild(node, newElm);
+				return null;
+			}
 			return null;
 		}
 

File src/YouCantSpell.ReSharper.Shared/Xml/XmlSpellingSuggestionFormatter.cs

-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace YouCantSpell.ReSharper.Xml
-{
-	class XmlSpellingSuggestionFormatter
-	{
-	}
-}

File src/YouCantSpell.ReSharper.Shared/Xml/XmlUtil.cs

-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace YouCantSpell.ReSharper.Xml
-{
-	public static class XmlUtil
-	{
-		public static void Util(){}
-	}
-}

File src/YouCantSpell.ReSharper.v61.Net35/YouCantSpell.ReSharper.v61.Net35.csproj

     <Compile Include="..\YouCantSpell.ReSharper.Shared\CSharp\CSharpUtil.cs">
       <Link>CSharp\CSharpUtil.cs</Link>
     </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlFreeTextSpellingHighlightFinder.cs">
+      <Link>Html\HtmlFreeTextSpellingHighlightFinder.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlSpellCheckDaemonStageProcess.cs">
+      <Link>Html\HtmlSpellCheckDaemonStageProcess.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlSpellingErrorHighlighting.cs">
+      <Link>Html\HtmlSpellingErrorHighlighting.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlSpellingFixBulbItem.cs">
+      <Link>Html\HtmlSpellingFixBulbItem.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlSpellingQuickFix.cs">
+      <Link>Html\HtmlSpellingQuickFix.cs</Link>
+    </Compile>
     <Compile Include="..\YouCantSpell.ReSharper.Shared\JavaScript\JavaScriptFreeTextSpellingHighlightFinder.cs">
       <Link>JavaScript\JavaScriptFreeTextSpellingHighlightFinder.cs</Link>
     </Compile>
     <Compile Include="..\YouCantSpell.ReSharper.Shared\SpellingQuickFixBase.cs">
       <Link>SpellingQuickFixBase.cs</Link>
     </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlFreeTextSpellingHighlightFinder.cs">
+      <Link>Xml\XmlFreeTextSpellingHighlightFinder.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlSpellCheckDaemonStageProcess.cs">
+      <Link>Xml\XmlSpellCheckDaemonStageProcess.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlSpellingErrorHighlighting.cs">
+      <Link>Xml\XmlSpellingErrorHighlighting.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlSpellingFixBulbItem.cs">
+      <Link>Xml\XmlSpellingFixBulbItem.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlSpellingQuickFix.cs">
+      <Link>Xml\XmlSpellingQuickFix.cs</Link>
+    </Compile>
     <Compile Include="..\YouCantSpellAssemblyInfo.cs">
       <Link>Properties\YouCantSpellAssemblyInfo.cs</Link>
     </Compile>

File src/YouCantSpell.ReSharper.v61/YouCantSpell.ReSharper.v61.csproj

     <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlSpellingQuickFix.cs">
       <Link>Html\HtmlSpellingQuickFix.cs</Link>
     </Compile>
-    <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlUtil.cs">
-      <Link>Html\HtmlUtil.cs</Link>
-    </Compile>
     <Compile Include="..\YouCantSpell.ReSharper.Shared\JavaScript\JavaScriptFreeTextSpellingHighlightFinder.cs">
       <Link>JavaScript\JavaScriptFreeTextSpellingHighlightFinder.cs</Link>
     </Compile>
     <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlSpellingQuickFix.cs">
       <Link>Xml\XmlSpellingQuickFix.cs</Link>
     </Compile>
-    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlSpellingSuggestionFormatter.cs">
-      <Link>Xml\XmlSpellingSuggestionFormatter.cs</Link>
-    </Compile>
-    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlUtil.cs">
-      <Link>Xml\XmlUtil.cs</Link>
-    </Compile>
     <Compile Include="..\YouCantSpellAssemblyInfo.cs">
       <Link>Properties\YouCantSpellAssemblyInfo.cs</Link>
     </Compile>

File src/YouCantSpell.ReSharper.v70.Net35/YouCantSpell.ReSharper.v70.Net35.csproj

     <Compile Include="..\YouCantSpell.ReSharper.Shared\CSharp\CSharpUtil.cs">
       <Link>CSharp\CSharpUtil.cs</Link>
     </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlFreeTextSpellingHighlightFinder.cs">
+      <Link>Html\HtmlFreeTextSpellingHighlightFinder.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlSpellCheckDaemonStageProcess.cs">
+      <Link>Html\HtmlSpellCheckDaemonStageProcess.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlSpellingErrorHighlighting.cs">
+      <Link>Html\HtmlSpellingErrorHighlighting.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlSpellingFixBulbItem.cs">
+      <Link>Html\HtmlSpellingFixBulbItem.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlSpellingQuickFix.cs">
+      <Link>Html\HtmlSpellingQuickFix.cs</Link>
+    </Compile>
     <Compile Include="..\YouCantSpell.ReSharper.Shared\JavaScript\JavaScriptFreeTextSpellingHighlightFinder.cs">
       <Link>JavaScript\JavaScriptFreeTextSpellingHighlightFinder.cs</Link>
     </Compile>
     <Compile Include="..\YouCantSpell.ReSharper.Shared\SpellingQuickFixBase.cs">
       <Link>SpellingQuickFixBase.cs</Link>
     </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlFreeTextSpellingHighlightFinder.cs">
+      <Link>Xml\XmlFreeTextSpellingHighlightFinder.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlSpellCheckDaemonStageProcess.cs">
+      <Link>Xml\XmlSpellCheckDaemonStageProcess.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlSpellingErrorHighlighting.cs">
+      <Link>Xml\XmlSpellingErrorHighlighting.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlSpellingFixBulbItem.cs">
+      <Link>Xml\XmlSpellingFixBulbItem.cs</Link>
+    </Compile>
+    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlSpellingQuickFix.cs">
+      <Link>Xml\XmlSpellingQuickFix.cs</Link>
+    </Compile>
     <Compile Include="..\YouCantSpellAssemblyInfo.cs">
       <Link>Properties\YouCantSpellAssemblyInfo.cs</Link>
     </Compile>
   <ItemGroup>
     <ThemedIconPng Include="resources\SpellCheckOptionsIcon.png" />
   </ItemGroup>
+  <ItemGroup />
   <PropertyGroup>
     <ReSharperSdkTargets Condition=" '$(ReSharperSdkTargets)' == '' ">$(MSBuildExtensionsPath)\JetBrains\ReSharper.SDK\v7.0</ReSharperSdkTargets>
   </PropertyGroup>

File src/YouCantSpell.ReSharper.v70/YouCantSpell.ReSharper.v70.csproj

     <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlSpellingQuickFix.cs">
       <Link>Html\HtmlSpellingQuickFix.cs</Link>
     </Compile>
-    <Compile Include="..\YouCantSpell.ReSharper.Shared\Html\HtmlUtil.cs">
-      <Link>Html\HtmlUtil.cs</Link>
-    </Compile>
     <Compile Include="..\YouCantSpell.ReSharper.Shared\JavaScript\JavaScriptFreeTextSpellingHighlightFinder.cs">
       <Link>JavaScript\JavaScriptFreeTextSpellingHighlightFinder.cs</Link>
     </Compile>
     <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlSpellingQuickFix.cs">
       <Link>Xml\XmlSpellingQuickFix.cs</Link>
     </Compile>
-    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlSpellingSuggestionFormatter.cs">
-      <Link>Xml\XmlSpellingSuggestionFormatter.cs</Link>
-    </Compile>
-    <Compile Include="..\YouCantSpell.ReSharper.Shared\Xml\XmlUtil.cs">
-      <Link>Xml\XmlUtil.cs</Link>
-    </Compile>
     <Compile Include="..\YouCantSpellAssemblyInfo.cs">
       <Link>Properties\YouCantSpellAssemblyInfo.cs</Link>
     </Compile>