<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -4,6 +4,8 @@ using System.ComponentModel.Composition;
 using System.Linq;
 using Microsoft.VisualStudio.Text;
 using Microsoft.VisualStudio.Text.Classification;
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Text.Tagging;
 using Microsoft.VisualStudio.Utilities;
 
 namespace Winterdom.VisualStudio.Extensions.Text {
@@ -14,111 +16,85 @@ namespace Winterdom.VisualStudio.Extensions.Text {
       public const String VISIBILITY_CLASSIF_NAME = &quot;VisibilityKeyword&quot;;
    }
 
-   [Export(typeof(IClassifierProvider))]
+   [Export(typeof(IViewTaggerProvider))]
    [ContentType(CSharp.ContentType)]
    [ContentType(Cpp.ContentType)]
-   public class KeywordClassifierProvider : IClassifierProvider {
+   [TagType(typeof(ClassificationTag))]
+   public class KeywordTaggerProvider : IViewTaggerProvider {
       [Import]
       internal IClassificationTypeRegistryService ClassificationRegistry = null;
       [Import]
-      internal IClassifierAggregatorService Aggregator = null;
-      private static bool ignoreRequest = false;
-
-      public IClassifier GetClassifier(ITextBuffer buffer) {
-         // ignoreRequest ensures that our own classifier doesn't get added when we 
-         // go through the Aggregator Service below.
-         if ( ignoreRequest ) return null;
-         try {
-            ignoreRequest = true;
-            return buffer.Properties.GetOrCreateSingletonProperty&lt;KeywordClassifier&gt;(
-               delegate {
-                  return new KeywordClassifier(
-                     ClassificationRegistry,
-                     Aggregator.GetClassifier(buffer)
-                  );
-               });
-         } finally {
-            ignoreRequest = false;
+      internal IBufferTagAggregatorFactoryService Aggregator = null;
+
+      public ITagger&lt;T&gt; CreateTagger&lt;T&gt;(ITextView textView, ITextBuffer buffer) where T : ITag {
+         if ( typeof(T) == typeof(ClassificationTag) ) {
+            return new KeywordTagger(
+               ClassificationRegistry,
+               Aggregator.CreateTagAggregator&lt;ClassificationTag&gt;(buffer)
+            ) as ITagger&lt;T&gt;;
          }
+         return null;
       }
    }
 
-   class KeywordClassifier : IClassifier {
-      private IClassificationType keywordClassification;
-      private IClassificationType linqClassification;
-      private IClassificationType visClassification;
-      private IClassifier classifier;
-      private bool alreadyRunning;
+   class KeywordTagger : ITagger&lt;ClassificationTag&gt; {
+      private ClassificationTag keywordClassification;
+      private ClassificationTag linqClassification;
+      private ClassificationTag visClassification;
+      private ITagAggregator&lt;ClassificationTag&gt; aggregator;
       private static readonly IList&lt;ClassificationSpan&gt; EmptyList = 
          new List&lt;ClassificationSpan&gt;();
 
 #pragma warning disable 67
-      public event EventHandler&lt;ClassificationChangedEventArgs&gt; ClassificationChanged;
+      public event EventHandler&lt;SnapshotSpanEventArgs&gt; TagsChanged;
 #pragma warning restore 67
 
-      internal KeywordClassifier(
+      internal KeywordTagger(
             IClassificationTypeRegistryService registry, 
-            IClassifier classifier) {
-         keywordClassification = registry.GetClassificationType(Constants.CLASSIF_NAME);
-         linqClassification = registry.GetClassificationType(Constants.LINQ_CLASSIF_NAME);
-         visClassification = registry.GetClassificationType(Constants.VISIBILITY_CLASSIF_NAME);
-         this.classifier = classifier;
-         this.alreadyRunning = false;
+            ITagAggregator&lt;ClassificationTag&gt; aggregator) {
+         keywordClassification = 
+            new ClassificationTag(registry.GetClassificationType(Constants.CLASSIF_NAME));
+         linqClassification = 
+            new ClassificationTag(registry.GetClassificationType(Constants.LINQ_CLASSIF_NAME));
+         visClassification = 
+            new ClassificationTag(registry.GetClassificationType(Constants.VISIBILITY_CLASSIF_NAME));
+         this.aggregator = aggregator;
       }
 
-      public IList&lt;ClassificationSpan&gt; GetClassificationSpans(SnapshotSpan span) {
-         // need this here as well because the C# signature help display will
-         // try to call us through an aggregator that already contains us
-         // so we end up calling ourselves recursively and blowing the stack!
-         if ( alreadyRunning ) return EmptyList;
-         try {
-            alreadyRunning = true;
-            return GetMyClassificationSpans(span);
-         } finally {
-            alreadyRunning = false;
+      public IEnumerable&lt;ITagSpan&lt;ClassificationTag&gt;&gt; GetTags(NormalizedSnapshotSpanCollection spans) {
+         if ( spans.Count == 0 ) {
+            yield break;
          }
-      }
-
-      private IList&lt;ClassificationSpan&gt; GetMyClassificationSpans(SnapshotSpan span) {
-         List&lt;ClassificationSpan&gt; list = new List&lt;ClassificationSpan&gt;();
-         if ( span.IsEmpty ) return list;
-
+         ITextSnapshot snapshot = spans[0].Snapshot;
          ILanguageKeywords keywords =
-            GetKeywordsByContentType(span.Snapshot.TextBuffer.ContentType);
+            GetKeywordsByContentType(snapshot.TextBuffer.ContentType);
          if ( keywords == null ) {
-            return list;
+            yield break;
          }
 
          // find spans that the language service has already classified as keywords ...
-         var classifiedSpans =
-            from cs in classifier.GetClassificationSpans(span)
-            let name = cs.ClassificationType.Classification.ToLower()
+         var mappedSpans =
+            from tagSpan in aggregator.GetTags(spans)
+            let name = tagSpan.Tag.ClassificationType.Classification.ToLower()
             where name.Contains(&quot;keyword&quot;)
-            select cs.Span;
+            select tagSpan.Span;
+         var classifiedSpans =
+            from mappedSpan in mappedSpans
+            let cs = mappedSpan.GetSpans(snapshot)
+            where cs.Count &gt; 0
+            select cs[0];
 
          // ... and from those, ones that match our keywords
-         var controlFlowSpans = from kwSpan in classifiedSpans
-                                where keywords.ControlFlow.Contains(kwSpan.GetText())
-                                select kwSpan;
-
-         list.AddRange(controlFlowSpans.Select(
-               cfs =&gt; new ClassificationSpan(cfs, keywordClassification)
-            ));
-
-         var linqSpans = from kwSpan in classifiedSpans
-                         where keywords.Linq.Contains(kwSpan.GetText())
-                         select kwSpan;
-         list.AddRange(linqSpans.Select(
-               cfs =&gt; new ClassificationSpan(cfs, linqClassification)
-            ));
-
-         var visSpans = from kwSpan in classifiedSpans
-                        where keywords.Visibility.Contains(kwSpan.GetText())
-                        select kwSpan;
-         list.AddRange(visSpans.Select(
-               cfs =&gt; new ClassificationSpan(cfs, visClassification)
-            ));
-         return list;
+         foreach ( var cs in classifiedSpans ) {
+            String text = cs.GetText();
+            if ( keywords.ControlFlow.Contains(text) ) {
+               yield return new TagSpan&lt;ClassificationTag&gt;(cs, keywordClassification);
+            } else if ( keywords.Visibility.Contains(text) ) {
+               yield return new TagSpan&lt;ClassificationTag&gt;(cs, visClassification);
+            } else if ( keywords.Linq.Contains(text) ) {
+               yield return new TagSpan&lt;ClassificationTag&gt;(cs, linqClassification);
+            }
+         }
       }
 
       private ILanguageKeywords GetKeywordsByContentType(IContentType contentType) {</diff>
      <filename>KeywordClassifier.cs</filename>
    </modified>
    <modified>
      <diff>@@ -10,11 +10,11 @@ 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(&quot;ControlFlowClassifier&quot;)]
+[assembly: AssemblyTitle(&quot;KeywordClassifier&quot;)]
 [assembly: AssemblyDescription(&quot;&quot;)]
 [assembly: AssemblyConfiguration(&quot;&quot;)]
 [assembly: AssemblyCompany(&quot;&quot;)]
-[assembly: AssemblyProduct(&quot;ControlFlowClassifier&quot;)]
+[assembly: AssemblyProduct(&quot;KeywordClassifier&quot;)]
 [assembly: AssemblyCopyright(&quot;&quot;)]
 [assembly: AssemblyTrademark(&quot;&quot;)]
 [assembly: AssemblyCulture(&quot;&quot;)]
@@ -34,5 +34,5 @@ using System.Runtime.InteropServices;
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion(&quot;1.0.*&quot;)]
-[assembly: AssemblyVersion(&quot;1.0.0.0&quot;)]
-[assembly: AssemblyFileVersion(&quot;1.0.0.0&quot;)]
+[assembly: AssemblyVersion(&quot;1.1.0.0&quot;)]
+[assembly: AssemblyFileVersion(&quot;1.1.0.0&quot;)]</diff>
      <filename>Properties/AssemblyInfo.cs</filename>
    </modified>
    <modified>
      <diff>@@ -3,7 +3,7 @@
    &lt;Identifier Id=&quot;KeywordClassifier.Winterdom.a887584b-9f87-4354-beec-8a751e5f925a&quot;&gt;
       &lt;Name&gt;Keyword Classifier&lt;/Name&gt;
       &lt;Author&gt;Tomas Restrepo&lt;/Author&gt;
-      &lt;Version&gt;1.0&lt;/Version&gt;
+      &lt;Version&gt;1.1&lt;/Version&gt;
       &lt;Description xml:space=&quot;preserve&quot;&gt;Sample classifier extension for the Visual Studio Editor that extends the built-in C#/C++ keyword highlighing features.
 
 The extension provides separate control for colorization of:</diff>
      <filename>source.extension.vsixmanifest</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>b2472cc2bbdd823a4d8a2ff5fdbfc82c4da1423e</id>
    </parent>
  </parents>
  <author>
    <name>Tomas Restrepo</name>
    <email>tomas@winterdom.com</email>
  </author>
  <url>http://github.com/tomasr/KeywordClassifier/commit/c9cc01869270415efa22da995dbb2a6dab989451</url>
  <id>c9cc01869270415efa22da995dbb2a6dab989451</id>
  <committed-date>2009-10-22T09:12:44-07:00</committed-date>
  <authored-date>2009-10-22T09:12:44-07:00</authored-date>
  <message>Changing the classifier to a view-specific tagger</message>
  <tree>767684def01b4c9c21628288d42e9c98673efe93</tree>
  <committer>
    <name>Tomas Restrepo</name>
    <email>tomas@winterdom.com</email>
  </committer>
</commit>
