static void RevaluatePropertyInheritanceAdornments(InheritanceTracker @this)
        {
            Contract.Requires(@this != null);

            var workingSnapshot = @this._textViewTracker.TextView.TextSnapshot; //Save the current snapshot so it doesn't change while you work, we assume that the snapshot is the same as the source file.

            //Check if model is ready
            var parseTree = @this._textViewTracker.LatestSourceFile == null ? null : @this._textViewTracker.LatestSourceFile.GetParseTree();

            if (parseTree == null || !VSServiceProvider.IsModelReady(parseTree))
            {
                @this._textViewTracker.IsLatestSourceFileStale = true;
                Utilities.Delay(() => VSServiceProvider.Current.AskForNewVSModel(), DelayOnVSModelFailedBeforeTryingAgain);
                return;
            }

            //Collect all the properties in this text view
            var propertyCollector = new PropertyCollector(workingSnapshot);

            propertyCollector.Visit(parseTree.RootNode);
            var properties = propertyCollector.GetProperties();

            //Get our property keys
            var keys      = new List <object>();
            var newTuples = new List <Tuple <object, object> >();

            foreach (var tuple in properties.Keys)
            {
                if (tuple.Item1 != null)
                {
                    keys.Add(tuple.Item1);
                }
                if (tuple.Item2 != null)
                {
                    keys.Add(tuple.Item2);
                }
                if (!(@this._propertyKeys.Contains(tuple.Item1) && @this._propertyKeys.Contains(tuple.Item1)))
                {
                    newTuples.Add(tuple);
                }
            }

            VSServiceProvider.Current.Logger.WriteToLog(String.Format("Found {0} new properties.", newTuples.Count));

            //Update our property keys
            @this._propertyKeys.Clear();
            @this._propertyKeys.AddAll(keys);

            VSServiceProvider.Current.QueueWorkItem(() => {
                if (@this._textViewTracker.TextView.IsClosed)
                {
                    return;
                }
                var adornmentKeys = new List <object>(@this._adornmentManager.Adornments.Keys);
                foreach (var key in adornmentKeys)
                {
                    var keyAsString = key as string;
                    if (keyAsString == null)
                    {
                        VSServiceProvider.Current.Logger.WriteToLog("Unexpected: A key in the AdornmentManager wasn't a string! key: " + key.ToString());
                        continue;
                    }
                    if (!@this._propertyKeys.Contains(key) && keyAsString.EndsWith(PropertyCollector.PropertyTagSuffix))
                    {
                        @this._adornmentManager.RemoveAdornment(key);
                        VSServiceProvider.Current.Logger.WriteToLog("Removing obsolete property adornment with tag: " + keyAsString);
                    }
                }
            }, () => @this._textViewTracker.TextView.IsClosed || @this._textViewTracker.TextView.HasAggregateFocus);

            //Create placeholder adornments for our new properties and queue them for contract lookup
            VSServiceProvider.Current.QueueWorkItem(() => {
                foreach (var tuple in newTuples)
                {
                    PropertyDeclarationNode property;
                    if (properties.TryGetValue(tuple, out property))
                    {
                        if (tuple.Item1 != null && tuple.Item2 != null &&
                            property.GetAccessorDeclaration.GetSpan().Start.Line == property.SetAccessorDeclaration.GetSpan().Start.Line)
                        {
                            // set and get on same line, don't add adornment
                            VSServiceProvider.Current.Logger.WriteToLog("Skipping adornments for " + property.GetName(workingSnapshot) + " because get and set are on same line");
                        }
                        else
                        {
                            VSServiceProvider.Current.Logger.WriteToLog("Creating placeholder adornment and enqueueing for future contract lookup for: " + property.GetName(workingSnapshot));
                            if (tuple.Item1 != null)
                            {
                                #region Create getter placeholder adornment
                                VSServiceProvider.Current.Logger.WriteToLog(String.Format("\t(Creating getter placeholder with tag {0})", tuple.Item1));
                                //We add the placeholder adornment here because our workingSnapshot corresponds most closely to the syntactic model's text
                                var snapshotSpan = new SnapshotSpan(property.GetAccessorDeclaration.GetSpan().Convert(workingSnapshot).Start, 1);
                                var trackingSpan = workingSnapshot.CreateTrackingSpan(snapshotSpan.Span, SpanTrackingMode.EdgeExclusive);
                                var ops          = AdornmentOptionsHelper.GetAdornmentOptions(VSServiceProvider.Current.VSOptionsPage);
                                @this._adornmentManager.AddAdornment(new InheritanceContractAdornment(trackingSpan, @this._textViewTracker.VSTextProperties, VSServiceProvider.Current.Logger, @this._adornmentManager.QueueRefreshLineTransformer, ops), tuple.Item1);
                                #endregion
                            }
                            if (tuple.Item2 != null)
                            {
                                #region Create setter placeholder adornment
                                VSServiceProvider.Current.Logger.WriteToLog(String.Format("\t(Creating setter placeholder with tag {0})", tuple.Item2));
                                //We add the placeholder adornment here because our workingSnapshot corresponds most closely to the syntactic model's text
                                var snapshotSpan = new SnapshotSpan(property.SetAccessorDeclaration.GetSpan().Convert(workingSnapshot).Start, 1);
                                var trackingSpan = workingSnapshot.CreateTrackingSpan(snapshotSpan.Span, SpanTrackingMode.EdgeExclusive);
                                var ops          = AdornmentOptionsHelper.GetAdornmentOptions(VSServiceProvider.Current.VSOptionsPage);
                                @this._adornmentManager.AddAdornment(new InheritanceContractAdornment(trackingSpan, @this._textViewTracker.VSTextProperties, VSServiceProvider.Current.Logger, @this._adornmentManager.QueueRefreshLineTransformer, ops), tuple.Item2);
                                #endregion
                            }
                            @this._propertiesNeedingContractLookup.Enqueue(new KeyValuePair <Tuple <object, object>, PropertyDeclarationNode>(tuple, property));
                        }
                    }
                }
            });

            //Most likely we've changed something (and this is a pretty cheap call), so let's ask for a refresh
            Utilities.Delay(() => VSServiceProvider.Current.QueueWorkItem(@this._adornmentManager.QueueRefreshLineTransformer, () => @this._textViewTracker.TextView.HasAggregateFocus), DelayAfterMembersRevalutation);

            //Ask for the new VS model so we can look up contracts
            Utilities.Delay(() => VSServiceProvider.Current.QueueWorkItem(VSServiceProvider.Current.AskForNewVSModel, () => @this._textViewTracker.TextView.HasAggregateFocus), DelayAfterMembersRevalutation);
        }
    static void RevaluatePropertyInheritanceAdornments(InheritanceTracker @this) {
      Contract.Requires(@this != null);

      var workingSnapshot = @this._textViewTracker.TextView.TextSnapshot;  //Save the current snapshot so it doesn't change while you work, we assume that the snapshot is the same as the source file.

      //Check if model is ready
      var parseTree = @this._textViewTracker.LatestSourceFile == null ? null : @this._textViewTracker.LatestSourceFile.GetParseTree();
      if (parseTree == null || !parseTree.IsModelReady()) {
        @this._textViewTracker.IsLatestSourceFileStale = true;
        Utilities.Delay(() => ContractsPackageAccessor.Current.AskForNewVSModel(), DelayOnVSModelFailedBeforeTryingAgain);
        return;
      }

      //Collect all the properties in this text view
      var propertyCollector = new PropertyCollector(workingSnapshot);
      propertyCollector.Visit(parseTree.RootNode);
      var properties = propertyCollector.GetProperties();

      //Get our property keys
      var keys = new List<object>();
      var newTuples = new List<Tuple<object, object>>();
      foreach (var tuple in properties.Keys) {
        if (tuple.Item1 != null)
          keys.Add(tuple.Item1);
        if (tuple.Item2 != null)
          keys.Add(tuple.Item2);
        if (!(@this._propertyKeys.Contains(tuple.Item1) && @this._propertyKeys.Contains(tuple.Item1)))
          newTuples.Add(tuple);
      }

      ContractsPackageAccessor.Current.Logger.WriteToLog(String.Format("Found {0} new properties.", newTuples.Count));

      //Update our property keys
      @this._propertyKeys.Clear();
      @this._propertyKeys.AddAll(keys);

      ContractsPackageAccessor.Current.QueueWorkItem(() => {
        if (@this._textViewTracker.TextView.IsClosed)
          return;
        var adornmentKeys = new List<object>(@this._adornmentManager.Adornments.Keys);
        foreach (var key in adornmentKeys) {
          var keyAsString = key as string;
          if (keyAsString == null) {
            ContractsPackageAccessor.Current.Logger.WriteToLog("Unexpected: A key in the AdornmentManager wasn't a string! key: " + key.ToString());
            continue;
          }
          if (!@this._propertyKeys.Contains(key) && keyAsString.EndsWith(PropertyCollector.PropertyTagSuffix)) {
            @this._adornmentManager.RemoveAdornment(key);
            ContractsPackageAccessor.Current.Logger.WriteToLog("Removing obsolete property adornment with tag: " + keyAsString);
          }
        }
      }, () => @this._textViewTracker.TextView.IsClosed || @this._textViewTracker.TextView.HasAggregateFocus);

      //Create placeholder adornments for our new properties and queue them for contract lookup
      ContractsPackageAccessor.Current.QueueWorkItem(() => {
        foreach (var tuple in newTuples) {
          PropertyDeclarationNode property;
          if (properties.TryGetValue(tuple, out property)) {
            if (tuple.Item1 != null && tuple.Item2 != null &&
                property.GetAccessorDeclaration.GetSpan().Start.Line == property.SetAccessorDeclaration.GetSpan().Start.Line)
            {
              // set and get on same line, don't add adornment
              ContractsPackageAccessor.Current.Logger.WriteToLog("Skipping adornments for " + property.GetName(workingSnapshot) + " because get and set are on same line");
            }
            else
            {
              ContractsPackageAccessor.Current.Logger.WriteToLog("Creating placeholder adornment and enqueueing for future contract lookup for: " + property.GetName(workingSnapshot));
              if (tuple.Item1 != null)
              {
                #region Create getter placeholder adornment
                ContractsPackageAccessor.Current.Logger.WriteToLog(String.Format("\t(Creating getter placeholder with tag {0})", tuple.Item1));
                //We add the placeholder adornment here because our workingSnapshot corresponds most closely to the syntactic model's text
                var snapshotSpan = new SnapshotSpan(property.GetAccessorDeclaration.GetSpan().Convert(workingSnapshot).Start, 1);
                var trackingSpan = workingSnapshot.CreateTrackingSpan(snapshotSpan.Span, SpanTrackingMode.EdgeExclusive);
                var ops = AdornmentOptionsHelper.GetAdornmentOptions(ContractsPackageAccessor.Current.VSOptionsPage);
                @this._adornmentManager.AddAdornment(new InheritanceContractAdornment(trackingSpan, @this._textViewTracker.VSTextProperties, ContractsPackageAccessor.Current.Logger, @this._adornmentManager.QueueRefreshLineTransformer, ops), tuple.Item1);
                #endregion
              }
              if (tuple.Item2 != null)
              {
                #region Create setter placeholder adornment
                ContractsPackageAccessor.Current.Logger.WriteToLog(String.Format("\t(Creating setter placeholder with tag {0})", tuple.Item2));
                //We add the placeholder adornment here because our workingSnapshot corresponds most closely to the syntactic model's text
                var snapshotSpan = new SnapshotSpan(property.SetAccessorDeclaration.GetSpan().Convert(workingSnapshot).Start, 1);
                var trackingSpan = workingSnapshot.CreateTrackingSpan(snapshotSpan.Span, SpanTrackingMode.EdgeExclusive);
                var ops = AdornmentOptionsHelper.GetAdornmentOptions(ContractsPackageAccessor.Current.VSOptionsPage);
                @this._adornmentManager.AddAdornment(new InheritanceContractAdornment(trackingSpan, @this._textViewTracker.VSTextProperties, ContractsPackageAccessor.Current.Logger, @this._adornmentManager.QueueRefreshLineTransformer, ops), tuple.Item2);
                #endregion
              }
              @this._propertiesNeedingContractLookup.Enqueue(new KeyValuePair<Tuple<object, object>, PropertyDeclarationNode>(tuple, property));
            }
          }
        }
      });

      //Most likely we've changed something (and this is a pretty cheap call), so let's ask for a refresh
      Utilities.Delay(() => ContractsPackageAccessor.Current.QueueWorkItem(@this._adornmentManager.QueueRefreshLineTransformer, () => @this._textViewTracker.TextView.HasAggregateFocus), DelayAfterMembersRevalutation);

      //Ask for the new VS model so we can look up contracts
      Utilities.Delay(() => ContractsPackageAccessor.Current.QueueWorkItem(ContractsPackageAccessor.Current.AskForNewVSModel, () => @this._textViewTracker.TextView.HasAggregateFocus), DelayAfterMembersRevalutation);
    }