Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/microsoft/vs-editor-api.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleg Tkachenko <olegtk@microsoft.com>2017-05-08 21:24:33 +0300
committerOleg Tkachenko <olegtk@microsoft.com>2017-05-08 21:24:33 +0300
commit19fbcc14e30219af42e3880703531fa0a89d18c2 (patch)
tree6a3a5db0a9eab4b939920c19188d5179f9e35f7b /src/Text/Def
parent7f6a5fc245efb9415caa7ecc3afbe0be2bba7833 (diff)
Initial commit of VS 2017 RTW bits
Diffstat (limited to 'src/Text/Def')
-rw-r--r--src/Text/Def/Platform.Settings.targets7
-rw-r--r--src/Text/Def/TextData/AssemblyInfo.cs31
-rw-r--r--src/Text/Def/TextData/Diagrams/BufferMarkers.cd47
-rw-r--r--src/Text/Def/TextData/Diagrams/Projection.cd131
-rw-r--r--src/Text/Def/TextData/Diagrams/ReadOnlyRegions.cd92
-rw-r--r--src/Text/Def/TextData/Diagrams/SnapshotMarkers.cd50
-rw-r--r--src/Text/Def/TextData/Diagrams/Text.cd137
-rw-r--r--src/Text/Def/TextData/Diagrams/TextEdit.cd25
-rw-r--r--src/Text/Def/TextData/Diagrams/TextEvents.cd75
-rw-r--r--src/Text/Def/TextData/Differencing/ContinueProcessingPredicate.cs19
-rw-r--r--src/Text/Def/TextData/Differencing/Deprecated/DetermineLocalityCallback.cs21
-rw-r--r--src/Text/Def/TextData/Differencing/Deprecated/IHierarchicalStringDifferenceService.cs66
-rw-r--r--src/Text/Def/TextData/Differencing/Difference.cs128
-rw-r--r--src/Text/Def/TextData/Differencing/DifferenceType.cs26
-rw-r--r--src/Text/Def/TextData/Differencing/IDifferenceCollection.cs50
-rw-r--r--src/Text/Def/TextData/Differencing/IDifferenceService.cs37
-rw-r--r--src/Text/Def/TextData/Differencing/IHierarchicalDifferenceCollection.cs61
-rw-r--r--src/Text/Def/TextData/Differencing/ITextDifferencingSelectorService.cs39
-rw-r--r--src/Text/Def/TextData/Differencing/ITextDifferencingService.cs98
-rw-r--r--src/Text/Def/TextData/Differencing/ITokenizedStringList.cs39
-rw-r--r--src/Text/Def/TextData/Differencing/Match.cs116
-rw-r--r--src/Text/Def/TextData/Differencing/StringDifferenceOptions.cs175
-rw-r--r--src/Text/Def/TextData/Differencing/StringDifferenceTypes.cs33
-rw-r--r--src/Text/Def/TextData/Differencing/WordSplitBehavior.cs51
-rw-r--r--src/Text/Def/TextData/Document/EncodingChangedEventArgs.cs35
-rw-r--r--src/Text/Def/TextData/Document/FileUtilities.cs250
-rw-r--r--src/Text/Def/TextData/Document/IEncodingDetector.cs34
-rw-r--r--src/Text/Def/TextData/Document/ITextDocument.cs236
-rw-r--r--src/Text/Def/TextData/Document/ITextDocumentFactoryService.cs79
-rw-r--r--src/Text/Def/TextData/Document/ReloadResult.cs23
-rw-r--r--src/Text/Def/TextData/Document/TextDocumentEventArgs.cs41
-rw-r--r--src/Text/Def/TextData/Document/TextDocumentFileActionEventArgs.cs101
-rw-r--r--src/Text/Def/TextData/FxCopSuppressions.cs52
-rw-r--r--src/Text/Def/TextData/Model/ContentTypeChangedEventArgs.cs76
-rw-r--r--src/Text/Def/TextData/Model/CustomTrackToVersion.cs17
-rw-r--r--src/Text/Def/TextData/Model/DynamicReadOnlyRegionQuery.cs12
-rw-r--r--src/Text/Def/TextData/Model/EdgeInsertionMode.cs25
-rw-r--r--src/Text/Def/TextData/Model/EditOptions.cs144
-rw-r--r--src/Text/Def/TextData/Model/IExtensionErrorHandler.cs21
-rw-r--r--src/Text/Def/TextData/Model/IExtensionPerformanceTracker.cs26
-rw-r--r--src/Text/Def/TextData/Model/IMappingPoint.cs92
-rw-r--r--src/Text/Def/TextData/Model/IMappingSpan.cs62
-rw-r--r--src/Text/Def/TextData/Model/INormalizedTextChangeCollection.cs22
-rw-r--r--src/Text/Def/TextData/Model/IPersistentSpan.cs81
-rw-r--r--src/Text/Def/TextData/Model/IPersistentSpanFactory.cs74
-rw-r--r--src/Text/Def/TextData/Model/IReadOnlyRegion.cs47
-rw-r--r--src/Text/Def/TextData/Model/IReadOnlyRegionEdit.cs106
-rw-r--r--src/Text/Def/TextData/Model/ITextBuffer.cs273
-rw-r--r--src/Text/Def/TextData/Model/ITextBufferEdit.cs49
-rw-r--r--src/Text/Def/TextData/Model/ITextBufferFactory.cs84
-rw-r--r--src/Text/Def/TextData/Model/ITextChange.cs101
-rw-r--r--src/Text/Def/TextData/Model/ITextChange2.cs21
-rw-r--r--src/Text/Def/TextData/Model/ITextChange3.cs35
-rw-r--r--src/Text/Def/TextData/Model/ITextEdit.cs124
-rw-r--r--src/Text/Def/TextData/Model/ITextSnapshot.cs224
-rw-r--r--src/Text/Def/TextData/Model/ITextSnapshotLine.cs85
-rw-r--r--src/Text/Def/TextData/Model/ITextVersion.cs139
-rw-r--r--src/Text/Def/TextData/Model/ITrackingPoint.cs65
-rw-r--r--src/Text/Def/TextData/Model/ITrackingSpan.cs75
-rw-r--r--src/Text/Def/TextData/Model/Microsoft.VisualStudio.Text.Model.Overview.mht4612
-rw-r--r--src/Text/Def/TextData/Model/NormalizedSnapshotSpanCollection.cs1188
-rw-r--r--src/Text/Def/TextData/Model/NormalizedSpanCollection.cs632
-rw-r--r--src/Text/Def/TextData/Model/PointTrackingMode.cs25
-rw-r--r--src/Text/Def/TextData/Model/PositionAffinity.cs22
-rw-r--r--src/Text/Def/TextData/Model/PreContentChangedEventArgs.cs36
-rw-r--r--src/Text/Def/TextData/Model/Projection/ElisionBufferOptions.cs24
-rw-r--r--src/Text/Def/TextData/Model/Projection/ElisionSourceSpansChangedEventArgs.cs78
-rw-r--r--src/Text/Def/TextData/Model/Projection/GraphBufferContentTypeChangedEventArgs.cs67
-rw-r--r--src/Text/Def/TextData/Model/Projection/GraphBuffersChangedEventArgs.cs51
-rw-r--r--src/Text/Def/TextData/Model/Projection/IBufferGraph.cs259
-rw-r--r--src/Text/Def/TextData/Model/Projection/IBufferGraphFactoryService.cs25
-rw-r--r--src/Text/Def/TextData/Model/Projection/IElisionBuffer.cs74
-rw-r--r--src/Text/Def/TextData/Model/Projection/IElisionSnapshot.cs37
-rw-r--r--src/Text/Def/TextData/Model/Projection/IProjectionBuffer.cs109
-rw-r--r--src/Text/Def/TextData/Model/Projection/IProjectionBufferBase.cs76
-rw-r--r--src/Text/Def/TextData/Model/Projection/IProjectionBufferFactoryService.cs96
-rw-r--r--src/Text/Def/TextData/Model/Projection/IProjectionEditResolver.cs63
-rw-r--r--src/Text/Def/TextData/Model/Projection/IProjectionSnapshot.cs150
-rw-r--r--src/Text/Def/TextData/Model/Projection/IProjectionSnapshot2.cs25
-rw-r--r--src/Text/Def/TextData/Model/Projection/ProjectionBufferOptions.cs32
-rw-r--r--src/Text/Def/TextData/Model/Projection/ProjectionSourceBuffersChangedEventArgs.cs72
-rw-r--r--src/Text/Def/TextData/Model/Projection/ProjectionSourceSpansChangedEventArgs.cs93
-rw-r--r--src/Text/Def/TextData/Model/SnapshotPoint.cs304
-rw-r--r--src/Text/Def/TextData/Model/SnapshotSpan.cs496
-rw-r--r--src/Text/Def/TextData/Model/SnapshotSpanEventArgs.cs27
-rw-r--r--src/Text/Def/TextData/Model/Span.cs264
-rw-r--r--src/Text/Def/TextData/Model/SpanTrackingMode.cs44
-rw-r--r--src/Text/Def/TextData/Model/TextBufferCreatedEventArgs.cs31
-rw-r--r--src/Text/Def/TextData/Model/TextContentChangedEventArgs.cs55
-rw-r--r--src/Text/Def/TextData/Model/TextContentChangingEventArgs.cs75
-rw-r--r--src/Text/Def/TextData/Model/TextSnapshotChangedEventArgs.cs88
-rw-r--r--src/Text/Def/TextData/Model/TextSnapshotToTextReader.cs177
-rw-r--r--src/Text/Def/TextData/Model/Tracking.cs378
-rw-r--r--src/Text/Def/TextData/Model/TrackingFidelityMode.cs35
-rw-r--r--src/Text/Def/TextData/Strings.Designer.cs171
-rw-r--r--src/Text/Def/TextData/Strings.resx156
-rw-r--r--src/Text/Def/TextData/TextData.csproj146
-rw-r--r--src/Text/Def/TextDef.fxcop61
-rw-r--r--src/Text/Def/TextLogic/AssemblyInfo.cs23
-rw-r--r--src/Text/Def/TextLogic/Classification/ClassificationChangedEventArgs.cs34
-rw-r--r--src/Text/Def/TextLogic/Classification/ClassificationSpan.cs54
-rw-r--r--src/Text/Def/TextLogic/Classification/ClassificationTypeAttribute.cs57
-rw-r--r--src/Text/Def/TextLogic/Classification/ClassificationTypeDefinition.cs25
-rw-r--r--src/Text/Def/TextLogic/Classification/IClassificationType.cs47
-rw-r--r--src/Text/Def/TextLogic/Classification/IClassificationTypeRegistryService.cs92
-rw-r--r--src/Text/Def/TextLogic/Classification/IClassifier.cs35
-rw-r--r--src/Text/Def/TextLogic/Classification/IClassifierAggregatorService.cs32
-rw-r--r--src/Text/Def/TextLogic/Classification/IClassifierProvider.cs23
-rw-r--r--src/Text/Def/TextLogic/Classification/Microsoft.VisualStudio.Text.Classification.Overview.mht3155
-rw-r--r--src/Text/Def/TextLogic/Diagrams/Tagging.cd77
-rw-r--r--src/Text/Def/TextLogic/Diagrams/Undo.cd98
-rw-r--r--src/Text/Def/TextLogic/DifferenceBuffer/DifferenceBufferOptions.cs31
-rw-r--r--src/Text/Def/TextLogic/DifferenceBuffer/DifferenceMappingMode.cs31
-rw-r--r--src/Text/Def/TextLogic/DifferenceBuffer/DifferenceTrackingSpans.cs31
-rw-r--r--src/Text/Def/TextLogic/DifferenceBuffer/IDifferenceBuffer.cs133
-rw-r--r--src/Text/Def/TextLogic/DifferenceBuffer/IDifferenceBufferFactoryService.cs46
-rw-r--r--src/Text/Def/TextLogic/DifferenceBuffer/ISnapshotDifference.cs131
-rw-r--r--src/Text/Def/TextLogic/DifferenceBuffer/IgnoreDifferencePredicate.cs12
-rw-r--r--src/Text/Def/TextLogic/DifferenceBuffer/IgnoreWhiteSpaceBehavior.cs21
-rw-r--r--src/Text/Def/TextLogic/DifferenceBuffer/LineType.cs23
-rw-r--r--src/Text/Def/TextLogic/DifferenceBuffer/SnapshotDifferenceChangeEventArgs.cs34
-rw-r--r--src/Text/Def/TextLogic/DifferenceBuffer/SnapshotLineTransform.cs12
-rw-r--r--src/Text/Def/TextLogic/EditorOptions/DefaultOptions.cs371
-rw-r--r--src/Text/Def/TextLogic/EditorOptions/DeferCreationAttribute.cs45
-rw-r--r--src/Text/Def/TextLogic/EditorOptions/EditorOptionChangedEventArgs.cs28
-rw-r--r--src/Text/Def/TextLogic/EditorOptions/EditorOptionDefinition.cs146
-rw-r--r--src/Text/Def/TextLogic/EditorOptions/EditorOptionKey.cs85
-rw-r--r--src/Text/Def/TextLogic/EditorOptions/IEditorOptions.cs117
-rw-r--r--src/Text/Def/TextLogic/EditorOptions/IEditorOptionsFactoryService.cs52
-rw-r--r--src/Text/Def/TextLogic/Find/FindData.cs184
-rw-r--r--src/Text/Def/TextLogic/Find/FindOptions.cs60
-rw-r--r--src/Text/Def/TextLogic/Find/ITextSearchNavigator.cs100
-rw-r--r--src/Text/Def/TextLogic/Find/ITextSearchNavigatorFactoryService.cs35
-rw-r--r--src/Text/Def/TextLogic/Find/ITextSearchService.cs52
-rw-r--r--src/Text/Def/TextLogic/Find/ITextSearchService2.cs214
-rw-r--r--src/Text/Def/TextLogic/FxCopSuppressions.cs59
-rw-r--r--src/Text/Def/TextLogic/Navigation/ITextStructureNavigator.cs99
-rw-r--r--src/Text/Def/TextLogic/Navigation/ITextStructureNavigatorProvider.cs28
-rw-r--r--src/Text/Def/TextLogic/Navigation/ITextStructureNavigatorSelectorService.cs69
-rw-r--r--src/Text/Def/TextLogic/Navigation/TextExtent.cs116
-rw-r--r--src/Text/Def/TextLogic/Tagging/BatchedTagsChangedEventArgs.cs37
-rw-r--r--src/Text/Def/TextLogic/Tagging/IBufferTagAggregatorFactoryService.cs38
-rw-r--r--src/Text/Def/TextLogic/Tagging/ITag.cs12
-rw-r--r--src/Text/Def/TextLogic/Tagging/ITagAggregator.cs90
-rw-r--r--src/Text/Def/TextLogic/Tagging/ITagger.cs33
-rw-r--r--src/Text/Def/TextLogic/Tagging/ITaggerProvider.cs21
-rw-r--r--src/Text/Def/TextLogic/Tagging/MappingTagSpan.cs65
-rw-r--r--src/Text/Def/TextLogic/Tagging/SimpleTagger.cs288
-rw-r--r--src/Text/Def/TextLogic/Tagging/TagAggregatorOptions.cs33
-rw-r--r--src/Text/Def/TextLogic/Tagging/TagSpan.cs63
-rw-r--r--src/Text/Def/TextLogic/Tagging/TagTypeAttribute.cs45
-rw-r--r--src/Text/Def/TextLogic/Tagging/TagsChangedEventArgs.cs32
-rw-r--r--src/Text/Def/TextLogic/Tagging/TrackingTagSpan.cs42
-rw-r--r--src/Text/Def/TextLogic/Tags/ClassificationTag.cs31
-rw-r--r--src/Text/Def/TextLogic/Tags/IClassificationTag.cs17
-rw-r--r--src/Text/Def/TextLogic/Tags/IUrlTag.cs14
-rw-r--r--src/Text/Def/TextLogic/Tags/UrlTag.cs24
-rw-r--r--src/Text/Def/TextLogic/TextLogic.csproj132
-rw-r--r--src/Text/Def/TextLogic/TextModel/ChangeTag.cs32
-rw-r--r--src/Text/Def/TextLogic/TextModel/ChangeTypes.cs27
-rw-r--r--src/Text/Def/TextLogic/TextModel/ITextDataModel.cs48
-rw-r--r--src/Text/Def/TextLogic/TextModel/TextDataModelContentTypeChangedEventArgs.cs35
-rw-r--r--src/Text/Def/TextLogic/TextModel/VirtualSnapshotPoint.cs322
-rw-r--r--src/Text/Def/TextLogic/TextModel/VirtualSnapshotSpan.cs393
-rw-r--r--src/Text/Def/TextLogic/Undo/IMergeTextUndoTransactionPolicy.cs52
-rw-r--r--src/Text/Def/TextLogic/Undo/ITextBufferUndoManager.cs28
-rw-r--r--src/Text/Def/TextLogic/Undo/ITextBufferUndoManagerProvider.cs33
-rw-r--r--src/Text/Def/TextLogic/Undo/ITextUndoHistory.cs150
-rw-r--r--src/Text/Def/TextLogic/Undo/ITextUndoHistoryRegistry.cs51
-rw-r--r--src/Text/Def/TextLogic/Undo/ITextUndoPrimitive.cs55
-rw-r--r--src/Text/Def/TextLogic/Undo/ITextUndoTransaction.cs90
-rw-r--r--src/Text/Def/TextLogic/Undo/TextUndoHistoryState.cs34
-rw-r--r--src/Text/Def/TextLogic/Undo/TextUndoRedoEventArgs.cs48
-rw-r--r--src/Text/Def/TextLogic/Undo/TextUndoTransactionCompletedEventArgs.cs72
-rw-r--r--src/Text/Def/TextLogic/Undo/TextUndoTransactionState.cs55
-rw-r--r--src/Text/Def/TextUI/Adornments/BlockContext.cs62
-rw-r--r--src/Text/Def/TextUI/Adornments/ErrorTypeDefinition.cs20
-rw-r--r--src/Text/Def/TextUI/Adornments/IBlockContext.cs26
-rw-r--r--src/Text/Def/TextUI/Adornments/IBlockContextProvider.cs23
-rw-r--r--src/Text/Def/TextUI/Adornments/IBlockContextSource.cs23
-rw-r--r--src/Text/Def/TextUI/Adornments/IErrorProviderFactory.cs29
-rw-r--r--src/Text/Def/TextUI/Adornments/ITextMarkerProviderFactory.cs29
-rw-r--r--src/Text/Def/TextUI/Adornments/IToolTipProvider.cs45
-rw-r--r--src/Text/Def/TextUI/Adornments/IToolTipProviderFactory.cs27
-rw-r--r--src/Text/Def/TextUI/Adornments/PopupStyles.cs49
-rw-r--r--src/Text/Def/TextUI/Adornments/PredefinedErrorTypeNames.cs36
-rw-r--r--src/Text/Def/TextUI/Adornments/PredefinedStructureTypes.cs40
-rw-r--r--src/Text/Def/TextUI/Adornments/StructureAdornmentStyle.cs26
-rw-r--r--src/Text/Def/TextUI/AssemblyInfo.cs24
-rw-r--r--src/Text/Def/TextUI/BraceCompletion/BracePairAttribute.cs56
-rw-r--r--src/Text/Def/TextUI/BraceCompletion/IBraceCompletionContext.cs48
-rw-r--r--src/Text/Def/TextUI/BraceCompletion/IBraceCompletionContextProvider.cs41
-rw-r--r--src/Text/Def/TextUI/BraceCompletion/IBraceCompletionDefaultProvider.cs24
-rw-r--r--src/Text/Def/TextUI/BraceCompletion/IBraceCompletionSession.cs117
-rw-r--r--src/Text/Def/TextUI/BraceCompletion/IBraceCompletionSessionProvider.cs38
-rw-r--r--src/Text/Def/TextUI/Classification/IViewClassifierAggregatorService.cs35
-rw-r--r--src/Text/Def/TextUI/Diagrams/BasePrimitives.cd72
-rw-r--r--src/Text/Def/TextUI/Diagrams/Editor.cd102
-rw-r--r--src/Text/Def/TextUI/DifferenceViewer/DifferenceHighlightMode.cs21
-rw-r--r--src/Text/Def/TextUI/DifferenceViewer/DifferenceHighlightMode2.cs26
-rw-r--r--src/Text/Def/TextUI/DifferenceViewer/DifferenceViewMode.cs28
-rw-r--r--src/Text/Def/TextUI/DifferenceViewer/DifferenceViewType.cs23
-rw-r--r--src/Text/Def/TextUI/DifferenceViewer/DifferenceViewerOptions.cs46
-rw-r--r--src/Text/Def/TextUI/DifferenceViewer/DifferenceViewerRoles.cs28
-rw-r--r--src/Text/Def/TextUI/DifferenceViewer/IDifferenceViewer.cs129
-rw-r--r--src/Text/Def/TextUI/Editor/CaretPosition.cs160
-rw-r--r--src/Text/Def/TextUI/Editor/CaretPositionChangedEventArgs.cs76
-rw-r--r--src/Text/Def/TextUI/Editor/IScrollMap.cs65
-rw-r--r--src/Text/Def/TextUI/Editor/IScrollMapFactoryService.cs34
-rw-r--r--src/Text/Def/TextUI/Editor/ISmartIndent.cs20
-rw-r--r--src/Text/Def/TextUI/Editor/ISmartIndentProvider.cs31
-rw-r--r--src/Text/Def/TextUI/Editor/ISmartIndentationService.cs27
-rw-r--r--src/Text/Def/TextUI/Editor/ITextCaret.cs287
-rw-r--r--src/Text/Def/TextUI/Editor/ITextSelection.cs158
-rw-r--r--src/Text/Def/TextUI/Editor/ITextView.cs467
-rw-r--r--src/Text/Def/TextUI/Editor/ITextViewLineCollection.cs174
-rw-r--r--src/Text/Def/TextUI/Editor/ITextViewMargin.cs40
-rw-r--r--src/Text/Def/TextUI/Editor/ITextViewModel.cs84
-rw-r--r--src/Text/Def/TextUI/Editor/ITextViewModelProvider.cs25
-rw-r--r--src/Text/Def/TextUI/Editor/ITextViewRoleSet.cs49
-rw-r--r--src/Text/Def/TextUI/Editor/IVerticalFractionMap.cs53
-rw-r--r--src/Text/Def/TextUI/Editor/IVerticalScrollBar.cs77
-rw-r--r--src/Text/Def/TextUI/Editor/IViewScroller.cs176
-rw-r--r--src/Text/Def/TextUI/Editor/MarginContainerAttribute.cs46
-rw-r--r--src/Text/Def/TextUI/Editor/MouseHoverAttribute.cs40
-rw-r--r--src/Text/Def/TextUI/Editor/MouseHoverEventArgs.cs78
-rw-r--r--src/Text/Def/TextUI/Editor/PredefinedMarginNames.cs137
-rw-r--r--src/Text/Def/TextUI/Editor/PredefinedTextViewRoles.cs85
-rw-r--r--src/Text/Def/TextUI/Editor/ReplacesAttribute.cs50
-rw-r--r--src/Text/Def/TextUI/Editor/ScrollDirection.cs21
-rw-r--r--src/Text/Def/TextUI/Editor/TextSelectionMode.cs21
-rw-r--r--src/Text/Def/TextUI/Editor/TextViewCreatedEventArgs.cs31
-rw-r--r--src/Text/Def/TextUI/Editor/TextViewLayoutChangedEventArgs.cs150
-rw-r--r--src/Text/Def/TextUI/Editor/TextViewRoleAttribute.cs35
-rw-r--r--src/Text/Def/TextUI/Editor/ViewRelativePosition.cs20
-rw-r--r--src/Text/Def/TextUI/Editor/ViewState.cs86
-rw-r--r--src/Text/Def/TextUI/Editor/WordWrapStyles.cs32
-rw-r--r--src/Text/Def/TextUI/Editor/ZoomConstants.cs32
-rw-r--r--src/Text/Def/TextUI/EditorOptions/ViewOptionDefinition.cs25
-rw-r--r--src/Text/Def/TextUI/EditorOptions/ViewOptions.cs898
-rw-r--r--src/Text/Def/TextUI/Find/IIncrementalSearch.cs127
-rw-r--r--src/Text/Def/TextUI/Find/IIncrementalSearchFactoryService.cs35
-rw-r--r--src/Text/Def/TextUI/Find/IncrementalSearchDirection.cs22
-rw-r--r--src/Text/Def/TextUI/Find/IncrementalSearchResult.cs110
-rw-r--r--src/Text/Def/TextUI/Formatting/IAdornmentElement.cs63
-rw-r--r--src/Text/Def/TextUI/Formatting/ISequenceElement.cs21
-rw-r--r--src/Text/Def/TextUI/Formatting/ITextAndAdornmentCollection.cs18
-rw-r--r--src/Text/Def/TextUI/Formatting/ITextAndAdornmentSequencer.cs50
-rw-r--r--src/Text/Def/TextUI/Formatting/ITextAndAdornmentSequencerFactoryService.cs24
-rw-r--r--src/Text/Def/TextUI/Formatting/ITextViewLine.cs492
-rw-r--r--src/Text/Def/TextUI/Formatting/LineTransform.cs192
-rw-r--r--src/Text/Def/TextUI/Formatting/TextAndAdornmentSequenceChangedEventArgs.cs33
-rw-r--r--src/Text/Def/TextUI/Formatting/TextBounds.cs288
-rw-r--r--src/Text/Def/TextUI/Formatting/TextViewLineChange.cs27
-rw-r--r--src/Text/Def/TextUI/Formatting/VisibilityState.cs38
-rw-r--r--src/Text/Def/TextUI/FxCopSuppressions.cs99
-rw-r--r--src/Text/Def/TextUI/Operations/IEditorOperations.cs930
-rw-r--r--src/Text/Def/TextUI/Operations/IEditorOperations2.cs33
-rw-r--r--src/Text/Def/TextUI/Operations/IEditorOperations3.cs38
-rw-r--r--src/Text/Def/TextUI/Operations/IEditorOperationsFactoryService.cs25
-rw-r--r--src/Text/Def/TextUI/Operations/Microsoft.VisualStudio.Text.Operations.Overview.mht3843
-rw-r--r--src/Text/Def/TextUI/Outlining/ICollapsible.cs55
-rw-r--r--src/Text/Def/TextUI/Outlining/IOutliningManager.cs154
-rw-r--r--src/Text/Def/TextUI/Outlining/IOutliningManagerService.cs31
-rw-r--r--src/Text/Def/TextUI/Outlining/OutliningEnabledEventArgs.cs31
-rw-r--r--src/Text/Def/TextUI/Outlining/RegionsChangedEventArgs.cs32
-rw-r--r--src/Text/Def/TextUI/Outlining/RegionsCollapsedEventArgs.cs32
-rw-r--r--src/Text/Def/TextUI/Outlining/RegionsExpandedEventArgs.cs47
-rw-r--r--src/Text/Def/TextUI/Strings.Designer.cs81
-rw-r--r--src/Text/Def/TextUI/Strings.resx126
-rw-r--r--src/Text/Def/TextUI/Tagging/IViewTagAggregatorFactoryService.cs36
-rw-r--r--src/Text/Def/TextUI/Tagging/IViewTaggerProvider.cs26
-rw-r--r--src/Text/Def/TextUI/Tags/BlockTag.cs98
-rw-r--r--src/Text/Def/TextUI/Tags/ErrorTag.cs53
-rw-r--r--src/Text/Def/TextUI/Tags/IBlockTag.cs84
-rw-r--r--src/Text/Def/TextUI/Tags/IErrorTag.cs27
-rw-r--r--src/Text/Def/TextUI/Tags/IOutliningRegionTag.cs37
-rw-r--r--src/Text/Def/TextUI/Tags/IOverviewMarkTag.cs16
-rw-r--r--src/Text/Def/TextUI/Tags/ITextMarkerTag.cs15
-rw-r--r--src/Text/Def/TextUI/Tags/OutliningRegionTag.cs65
-rw-r--r--src/Text/Def/TextUI/Tags/OverviewMarkTag.cs30
-rw-r--r--src/Text/Def/TextUI/Tags/SpaceNegotiatingAdornmentTag.cs84
-rw-r--r--src/Text/Def/TextUI/Tags/TextMarkerTag.cs28
-rw-r--r--src/Text/Def/TextUI/TextUI.csproj176
284 files changed, 36453 insertions, 0 deletions
diff --git a/src/Text/Def/Platform.Settings.targets b/src/Text/Def/Platform.Settings.targets
new file mode 100644
index 0000000..0de95c9
--- /dev/null
+++ b/src/Text/Def/Platform.Settings.targets
@@ -0,0 +1,7 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <PlatformRelativePath>$(PlatformRelativePath)\..</PlatformRelativePath>
+ </PropertyGroup>
+
+ <Import Project="..\Platform.Settings.targets" />
+</Project> \ No newline at end of file
diff --git a/src/Text/Def/TextData/AssemblyInfo.cs b/src/Text/Def/TextData/AssemblyInfo.cs
new file mode 100644
index 0000000..765736d
--- /dev/null
+++ b/src/Text/Def/TextData/AssemblyInfo.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+using System.Security.Permissions;
+
+//
+// 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: ComponentGuarantees(ComponentGuaranteesOptions.Stable)]
+
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+#pragma warning disable 618
+[assembly: SecurityPermission (SecurityAction.RequestMinimum, Flags = SecurityPermissionFlag.Execution)]
+#pragma warning restore 618
+[assembly: ReliabilityContract(Consistency.MayCorruptProcess, Cer.MayFail)]
+
+[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Text.Implementation, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
+[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Platform.Editor, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
+[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Platform.VSEditor, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
+[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Implementation, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
+[assembly: InternalsVisibleTo("CFEditor, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293")]
+
diff --git a/src/Text/Def/TextData/Diagrams/BufferMarkers.cd b/src/Text/Def/TextData/Diagrams/BufferMarkers.cd
new file mode 100644
index 0000000..0c1ef8b
--- /dev/null
+++ b/src/Text/Def/TextData/Diagrams/BufferMarkers.cd
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+ <Interface Name="Microsoft.VisualStudio.Text.ITrackingPoint">
+ <Position X="3.5" Y="2.25" Width="2.25" />
+ <TypeIdentifier>
+ <HashCode>AAAAIAAABCAAAAAAKAAAAAAABAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Model\ITrackingPoint.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="TextBuffer" />
+ <Property Name="TrackingMode" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITrackingSpan">
+ <Position X="6.75" Y="2.25" Width="2" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAABAAAAAAIIIAAAAAABAAAAAAAAAAAQAAAAAg=</HashCode>
+ <FileName>Model\ITrackingSpan.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="TextBuffer" />
+ <Property Name="TrackingMode" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextBuffer" Collapsed="true">
+ <Position X="5.5" Y="1" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>AAAABEAQAAABAAAABAAAAAgAAAGAAAAAAAAQAAQAACA=</HashCode>
+ <FileName>Model\ITextBuffer.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Enum Name="Microsoft.VisualStudio.Text.PointTrackingMode">
+ <Position X="3.5" Y="4.75" Width="2.25" />
+ <TypeIdentifier>
+ <HashCode>AIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAA=</HashCode>
+ <FileName>Model\PointTrackingMode.cs</FileName>
+ </TypeIdentifier>
+ </Enum>
+ <Enum Name="Microsoft.VisualStudio.Text.SpanTrackingMode">
+ <Position X="6.75" Y="4.75" Width="2" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAgAAgAAAAAAAAAgAAAAAAAAAAAAIAAAAAAAAAA=</HashCode>
+ <FileName>Model\SpanTrackingMode.cs</FileName>
+ </TypeIdentifier>
+ </Enum>
+ <Font Name="Segoe UI" Size="9" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/Text/Def/TextData/Diagrams/Projection.cd b/src/Text/Def/TextData/Diagrams/Projection.cd
new file mode 100644
index 0000000..261bd76
--- /dev/null
+++ b/src/Text/Def/TextData/Diagrams/Projection.cd
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+ <Interface Name="Microsoft.VisualStudio.Text.ITextBuffer" Collapsed="true">
+ <Position X="1.25" Y="0.75" Width="2.25" />
+ <Members>
+ <Method Name="Delete" Hidden="true" />
+ <Method Name="Insert" Hidden="true" />
+ <Method Name="Replace" Hidden="true" />
+ </Members>
+ <AssociationLine Name="CurrentSnapshot" Type="Microsoft.VisualStudio.Text.ITextSnapshot" FixedFromPoint="true">
+ <Path>
+ <Point X="3.5" Y="1.188" />
+ <Point X="5.25" Y="1.188" />
+ </Path>
+ </AssociationLine>
+ <TypeIdentifier>
+ <HashCode>IAAABEAQAQABEAAABAAAABgAAAOAAAAAEAAQAAQCACA=</HashCode>
+ <FileName>Model\ITextBuffer.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="CurrentSnapshot" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Projection.IProjectionBuffer">
+ <Position X="2.5" Y="5" Width="2.25" />
+ <TypeIdentifier>
+ <HashCode>AAAAAgAAAAAAAAAAAAAgAAAAAIAQBAAAAAAQAAAAAAA=</HashCode>
+ <FileName>Model\Projection\IProjectionBuffer.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Projection.IProjectionSnapshot">
+ <Position X="5.25" Y="2" Width="3" />
+ <AssociationLine Name="TextBuffer" Type="Microsoft.VisualStudio.Text.Projection.IProjectionBufferBase" FixedFromPoint="true">
+ <Path>
+ <Point X="5.25" Y="2.625" />
+ <Point X="3.5" Y="2.625" />
+ </Path>
+ </AssociationLine>
+ <AssociationLine Name="SourceSnapshots" Type="Microsoft.VisualStudio.Text.ITextSnapshot" FixedFromPoint="true" FixedToPoint="true">
+ <Path>
+ <Point X="8.25" Y="2.521" />
+ <Point X="8.625" Y="2.521" />
+ <Point X="8.625" Y="1.062" />
+ <Point X="8.25" Y="1.062" />
+ </Path>
+ </AssociationLine>
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAgIAAQQgAIAAAQAAAAAAgAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Model\Projection\IProjectionSnapshot.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="TextBuffer" />
+ </ShowAsAssociation>
+ <ShowAsCollectionAssociation>
+ <Property Name="SourceSnapshots" />
+ </ShowAsCollectionAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextSnapshot" Collapsed="true">
+ <Position X="5.25" Y="0.75" Width="3" />
+ <AssociationLine Name="TextBuffer" Type="Microsoft.VisualStudio.Text.ITextBuffer" FixedFromPoint="true">
+ <Path>
+ <Point X="5.25" Y="0.875" />
+ <Point X="3.5" Y="0.875" />
+ </Path>
+ </AssociationLine>
+ <TypeIdentifier>
+ <HashCode>IACAAIAAgAAAAAAYKAAIAARAAAQAAAQCAAAAAAEAKAA=</HashCode>
+ <FileName>Model\ITextSnapshot.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="TextBuffer" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Projection.IProjectionBufferBase">
+ <Position X="1.25" Y="2" Width="2.25" />
+ <AssociationLine Name="CurrentSnapshot" Type="Microsoft.VisualStudio.Text.Projection.IProjectionSnapshot" FixedFromPoint="true">
+ <Path>
+ <Point X="3.5" Y="3.5" />
+ <Point X="5.25" Y="3.5" />
+ </Path>
+ </AssociationLine>
+ <AssociationLine Name="SourceBuffers" Type="Microsoft.VisualStudio.Text.ITextBuffer" FixedFromPoint="true">
+ <Path>
+ <Point X="3.062" Y="2" />
+ <Point X="3.062" Y="1.441" />
+ </Path>
+ <MemberNameLabel ManuallyPlaced="true">
+ <Position X="-1.057" Y="0.112" />
+ </MemberNameLabel>
+ </AssociationLine>
+ <TypeIdentifier>
+ <HashCode>AAAABEAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAACA=</HashCode>
+ <FileName>Model\Projection\IProjectionBufferBase.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="CurrentSnapshot" />
+ </ShowAsAssociation>
+ <ShowAsCollectionAssociation>
+ <Property Name="SourceBuffers" />
+ </ShowAsCollectionAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Projection.IElisionBuffer">
+ <Position X="0.5" Y="5" Width="1.75" />
+ <TypeIdentifier>
+ <HashCode>AAAABAAAAAAAAAAAAAAAAAgBAAAQEAAAAAAAAgBAAAA=</HashCode>
+ <FileName>Model\Projection\IElisionBuffer.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="SourceBuffer" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Projection.IElisionSnapshot">
+ <Position X="5.25" Y="5.25" Width="3" />
+ <AssociationLine Name="SourceSnapshot" Type="Microsoft.VisualStudio.Text.ITextSnapshot" ManuallyRouted="true">
+ <Path>
+ <Point X="8.25" Y="6.092" />
+ <Point X="8.802" Y="6.092" />
+ <Point X="8.802" Y="0.875" />
+ <Point X="8.25" Y="0.875" />
+ </Path>
+ </AssociationLine>
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAQAAIAAAAAAAAAAAAAAAAAAQAAAAAAA=</HashCode>
+ <FileName>Model\Projection\IElisionSnapshot.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="SourceSnapshot" />
+ </ShowAsAssociation>
+ </Interface>
+ <Font Name="Segoe UI" Size="9" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/Text/Def/TextData/Diagrams/ReadOnlyRegions.cd b/src/Text/Def/TextData/Diagrams/ReadOnlyRegions.cd
new file mode 100644
index 0000000..1de57b4
--- /dev/null
+++ b/src/Text/Def/TextData/Diagrams/ReadOnlyRegions.cd
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+ <Class Name="Microsoft.VisualStudio.Text.ReadOnlyRegionsChangedEventArgs">
+ <Position X="3.5" Y="3.25" Width="2.75" />
+ <Members>
+ <Field Name="newlyReadonlyRegions" Hidden="true" />
+ <Field Name="newlyWritableRegions" Hidden="true" />
+ <Method Name="ReadOnlyRegionsChangedEventArgs" Hidden="true" />
+ </Members>
+ <Compartments>
+ <Compartment Name="Fields" Collapsed="true" />
+ </Compartments>
+ <AssociationLine Name="NewlyReadonlyRegions" Type="Microsoft.VisualStudio.Text.NormalizedSpanCollection" FixedFromPoint="true">
+ <Path>
+ <Point X="4.062" Y="4.247" />
+ <Point X="4.062" Y="5.5" />
+ </Path>
+ </AssociationLine>
+ <AssociationLine Name="NewlyWritableRegions" Type="Microsoft.VisualStudio.Text.NormalizedSpanCollection" FixedFromPoint="true">
+ <Path>
+ <Point X="5.875" Y="4.247" />
+ <Point X="5.875" Y="5.5" />
+ </Path>
+ </AssociationLine>
+ <TypeIdentifier>
+ <HashCode>AAAAAAAACAAAAAAAAAAAAAAAAAAAAAAEAAAABAAgAAA=</HashCode>
+ <FileName>Model\ReadOnlyRegionsChangedEventArgs.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="NewlyReadonlyRegions" />
+ <Property Name="NewlyWritableRegions" />
+ </ShowAsAssociation>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.NormalizedSpanCollection" Collapsed="true">
+ <Position X="3.5" Y="5.5" Width="2.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAQAAAkgAAAAABAQAAQAIAAAAAAAwAAEiA=</HashCode>
+ <FileName>Model\NormalizedSpanCollection.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Interface Name="Microsoft.VisualStudio.Text.IReadOnlyRegion">
+ <Position X="3.75" Y="1" Width="2" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAIAAAA=</HashCode>
+ <FileName>Model\IReadOnlyRegion.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="EdgeInsertionMode" />
+ <Property Name="Span" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextSpan">
+ <Position X="7.25" Y="1" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAABAAAAAAIIIAAAAAAAAAAAAAAAAAAQAAAAAg=</HashCode>
+ <FileName>Model\ITextSpan.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="TextBuffer" />
+ <Property Name="TrackingMode" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextBuffer" Collapsed="true">
+ <Position X="10.5" Y="1" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>AAAABEAQAAABAAAABAAAAAgAAAGAAAAAAAAQAAQAACA=</HashCode>
+ <FileName>Model\ITextBuffer.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.IReadOnlyRegionEdit">
+ <Position X="7.25" Y="3.5" Width="2.5" />
+ <TypeIdentifier>
+ <HashCode>AAAAABAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Model\IReadOnlyRegionEdit.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Enum Name="Microsoft.VisualStudio.Text.EdgeInsertionMode">
+ <Position X="0.5" Y="1" Width="1.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAEAAAAAAAA=</HashCode>
+ <FileName>Model\EdgeInsertionMode.cs</FileName>
+ </TypeIdentifier>
+ </Enum>
+ <Enum Name="Microsoft.VisualStudio.Text.SpanTrackingMode">
+ <Position X="10.5" Y="2" Width="1.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAgAAgAAAAAAAAAgAAAAAAAAAAAAIAAAAAAAAAA=</HashCode>
+ <FileName>Model\SpanTrackingMode.cs</FileName>
+ </TypeIdentifier>
+ </Enum>
+ <Font Name="Segoe UI" Size="9" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/Text/Def/TextData/Diagrams/SnapshotMarkers.cd b/src/Text/Def/TextData/Diagrams/SnapshotMarkers.cd
new file mode 100644
index 0000000..2595a22
--- /dev/null
+++ b/src/Text/Def/TextData/Diagrams/SnapshotMarkers.cd
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+ <Struct Name="Microsoft.VisualStudio.Text.SnapshotPoint">
+ <Position X="3.25" Y="3.5" Width="1.75" />
+ <Members>
+ <Method Name="Equals" Hidden="true" />
+ <Method Name="GetHashCode" Hidden="true" />
+ <Method Name="operator !=" Hidden="true" />
+ <Method Name="operator ==" Hidden="true" />
+ <Field Name="position" Hidden="true" />
+ <Field Name="snapshot" Hidden="true" />
+ <Method Name="SnapshotPoint" Hidden="true" />
+ <Method Name="ToInt32" Hidden="true" />
+ </Members>
+ <TypeIdentifier>
+ <HashCode>AAIAACAAAAggAAQkwAGCIgAAQAAAAIAAAABAKAAAAiE=</HashCode>
+ <FileName>Model\SnapshotPoint.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="Snapshot" />
+ </ShowAsAssociation>
+ <Lollipop Position="0.2" />
+ </Struct>
+ <Struct Name="Microsoft.VisualStudio.Text.SnapshotSpan">
+ <Position X="6.75" Y="3.5" Width="2.25" />
+ <Members>
+ <Method Name="Equals" Hidden="true" />
+ <Method Name="GetHashCode" Hidden="true" />
+ <Method Name="operator !=" Hidden="true" />
+ <Method Name="operator ==" Hidden="true" />
+ <Method Name="SnapshotSpan" Hidden="true" />
+ <Method Name="ToString" Hidden="true" />
+ </Members>
+ <TypeIdentifier>
+ <HashCode>AAJAAAAAADAgAAAsgEAAAABAAAAQAoAAAAAACgIQAiA=</HashCode>
+ <FileName>Model\SnapshotSpan.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="Snapshot" />
+ </ShowAsAssociation>
+ </Struct>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextSnapshot" Collapsed="true">
+ <Position X="5" Y="2.25" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>IACAAIAAgAAAAAAYKAAIAARAAAQAAAQCAAAAAAEAKAA=</HashCode>
+ <FileName>Model\ITextSnapshot.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Font Name="Segoe UI" Size="9" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/Text/Def/TextData/Diagrams/Text.cd b/src/Text/Def/TextData/Diagrams/Text.cd
new file mode 100644
index 0000000..4d197ca
--- /dev/null
+++ b/src/Text/Def/TextData/Diagrams/Text.cd
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+ <Class Name="Microsoft.VisualStudio.Text.TextSnapshotChangedEventArgs">
+ <Position X="7" Y="5" Width="2.25" />
+ <Members>
+ <Field Name="after" Hidden="true" />
+ <Field Name="before" Hidden="true" />
+ <Field Name="editTag" Hidden="true" />
+ </Members>
+ <AssociationLine Name="Before" Type="Microsoft.VisualStudio.Text.ITextSnapshot" FixedFromPoint="true">
+ <Path>
+ <Point X="7" Y="5.302" />
+ <Point X="5.75" Y="5.302" />
+ </Path>
+ </AssociationLine>
+ <AssociationLine Name="After" Type="Microsoft.VisualStudio.Text.ITextSnapshot" ManuallyRouted="true" FixedFromPoint="true" FixedToPoint="true">
+ <Path>
+ <Point X="7" Y="5.642" />
+ <Point X="6.596" Y="5.642" />
+ <Point X="6.596" Y="6.438" />
+ <Point X="5.75" Y="6.438" />
+ </Path>
+ </AssociationLine>
+ <AssociationLine Name="AfterVersion" Type="Microsoft.VisualStudio.Text.ITextVersion" FixedFromPoint="true">
+ <Path>
+ <Point X="7.688" Y="5" />
+ <Point X="7.688" Y="3.4" />
+ </Path>
+ </AssociationLine>
+ <AssociationLine Name="BeforeVersion" Type="Microsoft.VisualStudio.Text.ITextVersion" FixedFromPoint="true">
+ <Path>
+ <Point X="8.938" Y="5" />
+ <Point X="8.938" Y="3.4" />
+ </Path>
+ </AssociationLine>
+ <TypeIdentifier>
+ <HashCode>BABAAAAAAAAAAAAAAAIAAAAAAAAAAAAQAAAAEgQAQAA=</HashCode>
+ <FileName>Model\TextSnapshotChangedEventArgs.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="Before" />
+ <Property Name="After" />
+ <Property Name="AfterVersion" />
+ <Property Name="BeforeVersion" />
+ </ShowAsAssociation>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.TextContentChangedEventArgs">
+ <Position X="7" Y="7.75" Width="2.25" />
+ <Members>
+ <Field Name="options" Hidden="true" />
+ <Method Name="TextContentChangedEventArgs" Hidden="true" />
+ </Members>
+ <TypeIdentifier>
+ <HashCode>AEAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAABAAAA=</HashCode>
+ <FileName>Model\TextContentChangedEventArgs.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="Changes" />
+ </ShowAsAssociation>
+ </Class>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextEdit">
+ <Position X="0.75" Y="2.75" Width="1.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAEAAABAAAAAAAAAEAAAAAAEAAAAAAAAAAAAAACA=</HashCode>
+ <FileName>Model\ITextEdit.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextSnapshotLine">
+ <Position X="0.5" Y="5.5" Width="2" />
+ <TypeIdentifier>
+ <HashCode>EAMAAAAAACAiAAAIIAAIEIBAAAAAAAAAAAAAAAAABAA=</HashCode>
+ <FileName>Model\ITextSnapshotLine.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextBuffer">
+ <Position X="3.5" Y="0.5" Width="2.25" />
+ <Members>
+ <Method Name="Delete" Hidden="true" />
+ <Method Name="Insert" Hidden="true" />
+ <Method Name="Replace" Hidden="true" />
+ </Members>
+ <AssociationLine Name="CurrentSnapshot" Type="Microsoft.VisualStudio.Text.ITextSnapshot">
+ <MemberNameLabel ManuallyPlaced="true">
+ <Position X="0.06" Y="0.11" />
+ </MemberNameLabel>
+ </AssociationLine>
+ <TypeIdentifier>
+ <HashCode>IAAABEAQAQABEAAABAAAABgAAAOAAAAAEAAQAAQCACA=</HashCode>
+ <FileName>Model\ITextBuffer.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="CurrentSnapshot" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextSnapshot">
+ <Position X="3.5" Y="5" Width="2.25" />
+ <TypeIdentifier>
+ <HashCode>IACAAIAAgAAAAAAYKAAIAARAAAQAAAQCAAAAAAEAKAA=</HashCode>
+ <FileName>Model\ITextSnapshot.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="TextBuffer" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.INormalizedTextChangeCollection" Collapsed="true">
+ <Position X="10.25" Y="6.25" Width="2.5" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAA=</HashCode>
+ <FileName>Model\INormalizedTextChangeCollection.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextChange">
+ <Position X="11.25" Y="2.75" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>QAAAAEAIAAAAUBAAgAAARAAAAAEQAAAAAAAAAEAAAAA=</HashCode>
+ <FileName>Model\ITextChange.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextBufferEdit">
+ <Position X="0.75" Y="0.5" Width="1.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAQBAgAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Model\ITextBufferEdit.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="Snapshot" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextVersion">
+ <Position X="7.25" Y="0.75" Width="2.5" />
+ <TypeIdentifier>
+ <HashCode>AgCAAAAAAAAAAEgAMAAAAABAAAQAAAAAAAAAAAACAAA=</HashCode>
+ <FileName>Model\ITextVersion.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Font Name="Tahoma" Size="8.25" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/Text/Def/TextData/Diagrams/TextEdit.cd b/src/Text/Def/TextData/Diagrams/TextEdit.cd
new file mode 100644
index 0000000..792d70c
--- /dev/null
+++ b/src/Text/Def/TextData/Diagrams/TextEdit.cd
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+ <Interface Name="Microsoft.VisualStudio.Text.ITextBufferEdit">
+ <Position X="6" Y="0.75" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAQBAgAAAQgAAIAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Model\ITextBufferEdit.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.IReadOnlyRegionEdit">
+ <Position X="7" Y="3.75" Width="2" />
+ <TypeIdentifier>
+ <HashCode>AAAAABAAAAEAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Model\IReadOnlyRegionEdit.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextEdit">
+ <Position X="4.5" Y="3.75" Width="2" />
+ <TypeIdentifier>
+ <HashCode>AAAAAEAAABAAAAAAAAAEAAAAAAEAAAAAAAAAAAAAACA=</HashCode>
+ <FileName>Model\ITextEdit.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Font Name="Segoe UI" Size="9" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/Text/Def/TextData/Diagrams/TextEvents.cd b/src/Text/Def/TextData/Diagrams/TextEvents.cd
new file mode 100644
index 0000000..74bcb98
--- /dev/null
+++ b/src/Text/Def/TextData/Diagrams/TextEvents.cd
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+ <Class Name="Microsoft.VisualStudio.Text.TextSnapshotChangedEventArgs">
+ <Position X="6" Y="0.5" Width="2.5" />
+ <Members>
+ <Field Name="after" Hidden="true" />
+ <Field Name="before" Hidden="true" />
+ <Method Name="TextSnapshotChangedEventArgs" Hidden="true" />
+ </Members>
+ <TypeIdentifier>
+ <HashCode>BABAAAAAAAAAAAAAAAIAAAAAAAAAAAAQAAAAEgQAQAA=</HashCode>
+ <FileName>Model\TextSnapshotChangedEventArgs.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.TextContentChangedEventArgs">
+ <Position X="3.75" Y="3.75" Width="2.5" />
+ <Members>
+ <Field Name="options" Hidden="true" />
+ <Method Name="TextContentChangedEventArgs" Hidden="true" />
+ </Members>
+ <TypeIdentifier>
+ <HashCode>AEAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAABAAAA=</HashCode>
+ <FileName>Model\TextContentChangedEventArgs.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.Projection.ProjectionSourceSpansChangedEventArgs">
+ <Position X="5" Y="6" Width="3" />
+ <Members>
+ <Field Name="deletedSpans" Hidden="true" />
+ <Field Name="insertedSpans" Hidden="true" />
+ <Method Name="ProjectionSourceSpansChangedEventArgs" Hidden="true" />
+ <Field Name="spanPosition" Hidden="true" />
+ </Members>
+ <TypeIdentifier>
+ <HashCode>IIAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAEACQARAA=</HashCode>
+ <FileName>Model\Projection\ProjectionSourceSpansChangedEventArgs.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.Projection.ProjectionSourceBuffersChangedEventArgs">
+ <Position X="5" Y="8.75" Width="3" />
+ <Members>
+ <Field Name="addedBuffers" Hidden="true" />
+ <Method Name="ProjectionSourceBuffersChangedEventArgs" Hidden="true" />
+ <Field Name="removedBuffers" Hidden="true" />
+ </Members>
+ <TypeIdentifier>
+ <HashCode>AAAAAAAgAAAAIAAAAAAAAAAAAAAAAAAEAAAABAAAAAA=</HashCode>
+ <FileName>Model\Projection\ProjectionSourceBuffersChangedEventArgs.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.ReadOnlyRegionsChangedEventArgs">
+ <Position X="8.25" Y="3.75" Width="2.75" />
+ <Members>
+ <Field Name="newlyReadonlyRegions" Hidden="true" />
+ <Field Name="newlyWritableRegions" Hidden="true" />
+ <Method Name="ReadOnlyRegionsChangedEventArgs" Hidden="true" />
+ </Members>
+ <TypeIdentifier>
+ <HashCode>AAAAAAAACAAAAAAAAAAAAAAAAAAAAAAEAAAABAAgAAA=</HashCode>
+ <FileName>Model\ReadOnlyRegionsChangedEventArgs.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.Projection.ElisionSourceSpansChangedEventArgs">
+ <Position X="1.75" Y="6" Width="2.75" />
+ <Members>
+ <Field Name="elidedSpans" Hidden="true" />
+ <Field Name="expandedSpans" Hidden="true" />
+ </Members>
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAgAAQAYAA=</HashCode>
+ <FileName>Model\Projection\ElisionSourceSpansChangedEventArgs.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Font Name="Segoe UI" Size="9" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/Text/Def/TextData/Differencing/ContinueProcessingPredicate.cs b/src/Text/Def/TextData/Differencing/ContinueProcessingPredicate.cs
new file mode 100644
index 0000000..d61f25f
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/ContinueProcessingPredicate.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// A predicate used by <see cref="IDifferenceService"/> that allows callers to stop differencing prematurely.
+ /// </summary>
+ /// <typeparam name="T">The type of sequences being differenced.</typeparam>
+ /// <param name="leftIndex">The current index in the left sequence being differenced.</param>
+ /// <param name="leftSequence">The left sequence being differenced.</param>
+ /// <param name="longestMatchSoFar">The length of the longest match so far.</param>
+ /// <returns><c>true</c> if the algorithm should continue processing, <c>false</c> to stop the algorithm.</returns>
+ /// <remarks>
+ /// When <c>false</c> is returned, the algorithm stops searching for matches and uses the information it has computed so
+ /// far to create the <see cref="IDifferenceCollection&lt;T&gt;"/> that will be returned.
+ /// </remarks>
+ public delegate bool ContinueProcessingPredicate<T>(int leftIndex, IList<T> leftSequence, int longestMatchSoFar);
+}
diff --git a/src/Text/Def/TextData/Differencing/Deprecated/DetermineLocalityCallback.cs b/src/Text/Def/TextData/Differencing/Deprecated/DetermineLocalityCallback.cs
new file mode 100644
index 0000000..b536baa
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/Deprecated/DetermineLocalityCallback.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// A delegate for determining the locality for a given difference type and left/right strings.
+ /// </summary>
+ /// <param name="differenceType">The type of difference to get the locality for. This is
+ /// guaranteed to be only a single type.</param>
+ /// <param name="leftStrings">The left text, decomposed into a list of strings.</param>
+ /// <param name="rightStrings">The right text, decomposed into a list of strings.</param>
+ /// <returns>The locality, if desired, or <c>null</c>, to fallback to the default
+ /// locality.</returns>
+ /// <remarks>
+ /// <para>This callback and methods that use it are now deprectated. Neither the default implementation of <see cref="ITextDifferencingService"/> or
+ /// extensions that implement that interface are required to use this callback.</para>
+ /// </remarks>
+ [Obsolete("Methods that use this callback are now deprecated, and instances of this callback will not be used.")]
+ public delegate int? DetermineLocalityCallback(StringDifferenceTypes differenceType, IList<string> leftStrings, IList<string> rightStrings);
+}
diff --git a/src/Text/Def/TextData/Differencing/Deprecated/IHierarchicalStringDifferenceService.cs b/src/Text/Def/TextData/Differencing/Deprecated/IHierarchicalStringDifferenceService.cs
new file mode 100644
index 0000000..6fa68a4
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/Deprecated/IHierarchicalStringDifferenceService.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// This service has several shortcut methods that compute
+ /// differences over strings, snapshots, and spans.
+ /// Differences are computed according to the specified <see cref="StringDifferenceTypes"/>,
+ /// starting with the most general type
+ /// (line is more general than word, and word is more general than character).
+ /// </summary>
+ /// <example>
+ /// Given string A:
+ /// ---
+ /// This is a
+ /// line!
+ /// ---
+ /// And string B:
+ /// ---
+ /// This is but a
+ /// line!
+ /// ---
+ ///
+ /// The returned difference collection contains one line difference, which maps to line 1 of each string.
+ /// This difference contains one
+ /// word difference, which is the addition of the words "but" and " ".
+ /// </example>
+ /// <remarks>
+ /// <para>
+ /// This type is deprecated. Use <see cref="ITextDifferencingSelectorService"/> instead, which allows you
+ /// to retrieve an <see cref="ITextDifferencingService"/> for a specific content type and provides a superset
+ /// of the methods available on this interface.
+ /// </para>
+ /// <para>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IHierarchicalStringDifferenceService diffService = null;
+ /// </para>
+ /// </remarks>
+ [Obsolete("This interface has been deprecated in favor of the ITextDifferencingSelectorService MEF service.")]
+ public interface IHierarchicalStringDifferenceService
+ {
+ /// <summary>
+ /// Computes the differences between two strings, using the given difference options.
+ /// </summary>
+ /// <param name="left">The left string. In most cases this is the the "old" string.</param>
+ /// <param name="right">The right string. In most cases this is the "new" string.</param>
+ /// <param name="differenceOptions">The options to use in differencing</param>
+ /// <returns>A hierarchical collection of differences.</returns>
+ IHierarchicalDifferenceCollection DiffStrings(string left,
+ string right,
+ StringDifferenceOptions differenceOptions);
+
+ /// <summary>
+ /// Computes the differences between two snapshot spans, using the given difference options.
+ /// </summary>
+ /// <param name="left">The left snapshot. In most cases this is the the "old" snapshot.</param>
+ /// <param name="right">The right snapshot. In most cases this is the "new" snapshot.</param>
+ /// <param name="differenceOptions">The options to use.</param>
+ /// <returns>A hierarchical collection of differences.</returns>
+ IHierarchicalDifferenceCollection DiffSnapshotSpans(SnapshotSpan left,
+ SnapshotSpan right,
+ StringDifferenceOptions differenceOptions);
+ }
+}
diff --git a/src/Text/Def/TextData/Differencing/Difference.cs b/src/Text/Def/TextData/Differencing/Difference.cs
new file mode 100644
index 0000000..ab394d5
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/Difference.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Globalization;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// Represents a single difference in the set of differences of two
+ /// lists of elements.
+ /// </summary>
+ /// <remarks>Each difference consists of a left span and a right span, either
+ /// of which may have zero length (that is, the operation may be an add operation or a delete operation).
+ /// The text before and after the difference matches.
+ /// In general, differencess are non-null. However, when the difference
+ /// appears at the beginning of the lists of differences, the "before" is null, and when the difference appears at
+ /// the end of the lists, the "after" is null.</remarks>
+ public class Difference
+ {
+ private Span left;
+ private Span right;
+ private Match before;
+ private Match after;
+ private DifferenceType type;
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="Difference"/> with the specified left and right spans and before and after matches.
+ /// </summary>
+ /// <param name="left">The left side of the difference (may have zero length).</param>
+ /// <param name="right">The right side of the difference (may have zero length).</param>
+ /// <param name="before">The non-differing element range before this difference.</param>
+ /// <param name="after">The non-differing element range after this difference.</param>
+ public Difference(Span left, Span right, Match before, Match after)
+ {
+ this.left = left;
+ this.right = right;
+ this.before = before;
+ this.after = after;
+
+ if (left.Length == 0)
+ type = DifferenceType.Add;
+ else if (right.Length == 0)
+ type = DifferenceType.Remove;
+ else
+ type = DifferenceType.Change;
+ }
+
+ /// <summary>
+ /// The left side of the difference (may be zero length).
+ /// </summary>
+ public Span Left
+ {
+ get { return left; }
+ }
+
+ /// <summary>
+ /// The right side of the difference (may be zero length).
+ /// </summary>
+ public Span Right
+ {
+ get { return right; }
+ }
+
+ /// <summary>
+ /// The match before this section. It is null at the beginning of
+ /// the sequence.
+ /// </summary>
+ public Match Before
+ {
+ get { return before; }
+ }
+
+ /// <summary>
+ /// The mtch after this difference. It is null at the end of the sequence.
+ /// </summary>
+ public Match After
+ {
+ get { return after; }
+ }
+
+ /// <summary>
+ /// The type of the difference (Add, Remove, or Change).
+ /// </summary>
+ public DifferenceType DifferenceType
+ {
+ get { return type; }
+ }
+
+ /// <summary>
+ /// The string representation of this difference.
+ /// </summary>
+ /// <returns></returns>
+ public override string ToString()
+ {
+ return string.Format(CultureInfo.CurrentCulture.NumberFormat, "(Difference; Type: {0}, Left count: {1}, Right count: {2}",
+ type, left.Length, right.Length);
+ }
+
+ /// <summary>
+ /// Determines whether two Difference objects are the same (have the same difference type and the same before and after matches).
+ /// </summary>
+ /// <param name="obj"></param>
+ /// <returns></returns>
+ public override bool Equals(object obj)
+ {
+ Difference other = obj as Difference;
+ if (other != null)
+ {
+ return object.Equals(type, other.type) &&
+ object.Equals(before, other.before) && object.Equals(after, other.after) &&
+ object.Equals(left, other.left) && object.Equals(right, other.right);
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Serves as a hash code for this type.
+ /// </summary>
+ /// <returns></returns>
+ public override int GetHashCode()
+ {
+ return before.GetHashCode() << 24 ^ after.GetHashCode() << 16 ^
+ left.GetHashCode() << 8 ^ right.GetHashCode();
+ }
+ }
+}
diff --git a/src/Text/Def/TextData/Differencing/DifferenceType.cs b/src/Text/Def/TextData/Differencing/DifferenceType.cs
new file mode 100644
index 0000000..cdac85f
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/DifferenceType.cs
@@ -0,0 +1,26 @@
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// The types of differences.
+ ///
+ /// </summary>
+ /// <remarks>Differences are read from left to right, so that Add means that only
+ /// the right span has text, Remove means that only the left span has text, and
+ /// Change means that both the left and right spans have text.</remarks>
+ public enum DifferenceType
+ {
+ /// <summary>
+ /// Lines were added, so the text is on the right-hand side
+ /// </summary>
+ Add,
+ /// <summary>
+ /// Lines were removed, so the text is on the left-hand side
+ /// </summary>
+ Remove,
+ /// <summary>
+ /// Lines were changed, so the text is on both sides
+ /// </summary>
+ Change
+ }
+}
+
diff --git a/src/Text/Def/TextData/Differencing/IDifferenceCollection.cs b/src/Text/Def/TextData/Differencing/IDifferenceCollection.cs
new file mode 100644
index 0000000..6b6c41f
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/IDifferenceCollection.cs
@@ -0,0 +1,50 @@
+using Microsoft.VisualStudio.Utilities;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Collections.ObjectModel;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// Represents a collection of <see cref="Difference"/> objects extracted from two lists of same-typed elements,
+ /// given a maximal match sequence generated from a difference algorithm.
+ /// </summary>
+ /// <typeparam name="T">The element type of the compared lists.</typeparam>
+ public interface IDifferenceCollection<T> : IEnumerable<Difference>
+ {
+ /// <summary>
+ /// Gets the original match sequence that was used to create this difference collection.
+ /// </summary>
+ IEnumerable<Tuple<int, int>> MatchSequence
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the left sequence that was used to create this difference collection.
+ /// </summary>
+ IList<T> LeftSequence
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the right sequence that was used to create this difference collection.
+ /// </summary>
+ IList<T> RightSequence
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Returns the difference collection as a list.
+ /// </summary>
+ /// <remarks>Since the difference collection itself implements the IEnumerable interface,
+ /// you can use it to iterate over the differences.</remarks>
+ IList<Difference> Differences
+ {
+ get;
+ }
+ }
+}
diff --git a/src/Text/Def/TextData/Differencing/IDifferenceService.cs b/src/Text/Def/TextData/Differencing/IDifferenceService.cs
new file mode 100644
index 0000000..3dcedfa
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/IDifferenceService.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// Determines the differences between two
+ /// sequences, based on adding or removing elements (but not translating or copying elements).
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IDifferenceService diffService = null;
+ /// </remarks>
+ public interface IDifferenceService
+ {
+ /// <summary>
+ /// Computes the differences between the two sequences.
+ /// </summary>
+ /// <typeparam name="T">The type of the sequences.</typeparam>
+ /// <param name="left">The left sequence. In most cases this is the "old" sequence.</param>
+ /// <param name="right">The right sequence. In most cases this is the "new" sequence.</param>
+ /// <returns>A collection of the differences between the two sequences.</returns>
+ IDifferenceCollection<T> DifferenceSequences<T>(IList<T> left, IList<T> right);
+
+ /// <summary>
+ /// Computes the differences between the two sequences. The supplied predicate will be called on each
+ /// step through the <paramref name="left"/> sequence.
+ /// </summary>
+ /// <typeparam name="T">The type of the sequences.</typeparam>
+ /// <param name="left">The left sequence. In most cases this is the "old" sequence.</param>
+ /// <param name="right">The right sequence. In most cases this is the "new" sequence.</param>
+ /// <param name="continueProcessingPredicate">A predicate that will be called on each step through the <paramref name="left"/> sequence,
+ /// with the option of stopping the algorithm prematurely.</param>
+ /// <returns>A collection of the differences between the two sequences.</returns>
+ IDifferenceCollection<T> DifferenceSequences<T>(IList<T> left, IList<T> right, ContinueProcessingPredicate<T> continueProcessingPredicate);
+ }
+}
diff --git a/src/Text/Def/TextData/Differencing/IHierarchicalDifferenceCollection.cs b/src/Text/Def/TextData/Differencing/IHierarchicalDifferenceCollection.cs
new file mode 100644
index 0000000..22748c7
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/IHierarchicalDifferenceCollection.cs
@@ -0,0 +1,61 @@
+using Microsoft.VisualStudio.Utilities;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Collections.ObjectModel;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// Represents a difference collection in which the left and right
+ /// sequences are <see cref="ITokenizedStringList"/> objects, and each difference may itself contain
+ /// an <see cref="IHierarchicalDifferenceCollection"/>.
+ /// </summary>
+ /// <remarks>You can get this collection by using the <see cref="IHierarchicalStringDifferenceService" />.
+ /// When you request multiple types of string differencing
+ /// (e.g. line and word), the first level of differences will be the lines,
+ /// and each line difference may contain an <see cref="IHierarchicalDifferenceCollection" />
+ /// of word differences. See <see cref="IHierarchicalStringDifferenceService" />
+ /// for more information and examples.</remarks>
+ public interface IHierarchicalDifferenceCollection : IDifferenceCollection<string>
+ {
+ /// <summary>
+ /// Gets the original left tokenized list.
+ /// </summary>
+ /// <remarks>
+ /// This is the same as IDifferenceCollection.LeftSequence, except that
+ /// it is typed as an <see cref="ITokenizedStringList"/>.
+ /// </remarks>
+ ITokenizedStringList LeftDecomposition
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Get the original right tokenized list.
+ /// </summary>
+ /// <remarks>
+ /// This is the same as IDifferenceCollection.RightSequence, except that
+ /// it is typed as an <see cref="ITokenizedStringList"/>.
+ /// </remarks>
+ ITokenizedStringList RightDecomposition
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the contained difference collection for the given element, if
+ /// it has any. This forces an evaluation of the contained differences.
+ /// </summary>
+ /// <param name="index">The index at which to compute the contained differences.</param>
+ /// <returns>The contained differences at this level, or <c>null</c> if there are none.</returns>
+ IHierarchicalDifferenceCollection GetContainedDifferences(int index);
+
+ /// <summary>
+ /// Determines whether or not the <see cref="Difference"/> at the given index itself contains differences. This forces an evaluation of the contained differences for the given element.
+ /// </summary>
+ /// <param name="index">The index at which to check for contained differences.</param>
+ /// <returns><c>true</c> if the <see cref="Difference"/> in question has contained differences, otherwise <c>false</c>.</returns>
+ bool HasContainedDifferences(int index);
+ }
+}
diff --git a/src/Text/Def/TextData/Differencing/ITextDifferencingSelectorService.cs b/src/Text/Def/TextData/Differencing/ITextDifferencingSelectorService.cs
new file mode 100644
index 0000000..2c59f0e
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/ITextDifferencingSelectorService.cs
@@ -0,0 +1,39 @@
+using System;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// Used to retrieve an <see cref="ITextDifferencingService"/> for a given content type. These services may be
+ /// provided by extenders and may return differences that more closely match the semantics
+ /// of the given content type, instead of just simple textual differencing.
+ /// </summary>
+ /// <remarks>
+ /// <para>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// ITextDifferencingSelectorService diffService = null;
+ /// </para>
+ /// <para>The methods on this service are guaranteed to never return <c>null</c>. If there isn't a
+ /// specific <see cref="ITextDifferencingService"/> registered for the given content type or
+ /// any of its parent types, a default service will be used, which will use the default <see cref="IDifferenceService"/>
+ /// to perform simple textual differencing.</para>
+ /// </remarks>
+ public interface ITextDifferencingSelectorService
+ {
+ /// <summary>
+ /// Get the <see cref="ITextDifferencingService"/> for the given content type.
+ /// </summary>
+ /// <param name="contentType">The content type to use.</param>
+ /// <returns>An <see cref="ITextDifferencingService"/>, which is guaranteed to never be <c>null</c>.</returns>
+ /// <remarks><para>If two <see cref="ITextDifferencingService"/> exports tie for being most specific,
+ /// one will be chosen arbitrarily.</para></remarks>
+ ITextDifferencingService GetTextDifferencingService(IContentType contentType);
+
+ /// <summary>
+ /// Gets the default (fallback) <see cref="ITextDifferencingService"/>, which performs
+ /// simple textual differencing.
+ /// </summary>
+ /// <returns>The default <see cref="ITextDifferencingService"/> implementation (never <c>null</c>).</returns>
+ ITextDifferencingService DefaultTextDifferencingService { get; }
+ }
+}
diff --git a/src/Text/Def/TextData/Differencing/ITextDifferencingService.cs b/src/Text/Def/TextData/Differencing/ITextDifferencingService.cs
new file mode 100644
index 0000000..c380917
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/ITextDifferencingService.cs
@@ -0,0 +1,98 @@
+using System;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// This service has methods that compute differences over strings, snapshots, and spans.
+ /// Differences are computed according to the specified <see cref="StringDifferenceTypes"/>,
+ /// starting with the most general type (line is more general than word,
+ /// and word is more general than character).
+ /// This service is meant to be provided by extenders to override the diff behavior by content
+ /// type, thus allowing more control over the differences produced and how they align semantically
+ /// (based upon the given language/content type).
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This is a MEF component part, and should be exported with the following attribute:
+ /// <code>
+ /// [Export(typeof(ITextDifferencingService))]
+ /// </code>
+ /// Component exporters must add at least one content type attribute to specify the
+ /// content types for which the component is valid, such as:
+ /// <code>
+ /// [ContentType("basic")]
+ /// </code>
+ /// </para>
+ /// <para>Use the <see cref="ITextDifferencingSelectorService"/> to get the most specific <see cref="ITextDifferencingService"/>
+ /// for a particular content type.</para>
+ /// <para>
+ /// Implementors of this class are free to interpret differencing fairly liberally. For example, a text
+ /// differencing service for C# files could perform differencing by namespace/class/method, and then return
+ /// these results in line form (or whatever is requested by the <see cref="StringDifferenceOptions"/>). To that end,
+ /// the results returned are also allowed to be non-minimal, allowing implementations to return results that fit
+ /// better into the semantic model of a given language (in order to try to more closely match user intent, instead of being technically
+ /// minimal). The normal contract of <see cref="IDifferenceCollection&lt;T&gt;" /> does still apply, however, in that
+ /// differences cannot overlap, are sorted, etc.
+ /// </para>
+ /// <para>
+ /// When calling into an instance of this interface and choosing a <see cref="WordSplitBehavior"/>, you should be using
+ /// <see cref="WordSplitBehavior.LanguageAppropriate"/>, unless a different word splitting behavior is
+ /// explicitly needed. This allows the individual implementation latitude to apply the best word splitting rules
+ /// for the given content type.
+ /// </para>
+ /// </remarks>
+ public interface ITextDifferencingService
+ {
+ /// <summary>
+ /// Computes the differences between two strings, using the given difference options.
+ /// </summary>
+ /// <param name="left">The left string. In most cases this is the the "old" string.</param>
+ /// <param name="right">The right string. In most cases this is the "new" string.</param>
+ /// <param name="differenceOptions">The options to use in differencing</param>
+ /// <returns>A hierarchical collection of differences.</returns>
+ IHierarchicalDifferenceCollection DiffStrings(string left,
+ string right,
+ StringDifferenceOptions differenceOptions);
+
+ /// <summary>
+ /// Computes the differences between two snapshot spans, using the given difference options.
+ /// </summary>
+ /// <param name="left">The left span. In most cases this is from an "old" snapshot.</param>
+ /// <param name="right">The right span. In most cases this is from a "new" snapshot.</param>
+ /// <param name="differenceOptions">The options to use.</param>
+ /// <returns>A hierarchical collection of differences.</returns>
+ IHierarchicalDifferenceCollection DiffSnapshotSpans(SnapshotSpan left,
+ SnapshotSpan right,
+ StringDifferenceOptions differenceOptions);
+
+ /// <summary>
+ /// Computes the differences between two snapshot spans, using the given difference options.
+ /// </summary>
+ /// <param name="left">The left span. In most cases this is from an "old" snapshot.</param>
+ /// <param name="right">The right span. In most cases this is from a "new" snapshot.</param>
+ /// <param name="differenceOptions">The options to use.</param>
+ /// <param name="getLineTextCallback">A callback for retrieving the text of snapshot lines (when performing differencing
+ /// at the line level) that can optionally filter/modify the text, as long as it doesn't introduce line
+ /// breaks (i.e. split the given line into multiple lines).</param>
+ /// <returns>A hierarchical collection of differences.</returns>
+ /// <remarks>
+ /// <para>The <paramref name="getLineTextCallback"/> can be used for things like ignoring all intraline whitespace or
+ /// case during line differencing.
+ /// </para>
+ /// <para>
+ /// Also, the <paramref name="getLineTextCallback"/> is <i>only</i> used for line-level differencing. If word/character
+ /// differencing is requested, the implementation should use the original snapshot text directly, as there is no
+ /// guaranteed way to map from words in a filtered line back to the original line.
+ /// </para>
+ /// <para>
+ /// The <paramref name="getLineTextCallback"/> will be called only for full lines that intersect each requested
+ /// <see cref="SnapshotSpan"/>. If a line only partially intersects the given left or right span, then the
+ /// intersection of the line and the span is used directly.
+ /// </para>
+ /// </remarks>
+ IHierarchicalDifferenceCollection DiffSnapshotSpans(SnapshotSpan left,
+ SnapshotSpan right,
+ StringDifferenceOptions differenceOptions,
+ Func<ITextSnapshotLine, string> getLineTextCallback);
+ }
+}
diff --git a/src/Text/Def/TextData/Differencing/ITokenizedStringList.cs b/src/Text/Def/TextData/Differencing/ITokenizedStringList.cs
new file mode 100644
index 0000000..b85d827
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/ITokenizedStringList.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// A tokenized representation of a string into abutting and non-overlapping segments.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This interface implements IList so that it can be used with
+ /// <see cref="IDifferenceService" />, which finds the differences between two sequences represented
+ /// as ILists.</para>
+ /// </remarks>
+ public interface ITokenizedStringList : IList<string>
+ {
+ /// <summary>
+ /// The original string that was tokenized.
+ /// </summary>
+ string Original { get; }
+
+ /// <summary>
+ /// Maps the index of an element to its span in the original list.
+ /// </summary>
+ /// <param name="index">The index of the element in the element list.</param>
+ /// <returns>The span of the element.</returns>
+ /// <exception cref="ArgumentOutOfRangeException">The specified index is either negative or exceeds the list's Count property.</exception>
+ /// <remarks>This method returns a zero-length span at the end of the string if index
+ /// is equal to the list's Count property.</remarks>
+ Span GetElementInOriginal(int index);
+
+ /// <summary>
+ /// Maps a span of elements in this list to the span in the original list.
+ /// </summary>
+ /// <param name="span">The span of elements in the elements list.</param>
+ /// <returns>The span mapped onto the original list.</returns>
+ Span GetSpanInOriginal(Span span);
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Differencing/Match.cs b/src/Text/Def/TextData/Differencing/Match.cs
new file mode 100644
index 0000000..90dc532
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/Match.cs
@@ -0,0 +1,116 @@
+using Microsoft.VisualStudio.Utilities;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// Represents a range of matches between two sequences as a pair of spans of equal length.
+ /// </summary>
+ /// <remarks>
+ /// Given two sequences:
+ /// abCCd (left)
+ /// abFFd (right)
+ /// The generated pairs of matches would be:
+ /// (0, 0), (1, 1), (4, 4)
+ /// Which would turn into the Matches (left-start, right-start, length):
+ /// (0, 0, 2) and (4, 4, 1)
+ ///</remarks>
+ public class Match : IEnumerable<Tuple<int, int>>
+ {
+ private Span left;
+ private Span right;
+
+ /// <summary>
+ /// Creates a match from two spans of equal length.
+ /// </summary>
+ /// <param name="left">The span from the left sequence.</param>
+ /// <param name="right">The span from the right sequence.</param>
+ /// <exception cref="ArgumentNullException">The left span or right span is null.</exception>
+ /// <exception cref="ArgumentException">The spans are not of equal length.</exception>
+ public Match(Span left, Span right)
+ {
+ if (left.Length != right.Length)
+ throw new ArgumentException("Spans must be of equal length");
+
+ this.left = left;
+ this.right = right;
+ }
+
+ /// <summary>
+ /// Get the left-side range
+ /// </summary>
+ public Span Left
+ {
+ get { return left; }
+ }
+
+ /// <summary>
+ /// Gets the right span.
+ /// </summary>
+ public Span Right
+ {
+ get { return right; }
+ }
+
+ /// <summary>
+ /// Gets the length of the spans. Both spans have equal lengths.
+ /// </summary>
+ public int Length
+ {
+ get { return left.Length; }
+ }
+
+ /// <summary>
+ /// Determines whether two Match objects have the same left and right spans.
+ /// </summary>
+ /// <param name="obj"></param>
+ /// <returns></returns>
+ public override bool Equals(object obj)
+ {
+ Match other = obj as Match;
+
+ if(other != null)
+ return left.Equals(other.left) && right.Equals(other.right);
+
+ return false;
+ }
+
+ /// <summary>
+ /// Provides a hash function.
+ /// </summary>
+ /// <returns></returns>
+ public override int GetHashCode()
+ {
+ return left.GetHashCode() << 16 ^ right.GetHashCode();
+ }
+
+ #region IEnumerable<Tuple<int,int>> Members
+
+ /// <summary>
+ /// Gets an enumerator typed as a <see cref="Tuple"/> of integers.
+ /// </summary>
+ /// <returns>The typed enumerator.</returns>
+ public IEnumerator<Tuple<int, int>> GetEnumerator()
+ {
+ for (int i = 0; i < Length; i++)
+ yield return new Tuple<int, int>(left.Start + i, right.Start + i);
+ }
+
+ #endregion
+
+ #region IEnumerable Members
+
+ /// <summary>
+ /// Gets an untyped enumerator.
+ /// </summary>
+ /// <returns>The enumerator.</returns>
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Text/Def/TextData/Differencing/StringDifferenceOptions.cs b/src/Text/Def/TextData/Differencing/StringDifferenceOptions.cs
new file mode 100644
index 0000000..dc1a2f1
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/StringDifferenceOptions.cs
@@ -0,0 +1,175 @@
+using System;
+using System.Globalization;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+// Ignore the warnings about deprecated properties
+#pragma warning disable 0618
+
+ /// <summary>
+ /// Options to use in computing string differences.
+ /// </summary>
+ public struct StringDifferenceOptions
+ {
+ // These need to be fields and specifically in this order in order for the COM-friendly
+ // interfaces to be generated correctly.
+ private StringDifferenceTypes differenceType;
+ private int locality;
+ private bool ignoreTrimWhiteSpace;
+
+ /// <summary>
+ /// The type of string differencing to do, as a combination
+ /// of line, word, and character differencing.
+ /// </summary>
+ public StringDifferenceTypes DifferenceType
+ {
+ get { return differenceType; }
+ set { differenceType = value; }
+ }
+
+ /// <summary>
+ /// The greatest distance a differencing element (line, span, or character) can move
+ /// and still be considered part of the same source. A value of 0 disables locality checking.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// The use of locality in the default differencing implementation is now deprecated, and
+ /// the value of this field is ignored (the same as being <c>0</c>).
+ /// </para>
+ /// <para>
+ /// For example, if Locality is set to 100, a line is considered the same line
+ /// if it is separated by 100 or fewer lines from its neighboring lines.
+ /// If it is separated by more than 100 lines, it is considered a different line.
+ /// </para>
+ /// </remarks>
+ [Obsolete("This value is no longer used and will be ignored.")]
+ public int Locality
+ {
+ get { return locality; }
+ set { locality = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets whether to ignore white space.
+ /// </summary>
+ public bool IgnoreTrimWhiteSpace
+ {
+ get { return ignoreTrimWhiteSpace; }
+ set { ignoreTrimWhiteSpace = value; }
+ }
+
+ /// <summary>
+ /// The behavior to use when splitting words, if word differencing is requested
+ /// by the <see cref="DifferenceType" />.
+ /// </summary>
+ public WordSplitBehavior WordSplitBehavior { get; set; }
+
+ /// <summary>
+ /// An optional callback to override the locality for a specific round of differencing.
+ /// </summary>
+ /// <remarks>
+ /// This callback is no longer used by the default <see cref="ITextDifferencingService"/>, and is not
+ /// required to be used by an extensions that provide an implementation of a text differencing service.
+ /// </remarks>
+ [Obsolete("This callback is no longer used and will be ignored.")]
+ public DetermineLocalityCallback DetermineLocalityCallback { get; set; }
+
+ /// <summary>
+ /// An optional predicate that allows clients to cancel differencing before it has completely finished.
+ /// </summary>
+ public ContinueProcessingPredicate<string> ContinueProcessingPredicate { get; set; }
+
+ /// <summary>
+ /// Constructs a <see cref="StringDifferenceOptions"/>.
+ /// </summary>
+ /// <param name="differenceType">The type of string differencing to do, as a combination of line, word, and character differencing.</param>
+ /// <param name="locality">The greatest distance a differencing element (line, span, or character) can move and still be considered part of the same source. A value of 0 disables locality checking.</param>
+ /// <param name="ignoreTrimWhiteSpace">Determines whether whitespace should be ignored.</param>
+ public StringDifferenceOptions(StringDifferenceTypes differenceType, int locality, bool ignoreTrimWhiteSpace) : this()
+ {
+ this.differenceType = differenceType;
+ this.locality = locality;
+ this.ignoreTrimWhiteSpace = ignoreTrimWhiteSpace;
+ }
+
+ /// <summary>
+ /// Constructs a <see cref="StringDifferenceOptions"/> from a given <see cref="StringDifferenceOptions"/>.
+ /// </summary>
+ /// <param name="other">The <see cref="StringDifferenceOptions"/> to use in constructing a new <see cref="StringDifferenceOptions"/>.</param>
+ public StringDifferenceOptions(StringDifferenceOptions other) : this()
+ {
+ this.differenceType = other.DifferenceType;
+ this.locality = other.Locality;
+ this.ignoreTrimWhiteSpace = other.IgnoreTrimWhiteSpace;
+ this.WordSplitBehavior = other.WordSplitBehavior;
+ this.DetermineLocalityCallback = other.DetermineLocalityCallback;
+ this.ContinueProcessingPredicate = other.ContinueProcessingPredicate;
+ }
+
+ #region Overridden methods and operators
+
+ /// <summary>
+ /// Provides a string representation of these difference options.
+ /// </summary>
+ public override string ToString()
+ {
+ return string.Format(CultureInfo.InvariantCulture,
+ "Type: {0}, Locality: {1}, IgnoreTrimWhiteSpace: {2}, WordSplitBehavior: {3}, DetermineLocalityCallback: {4}, ContinueProcessingPredicate: {5}",
+ DifferenceType, Locality, IgnoreTrimWhiteSpace, WordSplitBehavior, DetermineLocalityCallback, ContinueProcessingPredicate);
+ }
+
+ /// <summary>
+ /// Provides a hash function for the type.
+ /// </summary>
+ public override int GetHashCode()
+ {
+ int callbackHashCode = (DetermineLocalityCallback != null) ? DetermineLocalityCallback.GetHashCode() : 0;
+ int predicateHashCode = (ContinueProcessingPredicate != null)? ContinueProcessingPredicate.GetHashCode() : 0;
+ return (DifferenceType.GetHashCode() ^ Locality.GetHashCode() ^ IgnoreTrimWhiteSpace.GetHashCode() ^ WordSplitBehavior.GetHashCode() ^ callbackHashCode ^ predicateHashCode);
+ }
+
+ /// <summary>
+ /// Determines whether two StringDifferenceOptions are the same.
+ /// </summary>
+ /// <param name="obj">The object to compare.</param>
+ public override bool Equals(object obj)
+ {
+ if (!(obj is StringDifferenceOptions))
+ return false;
+
+ return this == (StringDifferenceOptions)obj;
+ }
+
+ /// <summary>
+ /// Determines whether two StringDifferenceOptions are the same
+ /// </summary>
+ public static bool operator ==(StringDifferenceOptions left, StringDifferenceOptions right)
+ {
+ if (object.ReferenceEquals(left, right))
+ return true;
+
+ if ((object)left == null || (object)right == null)
+ return false;
+
+ return left.DifferenceType == right.DifferenceType &&
+ left.Locality == right.Locality &&
+ left.IgnoreTrimWhiteSpace == right.IgnoreTrimWhiteSpace &&
+ left.WordSplitBehavior == right.WordSplitBehavior &&
+ left.DetermineLocalityCallback == right.DetermineLocalityCallback &&
+ left.ContinueProcessingPredicate == right.ContinueProcessingPredicate;
+ }
+
+ /// <summary>
+ /// Determines whether two StringDifferenceOptions are different.
+ /// </summary>
+ public static bool operator !=(StringDifferenceOptions left, StringDifferenceOptions right)
+ {
+ return !(left == right);
+ }
+
+ #endregion // Overridden methods and operators
+
+ }
+
+#pragma warning restore 0618
+}
diff --git a/src/Text/Def/TextData/Differencing/StringDifferenceTypes.cs b/src/Text/Def/TextData/Differencing/StringDifferenceTypes.cs
new file mode 100644
index 0000000..58687fe
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/StringDifferenceTypes.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// A bitwise combination of the enumeration values to use when computing differences with the various methods in
+ /// <see cref="IHierarchicalStringDifferenceService" />.
+ /// </summary>
+ /// <remarks>
+ /// See the comments on
+ /// <see cref="IHierarchicalStringDifferenceService" /> for an explanation of how differences are computed.
+ /// Since computing differences can be slow with large data sets, you should not use the Character type
+ /// unless the given text is relatively small.
+ /// </remarks>
+ [Flags]
+ public enum StringDifferenceTypes
+ {
+ /// <summary>
+ /// Compute the line difference.
+ /// </summary>
+ Line = 1,
+
+ /// <summary>
+ /// Compute the word difference.
+ /// </summary>
+ Word = 2,
+
+ /// <summary>
+ /// Compute the character difference.
+ /// </summary>
+ Character = 4
+ }
+}
diff --git a/src/Text/Def/TextData/Differencing/WordSplitBehavior.cs b/src/Text/Def/TextData/Differencing/WordSplitBehavior.cs
new file mode 100644
index 0000000..7560548
--- /dev/null
+++ b/src/Text/Def/TextData/Differencing/WordSplitBehavior.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Globalization;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// Behavior to use while splitting words in string differencing.
+ /// </summary>
+ public enum WordSplitBehavior
+ {
+ /// <summary>
+ /// Split words by <see cref="CharacterClass" />.
+ /// </summary>
+ Default = 0,
+
+ /// <summary>
+ /// Split words by character class.
+ /// </summary>
+ /// <remarks>
+ /// The word split logic uses the following character classes:
+ /// <list type="number">
+ /// <item><description>Whitespace and control characters</description></item>
+ /// <item><description>Numbers/Digits</description></item>
+ /// <item><description>Punctuation/Symbols</description></item>
+ /// <item><description>Letters</description></item>
+ /// </list>
+ /// </remarks>
+ CharacterClass = 0,
+
+ /// <summary>
+ /// Split the text into words by whitespace only.
+ /// </summary>
+ WhiteSpace,
+
+ /// <summary>
+ /// Split the text into words by whitespace and punctuation/symbols.
+ /// </summary>
+ WhiteSpaceAndPunctuation,
+
+ /// <summary>
+ /// Split the text into language-appropriate words.
+ /// </summary>
+ /// <remarks>
+ /// When used in conjunction with the default <see cref="IHierarchicalStringDifferenceService"/>,
+ /// this is the same as <see cref="WhiteSpaceAndPunctuation"/>.
+ /// When used in conjunction with an <see cref="ITextDifferencingService"/>, the behavior
+ /// is controlled by the implementation.
+ /// </remarks>
+ LanguageAppropriate
+ }
+}
diff --git a/src/Text/Def/TextData/Document/EncodingChangedEventArgs.cs b/src/Text/Def/TextData/Document/EncodingChangedEventArgs.cs
new file mode 100644
index 0000000..0889290
--- /dev/null
+++ b/src/Text/Def/TextData/Document/EncodingChangedEventArgs.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using System.Text;
+
+ /// <summary>
+ /// Provides information for the <see cref="ITextDocument.EncodingChanged"/> event.
+ /// </summary>
+ public sealed class EncodingChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Initializes a new instance of <see cref="EncodingChangedEventArgs"/>
+ /// </summary>
+ /// <param name="oldEncoding">The previous encoding.</param>
+ /// <param name="newEncoding">The new encoding.</param>
+ public EncodingChangedEventArgs(Encoding oldEncoding, Encoding newEncoding)
+ {
+ OldEncoding = oldEncoding;
+ NewEncoding = newEncoding;
+ }
+
+ /// <summary>
+ /// Gets the previous encoding.
+ /// </summary>
+ public Encoding OldEncoding { get; private set; }
+
+ /// <summary>
+ /// Gets the new encoding.
+ /// </summary>
+ public Encoding NewEncoding { get; private set; }
+ }
+}
diff --git a/src/Text/Def/TextData/Document/FileUtilities.cs b/src/Text/Def/TextData/Document/FileUtilities.cs
new file mode 100644
index 0000000..47734dd
--- /dev/null
+++ b/src/Text/Def/TextData/Document/FileUtilities.cs
@@ -0,0 +1,250 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text
+{
+ internal class FileUtilities
+ {
+ public static void SaveSnapshot(ITextSnapshot snapshot,
+ FileMode fileMode,
+ Encoding encoding,
+ string filePath)
+ {
+ Debug.Assert((fileMode == FileMode.Create) || (fileMode == FileMode.CreateNew));
+
+ //Save the contents of the text buffer to disk.
+
+ string temporaryFilePath = null;
+ try
+ {
+ FileStream originalFileStream = null;
+ FileStream temporaryFileStream = FileUtilities.CreateFileStream(filePath, fileMode, out temporaryFilePath, out originalFileStream);
+ if (originalFileStream == null)
+ {
+ //The "normal" scenario: save the snapshot directly to disk. Either:
+ // there are no hard links to the target file so we can write the snapshot to the temporary and use File.Replace.
+ // we're creating a new file (in which case, temporaryFileStream is a misnomer: it is the stream for the file we are creating).
+ try
+ {
+ using (StreamWriter streamWriter = new StreamWriter(temporaryFileStream, encoding))
+ {
+ snapshot.Write(streamWriter);
+ }
+ }
+ finally
+ {
+ //This is somewhat redundant: disposing of streamWriter had the side-effect of disposing of temporaryFileStream
+ temporaryFileStream.Dispose();
+ temporaryFileStream = null;
+ }
+
+ if (temporaryFilePath != null)
+ {
+ //We were saving to the original file and already have a copy of the file on disk.
+ int remainingAttempts = 3;
+ do
+ {
+ try
+ {
+ //Replace the contents of filePath with the contents of the temporary using File.Replace to
+ //preserve the various attributes of the original file.
+ File.Replace(temporaryFilePath, filePath, null, true);
+ temporaryFilePath = null;
+
+ return;
+ }
+ catch (FileNotFoundException)
+ {
+ // The target file doesn't exist (someone deleted it after we detected it earlier).
+ // This is an acceptable condition so don't throw.
+ File.Move(temporaryFilePath, filePath);
+ temporaryFilePath = null;
+
+ return;
+ }
+ catch (IOException)
+ {
+ //There was some other exception when trying to replace the contents of the file
+ //(probably because some other process had the file locked).
+ //Wait a few ms and try again.
+ System.Threading.Thread.Sleep(5);
+ }
+ }
+ while (--remainingAttempts > 0);
+
+ //We're giving up on replacing the file. Try overwriting it directly (this is essentially the old Dev11 behavior).
+ //Do not try approach we are using for hard links (copying the original & restoring it if there is a failure) since
+ //getting here implies something strange is going on with the file system (Git or the like locking files) so we
+ //want the simplest possible fallback.
+
+ //Failing here causes the exception to be passed to the calling code.
+ using (FileStream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read))
+ {
+ using (StreamWriter streamWriter = new StreamWriter(stream, encoding))
+ {
+ snapshot.Write(streamWriter);
+ }
+ }
+ }
+ }
+ else
+ {
+ //filePath has hard links so we need to use a different approach to save the file:
+ // copy the original file to the temporary
+ // write directly to the original
+ // restore the original in the event of errors (which could be encoding errors and not disk issues) if there's a problem.
+ try
+ {
+ // Copy the contents of the original file to the temporary.
+ originalFileStream.CopyTo(temporaryFileStream);
+
+ //We've got a clean copy, try writing the snapshot directly to the original file
+ try
+ {
+ originalFileStream.Seek(0, SeekOrigin.Begin);
+ originalFileStream.SetLength(0);
+
+ //Make sure the StreamWriter is flagged leaveOpen == true. Otherwise disposing of the StreamWriter will dispose of originalFileStream and we need to
+ //leave originalFileStream open so we can use it to restore the original from the temporary copy we made.
+ using (var streamWriter = new StreamWriter(originalFileStream, encoding, bufferSize: 1024, leaveOpen: true)) //1024 == the default buffer size for a StreamWriter.
+ {
+ snapshot.Write(streamWriter);
+ }
+ }
+ catch
+ {
+ //Restore the original from the temporary copy we made (but rethrow the original exception since we didn't save the file).
+ temporaryFileStream.Seek(0, SeekOrigin.Begin);
+
+ originalFileStream.Seek(0, SeekOrigin.Begin);
+ originalFileStream.SetLength(0);
+
+ temporaryFileStream.CopyTo(originalFileStream);
+
+ throw;
+ }
+ }
+ finally
+ {
+ originalFileStream.Dispose();
+ originalFileStream = null;
+
+ temporaryFileStream.Dispose();
+ temporaryFileStream = null;
+ }
+ }
+ }
+ finally
+ {
+ if (temporaryFilePath != null)
+ {
+ try
+ {
+ //We do not need the temporary any longer.
+ if (File.Exists(temporaryFilePath))
+ {
+ File.Delete(temporaryFilePath);
+ }
+ }
+ catch
+ {
+ //Failing to clean up the temporary is an ignorable exception.
+ }
+ }
+ }
+ }
+
+ private static FileStream CreateFileStream(string filePath, FileMode fileMode, out string temporaryPath, out FileStream originalFileStream)
+ {
+ originalFileStream = null;
+
+ if (File.Exists(filePath))
+ {
+ // We're writing to a file that already exists. This is an error if we're trying to do a CreateNew.
+ if (fileMode == FileMode.CreateNew)
+ {
+ throw new IOException(filePath + " exists");
+ }
+
+ try
+ {
+ originalFileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
+
+ //Even thoug SafeFileHandle is an IDisposable, we don't dispose of it since that closes the strem.
+ var safeHandle = originalFileStream.SafeFileHandle;
+ if (!(safeHandle.IsClosed || safeHandle.IsInvalid))
+ {
+ BY_HANDLE_FILE_INFORMATION fi;
+ if (GetFileInformationByHandle(safeHandle, out fi))
+ {
+ if (fi.NumberOfLinks <= 1)
+ {
+ // The file we're trying to write to doesn't have any hard links ... clear out the originalFileStream
+ // as a clue.
+ originalFileStream.Dispose();
+ originalFileStream = null;
+ }
+ }
+ }
+ }
+ catch
+ {
+ if (originalFileStream != null)
+ {
+ originalFileStream.Dispose();
+ originalFileStream = null;
+ }
+
+ //We were not able to determine whether or not the file had hard links so throw here (aborting the save)
+ //since we don't know how to do it safely.
+ throw;
+ }
+
+ string root = Path.GetDirectoryName(filePath);
+
+ int count = 0;
+ while (++count < 20)
+ {
+ try
+ {
+ temporaryPath = Path.Combine(root, Path.GetRandomFileName() + "~"); //The ~ suffix hides the temporary file from GIT.
+ return new FileStream(temporaryPath, FileMode.CreateNew, (originalFileStream != null) ? FileAccess.ReadWrite : FileAccess.Write, FileShare.None);
+ }
+ catch (IOException)
+ {
+ //Ignore IOExceptions ... GetRandomFileName() came up with a duplicate so we need to try again.
+ }
+ }
+
+ Debug.Fail("Unable to create a temporary file");
+ }
+
+ temporaryPath = null;
+ return new FileStream(filePath, fileMode, FileAccess.Write, FileShare.Read);
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct BY_HANDLE_FILE_INFORMATION
+ {
+ public uint FileAttributes;
+ public System.Runtime.InteropServices.ComTypes.FILETIME CreationTime;
+ public System.Runtime.InteropServices.ComTypes.FILETIME LastAccessTime;
+ public System.Runtime.InteropServices.ComTypes.FILETIME LastWriteTime;
+ public uint VolumeSerialNumber;
+ public uint FileSizeHigh;
+ public uint FileSizeLow;
+ public uint NumberOfLinks;
+ public uint FileIndexHigh;
+ public uint FileIndexLow;
+ }
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ static extern bool GetFileInformationByHandle(
+ Microsoft.Win32.SafeHandles.SafeFileHandle hFile,
+ out BY_HANDLE_FILE_INFORMATION lpFileInformation
+ );
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Document/IEncodingDetector.cs b/src/Text/Def/TextData/Document/IEncodingDetector.cs
new file mode 100644
index 0000000..f54c839
--- /dev/null
+++ b/src/Text/Def/TextData/Document/IEncodingDetector.cs
@@ -0,0 +1,34 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System.IO;
+ using System.Text;
+
+ /// <summary>
+ /// Attempts to detect a text encoding associated with a stream.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This is a MEF component part, and should be exported with the following attribute:
+ /// [Export(NameSource=typeof(IEncodingDetector))]
+ /// </para>
+ /// <para>
+ /// Exports must include a [Name] attribute and at least one [ContentType] attribute.
+ /// Exports may optionally include the [Order] attribute.
+ /// </para>
+ /// </remarks>
+ public interface IEncodingDetector
+ {
+ /// <summary>
+ /// Attempts to detect an encoding associated with a stream.
+ /// </summary>
+ /// <remarks>
+ /// The stream is read from its current position. The encoding sniffer does not need to reset the stream's position.
+ /// </remarks>
+ /// <param name="stream">The stream to read.</param>
+ /// <returns>The detected encoding, or null if one could not be determined.</returns>
+ Encoding GetStreamEncoding(Stream stream);
+ }
+}
diff --git a/src/Text/Def/TextData/Document/ITextDocument.cs b/src/Text/Def/TextData/Document/ITextDocument.cs
new file mode 100644
index 0000000..a42a223
--- /dev/null
+++ b/src/Text/Def/TextData/Document/ITextDocument.cs
@@ -0,0 +1,236 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using System.Text;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Represents a document in the file system that persists an <see cref="ITextBuffer"/>.
+ /// </summary>
+ public interface ITextDocument : IDisposable
+ {
+ /// <summary>
+ /// The name and path of the file.
+ /// </summary>
+ string FilePath { get; }
+
+ /// <summary>
+ /// Gets the <see cref="ITextBuffer"/> containing the document. This value is always non-null.
+ /// </summary>
+ ITextBuffer TextBuffer { get; }
+
+ /// <summary>
+ /// Determines whether the <see cref="ITextBuffer"/> is dirty.
+ /// </summary>
+ /// <remarks>If <c>true</c>, the contents of <see cref="ITextDocument.TextBuffer"/> have
+ /// changed since the file was last loaded or saved. If <c>false</c>, the contents of <see cref="ITextDocument.TextBuffer"/> have
+ /// not changed since the file was last loaded or saved.</remarks>
+ bool IsDirty { get; }
+
+ /// <summary>
+ /// Gets the last <see cref="DateTime"/> the file was saved. This time exactly matches the last file written
+ /// time on the file system.
+ /// </summary>
+ DateTime LastSavedTime { get; }
+
+ /// <summary>
+ /// Gets the last <see cref="DateTime"/> a change was made to the contents of the document. If it has not been modified
+ /// since it was loaded or reloaded from disk, this will be the last write time of the underlying file at the time the
+ /// load or reload occurred; otherwise, it is the last time the contents of the text buffer were changed.
+ /// </summary>
+ DateTime LastContentModifiedTime { get; }
+
+ /// <summary>
+ /// Gets or sets the encoding of the document when saved to disk.
+ /// </summary>
+ Encoding Encoding { get; set; }
+
+ /// <summary>
+ /// Change the encoder fallback of <see cref="Encoding"/>.
+ /// </summary>
+ /// <param name="fallback">The new encoder fallback</param>
+ void SetEncoderFallback(EncoderFallback fallback);
+
+ /// <summary>
+ /// Occurs when the <see cref="Encoding"/> property changes.
+ /// </summary>
+ event EventHandler<EncodingChangedEventArgs> EncodingChanged;
+
+ /// <summary>
+ /// Occurs when the document has been loaded from or saved to disk.
+ /// You may not call Reload/Save/SaveAs to perform another file action while handling this event.
+ /// </summary>
+ event EventHandler<TextDocumentFileActionEventArgs> FileActionOccurred;
+
+ /// <summary>
+ /// Occurs when the value of <see cref="ITextDocument.IsDirty"/> changes.
+ /// You may not call <see cref="ITextDocument.UpdateDirtyState"/> in order to change
+ /// the <see cref="ITextDocument.IsDirty"/> property while handling this event.
+ /// </summary>
+ event EventHandler DirtyStateChanged;
+
+ /// <summary>
+ /// Rename the document to the given new file path.
+ /// </summary>
+ /// <param name="newFilePath">The new file path for this document.</param>
+ /// <exception cref="ObjectDisposedException">This object has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">This object is in the middle of raising events.</exception>
+ void Rename(string newFilePath);
+
+ /// <summary>
+ /// Reloads the contents of <see cref="FilePath"/> into <see cref="TextBuffer"/>.
+ /// If the load fails, the contents of the <see cref="ITextBuffer"/> remains unchanged.
+ /// </summary>
+ /// <returns>Indicates whether the reload took place and whether the encoding was sufficient.</returns>
+ /// <exception cref="System.IO.IOException">An I/O error occurred during file load.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">An access error occurred during file load.</exception>
+ /// <exception cref="ObjectDisposedException">This object has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">This object is in the middle of raising events.</exception>
+ ReloadResult Reload();
+
+ /// <summary>
+ /// Reloads the contents of <see cref="FilePath"/> into <see cref="TextBuffer"/>,
+ /// using the given <see cref="EditOptions" />.
+ /// If the load fails, the contents of the <see cref="ITextBuffer"/> remains unchanged.
+ /// </summary>
+ /// <param name="options">The options to use for the text buffer edit.</param>
+ /// <returns>Indicates whether the reload took place and whether the encoding was sufficient.</returns>
+ /// <exception cref="System.IO.IOException">An I/O error occurred during file load.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">An access error occurred during file load.</exception>
+ /// <exception cref="ObjectDisposedException">This object has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">This object is in the middle of raising events.</exception>
+ ReloadResult Reload(EditOptions options);
+
+ /// <summary>
+ /// Determines whether the document is currently being reloaded.
+ /// </summary>
+ bool IsReloading { get; }
+
+ /// <summary>
+ /// Saves the contents of the <see cref="ITextDocument.TextBuffer"/> to <see cref="ITextDocument.FilePath"/>.
+ /// If the save operation fails, the value of <see cref="ITextDocument.IsDirty"/> remains unchanged.
+ /// </summary>
+ /// <exception cref="System.IO.IOException"> An I/O error occurred during file save.</exception>
+ /// <exception cref="System.UnauthorizedAccessException">An access error occurred during file save.</exception>
+ /// <exception cref="ObjectDisposedException">This object has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">This object is in the middle of raising events.</exception>
+ void Save();
+
+ /// <summary>
+ /// Saves the contents of the <see cref="ITextDocument.TextBuffer"/> to the given <paramref name="filePath"/>.
+ /// If the save operation is successful, <see cref="ITextDocument.FilePath"/> is set to <paramref name="filePath"/>,
+ /// and <see cref="ITextDocument.IsDirty"/> is set to <c>false</c>. If the save operation fails,
+ /// <see cref="ITextDocument.FilePath"/> and <see cref="ITextDocument.IsDirty"/> remains unchanged.
+ /// </summary>
+ /// <param name="filePath">The name of the new file.</param>
+ /// <param name="overwrite"><c>true</c> if <paramref name="filePath"/> should be overwritten if it exists, otherwise <c>false</c>.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="filePath"/> is null.</exception>
+ /// <exception cref="System.IO.IOException">An I/O error occurred (including an error caused by attempting
+ /// to overwrite an existing file when <paramref name="overwrite"/> is <c>false</c>).</exception>
+ /// <exception cref="System.UnauthorizedAccessException">An access error occurred during file save.</exception>
+ /// <exception cref="ObjectDisposedException">This object has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">This object is in the middle of raising events.</exception>
+ void SaveAs(string filePath, bool overwrite);
+
+ /// <summary>
+ /// Saves the contents of the <see cref="ITextDocument.TextBuffer"/> to the given <paramref name="filePath"/>.
+ /// If the save operation is successful, <see cref="ITextDocument.FilePath"/> is set to <paramref name="filePath"/>,
+ /// and <see cref="ITextDocument.IsDirty"/> is set to <c>false</c>. If the save operation fails,
+ /// <see cref="ITextDocument.FilePath"/> and <see cref="ITextDocument.IsDirty"/> remains unchanged.
+ /// </summary>
+ /// <param name="filePath">The name of the new file.</param>
+ /// <param name="overwrite"><c>true</c> if <paramref name="filePath"/> should be overwritten if it exists, otherwise <c>false</c>.</param>
+ /// <param name="createFolder"><c>true</c> if the folder containing <paramref name="filePath"/> should be created if it does not exist, otherwise <c>false</c>.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="filePath"/> is null.</exception>
+ /// <exception cref="System.IO.IOException">An I/O error occurred (including an error caused by attempting
+ /// to overwrite an existing file when <paramref name="overwrite"/> is <c>false</c>).</exception>
+ /// <exception cref="System.UnauthorizedAccessException">An access error occurred during file save.</exception>
+ /// <exception cref="ObjectDisposedException">This object has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">This object is in the middle of raising events.</exception>
+ void SaveAs(string filePath, bool overwrite, bool createFolder);
+
+ /// <summary>
+ /// Saves the contents of the <see cref="ITextDocument.TextBuffer"/> to the given <paramref name="filePath"/>.
+ /// If the save is successful, <see cref="ITextDocument.FilePath"/> is set to <paramref name="filePath"/>,
+ /// and <see cref="ITextDocument.IsDirty"/> is set to <c>false</c>. If the save fails,
+ /// <see cref="ITextDocument.FilePath"/> and <see cref="ITextDocument.IsDirty"/> remains unchanged.
+ /// </summary>
+ /// <param name="filePath">The name of the new file.</param>
+ /// <param name="overwrite"><c>true</c> if <paramref name="filePath"/> should be overwritten if it exists, otherwise <c>false</c>.</param>
+ /// <param name="newContentType">The new <see cref="IContentType"/>.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="filePath"/> or <paramref name="newContentType"/> is null.</exception>
+ /// <exception cref="System.IO.IOException">An I/O error occurred (including an error caused by attempting
+ /// to overwrite an existing file when <paramref name="overwrite"/> is false).</exception>
+ /// <exception cref="System.UnauthorizedAccessException">An access error occurred during file save.</exception>
+ /// <exception cref="ObjectDisposedException">This object has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">This object is in the middle of raising events.</exception>
+ /// <remarks>
+ /// The order of events raised as a result of a successful file SaveAs
+ /// operation is <see cref="ITextDocument.FileActionOccurred"/> followed by <see cref="ITextBuffer.ContentTypeChanged"/>.
+ /// </remarks>
+ void SaveAs(string filePath, bool overwrite, IContentType newContentType);
+
+ /// <summary>
+ /// Saves the contents of the <see cref="ITextDocument.TextBuffer"/> to the given <paramref name="filePath"/>.
+ /// If the save is successful, <see cref="ITextDocument.FilePath"/> is set to <paramref name="filePath"/>,
+ /// and <see cref="ITextDocument.IsDirty"/> is set to <c>false</c>. If the save fails,
+ /// <see cref="ITextDocument.FilePath"/> and <see cref="ITextDocument.IsDirty"/> remains unchanged.
+ /// </summary>
+ /// <param name="filePath">The name of the new file.</param>
+ /// <param name="overwrite"><c>true</c> if <paramref name="filePath"/> should be overwritten if it exists, otherwise <c>false</c>.</param>
+ /// <param name="createFolder"><c>true</c> if the folder containing <paramref name="filePath"/> should be created if it does not exist, otherwise <c>false</c>.</param>
+ /// <param name="newContentType">The new <see cref="IContentType"/>.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="filePath"/> or <paramref name="newContentType"/> is null.</exception>
+ /// <exception cref="System.IO.IOException">An I/O error occurred (including an error caused by attempting
+ /// to overwrite an existing file when <paramref name="overwrite"/> is false).</exception>
+ /// <exception cref="System.UnauthorizedAccessException">An access error occurred during file save.</exception>
+ /// <exception cref="ObjectDisposedException">This object has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">This object is in the middle of raising events.</exception>
+ /// <remarks>
+ /// The order of events raised as a result of a successful file SaveAs
+ /// operation is <see cref="ITextDocument.FileActionOccurred"/> followed by <see cref="ITextBuffer.ContentTypeChanged"/>.
+ /// </remarks>
+ void SaveAs(string filePath, bool overwrite, bool createFolder, IContentType newContentType);
+
+ /// <summary>
+ /// Saves the contents of the <see cref="ITextDocument.TextBuffer"/> to the given <paramref name="filePath"/>.
+ /// </summary>
+ /// <param name="filePath">The name of the file.</param>
+ /// <param name="overwrite"><c>true</c> if <paramref name="filePath"/> should be overwritten if it exists, otherwise <c>false</c>.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="filePath"/> is null.</exception>
+ /// <exception cref="System.IO.IOException">An I/O error occurred (including an error caused by attempting
+ /// to overwrite an existing file when <paramref name="overwrite"/> is <c>false</c>).</exception>
+ /// <exception cref="System.UnauthorizedAccessException">An access error occurred during file save.</exception>
+ /// <exception cref="ObjectDisposedException">This object has been disposed.</exception>
+ /// <remarks>This call does not affect the <see cref="IsDirty"/>, <see cref="LastSavedTime"/>, and <see cref="FilePath"/> properties.
+ /// The <see cref="FileActionOccurred"/> event is not raised.</remarks>
+ void SaveCopy(string filePath, bool overwrite);
+
+ /// <summary>
+ /// Saves the contents of the <see cref="ITextDocument.TextBuffer"/> to the given <paramref name="filePath"/>.
+ /// </summary>
+ /// <param name="filePath">The name of the file.</param>
+ /// <param name="overwrite"><c>true</c> if <paramref name="filePath"/> should be overwritten if it exists, otherwise <c>false</c>.</param>
+ /// <param name="createFolder"><c>true</c> if the folder containing <paramref name="filePath"/> should be created if it does not exist, otherwise <c>false</c>.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="filePath"/> is null.</exception>
+ /// <exception cref="System.IO.IOException">An I/O error occurred (including an error caused by attempting
+ /// to overwrite an existing file when <paramref name="overwrite"/> is <c>false</c>).</exception>
+ /// <exception cref="System.UnauthorizedAccessException">An access error occurred during file save.</exception>
+ /// <exception cref="ObjectDisposedException">This object has been disposed.</exception>
+ /// <remarks>This call does not affect the <see cref="IsDirty"/>, <see cref="LastSavedTime"/>, and <see cref="FilePath"/> properties.
+ /// The <see cref="FileActionOccurred"/> event is not raised.</remarks>
+ void SaveCopy(string filePath, bool overwrite, bool createFolder);
+
+ /// <summary>
+ /// Updates the <see cref="IsDirty"/> and <see cref="LastContentModifiedTime"/> properties.
+ /// </summary>
+ /// <param name="isDirty">The new value for <see cref="ITextDocument.IsDirty" />.</param>
+ /// <param name="lastContentModifiedTime">The new value for <see cref="ITextDocument.LastContentModifiedTime"/>.</param>
+ /// <exception cref="ObjectDisposedException">This object has been disposed.</exception>
+ /// <exception cref="InvalidOperationException">This object is in the middle of raising events.</exception>
+ void UpdateDirtyState(bool isDirty, DateTime lastContentModifiedTime);
+ }
+}
diff --git a/src/Text/Def/TextData/Document/ITextDocumentFactoryService.cs b/src/Text/Def/TextData/Document/ITextDocumentFactoryService.cs
new file mode 100644
index 0000000..cbe74c7
--- /dev/null
+++ b/src/Text/Def/TextData/Document/ITextDocumentFactoryService.cs
@@ -0,0 +1,79 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <remarks>
+ /// Represents a service that creates, load, and disposes text documents. This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// ITextDocumentFactoryService factory = null;
+ /// </remarks>
+ public interface ITextDocumentFactoryService
+ {
+ /// <summary>
+ /// Creates an <see cref="ITextDocument"/> that opens and loads the contents of <paramref name="filePath"/> into a new <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="filePath">The full path to the file to be loaded.</param>
+ /// <param name="contentType">The <see cref="IContentType"/> for the <see cref="ITextBuffer"/>.</param>
+ /// <returns>An <see cref="ITextDocument"/>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="filePath"/> or <paramref name="contentType"/> is null.</exception>
+ /// <remarks>This method is equivalent to CreateAndLoadTextDocument(filePath, contentType, true, out unusedBoolean).</remarks>
+ ITextDocument CreateAndLoadTextDocument(string filePath, IContentType contentType);
+
+ /// <summary>
+ /// Creates an <see cref="ITextDocument"/> that opens and loads the contents of <paramref name="filePath"/> into a new <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="filePath">The full path to the file to be loaded.</param>
+ /// <param name="contentType">The <see cref="IContentType"/> for the <see cref="ITextBuffer"/>.</param>
+ /// <param name="encoding">The encoding to use. The decoder part of the Encoding object won't be used.</param>
+ /// <param name="characterSubstitutionsOccurred">Set to true if some of the file bytes could not be directly translated using the given encoding.</param>
+ /// <returns>An <see cref="ITextDocument"/>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="filePath"/>, <paramref name="contentType"/>, or <paramref name="encoding"/> is null.</exception>
+ ITextDocument CreateAndLoadTextDocument(string filePath, IContentType contentType, Encoding encoding, out bool characterSubstitutionsOccurred);
+
+ /// <summary>
+ /// Creates an <see cref="ITextDocument"/> that opens and loads the contents of <paramref name="filePath"/> into a new <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="filePath">The full path to the file to be loaded.</param>
+ /// <param name="contentType">The <see cref="IContentType"/> for the <see cref="ITextBuffer"/>.</param>
+ /// <param name="attemptUtf8Detection">Whether to attempt to load the document as a UTF-8 file.</param>
+ /// <param name="characterSubstitutionsOccurred">Set to true if some of the file bytes could not be directly translated using the given encoding.</param>
+ /// <returns>An <see cref="ITextDocument"/>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="filePath"/> or <paramref name="contentType"/> is null.</exception>
+ ITextDocument CreateAndLoadTextDocument(string filePath, IContentType contentType, bool attemptUtf8Detection, out bool characterSubstitutionsOccurred);
+
+ /// <summary>
+ /// Creates an <see cref="ITextDocument"/> with <paramref name="textBuffer"/>, which is to be saved to <paramref name="filePath"/>
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> to be saved to <paramref name="filePath"/>.</param>
+ /// <param name="filePath">The full path to the file.</param>
+ /// <returns>An <see cref="ITextDocument"/>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="textBuffer"/> or <paramref name="filePath"/> is null.</exception>
+ /// <remarks>This call does not save the contents of the buffer to the given path.</remarks>
+ ITextDocument CreateTextDocument(ITextBuffer textBuffer, string filePath);
+
+ /// <summary>
+ /// Retrieve an <see cref="ITextDocument"/> for the given buffer, if one exists.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> to get a document for.</param>
+ /// <param name="textDocument">The <see cref="ITextDocument"/> for this buffer, if one exists.</param>
+ /// <returns><c>true</c> if a document exists for this buffer, <c>false</c> otherwise.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="textBuffer"/> is null.</exception>
+ bool TryGetTextDocument(ITextBuffer textBuffer, out ITextDocument textDocument);
+
+ /// <summary>
+ /// Occurs when an <see cref="ITextDocument"/> is created.
+ /// </summary>
+ event EventHandler<TextDocumentEventArgs> TextDocumentCreated;
+
+ /// <summary>
+ /// Occurs when an <see cref="ITextDocument"/> is disposed.
+ /// </summary>
+ event EventHandler<TextDocumentEventArgs> TextDocumentDisposed;
+ }
+}
diff --git a/src/Text/Def/TextData/Document/ReloadResult.cs b/src/Text/Def/TextData/Document/ReloadResult.cs
new file mode 100644
index 0000000..01cf593
--- /dev/null
+++ b/src/Text/Def/TextData/Document/ReloadResult.cs
@@ -0,0 +1,23 @@
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// The return value of Reload methods on <see cref="ITextDocument" />.
+ /// </summary>
+ public enum ReloadResult
+ {
+ /// <summary>
+ /// The reload was blocked by the text document buffer's read only regions or <see cref="ITextBuffer.Changing"/> event.
+ /// </summary>
+ Aborted,
+
+ /// <summary>
+ /// The reload completed.
+ /// </summary>
+ Succeeded,
+
+ /// <summary>
+ /// The reload completed but some bytes could not be decoded and were replaced with a replacement character.
+ /// </summary>
+ SucceededWithCharacterSubstitutions
+ }
+}
diff --git a/src/Text/Def/TextData/Document/TextDocumentEventArgs.cs b/src/Text/Def/TextData/Document/TextDocumentEventArgs.cs
new file mode 100644
index 0000000..ce7e411
--- /dev/null
+++ b/src/Text/Def/TextData/Document/TextDocumentEventArgs.cs
@@ -0,0 +1,41 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+
+ /// <summary>
+ /// Provides information for events when an <see cref="ITextDocument"/> has been created or disposed.
+ /// </summary>
+ public class TextDocumentEventArgs : EventArgs
+ {
+ #region Private Members
+
+ ITextDocument _textDocument;
+
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="TextDocumentEventArgs"/>.
+ /// </summary>
+ /// <param name="textDocument">The <see cref="ITextDocument"/> that was created or disposed.</param>
+ public TextDocumentEventArgs(ITextDocument textDocument)
+ {
+ _textDocument = textDocument;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="ITextDocument"/> that was created or disposed.
+ /// </summary>
+ public ITextDocument TextDocument
+ {
+ get
+ {
+ return _textDocument;
+ }
+ }
+ }
+}
diff --git a/src/Text/Def/TextData/Document/TextDocumentFileActionEventArgs.cs b/src/Text/Def/TextData/Document/TextDocumentFileActionEventArgs.cs
new file mode 100644
index 0000000..7d480a0
--- /dev/null
+++ b/src/Text/Def/TextData/Document/TextDocumentFileActionEventArgs.cs
@@ -0,0 +1,101 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+
+ /// <summary>
+ /// Describes the type of file action.
+ /// </summary>
+ [Flags]
+ public enum FileActionTypes
+ {
+ /// <summary>
+ /// The content was saved to disk.
+ /// </summary>
+ ContentSavedToDisk = 1,
+
+ /// <summary>
+ /// The content was loaded from disk.
+ /// </summary>
+ ContentLoadedFromDisk = 2,
+
+ /// <summary>
+ /// The document was renamed.
+ /// </summary>
+ DocumentRenamed = 4
+ }
+
+ /// <summary>
+ /// Provides information for events that are raised when an <see cref="ITextDocument"/> has loaded from or saved to disk.
+ /// </summary>
+ public class TextDocumentFileActionEventArgs : EventArgs
+ {
+ #region Private Members
+
+ string _filePath;
+ DateTime _time;
+ FileActionTypes _fileActionType;
+
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="TextDocumentFileActionEventArgs"/> for a file action event.
+ /// </summary>
+ /// <param name="filePath">The path to the file.</param>
+ /// <param name="time">The <see cref="DateTime"/> when the file action occurred.</param>
+ /// <param name="fileActionType">The <see cref="FileActionTypes"/> that occurred.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="filePath"/> is null.</exception>
+ public TextDocumentFileActionEventArgs(string filePath, DateTime time, FileActionTypes fileActionType)
+ {
+ if (filePath == null)
+ {
+ throw new ArgumentNullException("filePath");
+ }
+
+ _filePath = filePath;
+ _time = time;
+ _fileActionType = fileActionType;
+ }
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the path to the file.
+ /// </summary>
+ public string FilePath
+ {
+ get
+ {
+ return _filePath;
+ }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="DateTime"/> when the file action occurred.
+ /// </summary>
+ public DateTime Time
+ {
+ get
+ {
+ return _time;
+ }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="FileActionTypes"/> that occurred.
+ /// </summary>
+ public FileActionTypes FileActionType
+ {
+ get
+ {
+ return _fileActionType;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Text/Def/TextData/FxCopSuppressions.cs b/src/Text/Def/TextData/FxCopSuppressions.cs
new file mode 100644
index 0000000..73b5d0e
--- /dev/null
+++ b/src/Text/Def/TextData/FxCopSuppressions.cs
@@ -0,0 +1,52 @@
+#if CODE_ANALYSIS_BASELINE
+using System.Diagnostics.CodeAnalysis;
+
+[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly",
+ Scope = "member",
+ Target = "Microsoft.VisualStudio.Text.ITrackingSpan.GetEndPoint(Microsoft.VisualStudio.Text.ITextSnapshot):Microsoft.VisualStudio.Text.SnapshotPoint",
+ MessageId = "EndPoint",
+ Justification="EndPoint makes sense because it really comprises two words (it means 'the ending SnapshotPoint'), in duality with StartPoint.")]
+//[module: SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods",
+// Scope = "member",
+// Target = "Microsoft.VisualStudio.Text.NormalizedSpanCollection.op_Equality(Microsoft.VisualStudio.Text.NormalizedSpanCollection,Microsoft.VisualStudio.Text.NormalizedSpanCollection):System.Boolean",
+// Justification = "Argument already validated for null")]
+[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly",
+ Scope = "member",
+ Target = "Microsoft.VisualStudio.Text.ITextSnapshotLine.GetPositionOfNextNonWhiteSpaceCharacter(System.Int32):System.Int32",
+ MessageId = "NonWhite")]
+[module: SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue",
+ Scope = "type",
+ Target = "Microsoft.VisualStudio.Text.TrackingFidelityMode",
+ Justification = "'None' as the zero value makes no sense in this context")]
+
+[module: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames", Scope="", Target="microsoft.visualstudio.text.data.dll", MessageId="", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Scope="member", Target="Microsoft.VisualStudio.Text.ITextSnapshotLine.#End", MessageId="End", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Scope="member", Target="Microsoft.VisualStudio.Text.ITextSnapshotLine.#GetLineBreakText()", MessageId="", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Scope="member", Target="Microsoft.VisualStudio.Text.ITextSnapshotLine.#GetText()", MessageId="", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Scope="member", Target="Microsoft.VisualStudio.Text.ITextSnapshotLine.#GetTextIncludingLineBreak()", MessageId="", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Scope="member", Target="Microsoft.VisualStudio.Text.SnapshotPoint.#GetChar()", MessageId="", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Scope="member", Target="Microsoft.VisualStudio.Text.SnapshotPoint.#GetContainingLine()", MessageId="", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Scope="member", Target="Microsoft.VisualStudio.Text.SnapshotSpan.#GetText()", MessageId="", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.VisualStudio.Text.SnapshotSpan.#op_Equality(Microsoft.VisualStudio.Text.SnapshotSpan,Microsoft.VisualStudio.Text.SnapshotSpan)", MessageId="ss", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.VisualStudio.Text.SnapshotSpan.#op_Inequality(Microsoft.VisualStudio.Text.SnapshotSpan,Microsoft.VisualStudio.Text.SnapshotSpan)", MessageId="ss", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Scope="member", Target="Microsoft.VisualStudio.Text.ITextVersion.#Next", MessageId="Next", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+
+[module: SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope="member", Target="Microsoft.VisualStudio.Text.Projection.ProjectionSourceSpansChangedEventArgs.#spanPosition", MessageId="", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "End", Scope = "member", Target = "Microsoft.VisualStudio.Text.IMappingSpan.#End")]
+[module: SuppressMessage("Microsoft.Design","CA1021:AvoidOutParameters", MessageId="3#", Scope="member", Target="Microsoft.VisualStudio.Text.ITextDocumentFactoryService.#CreateAndLoadTextDocument(System.String,Microsoft.VisualStudio.Utilities.IContentType,System.Boolean,System.Boolean&)")]
+[module: SuppressMessage("Microsoft.Design","CA1021:AvoidOutParameters", MessageId="3#", Scope="member", Target="Microsoft.VisualStudio.Text.ITextDocumentFactoryService.#CreateAndLoadTextDocument(System.String,Microsoft.VisualStudio.Utilities.IContentType,System.Text.Encoding,System.Boolean&)")]
+
+// Differencing
+
+[module: SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Scope = "member", Target = "Microsoft.VisualStudio.Text.Differencing.IDifferenceCollection`1.#MatchSequence")]
+[module: SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Scope = "type", Target = "Microsoft.VisualStudio.Text.Differencing.MatchRange")]
+[module: SuppressMessage("Microsoft.Naming","CA1710:IdentifiersShouldHaveCorrectSuffix", Scope="type", Target="Microsoft.VisualStudio.Text.Differencing.ITokenizedStringList", Justification="It is an IList, so it should end in \"List\", not \"Collection\".")]
+[module: SuppressMessage("Microsoft.Naming","CA1710:IdentifiersShouldHaveCorrectSuffix", Scope="type", Target="Microsoft.VisualStudio.Text.Differencing.Match")]
+
+[module: SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Scope = "member", Target = "Microsoft.VisualStudio.Text.Differencing.IDifferenceCollection`1.#MatchSequence")]
+[module: SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Scope = "member", Target = "Microsoft.VisualStudio.Text.Differencing.IDifferenceCollection`1.#get_MatchSequence()")]
+[module: SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Scope = "type", Target = "Microsoft.VisualStudio.Text.Differencing.Match")]
+[module: SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Scope = "member", Target = "Microsoft.VisualStudio.Text.Differencing.Match.#GetEnumerator()")]
+[module: SuppressMessage("Microsoft.MSInternal", "CA908:AvoidTypesThatRequireJitCompilationInPrecompiledAssemblies", Scope = "member", Target = "Microsoft.VisualStudio.Text.Differencing.Match.#System.Collections.IEnumerable.GetEnumerator()")]
+
+#endif
diff --git a/src/Text/Def/TextData/Model/ContentTypeChangedEventArgs.cs b/src/Text/Def/TextData/Model/ContentTypeChangedEventArgs.cs
new file mode 100644
index 0000000..e79276c
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ContentTypeChangedEventArgs.cs
@@ -0,0 +1,76 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Provides information about a change to the <see cref="IContentType"/> on an <see cref="ITextBuffer"/>.
+ /// </summary>
+ public class ContentTypeChangedEventArgs : TextSnapshotChangedEventArgs
+ {
+ #region Private Members
+
+ IContentType _beforeContentType;
+ IContentType _afterContentType;
+
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="ContentTypeChangedEventArgs"/>
+ /// with the specified before and after snapshots and before and after content types.
+ /// </summary>
+ /// <param name="beforeSnapshot">The most recent <see cref="ITextSnapshot"/> before the change occurred.</param>
+ /// <param name="afterSnapshot">The <see cref="ITextSnapshot"/> immediately after the change occurred.</param>
+ /// <param name="beforeContentType">The <see cref="IContentType"/> before the change occurred.</param>
+ /// <param name="afterContentType">The <see cref="IContentType"/> after the change occurred.</param>
+ /// <param name="editTag">An arbitrary object associated with this change.</param>
+ /// <exception cref="ArgumentNullException"> One of <paramref name="beforeSnapshot"/>,
+ /// <paramref name="afterSnapshot"/>, <paramref name="beforeContentType"/>, or
+ /// <paramref name="afterContentType"/> is null.</exception>
+ public ContentTypeChangedEventArgs(ITextSnapshot beforeSnapshot,
+ ITextSnapshot afterSnapshot,
+ IContentType beforeContentType,
+ IContentType afterContentType,
+ object editTag)
+ : base(beforeSnapshot, afterSnapshot, editTag)
+ {
+ if (beforeContentType == null)
+ {
+ throw new ArgumentNullException("beforeContentType");
+ }
+
+ if (afterContentType == null)
+ {
+ throw new ArgumentNullException("afterContentType");
+ }
+
+ _beforeContentType = beforeContentType;
+ _afterContentType = afterContentType;
+ }
+
+ /// <summary>
+ /// The <see cref="IContentType"/> before the change occurred.
+ /// </summary>
+ public IContentType BeforeContentType
+ {
+ get
+ {
+ return _beforeContentType;
+ }
+ }
+
+ /// <summary>
+ /// The <see cref="IContentType"/> after the change occurred.
+ /// </summary>
+ public IContentType AfterContentType
+ {
+ get
+ {
+ return _afterContentType;
+ }
+ }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/CustomTrackToVersion.cs b/src/Text/Def/TextData/Model/CustomTrackToVersion.cs
new file mode 100644
index 0000000..9ff1323
--- /dev/null
+++ b/src/Text/Def/TextData/Model/CustomTrackToVersion.cs
@@ -0,0 +1,17 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Provides a custom implementation of span tracking. This delegate should be implemented by custom tracking spans.
+ /// </summary>
+ /// <param name="customSpan">The span to be tracked.</param>
+ /// <param name="currentVersion">The version to which <paramref name="currentSpan"/> belongs.</param>
+ /// <param name="targetVersion">The version to which <paramref name="currentSpan"/> is to be tracked.</param>
+ /// <param name="currentSpan">The span to track.</param>
+ /// <param name="customState">The custom state that was provided when the span was created.</param>
+ /// <returns>The span to which <paramref name="currentSpan"/> tracks.</returns>
+ /// <remarks><paramref name="targetVersion"/> may be earlier than <paramref name="currentVersion"/>.</remarks>
+ public delegate Span CustomTrackToVersion(ITrackingSpan customSpan, ITextVersion currentVersion, ITextVersion targetVersion, Span currentSpan, object customState);
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Model/DynamicReadOnlyRegionQuery.cs b/src/Text/Def/TextData/Model/DynamicReadOnlyRegionQuery.cs
new file mode 100644
index 0000000..cb393d5
--- /dev/null
+++ b/src/Text/Def/TextData/Model/DynamicReadOnlyRegionQuery.cs
@@ -0,0 +1,12 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// The callback delegate for notifying read only regions of edits.
+ /// </summary>
+ /// <param name="isEdit">True if an edit is being attempted. False if the read-only check should be side-effect free.</param>
+ /// <returns>Whether the read-only region is in effect.</returns>
+ public delegate bool DynamicReadOnlyRegionQuery(bool isEdit);
+}
diff --git a/src/Text/Def/TextData/Model/EdgeInsertionMode.cs b/src/Text/Def/TextData/Model/EdgeInsertionMode.cs
new file mode 100644
index 0000000..8d22607
--- /dev/null
+++ b/src/Text/Def/TextData/Model/EdgeInsertionMode.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Specifies the edge insertion modes for read-only regions.
+ /// </summary>
+ public enum EdgeInsertionMode
+ {
+ /// <summary>
+ /// Allows insertions at the edge of read-only regions. If
+ /// there is a read-only region [3, 6) that allows edge insertions, an insertion at
+ /// position 3 or position 6 will succeed.
+ /// </summary>
+ Allow,
+
+ /// <summary>
+ /// Prevents insertions at the edge of read-only regions. If
+ /// there is a read-only region [3, 6) that allows edge insertions, an insertion at
+ /// position 3 or position 6 will fail.
+ /// </summary>
+ Deny
+ }
+}
diff --git a/src/Text/Def/TextData/Model/EditOptions.cs b/src/Text/Def/TextData/Model/EditOptions.cs
new file mode 100644
index 0000000..d0b4ac7
--- /dev/null
+++ b/src/Text/Def/TextData/Model/EditOptions.cs
@@ -0,0 +1,144 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using Microsoft.VisualStudio.Text.Differencing;
+ using System;
+ using System.Globalization;
+
+ /// <summary>
+ /// Options applicable to text editing transactions.
+ /// </summary>
+ public struct EditOptions
+ {
+ private bool computeMinimalChange;
+ private StringDifferenceOptions differenceOptions;
+
+ #region Common EditOptions values
+
+ /// <summary>
+ /// Do nothing special with this edit.
+ /// </summary>
+ public readonly static EditOptions None = new EditOptions();
+
+ /// <summary>
+ /// Turn this edit into a minimal change, using line and word string differencing.
+ /// </summary>
+ public readonly static EditOptions DefaultMinimalChange =
+ new EditOptions(new StringDifferenceOptions() { DifferenceType = StringDifferenceTypes.Line | StringDifferenceTypes.Word });
+
+ #endregion
+
+ /// <summary>
+ /// Create a set of edit options for computing a minimal difference,
+ /// with the given <see cref="StringDifferenceOptions" />.
+ /// </summary>
+ public EditOptions(StringDifferenceOptions differenceOptions)
+ {
+ this.computeMinimalChange = true;
+ this.differenceOptions = differenceOptions;
+ }
+
+ /// <summary>
+ /// Create a set of edit options.
+ /// </summary>
+ public EditOptions(bool computeMinimalChange, StringDifferenceOptions differenceOptions)
+ {
+ this.computeMinimalChange = computeMinimalChange;
+ this.differenceOptions = differenceOptions;
+ }
+
+ /// <summary>
+ /// True if this edit computes minimal change using the differencing option <see cref="StringDifferenceOptions"/>, false otherwise.
+ /// </summary>
+ public bool ComputeMinimalChange
+ {
+ get { return this.computeMinimalChange; }
+ }
+
+ /// <summary>
+ /// The differencing options for this edit, if <see cref="ComputeMinimalChange" /> is true.
+ /// </summary>
+ /// <remarks>
+ /// <see cref="StringDifferenceOptions.IgnoreTrimWhiteSpace" /> will be
+ /// ignored.
+ /// </remarks>
+ public StringDifferenceOptions DifferenceOptions
+ {
+ get { return differenceOptions; }
+ }
+
+ #region Overridden methods and operators
+
+ /// <summary>
+ /// Provides a string representation of these edit options.
+ /// </summary>
+ public override string ToString()
+ {
+ if (this == EditOptions.None || !this.ComputeMinimalChange)
+ {
+ return "{none}";
+ }
+ else
+ {
+ return differenceOptions.ToString();
+ }
+ }
+
+ /// <summary>
+ /// Provides a hash function for the type.
+ /// </summary>
+ public override int GetHashCode()
+ {
+ if (this == EditOptions.None || !this.ComputeMinimalChange)
+ {
+ return 0;
+ }
+ else
+ {
+ return differenceOptions.GetHashCode();
+ }
+ }
+
+ /// <summary>
+ /// Determines whether two spans are the same.
+ /// </summary>
+ /// <param name="obj">The object to compare.</param>
+ public override bool Equals(object obj)
+ {
+ if (obj is EditOptions)
+ {
+ EditOptions other = (EditOptions)obj;
+ if (other.ComputeMinimalChange != this.ComputeMinimalChange)
+ return false;
+ if (!this.ComputeMinimalChange)
+ return true;
+
+ return other.differenceOptions == this.differenceOptions;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Determines whether two EditOptions are the same
+ /// </summary>
+ public static bool operator ==(EditOptions left, EditOptions right)
+ {
+ return left.Equals(right);
+ }
+
+ /// <summary>
+ /// Determines whether two EditOptions are different.
+ /// </summary>
+ public static bool operator !=(EditOptions left, EditOptions right)
+ {
+ return !(left == right);
+ }
+
+ #endregion // Overridden methods and operators
+ }
+}
diff --git a/src/Text/Def/TextData/Model/IExtensionErrorHandler.cs b/src/Text/Def/TextData/Model/IExtensionErrorHandler.cs
new file mode 100644
index 0000000..88550c7
--- /dev/null
+++ b/src/Text/Def/TextData/Model/IExtensionErrorHandler.cs
@@ -0,0 +1,21 @@
+using System;
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Allows editor hosts to detect exceptions that get captured at extension points.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IExtensionErrorHandler errorHandler = null;
+ /// </remarks>
+ public interface IExtensionErrorHandler
+ {
+ /// <summary>
+ /// Notifies that an exception has occured.
+ /// </summary>
+ /// <param name="sender">The extension object or event handler that threw the exception.</param>
+ /// <param name="exception">The exception that was thrown.</param>
+ void HandleError(object sender, Exception exception);
+ }
+}
diff --git a/src/Text/Def/TextData/Model/IExtensionPerformanceTracker.cs b/src/Text/Def/TextData/Model/IExtensionPerformanceTracker.cs
new file mode 100644
index 0000000..bfbe00a
--- /dev/null
+++ b/src/Text/Def/TextData/Model/IExtensionPerformanceTracker.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Allows editor hosts to track performance of extension points.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IExtensionPerformanceTracker errorHandler = null;
+ /// </remarks>
+ /// <experimental>This is an experimental interface, subject to breaking changes.</experimental>
+ public interface IExtensionPerformanceTracker
+ {
+ /// <summary>
+ /// Invoked before calling to an extension event handler.
+ /// </summary>
+ /// <param name="eventHandler"></param>
+ void BeforeCallingEventHandler(Delegate eventHandler);
+
+ /// <summary>
+ /// Invoked after calling to an extension event handler.
+ /// </summary>
+ void AfterCallingEventHandler(Delegate eventHandler);
+ }
+}
diff --git a/src/Text/Def/TextData/Model/IMappingPoint.cs b/src/Text/Def/TextData/Model/IMappingPoint.cs
new file mode 100644
index 0000000..4b3f59c
--- /dev/null
+++ b/src/Text/Def/TextData/Model/IMappingPoint.cs
@@ -0,0 +1,92 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using Microsoft.VisualStudio.Text.Projection;
+
+ /// <summary>
+ /// A position in a <see cref="ITextBuffer"/> that can be mapped within a <see cref="Microsoft.VisualStudio.Text.Projection.IBufferGraph"/>.
+ /// </summary>
+ public interface IMappingPoint
+ {
+ /// <summary>
+ /// Maps the point to a particular <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="targetBuffer">The <see cref="ITextBuffer"/> to which to map the point.</param>
+ /// <param name="affinity">If the mapping is ambiguous (the position lies on a source span seam), this parameter affects the mapping as follows:
+ /// if <paramref name="affinity"/> is <see cref="PositionAffinity.Predecessor"/>, the mapping targets
+ /// the position immediately after the preceding character in the anchor buffer; if <paramref name="affinity"/> is
+ /// <see cref="PositionAffinity.Successor"/>, the mapping targets the position immediately before the following character
+ /// in the anchor buffer. This parameter has no effect if the mapping is unambiguous.</param>
+ /// <returns>A <see cref="SnapshotPoint"/> in the targeted buffer or null if the point and affinity do not appear in that buffer.</returns>
+ /// <remarks>
+ /// In general, a source span seam occurs at the end of a source span of nonzero length
+ /// and the beginning of a source span of nonzero length, and
+ /// coincides with zero or more source spans of zero length. Every span on a seam
+ /// has a point in the result collection.
+ /// </remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="targetBuffer"/> is null.</exception>
+ SnapshotPoint? GetPoint(ITextBuffer targetBuffer, PositionAffinity affinity);
+
+ /// <summary>
+ /// Maps the point to a particular <see cref="ITextSnapshot"/>.
+ /// </summary>
+ /// <param name="targetSnapshot">The <see cref="ITextSnapshot"/> to which to map the point.</param>
+ /// <param name="affinity">If the mapping is ambiguous (the position lies on a source span seam), this parameter affects the mapping as follows:
+ /// if <paramref name="affinity"/> is <see cref="PositionAffinity.Predecessor"/>, the mapping targets
+ /// the position immediately after the preceding character in the anchor buffer; if <paramref name="affinity"/> is
+ /// <see cref="PositionAffinity.Successor"/>, the mapping targets the position immediately before the following character
+ /// in the anchor buffer. This parameter has no effect if the mapping is unambiguous.</param>
+ /// <returns>A <see cref="SnapshotPoint"/> in the targeted buffer or null if the point and affinity do not appear in that buffer.</returns>
+ /// <remarks>
+ /// In general, a source span seam occurs at the end of a source span of nonzero length
+ /// and the beginning of a source span of nonzero length, and
+ /// coincides with zero or more source spans of zero length. Every span on a seam
+ /// has a point in the result collection.
+ /// </remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="targetSnapshot"/> is null.</exception>
+ SnapshotPoint? GetPoint(ITextSnapshot targetSnapshot, PositionAffinity affinity);
+
+ /// <summary>
+ /// Maps the point to a matching <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="match">The predicate used to match the <see cref="ITextBuffer"/>.</param>
+ /// <param name="affinity">If the mapping is ambiguous (the position lies on a source span seam), this parameter affects the mapping as follows:
+ /// if <paramref name="affinity"/> is <see cref="PositionAffinity.Predecessor"/>, the mapping targets
+ /// the position immediately after the preceding character in the anchor buffer; if <paramref name="affinity"/> is
+ /// <see cref="PositionAffinity.Successor"/>, the mapping targets the position immediately before the following character
+ /// in the anchor buffer. This parameter has no effect if the mapping is unambiguous.</param>
+ /// <returns>A <see cref="SnapshotPoint"/> in the matching buffer, or null if the point and affinity do not appear in that buffer.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="match"/> is null.</exception>
+ /// <remarks><paramref name="match"/> will be called as text buffers in the buffer graph are encountered, until a match is found.
+ /// This selects the buffer of interest and <paramref name="match"/> is not called again.
+ /// If no match is found with any of the buffers, the result is null.</remarks>
+ SnapshotPoint? GetPoint(Predicate<ITextBuffer> match, PositionAffinity affinity);
+
+ /// <summary>
+ /// Maps the point to an insertion point in a matching <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="match">The predicate used to match the <see cref="ITextBuffer"/>.</param>
+ /// <returns>A <see cref="SnapshotPoint"/> in the matching buffer or null if the point does not appear in that buffer.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="match"/> is null.</exception>
+ /// <remarks>In the usual case, this is a straightforward computation that maps through projection buffers, subject to
+ /// caller approval using <paramref name="match"/>. If there is ambiguity in a projection mapping, the
+ /// <see cref="IProjectionEditResolver.GetTypicalInsertionPosition"/> method for the relevant projection buffer will be consulted.
+ /// <paramref name="match"/> will be called as text buffers in the buffer graph are encountered, until a match is found.
+ /// This selects the buffer of interest and the predicate will not be called again.
+ /// If no match is found with any of encountered buffers, the result will be null.</remarks>
+ SnapshotPoint? GetInsertionPoint(Predicate<ITextBuffer> match);
+
+ /// <summary>
+ /// The <see cref="ITextBuffer"/> from which this point was created.
+ /// </summary>
+ ITextBuffer AnchorBuffer { get; }
+
+ /// <summary>
+ /// The <see cref="IBufferGraph"/> that this point uses to perform the mapping.
+ /// </summary>
+ IBufferGraph BufferGraph { get; }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Model/IMappingSpan.cs b/src/Text/Def/TextData/Model/IMappingSpan.cs
new file mode 100644
index 0000000..7ef4dbb
--- /dev/null
+++ b/src/Text/Def/TextData/Model/IMappingSpan.cs
@@ -0,0 +1,62 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using System.Collections.ObjectModel;
+ using Microsoft.VisualStudio.Text.Projection;
+
+ /// <summary>
+ /// A span in a <see cref="ITextBuffer"/> that can be mapped within a <see cref="Microsoft.VisualStudio.Text.Projection.IBufferGraph"/>.
+ /// </summary>
+ public interface IMappingSpan
+ {
+ /// <summary>
+ /// Maps the span to a particular <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="targetBuffer">The <see cref="ITextBuffer"/> to which to map the span.</param>
+ /// <returns>The possibly empty collection of spans in the <paramref name="targetBuffer"/> to which the span maps.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="targetBuffer"/> is null.</exception>
+ NormalizedSnapshotSpanCollection GetSpans(ITextBuffer targetBuffer);
+
+ /// <summary>
+ /// Maps the span to a particular <see cref="ITextSnapshot"/>.
+ /// </summary>
+ /// <param name="targetSnapshot">The <see cref="ITextSnapshot"/> to which to map the span.</param>
+ /// <returns>The possibly empty collection of spans in the <paramref name="targetSnapshot"/> to which the span maps.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="targetSnapshot"/> is null.</exception>
+ NormalizedSnapshotSpanCollection GetSpans(ITextSnapshot targetSnapshot);
+
+ /// <summary>
+ /// Maps the span to a matching <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="match">The predicate used to identify the <see cref="ITextBuffer"/>.</param>
+ /// <returns>A possibly empty collection of spans in the matching buffer.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="match"/> is null.</exception>
+ /// <remarks><paramref name="match"/> is called on each text buffer in the buffer graph until it
+ /// returns <c>true</c>. The predicate will not be called again.</remarks>
+ NormalizedSnapshotSpanCollection GetSpans(Predicate<ITextBuffer> match);
+
+ /// <summary>
+ /// Gets the <see cref="IMappingPoint"/> for the start of this span.
+ /// </summary>
+ IMappingPoint Start { get; }
+
+ /// <summary>
+ /// Gets the <see cref="IMappingPoint"/> for the end of this span.
+ /// </summary>
+ IMappingPoint End { get; }
+
+ /// <summary>
+ /// Gets the <see cref="ITextBuffer"/> from which this span was created.
+ /// </summary>
+ ITextBuffer AnchorBuffer { get; }
+
+ /// <summary>
+ /// Gets the <see cref="IBufferGraph"/> that this span uses to perform mapping.
+ /// </summary>
+ IBufferGraph BufferGraph { get; }
+
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Model/INormalizedTextChangeCollection.cs b/src/Text/Def/TextData/Model/INormalizedTextChangeCollection.cs
new file mode 100644
index 0000000..9259f88
--- /dev/null
+++ b/src/Text/Def/TextData/Model/INormalizedTextChangeCollection.cs
@@ -0,0 +1,22 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// A normalized list of <see cref="ITextChange"/> objects. Changes are sorted in ascending order of position,
+ /// and abutting and overlapping changes are combined into a single change.
+ /// </summary>
+ /// <remarks>
+ /// <see cref="INormalizedTextChangeCollection"/> objects are immutable.
+ /// </remarks>
+ public interface INormalizedTextChangeCollection : IList<ITextChange>
+ {
+ /// <summary>
+ /// Determines whether any of the <see cref="ITextChange"/> objects in this list have a nonzero <see cref="ITextChange.LineCountDelta"/>.
+ /// </summary>
+ bool IncludesLineChanges { get; }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/IPersistentSpan.cs b/src/Text/Def/TextData/Model/IPersistentSpan.cs
new file mode 100644
index 0000000..72e9453
--- /dev/null
+++ b/src/Text/Def/TextData/Model/IPersistentSpan.cs
@@ -0,0 +1,81 @@
+// Copyright (c) Microsoft Corporation
+
+// All rights reserved
+
+using System;
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Describes span in a document that remains valid even when the document is closed, opened or modified (while it is open).
+ /// </summary>
+ /// <remarks>
+ /// <para>PersistentSpans are similar to <see cref="ITrackingSpan"/>s, except they can be created on closed documents and will continue to track even when a document is closed and reopened.</para>
+ /// <para>These spans only track changes made while the document is open. They will not track changes made to the document while the document is closed (through Notepad or something similar).</para>
+ /// </remarks>
+ public interface IPersistentSpan : IDisposable
+ {
+ /// <summary>
+ /// Returns true if the document associated with the <see cref="IPersistentSpan"/> is currently open.
+ /// </summary>
+ bool IsDocumentOpen { get; }
+
+ /// <summary>
+ /// Returns the span's <see cref="ITextDocument"/> if the underlying document is open (and null if the document is closed).
+ /// </summary>
+ ITextDocument Document { get; }
+
+ /// <summary>
+ /// Returns the span's <see cref="ITrackingSpan"/> if the underlying document is open (and null if the document is closed).
+ /// </summary>
+ ITrackingSpan Span { get; }
+
+ /// <summary>
+ /// Returns the file path of the document.
+ /// </summary>
+ /// <remarks>
+ /// This property is valid whether or not the document is open.
+ /// </remarks>
+ string FilePath { get; }
+
+ /// <summary>
+ /// Get the starting point of the span as a line number and offset from the start of the line.
+ /// </summary>
+ /// <param name="startLine">Line number of the start point.</param>
+ /// <param name="startIndex">Character offset from the start of the line containing the start point.</param>
+ /// <returns>true if the the out parameters are valid; false otherwise (in which case TryGetSpan will work).</returns>
+ /// <remarks>
+ /// <para>This method can be used on any span if the underlying document is open.</para>
+ /// <para>If the underlying document is closed, then this method can be used if either the document was created on the closed document using the line/index method
+ /// of the factory or the document had ever been opened after the span was created.</para>
+ /// <para>In general, you should try this method (and <see cref="TryGetEndLineIndex"/>) before using <see cref="TryGetSpan"/>.</para>
+ /// </remarks>
+ bool TryGetStartLineIndex(out int startLine, out int startIndex);
+
+ /// <summary>
+ /// Get the ending point of the span as a line number and offset from the start of the line.
+ /// </summary>
+ /// <param name="endLine">Line number of the end point.</param>
+ /// <param name="endIndex">Character offset from the start of the line containing the end point.</param>
+ /// <returns>true if the the out parameters are valid; false otherwise (in which case TryGetSpan will work).</returns>
+ /// <remarks>
+ /// <para>This method can be used on any span if the underlying document is open.</para>
+ /// <para>If the underlying document is closed, then this method can be used if either the document was created on the closed document using the line/index method
+ /// of the factory or the document had ever been opened after the span was created.</para>
+ /// <para>In general, you should try this method (and <see cref="TryGetStartLineIndex"/>) before using <see cref="TryGetSpan"/>.</para>
+ /// </remarks>
+ bool TryGetEndLineIndex(out int endLine, out int endIndex);
+
+ /// <summary>
+ /// Get the span as a character offset from the start of the buffer.
+ /// </summary>
+ /// <param name="span">Corresponding span in the buffer.</param>
+ /// <returns>true if the the out parameters are valid; false otherwise (in which case TryGetStartLineIndex/TryGetEndLineIndex will work).</returns>
+ /// <remarks>
+ /// <para>This method can be used on any span if the underlying document is open.</para>
+ /// <para>If the underlying document is closed, then this method only be used if the document was created using the span method of the factory and the
+ /// document has never been opened after the span was created.</para>
+ /// <para>In general, you should try to use <see cref="TryGetStartLineIndex"/> and <see cref="TryGetEndLineIndex"/> before using this method.</para>
+ /// </remarks>
+ bool TryGetSpan(out Span span);
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Model/IPersistentSpanFactory.cs b/src/Text/Def/TextData/Model/IPersistentSpanFactory.cs
new file mode 100644
index 0000000..3ffce14
--- /dev/null
+++ b/src/Text/Def/TextData/Model/IPersistentSpanFactory.cs
@@ -0,0 +1,74 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// A factory for creating <see cref="IPersistentSpan"/>s.
+ /// </summary>
+ /// <remarks>
+ /// <para>PersistentSpans are similar to <see cref="ITrackingSpan"/>s, except they can be created on closed documents and will continue to track even when a document is closed and reopened.</para>
+ /// <para>These spans only track changes made while the document is open. They will not track changes made to the document while the document is closed (through Notepad or something similar).</para>
+ /// </remarks>
+ public interface IPersistentSpanFactory
+ {
+ /// <summary>
+ /// Can an <see cref="IPersistentSpan"/> be created on the specified buffer.
+ /// </summary>
+ /// <param name="buffer">Buffer in question.</param>
+ /// <returns>True if a span can be created.</returns>
+ /// <remarks>
+ /// Buffers that are not associated with <see cref="ITextDocument"/>s can not be used to create <see cref="IPersistentSpan"/>.
+ /// </remarks>
+ bool CanCreate(ITextBuffer buffer);
+
+ /// <summary>
+ /// Create an <see cref="IPersistentSpan"/> for a snapshot span on a document that is currently open.
+ /// </summary>
+ /// <param name="span">The span of text in this snapshot.</param>
+ /// <param name="trackingMode">How the tracking span will react to changes at its boundaries.</param>
+ /// <returns>The newly created span or null if one can not be created.</returns>
+ IPersistentSpan Create(SnapshotSpan span, SpanTrackingMode trackingMode);
+
+ /// <summary>
+ /// Create an <see cref="IPersistentSpan"/> for a snapshot span on a document that is currently open.
+ /// </summary>
+ /// <param name="snapshot">The snapshot of the currently open document to create the span on.</param>
+ /// <param name="startLine">Line number of the start point.</param>
+ /// <param name="startIndex">Character offset from the start of the line containing the start point.</param>
+ /// <param name="endLine">Line number of the end point.</param>
+ /// <param name="endIndex">Character offset from the start of the line containing the end point.</param>
+ /// <param name="trackingMode">How the tracking span will react to changes at its boundaries.</param>
+ /// <returns>The newly created span.</returns>
+ IPersistentSpan Create(ITextSnapshot snapshot, int startLine, int startIndex, int endLine, int endIndex, SpanTrackingMode trackingMode);
+
+ /// <summary>
+ /// Create an <see cref="IPersistentSpan"/> for a snapshot span on a document that is currently closed.
+ /// </summary>
+ /// <param name="filePath">Name of the file that contains the span.</param>
+ /// <param name="startLine">Line number of the start point.</param>
+ /// <param name="startIndex">Character offset from the start of the line containing the start point.</param>
+ /// <param name="endLine">Line number of the end point.</param>
+ /// <param name="endIndex">Character offset from the start of the line containing the end point.</param>
+ /// <param name="trackingMode">How the tracking span will react to changes at its boundaries.</param>
+ /// <returns>The newly created span.</returns>
+ /// <remarks>
+ /// Using this method to create an <see cref="IPersistentSpan"/> on a document that is already open is
+ /// an error (and will prevent the span from tracking properly).
+ /// </remarks>
+ IPersistentSpan Create(string filePath, int startLine, int startIndex, int endLine, int endIndex, SpanTrackingMode trackingMode);
+
+ /// <summary>
+ /// Create an <see cref="IPersistentSpan"/> for a snapshot span on a document that is currently closed.
+ /// </summary>
+ /// <param name="filePath">Name of the file that contains the span.</param>
+ /// <param name="span">Span as character offsets from the start of the file.</param>
+ /// <param name="trackingMode">How the tracking span will react to changes at its boundaries.</param>
+ /// <returns>The newly created span.</returns>
+ /// <remarks>
+ /// Using this method to create an <see cref="IPersistentSpan"/> on a document that is already open is
+ /// an error (and will prevent the span from tracking properly).
+ /// </remarks>
+ IPersistentSpan Create(string filePath, Span span, SpanTrackingMode trackingMode);
+ }
+}
diff --git a/src/Text/Def/TextData/Model/IReadOnlyRegion.cs b/src/Text/Def/TextData/Model/IReadOnlyRegion.cs
new file mode 100644
index 0000000..d488374
--- /dev/null
+++ b/src/Text/Def/TextData/Model/IReadOnlyRegion.cs
@@ -0,0 +1,47 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// A handle that tracks a possibly empty read-only region of text.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// The text in a read-only region is not necessarily immutable; a read-only region created on a
+ /// projection buffer makes that region read-only to clients of the projection buffer but
+ /// does not affect the source buffers for that text. </para>
+ /// <para>
+ /// Read-only regions prevent edits only on their owning buffer.
+ /// A read-only region that does not prohibit edge insertions does not prevent any insertion if the
+ /// region has (or shrinks to) zero length.
+ /// A zero-length read-only region that prohibits edge insertions prevents insertions only at its starting
+ /// position, but allows deletions and modifications that span that position.
+ /// </para>
+ /// </remarks>
+ public interface IReadOnlyRegion
+ {
+ /// <summary>
+ /// The edge insertion behavior of the read-only region.
+ /// </summary>
+ EdgeInsertionMode EdgeInsertionMode { get; }
+
+ /// <summary>
+ /// The span of text marked read-only by this region.
+ /// </summary>
+ /// <remarks>
+ /// Not null.
+ /// </remarks>
+ ITrackingSpan Span { get; }
+
+ /// <summary>
+ /// The delegate that notifies the read-only region of read-only checks and edits.
+ /// </summary>
+ /// <remarks>
+ /// <para>May be null.</para>
+ /// </remarks>
+ DynamicReadOnlyRegionQuery QueryCallback { get; }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/IReadOnlyRegionEdit.cs b/src/Text/Def/TextData/Model/IReadOnlyRegionEdit.cs
new file mode 100644
index 0000000..a7008ff
--- /dev/null
+++ b/src/Text/Def/TextData/Model/IReadOnlyRegionEdit.cs
@@ -0,0 +1,106 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// Provides for an atomic set of read-only region editing operations on an <see cref="ITextBuffer"/>.
+ /// Edition positions are specified with respect to the state of the <see cref="ITextBuffer"/>
+ /// at the time the <see cref="IReadOnlyRegionEdit"/> object was created.
+ /// </summary>
+ /// <remarks>
+ /// <para>At most one <see cref="ITextBufferEdit"/> object may be active for a particular <see cref="ITextBuffer"/>. It is considered
+ /// active as long as it has been neither applied nor canceled; calling Dispose() on an unapplied object is equivalent to calling Cancel. </para>
+ /// <para>The operations performed using this object do not appear in the <see cref="ITextBuffer"/> until the <see cref="ITextBufferEdit.Apply"/>
+ /// method has been called.</para>
+ /// </remarks>
+ public interface IReadOnlyRegionEdit : ITextBufferEdit
+ {
+ /// <summary>
+ /// Marks a span of text in this buffer as read-only. The span remains
+ /// read-only until the <see cref="IReadOnlyRegion"/> is removed.
+ /// </summary>
+ /// <param name="span">
+ /// The span to mark as read-only.
+ /// </param>
+ /// <returns>
+ /// The <see cref="IReadOnlyRegion"/> used to track this read-only region. This object must be used
+ /// to remove the read-only region.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="span"/> is past the end of the buffer.</exception>
+ /// <remarks>Insertions at the edge of the read-only region are allowed by default.</remarks>
+ /// <remarks>The region is created edge exclusive by default.</remarks>
+ IReadOnlyRegion CreateReadOnlyRegion(Span span);
+
+ /// <summary>
+ /// Marks a span of text in this buffer as read-only. The span remains
+ /// read-only until it is marked as writable or forced writable again.
+ /// </summary>
+ /// <param name="span">
+ /// The span to mark as read-only.
+ /// </param>
+ /// <param name="trackingMode">
+ /// Specifies the tracking behavior of the read-only region.
+ /// </param>
+ /// <param name="edgeInsertionMode">
+ /// Specifies the edge insertion behavior of the read-only region.
+ /// </param>
+ /// <returns>
+ /// The <see cref="IReadOnlyRegion"/> used to track this read-only region. This object will be used
+ /// to remove the read-only region.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="span"/> is past the end of the buffer.</exception>
+ /// <remarks>
+ /// Zero-length read-only regions restrict inserts only at that point. A deletion or modification over that span
+ /// can still occur.
+ /// </remarks>
+ IReadOnlyRegion CreateReadOnlyRegion(Span span, SpanTrackingMode trackingMode, EdgeInsertionMode edgeInsertionMode);
+
+ /// <summary>
+ /// Marks a span of text in this buffer as as conditionally read-only,
+ /// subject to a check performed when the region is queried. The span remains
+ /// read-only until it is marked as writable or forced writable again.
+ /// </summary>
+ /// <param name="span">
+ /// The span to mark as read-only.
+ /// </param>
+ /// <param name="trackingMode">
+ /// Specifies the tracking behavior of the read-only region.
+ /// </param>
+ /// <param name="edgeInsertionMode">
+ /// Specifies the edge insertion behavior of the read-only region.
+ /// </param>
+ /// <param name="callback">
+ /// The delegate that notifies the read-only region of read-only checks and edits. May be null.
+ /// See <see cref="IReadOnlyRegion.QueryCallback"/>.
+ /// </param>
+ /// <returns>
+ /// The <see cref="IReadOnlyRegion"/> used to track this read-only region. This object will be used
+ /// to remove the read-only region.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="span"/> is past the end of the buffer.</exception>
+ /// <remarks>
+ /// Zero-length read-only regions restrict inserts only at that point. A deletion or modification over that span
+ /// can still occur.
+ /// </remarks>
+ IReadOnlyRegion CreateDynamicReadOnlyRegion(Span span, SpanTrackingMode trackingMode, EdgeInsertionMode edgeInsertionMode, DynamicReadOnlyRegionQuery callback);
+
+ /// <summary>
+ /// Removes the read-only region from the list of read-only regions in this buffer.
+ /// </summary>
+ /// <param name="readOnlyRegion">
+ /// The read-only region to remove.
+ /// </param>
+ /// <remarks>
+ /// Removing a read-only region that has already been removed does nothing.
+ /// </remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="readOnlyRegion"/> is null.</exception>
+ /// <exception cref="InvalidOperationException"><paramref name="readOnlyRegion"/> was created on another buffer.</exception>
+ void RemoveReadOnlyRegion(IReadOnlyRegion readOnlyRegion);
+ }
+}
diff --git a/src/Text/Def/TextData/Model/ITextBuffer.cs b/src/Text/Def/TextData/Model/ITextBuffer.cs
new file mode 100644
index 0000000..5e3e53e
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ITextBuffer.cs
@@ -0,0 +1,273 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// A mutable sequence of Unicode characters encoded using UTF-16.
+ /// Positions within the buffer are treated as a sequence of characters (starting at character zero) or
+ /// as a sequence of lines (starting at line zero). An empty buffer has a single line containing no characters.
+ /// </summary>
+ public interface ITextBuffer : IPropertyOwner
+ {
+ /// <summary>Gets the content type of the text in the buffer.
+ /// </summary>
+ IContentType ContentType { get; }
+
+ /// <summary>
+ /// Gets the current content of the buffer.
+ /// </summary>
+ /// <returns></returns>
+ ITextSnapshot CurrentSnapshot { get; }
+
+ /// <summary>
+ /// Creates an <see cref="ITextEdit"/> object that handles compound edit operations on this buffer.
+ /// </summary>
+ /// <param name="options">Options to apply to the compound edit operation.</param>
+ /// <param name="reiteratedVersionNumber">If not null, indicates that the version to be created by this edit operation is
+ /// the product of an undo or redo operation.</param>
+ /// <param name="editTag">An arbitrary object that will be associated with this edit transaction.</param>
+ /// <returns>A new <see cref="ITextEdit"/> object.</returns>
+ /// <exception cref="InvalidOperationException">Another <see cref="ITextBufferEdit"/> object is active for this text buffer, or
+ /// <see cref="CheckEditAccess"/> would return false.</exception>
+ ITextEdit CreateEdit(EditOptions options,
+ int? reiteratedVersionNumber,
+ object editTag);
+
+ /// <summary>
+ /// Creates an <see cref="ITextEdit"/> object that handles compound edit operations on this buffer.
+ /// </summary>
+ /// <returns>A new <see cref="ITextEdit"/> object.</returns>
+ /// <exception cref="InvalidOperationException">Another <see cref="ITextBufferEdit"/> object is active for this text buffer.</exception>
+ /// <remarks>This method is equivalent to CreateEdit(EditOptions.None, null, null).</remarks>
+ ITextEdit CreateEdit();
+
+ /// <summary>
+ /// Creates an <see cref="IReadOnlyRegionEdit"/> object that handles adding or removing read-only regions from this buffer.
+ /// </summary>
+ /// <returns>A new <see cref="IReadOnlyRegionEdit"/> object.</returns>
+ /// <exception cref="InvalidOperationException">Another <see cref="ITextBufferEdit"/> object is active for this text buffer, or
+ /// <see cref="CheckEditAccess"/> would return false.</exception>
+ IReadOnlyRegionEdit CreateReadOnlyRegionEdit();
+
+ /// <summary>
+ /// Determines whether an edit operation is currently in progress on the <see cref="ITextBuffer"/>.
+ /// </summary>
+ bool EditInProgress { get; }
+
+ /// <summary>
+ /// Claims ownership of this buffer for the current thread. All subsequent modifications of this <see cref="ITextBuffer"/>
+ /// must be made from the current thread, or else an <see cref="InvalidOperationException"/> will be raised.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">This method has been called previously from a different thread, or a
+ /// <see cref="ITextBufferEdit"/> object is active for this text buffer.</exception>
+ void TakeThreadOwnership();
+
+ /// <summary>
+ /// Determines whether edit operations on this text buffer are permitted on the calling thread. If <see cref="TakeThreadOwnership"/> has
+ /// previously been called, edit operations are permitted only from the same thread that made that call.
+ /// </summary>
+ /// <returns><c>true</c> if the calling thread is allowed to perform edit operations, otherwise <c>false</c>.</returns>
+ bool CheckEditAccess();
+
+ /// <summary>
+ /// Occurs when an <see cref="IReadOnlyRegionEdit"/> has created or removed read-only regions.
+ /// </summary>
+ event EventHandler<SnapshotSpanEventArgs> ReadOnlyRegionsChanged;
+
+ /// <summary>
+ /// Occurs when a non-empty <see cref="ITextEdit"/> is successfully applied.
+ /// </summary>
+ /// <remarks>
+ /// This event is raised after <see cref="ChangedHighPriority"/> events and before <see cref="ChangedLowPriority"/> events.
+ ///
+ /// In the case that a second edit is applied by a listener of the Changed event (or the
+ /// ChangedLowPriority or ChangedHighPriority events), the Changed events for the second edit
+ /// won't be raised until all listeners have been notified of the first edit (via ChangedLowPriority, Changed, and
+ /// ChangedHighPriority events). That is, the events for subsequent edits are queued. This ensures listeners
+ /// receive the Changed events in the order the edits were applied.
+ /// </remarks>
+ event EventHandler<TextContentChangedEventArgs> Changed;
+
+ /// <summary>
+ /// Occurs when a non-empty <see cref="ITextEdit"/> is successfully applied.
+ /// </summary>
+ /// <remarks>
+ /// This event is raised after <see cref="ChangedHighPriority"/> and <see cref="Changed"/> events.
+ ///
+ /// Changed events for edits made within a ChangedLowPriority, <see cref="Changed"/>, or
+ /// <see cref="ChangedHighPriority" /> listener are queued. See <see cref="Changed"/> for more
+ /// information about event queuing.
+ /// </remarks>
+ event EventHandler<TextContentChangedEventArgs> ChangedLowPriority;
+
+ /// <summary>
+ /// Occurs when a non-empty <see cref="ITextEdit"/> is successfully applied.
+ /// </summary>
+ /// <remarks>
+ /// This event is raised before <see cref="Changed"/> and <see cref="ChangedHighPriority"/> events.
+ ///
+ /// Changed events for edits made within a ChangedLowPriority, <see cref="Changed"/>, or
+ /// <see cref="ChangedHighPriority" /> listener are queued. See <see cref="Changed"/> for more
+ /// information about event queuing.
+ /// </remarks>
+ event EventHandler<TextContentChangedEventArgs> ChangedHighPriority;
+
+ /// <summary>
+ /// Occurs just before a non-empty <see cref="ITextEdit"/> is applied.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// If the edit operation is canceled in this event, another edit operation can be be started immediately in the event handler.
+ /// For example, this event may be used to provide checkout on edit as an implicit, user-cancelable source control functionality.
+ /// </para>
+ /// </remarks>
+ event EventHandler<TextContentChangingEventArgs> Changing;
+
+ /// <summary>
+ /// Occurs after the Changed event and any resulting edits.
+ /// </summary>
+ /// <remarks>
+ /// Once <see cref="Changed"/> events have been raised for an edit as well as any resulting
+ /// edits (i.e. when an edit is made within a Changed listener), the PostChanged event is
+ /// raised.
+ /// </remarks>
+ event EventHandler PostChanged;
+
+ /// <summary>
+ /// Occurs whenever the <see cref="IContentType"/> has been changed.
+ /// </summary>
+ event EventHandler<ContentTypeChangedEventArgs> ContentTypeChanged;
+
+ /// <summary>
+ /// Changes the <see cref="IContentType"/> for this <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="newContentType">The new <see cref="IContentType"/>.</param>
+ /// <param name="editTag">An arbitrary object that will be associated with this edit transaction.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="newContentType"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">Another <see cref="ITextBufferEdit"/> object is active for this <see cref="ITextBuffer"/>, or
+ /// <see cref="CheckEditAccess"/> would return false.</exception>
+ void ChangeContentType(IContentType newContentType, object editTag);
+
+ #region Editing shortcuts
+ /// <summary>
+ /// Inserts the given <paramref name="text"/>at the specified <paramref name="position"/>in the <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="position">The buffer position at which the first character of the text will appear.</param>
+ /// <param name="text">The text to be inserted.</param>
+ /// <remarks>
+ /// This is a shortcut for creating a new <see cref="ITextEdit"/> object, using it to insert the text, and then applying it. If the insertion
+ /// fails on account of a read-only region, the snapshot returned will be the same as the current snapshot of the buffer before
+ /// the attempted insertion.
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than the length of the buffer.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="text"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">A text edit is currently active, or
+ /// <see cref="CheckEditAccess"/> would return false.</exception>
+ ITextSnapshot Insert(int position, string text);
+
+ /// <summary>
+ /// Deletes a sequence of characters from the buffer.
+ /// </summary>
+ /// <param name="deleteSpan">The span of characters to delete.</param>
+ /// <remarks>
+ /// This is a shortcut for creating a new <see cref="ITextEdit"/> object, using it to delete the text, and then applying it. If the deletion
+ /// fails on account of a read-only region, the snapshot returned will be the same as the current snapshot of the buffer before
+ /// the attempted deletion.
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="deleteSpan"/>.End is greater than the length of the buffer.</exception>
+ /// <exception cref="InvalidOperationException">A TextEdit is currently active, or
+ /// <see cref="CheckEditAccess"/> would return false.</exception>
+ ITextSnapshot Delete(Span deleteSpan);
+
+ /// <summary>
+ /// Replaces a sequence of characters with different text. This is equivalent to first deleting the text to be replaced and then
+ /// inserting the new text.
+ /// </summary>
+ /// <param name="replaceSpan">The span of characters to replace.</param>
+ /// <param name="replaceWith">The new text to replace the old.</param>
+ /// <remarks>
+ /// This is a shortcut for creating a new <see cref="ITextEdit"/> object, using it to replace the text, and then applying it. If the replacement
+ /// fails on account of a read-only region, the snapshot returned will be the same as the current snapshot of the buffer before
+ /// the attempted replacement.
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="replaceSpan"/>.End is greater than the length of the buffer.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="replaceWith"/>is null.</exception>
+ /// <exception cref="InvalidOperationException">A text edit is currently active, or
+ /// <see cref="CheckEditAccess"/> would return false.</exception>
+ ITextSnapshot Replace(Span replaceSpan, string replaceWith);
+ #endregion
+
+ #region Read Only Region Queries
+ /// <summary>
+ /// Determines whether a text insertion would be prohibited at <paramref name="position"/> due to an <see cref="IReadOnlyRegion"/>.
+ /// </summary>
+ /// <param name="position">The position of the proposed text insertion.</param>
+ /// <returns>
+ /// <c>true</c> if an <see cref="IReadOnlyRegion"/> would prohibit insertions at this position, otherwise <c>false</c>.
+ /// </returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is negative or greater than <see cref="CurrentSnapshot"/>.Length.</exception>
+ /// <exception cref="InvalidOperationException"><see cref="TakeThreadOwnership"/> has previously been called, and this call is being made
+ /// from a different thread.</exception>
+ bool IsReadOnly(int position);
+
+ /// <summary>
+ /// Determines whether a text insertion would be prohibited at <paramref name="position"/> due to an <see cref="IReadOnlyRegion"/>.
+ /// </summary>
+ /// <param name="position">The position of the proposed text insertion.</param>
+ /// <param name="isEdit"><c>true</c> if this check is part of an edit. <c>false</c> for a query without side effects.</param>
+ /// <returns><c>true</c> if an <see cref="IReadOnlyRegion"/> would prohibit insertions at this position, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is negative or greater than <see cref="CurrentSnapshot"/>.Length.</exception>
+ /// <exception cref="InvalidOperationException"><see cref="TakeThreadOwnership"/> has previously been called, and this call is being made
+ /// from a different thread.</exception>
+ bool IsReadOnly(int position, bool isEdit);
+
+ /// <summary>
+ /// Determines whether a text modification or deletion would be prohibited at <paramref name="span"/> due to an <see cref="IReadOnlyRegion"/>
+ /// </summary>
+ /// <param name="span">The span to check.</param>
+ /// <returns>
+ /// <c>true</c> if the entire span could be deleted or replaced, otherwise <c>false</c>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">The <see cref="Span.End"/> property of <paramref name="span"/> is greater than <see cref="CurrentSnapshot"/>.Length.</exception>
+ /// <exception cref="InvalidOperationException"><see cref="TakeThreadOwnership"/> has previously been called, and this call is being made
+ /// from a different thread.</exception>
+ bool IsReadOnly(Span span);
+
+ /// <summary>
+ /// Determines whether a text modification or deletion would be prohibited at <paramref name="span"/> due to an <see cref="IReadOnlyRegion"/>
+ /// </summary>
+ /// <param name="span">The span to check.</param>
+ /// <param name="isEdit"><c>true</c> if this check is part of an edit. <c>false</c> for a query without side effects.</param>
+ /// <returns><c>true</c> if the entire span could be deleted or replaced, <c>false</c> otherwise.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">The <see cref="Span.End"/> property of <paramref name="span"/> is greater than <see cref="CurrentSnapshot"/>.Length.</exception>
+ /// <exception cref="InvalidOperationException"><see cref="TakeThreadOwnership"/> has previously been called, and this call is being made
+ /// from a different thread.</exception>
+ bool IsReadOnly(Span span, bool isEdit);
+
+ /// <summary>
+ /// Gets a list of read-only regions that overlap the given span.
+ /// </summary>
+ /// <param name="span">
+ /// The span to check for read-only regions.
+ /// </param>
+ /// <returns>
+ /// A <see cref="NormalizedSpanCollection"/> of read-only regions that intersect the given span.
+ /// </returns>
+ /// <remarks>
+ /// This method returns an empty list if there are no read-only
+ /// regions intersecting the span, or if the span is zero-length.
+ /// </remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="span"/> is past the end of the buffer.</exception>
+ /// <exception cref="InvalidOperationException"><see cref="TakeThreadOwnership"/> has previously been called, and this call is being made
+ /// from a different thread.</exception>
+ NormalizedSpanCollection GetReadOnlyExtents(Span span);
+ #endregion
+ }
+}
diff --git a/src/Text/Def/TextData/Model/ITextBufferEdit.cs b/src/Text/Def/TextData/Model/ITextBufferEdit.cs
new file mode 100644
index 0000000..f70431c
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ITextBufferEdit.cs
@@ -0,0 +1,49 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// Represents edit operations against a <see cref="ITextBuffer"/>.
+ /// </summary>
+ public interface ITextBufferEdit : IDisposable
+ {
+ /// <summary>
+ /// A snapshot of the <see cref="ITextBuffer"/> at the time this ITextBufferEdit object was created.
+ /// </summary>
+ ITextSnapshot Snapshot { get; }
+
+ /// <summary>
+ /// Commits all the modifications made with this <see cref="ITextBufferEdit"/> object to the underlying <see cref="ITextBuffer"/>.
+ /// Depending on the type of edit, it may also cause the <see cref="ITextBuffer"/> to generate a new snapshot and raise its Changed
+ /// event if any modifications were made. This method may be called only
+ /// once. After it is called, any other calls on this object (other than Dispose) will result in an <see cref="InvalidOperationException"/>.
+ /// </summary>
+ /// <remarks>
+ /// Canceled will be <c>true</c> after this method returns if a handler of the buffer's Changing event canceled the change.
+ /// </remarks>
+ /// <returns>
+ /// A snapshot of the state of the <see cref="ITextBuffer"/> after the change is applied.
+ /// If there was no change, or edit was canceled, or the edit is of a type that does not generate snapshots, no new snapshot will be created,
+ /// and the previous snapshot will be returned.
+ /// </returns>
+ /// <exception cref="InvalidOperationException">The <see cref="Apply"/> or <see cref="Cancel"/> or <see cref="IDisposable.Dispose"/>
+ /// method has previously been called on this object.</exception>
+ ITextSnapshot Apply();
+
+ /// <summary>
+ /// Abandons all modifications started using this <see cref="ITextBufferEdit"/> object. Any further calls
+ /// on this object will result in an <see cref="InvalidOperationException"/>.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">The <see cref="IDisposable.Dispose"/>
+ /// method has previously been called on this object, or the edit has already been applied.</exception>
+ void Cancel();
+
+ /// <summary>
+ /// Determines whether this edit has been canceled.
+ /// </summary>
+ bool Canceled { get; }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Model/ITextBufferFactory.cs b/src/Text/Def/TextData/Model/ITextBufferFactory.cs
new file mode 100644
index 0000000..78aafbc
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ITextBufferFactory.cs
@@ -0,0 +1,84 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using System.IO;
+
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// The factory service for ordinary TextBuffers.
+ /// </summary>
+ /// <remarks>This is a MEF Component, and should be imported as follows:
+ /// [Import]
+ /// ITextBufferFactoryService factory = null;
+ /// </remarks>
+ public interface ITextBufferFactoryService
+ {
+ /// <summary>
+ /// Predefined default content type. This is the base type for most content types.
+ /// </summary>
+ IContentType TextContentType { get; }
+
+ /// <summary>
+ /// Predefined content type for plain text files.
+ /// </summary>
+ IContentType PlaintextContentType { get; }
+
+ /// <summary>
+ /// A content type for which no associated artifacts are automatically created.
+ /// </summary>
+ IContentType InertContentType { get; }
+
+ /// <summary>
+ /// Creates an empty <see cref="ITextBuffer"/> with <see cref="IContentType"/> "text".
+ /// </summary>
+ /// <returns>
+ /// An empty <see cref="ITextBuffer"/> object.
+ /// </returns>
+ ITextBuffer CreateTextBuffer();
+
+ /// <summary>
+ /// Creates an empty <see cref="ITextBuffer"/> with the specified <see cref="IContentType"/>.
+ /// </summary>
+ /// <param name="contentType">The <see cref="IContentType"/> for the new <see cref="ITextBuffer"/>.</param>
+ /// <returns>
+ /// An empty <see cref="ITextBuffer"/> with the given ContentType.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="contentType"/> is null.</exception>
+ ITextBuffer CreateTextBuffer(IContentType contentType);
+
+ /// <summary>
+ /// Creates an <see cref="ITextBuffer"/> with the specified <see cref="IContentType"/> and populates it
+ /// with the given text.
+ /// </summary>
+ /// <param name="text">The initial text to add.</param>
+ /// <param name="contentType">The <see cref="IContentType"/> for the new <see cref="ITextBuffer"/>.</param>
+ /// <returns>
+ /// A <see cref="ITextBuffer"/> object with the given text and <see cref="IContentType"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">Either <paramref name="text"/> or <paramref name="contentType"/> is null.</exception>
+ ITextBuffer CreateTextBuffer(string text, IContentType contentType);
+
+ /// <summary>
+ /// Creates an <see cref="ITextBuffer"/> with the given <paramref name="contentType"/> and populates it by
+ /// reading data from the specified TextReader.
+ /// </summary>
+ /// <param name="reader">The TextReader from which to read.</param>
+ /// <param name="contentType">The <paramref name="contentType"/> for the text contained in the new <see cref="ITextBuffer"/></param>
+ /// <returns>
+ /// An <see cref="ITextBuffer"/> object with the given TextReader and <paramref name="contentType"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="reader"/> is null.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="contentType"/> is null.</exception>
+ /// <remarks>The <paramref name="reader"/> is not closed by this operation.</remarks>
+ ITextBuffer CreateTextBuffer(TextReader reader, IContentType contentType);
+
+ /// <summary>
+ /// Raised when any <see cref="ITextBuffer"/> is created.
+ /// </summary>
+ event EventHandler<TextBufferCreatedEventArgs> TextBufferCreated;
+ }
+}
diff --git a/src/Text/Def/TextData/Model/ITextChange.cs b/src/Text/Def/TextData/Model/ITextChange.cs
new file mode 100644
index 0000000..966a98d
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ITextChange.cs
@@ -0,0 +1,101 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Describes a single contiguous text change operation on the Text Buffer.
+ ///
+ /// All text changes are considered to be the replacement of <c>oldText</c> with <c>newText</c>.
+ /// <para>
+ /// Insertion is a text change in which <c>oldText</c> is an empty string and <c>newText</c> a non-empty string.
+ /// </para>
+ /// <para>
+ /// Deletion is a text change in which <c>oldText</c> is a non-empty string and <c>newText</c> is an empty string.
+ /// </para>
+ /// <para>
+ /// Modification is a text change in which both <c>oldText</c> and <c>newText</c> are non-empty strings.
+ /// </para>
+ /// </summary>
+ /// <remarks>
+ /// <see cref="ITextChange"/> objects are immutable.
+ /// </remarks>
+ public interface ITextChange
+ {
+ /// <summary>
+ /// The span of the text change in the snapshot immediately before the change.
+ /// </summary>
+ /// <remarks>
+ /// This span is empty for a pure insertion. Its start position may differ from NewSpan.Start only when there is more
+ /// than one <see cref="ITextChange"/> included in moving from one snapshot to the next.
+ /// </remarks>
+ Span OldSpan { get; }
+
+ /// <summary>
+ /// The span of the <see cref="ITextChange"/> in the snapshot immediately after the change.
+ /// </summary>
+ /// <remarks>
+ /// This span is empty for a pure deletion. Its start position may differ from OldSpan.Start only when there is more
+ /// than one <see cref="ITextChange"/> included in moving from one snapshot to the next.
+ /// </remarks>
+ Span NewSpan { get; }
+
+ /// <summary>
+ /// The position of the text change in the snapshot immediately before the change. The position can differ from
+ /// NewPosition only when there is more than one <see cref="ITextChange"/> included in moving from one snapshot to the next.
+ /// </summary>
+ /// <remarks>This is the equivalent of <c>OldSpan.Start</c>.</remarks>
+ int OldPosition { get; }
+
+ /// <summary>
+ /// The position of the text change in the snapshot immediately after the change. The position can differ from
+ /// OldPosition only when there is more than one <see cref="ITextChange"/> included in moving from one snapshot to the next.
+ /// </summary>
+ /// <remarks>This is the equivalent of <c>NewSpan.Start</c>.</remarks>
+ int NewPosition { get; }
+
+ /// <summary>
+ /// The effect On the length of the buffer resulting from this change.
+ /// </summary>
+ int Delta { get; }
+
+ /// <summary>
+ /// The end position of the <see cref="OldText"/> in the snapshot immediately before the change.
+ /// </summary>
+ /// <remarks>Equivalent to <c>OldSpan.End</c>.</remarks>
+ int OldEnd { get; }
+
+ /// <summary>
+ /// The end position of the <see cref="NewText"/> in the snapshot immediately after the text change.
+ /// </summary>
+ /// <remarks>Equivalent to <c>NewSpan.End</c>.</remarks>
+ int NewEnd { get; }
+
+ /// <summary>
+ /// The text that was replaced.
+ /// </summary>
+ string OldText { get; }
+
+ /// <summary>
+ /// The text that replaced the old text.
+ /// </summary>
+ string NewText { get; }
+
+ /// <summary>
+ /// The length of <see cref="OldText"/>.
+ /// </summary>
+ /// <remarks>This is the equivalent of <c>OldSpan.Length</c>.</remarks>
+ int OldLength { get; }
+
+ /// <summary>
+ /// The length of <see cref="NewText"/>.
+ /// </summary>
+ /// <remarks>This is the equivalent of <c>NewSpan.Length</c>.</remarks>
+ int NewLength { get; }
+
+ /// <summary>
+ /// The effect of this change on the number of lines in the snapshot.
+ /// </summary>
+ int LineCountDelta { get; }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/ITextChange2.cs b/src/Text/Def/TextData/Model/ITextChange2.cs
new file mode 100644
index 0000000..8acc0b5
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ITextChange2.cs
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Extends <see cref="ITextChange"/> with the concept of an opaque change.
+ /// </summary>
+ public interface ITextChange2 : ITextChange
+ {
+ /// <summary>
+ /// Indicates whether the change is opaque. Opaque changes are always replacements in which both the
+ /// old text and new text are non-empty. The differ from other changes in the
+ /// manner in which <see cref="ITrackingPoint"/>s and <see cref="ITrackingSpan"/>s behave. When tracking
+ /// across an opaque replacement, a point or span endpoint that lies within the deleted text will keep the same offset
+ /// within the inserted text (normally a point would move either to the beginning or end of the inserted text,
+ /// depending on its tracking mode).
+ /// </summary>
+ bool IsOpaque { get; }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/ITextChange3.cs b/src/Text/Def/TextData/Model/ITextChange3.cs
new file mode 100644
index 0000000..7827c1d
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ITextChange3.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Extends <see cref="ITextChange2"/> with an ability to efficiently get a substring of old and new text.
+ /// </summary>
+ public interface ITextChange3 : ITextChange2
+ {
+ /// <summary>
+ /// Gets the text that was replaced, starting at the beginning of the span and having length equal to the length of the span.
+ /// </summary>
+ /// <param name="span">The span of text to return.</param>
+ string GetOldText(Span span);
+
+ /// <summary>
+ /// The text that replaced the old text, starting at the beginning of the span and having length equal to the length of the span.
+ /// </summary>
+ /// <param name="span">The span of text to return.</param>
+ string GetNewText(Span span);
+
+ /// <summary>
+ /// Gets a character at given position of the text that was replaced.
+ /// </summary>
+ /// <param name="position">The position of the character to return.</param>
+ char GetOldTextAt(int position);
+
+ /// <summary>
+ /// Gets a character at given position of the text that replaced the old text.
+ /// </summary>
+ /// <param name="position">The position of the character to return.</param>
+ char GetNewTextAt(int position);
+ }
+}
diff --git a/src/Text/Def/TextData/Model/ITextEdit.cs b/src/Text/Def/TextData/Model/ITextEdit.cs
new file mode 100644
index 0000000..8aa711b
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ITextEdit.cs
@@ -0,0 +1,124 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// Represents a set of editing operations on an <see cref="ITextBuffer"/>. The positions of all edit operations are specified
+ /// with respect to the state of the <see cref="ITextBuffer"/> at the time this object was created.
+ /// </summary>
+ /// <remarks>
+ /// <para>At most one <see cref="ITextBufferEdit"/> object may be active at a given time for a particular <see cref="ITextBuffer"/>.
+ /// This object is considered
+ /// active as long as it has been neither Applied nor Cancelled; calling Dispose on an unapplied object is equivalent to calling Cancel. </para>
+ /// <para>The operations performed using this object are not reflected in the <see cref="ITextBuffer"/> until the <see cref="ITextBufferEdit.Apply"/>
+ /// method has been called.</para>
+ /// </remarks>
+ public interface ITextEdit : ITextBufferEdit
+ {
+ /// <summary>
+ /// Inserts the given <paramref name="text"/> at the specified <paramref name="position"/>in the text buffer.
+ /// </summary>
+ /// <param name="position">The buffer position at which the first character of the text will appear.</param>
+ /// <param name="text">The text to be inserted.</param>
+ /// <returns><c>true</c> if the insertion succeeded, <c>false</c> if it failed due to a read-only region.</returns>
+ /// <remarks>Inserting an empty string will succeed but will not generate a new snapshot or raise a
+ /// <see cref="ITextBuffer.Changed"/> event.</remarks>
+ /// <exception cref="InvalidOperationException">The <see cref="ITextBufferEdit.Apply"/> or <see cref="ITextBufferEdit.Cancel"/> or <see cref="IDisposable.Dispose"/>
+ /// method has previously been called on this object.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than the length of the buffer.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="text"/> is null.</exception>
+ bool Insert(int position, string text);
+
+ /// <summary>
+ /// Inserts an array of characters at the specified <paramref name="position"/> in the <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="position">The buffer position at which the first character of the text will appear.</param>
+ /// <param name="characterBuffer">The character array from which characters will be inserted.</param>
+ /// <param name="startIndex">The index in <paramref name="characterBuffer"/> of the first character to insert.</param>
+ /// <param name="length">The number of characters to insert from <paramref name="characterBuffer"/>.</param>
+ /// <returns><c>true</c> if the insertion succeeded, <c>false</c> if it was prevented by a read-only region.</returns>
+ /// <remarks>Inserting zero characters will succeed but will not generate a new snapshot or raise a
+ /// <see cref="ITextBuffer.Changed"/> event.</remarks>
+ /// <exception cref="InvalidOperationException">The <see cref="ITextBufferEdit.Apply"/> or <see cref="ITextBufferEdit.Cancel"/> or <see cref="IDisposable.Dispose"/>
+ /// method has previously been called on this object.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="characterBuffer"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than the length of the buffer, or
+ /// <paramref name="startIndex"/> is less than zero, or <paramref name="length"/> is less than zero, or <paramref name="startIndex"/> + <paramref name="length"/> is
+ /// greater than the length of <paramref name="characterBuffer"/>.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">.</exception>
+ bool Insert(int position, char[] characterBuffer, int startIndex, int length);
+
+ /// <summary>
+ /// Deletes a sequence of characters from the buffer.
+ /// </summary>
+ /// <param name="deleteSpan">The span of characters to delete.</param>
+ /// <returns><c>true</c> if the deletion succeeded, <c>false</c> if it was prevented by a read-only region.</returns>
+ /// <remarks>Deleting an empty span will succeed but will not generate a new snapshot or raise a
+ /// <see cref="ITextBuffer.Changed"/> event.</remarks>
+ /// <exception cref="InvalidOperationException">The <see cref="ITextBufferEdit.Apply"/> or <see cref="ITextBufferEdit.Cancel"/> or <see cref="IDisposable.Dispose"/>
+ /// method has previously been called on this object.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="deleteSpan"/>.End is greater than the length of the buffer.</exception>
+ bool Delete(Span deleteSpan);
+
+ /// <summary>
+ /// Deletes a equence of characters from the buffer.
+ /// </summary>
+ /// <param name="startPosition">The position of the first character to delete.</param>
+ /// <param name="charsToDelete">The number of characters to delete.</param>
+ /// <returns><c>true</c> if the deletion succeeded; <c>false</c> if it was prevented by a read-only region.</returns>
+ /// <remarks>Deleting zero characters will succeed but will not generate a new snapshot or raise a
+ /// <see cref="ITextBuffer.Changed"/> event.</remarks>
+ /// <exception cref="InvalidOperationException">The <see cref="ITextBufferEdit.Apply"/> or <see cref="ITextBufferEdit.Cancel"/> or <see cref="IDisposable.Dispose"/>
+ /// method has previously been called on this object.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="startPosition"/> is less than zero or greater than the length of the buffer, or
+ /// <paramref name="charsToDelete"/> is less than zero, or <paramref name="startPosition"/> + <paramref name="charsToDelete"/>
+ /// is greater than the length of the buffer.</exception>
+ bool Delete(int startPosition, int charsToDelete);
+
+ /// <summary>
+ /// Replaces a sequence of characters with different text. This method has the same effect as first deleting the characters in
+ /// <paramref name="replaceSpan"/> and then inserting <paramref name="replaceWith"/>.
+ /// </summary>
+ /// <param name="replaceSpan">The span of characters to replace.</param>
+ /// <param name="replaceWith">The new text.</param>
+ /// <returns><c>true</c> if the replacement succeeded, <c>false</c> if it was prevented by a read-only region.</returns>
+ /// <remarks>Replacing an empty span with an empty string will succeed but will not generate a new snapshot or raise a
+ /// <see cref="ITextBuffer.Changed"/> event.</remarks>
+ /// <exception cref="InvalidOperationException">The <see cref="ITextBufferEdit.Apply"/> or <see cref="ITextBufferEdit.Cancel"/> or <see cref="IDisposable.Dispose"/>
+ /// method has previously been called on this object.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="replaceSpan"/>.End is greater than the length of the buffer.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="replaceWith"/>is null.</exception>
+ bool Replace(Span replaceSpan, string replaceWith);
+
+ /// <summary>
+ /// Replaces a sequence of characters with different text. This method has the same effect as first deleting the
+ /// <paramref name="charsToReplace"/> and then inserting <paramref name="replaceWith"/>.
+ /// </summary>
+ /// <param name="startPosition">The buffer position at which to start replacing.</param>
+ /// <param name="charsToReplace">The number of characters to replace.</param>
+ /// <param name="replaceWith">The new text.</param>
+ /// <returns><c>true</c> if the replacement succeeded; <c>false</c> if it was prevented by a read-only region.</returns>
+ /// <remarks>Replacing zero characters with an empty string will succeed but will not generate a new snapshot or raise a
+ /// <see cref="ITextBuffer.Changed"/> event.</remarks>
+ /// <exception cref="InvalidOperationException">The <see cref="ITextBufferEdit.Apply"/> or <see cref="ITextBufferEdit.Cancel"/> or <see cref="IDisposable.Dispose"/>
+ /// method has previously been called on this object.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="startPosition"/> is less than zero or greater than the length of the buffer, or
+ /// <paramref name="charsToReplace"/> is less than zero, or <paramref name="startPosition"/> + <paramref name="charsToReplace"/>
+ /// is greater than the length of the buffer.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="replaceWith"/>is null.</exception>
+ bool Replace(int startPosition, int charsToReplace, string replaceWith);
+
+ /// <summary>
+ /// Determines whether the edit has changes in non-read-only regions.
+ /// </summary>
+ bool HasEffectiveChanges { get; }
+
+ /// <summary>
+ /// Determines whether any changes failed to be added to this edit due to read-only regions.
+ /// </summary>
+ bool HasFailedChanges { get; }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/ITextSnapshot.cs b/src/Text/Def/TextData/Model/ITextSnapshot.cs
new file mode 100644
index 0000000..1233216
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ITextSnapshot.cs
@@ -0,0 +1,224 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Provides read access to an immutable snapshot of a <see cref="ITextBuffer"/> containing a sequence of Unicode characters.
+ /// The first character in the sequence has index zero.
+ /// </summary>
+ public interface ITextSnapshot
+ {
+ /// <summary>
+ /// The <see cref="ITextBuffer"/> of which this is a snapshot.
+ /// </summary>
+ /// <remarks>
+ /// This property always returns the same <see cref="ITextBuffer"/> object, but the <see cref="ITextBuffer"/> is not itself immutable.
+ /// </remarks>
+ ITextBuffer TextBuffer { get; }
+
+ /// <summary>
+ /// The <see cref="IContentType"/> of the <see cref="TextBuffer"/> when this snapshot was current.
+ /// </summary>
+ IContentType ContentType { get; }
+
+ /// <summary>
+ /// The version of the <see cref="ITextBuffer"/> that this <see cref="ITextSnapshot"/> represents.
+ /// </summary>
+ /// <remarks>
+ /// This property always returns the same <see cref="ITextVersion"/>. The <see cref="ITextVersion.Changes"/> property is
+ /// initially null and becomes populated when it ceases to be the most recent version.
+ /// </remarks>
+ ITextVersion Version { get; }
+
+ /// <summary>
+ /// Gets the number of UTF-16 characters contained in the snapshot.
+ /// </summary>
+ int Length { get; }
+
+ /// <summary>
+ /// Gets the positive number of lines in the snapshot. A snapshot whose <see cref="Length"/> is zero is considered to have one line.
+ /// </summary>
+ int LineCount { get; }
+
+ /// <summary>
+ /// Gets text from the snapshot starting at the beginning of the span and having length equal to the length of the span.
+ /// </summary>
+ /// <param name="span">The span to return.</param>
+ /// <exception cref="ArgumentOutOfRangeException">The end of the span is greater than <see cref="Length"/>.</exception>
+ /// <returns>A non-null string.</returns>
+ string GetText(Span span);
+
+ /// <summary>
+ /// Gets text from the snapshot starting at <paramref name="startIndex"/> and having length equal to <paramref name="length"/>.
+ /// </summary>
+ /// <param name="startIndex">The starting index.</param>
+ /// <param name="length">The length of text to get.</param>
+ /// <returns>The string of length <paramref name="length"/> starting at <paramref name="startIndex"/> in the underlying <see cref="ITextBuffer"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="startIndex"/> is less than zero or greater than the length of the snapshot,
+ /// or <paramref name="length"/> is less than zero, or <paramref name="startIndex"/> plus <paramref name="length"/> is greater than the length of the snapshot.</exception>
+ string GetText(int startIndex, int length);
+
+ /// <summary>
+ /// Gets all the text in the snapshot.
+ /// </summary>
+ /// <returns>A non-null string.</returns>
+ string GetText();
+
+ /// <summary>
+ /// Converts a range of text to a character array.
+ /// </summary>
+ /// <param name="startIndex">
+ /// The starting index of the range of text.
+ /// </param>
+ /// <param name="length">
+ /// The length of the text.
+ /// </param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="startIndex"/> is less than zero or greater than the length of the snapshot, or
+ /// <paramref name="length"/> is less than zero, or <paramref name="startIndex"/> plus <paramref name="length"/> is greater than the length of the snapshot.</exception>
+ /// <returns>The array of characters starting at <paramref name="startIndex"/> in the underlying <see cref="ITextBuffer"/> and extend to its end.</returns>
+ char[] ToCharArray(int startIndex, int length);
+
+ /// <summary>
+ /// Copies a range of text to a character array.
+ /// </summary>
+ /// <param name="sourceIndex">
+ /// The starting index in the text snapshot.
+ /// </param>
+ /// <param name="destination">
+ /// The destination array.
+ /// </param>
+ /// <param name="destinationIndex">
+ /// The index in the destination array at which to start copying the text.
+ /// </param>
+ /// <param name="count">
+ /// The number of characters to copy.
+ /// </param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="sourceIndex"/> is less than zero or greater than the length of the snapshot, or
+ /// <paramref name="count"/> is less than zero, or <paramref name="sourceIndex"/> + <paramref name="count"/> is greater than the length of the snapshot, or
+ /// <paramref name="destinationIndex"/> is less than zero, or <paramref name="destinationIndex"/> plus <paramref name="count"/> is greater than the length of <paramref name="destination"/>.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="destination"/> is null.</exception>
+ void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count);
+
+ /// <summary>
+ /// Gets a single character at the specified position.
+ /// </summary>
+ /// <param name="position">The position of the character.</param>
+ /// <returns>The character at <paramref name="position"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than or equal to the length of the snapshot.</exception>
+ char this[int position] { get; }
+
+ /// <summary>
+ /// Creates a <see cref="ITrackingPoint"/> against this snapshot.
+ /// </summary>
+ /// <param name="position">The position of the point.</param>
+ /// <param name="trackingMode">The tracking mode of the point.</param>
+ /// <returns>A non-null TrackingPoint.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than the length of the snapshot.</exception>
+ ITrackingPoint CreateTrackingPoint(int position, PointTrackingMode trackingMode);
+
+ /// <summary>
+ /// Creates a <see cref="ITrackingPoint"/> against this snapshot.
+ /// </summary>
+ /// <param name="position">The position of the point.</param>
+ /// <param name="trackingMode">The tracking mode of the point.</param>
+ /// <param name="trackingFidelity">The tracking fidelity of the point.</param>
+ /// <returns>A non-null TrackingPoint.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than the length of the snapshot.</exception>
+ /// <remarks>This text point reprises its previous position when visiting a version that was created by undo or redo.</remarks>
+ ITrackingPoint CreateTrackingPoint(int position, PointTrackingMode trackingMode, TrackingFidelityMode trackingFidelity);
+
+ /// <summary>
+ /// Creates a <see cref="ITrackingSpan"/> against this snapshot.
+ /// </summary>
+ /// <param name="span">The span of text in this snapshot.</param>
+ /// <param name="trackingMode">How the tracking span will react to changes at its boundaries.</param>
+ /// <returns>A non-null <see cref="ITrackingSpan"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException">The end of the span is greater than the length of the text snapshot.</exception>
+ ITrackingSpan CreateTrackingSpan(Span span, SpanTrackingMode trackingMode);
+
+ /// <summary>
+ /// Creates a <see cref="ITrackingSpan"/> against this snapshot.
+ /// </summary>
+ /// <param name="span">The span of text in this snapshot.</param>
+ /// <param name="trackingMode">How the tracking span should react to changes at its boundaries.</param>
+ /// <param name="trackingFidelity">The tracking fidelity of the span.</param>
+ /// <returns>A non-null <see cref="ITrackingSpan"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException">The end of the span is greater than the length of the text snapshot.</exception>
+ ITrackingSpan CreateTrackingSpan(Span span, SpanTrackingMode trackingMode, TrackingFidelityMode trackingFidelity);
+
+ /// <summary>
+ /// Creates a <see cref="ITrackingSpan"/> against this snapshot.
+ /// </summary>
+ /// <param name="start">The starting position of the tracking span.</param>
+ /// <param name="length">The length of the tracking span.</param>
+ /// <param name="trackingMode">How the tracking span should react to changes at its boundaries.</param>
+ /// <returns>A non-null <see cref="ITrackingSpan"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> is negative or greater than <see cref="Length"/>, or
+ /// <paramref name="length"/> is negative, or <paramref name="start"/> plus <paramref name="length"/>
+ /// is less than <paramref name="start"/>.</exception>
+ ITrackingSpan CreateTrackingSpan(int start, int length, SpanTrackingMode trackingMode);
+
+ /// <summary>
+ /// Creates a <see cref="ITrackingSpan"/> against this snapshot.
+ /// </summary>
+ /// <param name="start">The starting position of the tracking span.</param>
+ /// <param name="length">The length of the tracking span.</param>
+ /// <param name="trackingMode">How the tracking span should react to changes at its boundaries.</param>
+ /// <param name="trackingFidelity">The tracking fidelilty mode.</param>
+ /// <returns>A non-null <see cref="ITrackingSpan"/>..</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> is negative or greater than <see cref="Length"/>, or
+ /// <paramref name="length"/> is negative, or <paramref name="start"/> plus <paramref name="length"/>
+ /// is less than <paramref name="start"/>.</exception>
+ ITrackingSpan CreateTrackingSpan(int start, int length, SpanTrackingMode trackingMode, TrackingFidelityMode trackingFidelity);
+
+ /// <summary>
+ /// Gets an <see cref="ITextSnapshotLine"/> for the given line number.
+ /// </summary>
+ /// <param name="lineNumber">The line number.</param>
+ /// <returns>A non-null <see cref="ITextSnapshotLine"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="lineNumber"/> is less than zero or greater than or equal to <see cref="LineCount"/>.</exception>
+ ITextSnapshotLine GetLineFromLineNumber(int lineNumber);
+
+ /// <summary>
+ /// Gets an <see cref="ITextSnapshotLine"/> for a line at the given position.
+ /// </summary>
+ /// <param name="position">The position.</param>
+ /// <returns>A non-null <see cref="ITextSnapshotLine"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than length of line.</exception>
+ ITextSnapshotLine GetLineFromPosition(int position);
+
+ /// <summary>
+ /// Gets the number of the line that contains the character at the specified position.
+ /// </summary>
+ /// <returns>The line number of the line in which <paramref name="position"/> lies.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than Length/>.</exception>
+ int GetLineNumberFromPosition(int position);
+
+ /// <summary>
+ /// An enumerator for the set of lines in the snapshot.
+ /// </summary>
+ IEnumerable<ITextSnapshotLine> Lines { get; }
+
+ /// <summary>
+ /// Writes a substring of the contents of the snapshot.
+ /// </summary>
+ /// <param name="writer">The <see cref="System.IO.TextWriter"/> to use.</param>
+ /// <param name="span">The span of text to write.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="writer"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">The end of the span is greater than the length of the snapshot.
+ /// </exception>
+ void Write(System.IO.TextWriter writer, Span span);
+
+ /// <summary>
+ /// Writes the contents of the snapshot.
+ /// </summary>
+ /// <param name="writer">The <see cref="System.IO.TextWriter"/>to use.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="writer"/> is null.</exception>
+ void Write(System.IO.TextWriter writer);
+ }
+}
diff --git a/src/Text/Def/TextData/Model/ITextSnapshotLine.cs b/src/Text/Def/TextData/Model/ITextSnapshotLine.cs
new file mode 100644
index 0000000..c11cf08
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ITextSnapshotLine.cs
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Immutable information about a line of text from an ITextSnapshot.
+ /// </summary>
+ public interface ITextSnapshotLine
+ {
+ /// <summary>
+ /// The <see cref="ITextSnapshot"/> in which the line appears.
+ /// </summary>
+ ITextSnapshot Snapshot { get; }
+
+ /// <summary>
+ /// The extent of the line, excluding any line break characters.
+ /// </summary>
+ SnapshotSpan Extent { get; }
+
+ /// <summary>
+ /// The extent of the line, including any line break characters.
+ /// </summary>
+ SnapshotSpan ExtentIncludingLineBreak { get; }
+
+ /// <summary>
+ /// The 0-origin line number of the line.
+ /// </summary>
+ int LineNumber { get; }
+
+ /// <summary>
+ /// The <see cref="SnapshotPoint"/> of the first character in the line.
+ /// </summary>
+ SnapshotPoint Start { get; }
+
+ /// <summary>
+ /// Length of the line, excluding any line break characters.
+ /// </summary>
+ int Length { get; }
+
+ /// <summary>
+ /// Length of the line, including any line break characters.
+ /// </summary>
+ int LengthIncludingLineBreak { get; }
+
+ /// <summary>
+ /// The <see cref="SnapshotPoint"/> of the first character past the end of the line, excluding any
+ /// line break characters (thus will address a line break character, except
+ /// for the last line in the buffer, in which case it addresses a
+ /// position past the end of the buffer).
+ /// </summary>
+ SnapshotPoint End { get; }
+
+ /// <summary>
+ /// The <see cref="SnapshotPoint"/> of the first character past the end of the line, including any
+ /// line break characters (thus will address the first character in
+ /// the succeeding line, unless this is the last line, in which case it addresses a
+ /// position past the end of the buffer).
+ /// </summary>
+ SnapshotPoint EndIncludingLineBreak { get; }
+
+ /// <summary>
+ /// Length of line break characters (always falls in the range [0..2]).
+ /// </summary>
+ int LineBreakLength { get; }
+
+ /// <summary>
+ /// The text of the line, excluding any line break characters.
+ /// </summary>
+ string GetText();
+
+ /// <summary>
+ /// The text of the line, including any line break characters.
+ /// </summary>
+ /// <returns></returns>
+ string GetTextIncludingLineBreak();
+
+ /// <summary>
+ /// The string consisting of the line break characters (if any) at the
+ /// end of the line. Has zero length for the last line in the buffer.
+ /// </summary>
+ /// <returns></returns>
+ string GetLineBreakText();
+ }
+}
diff --git a/src/Text/Def/TextData/Model/ITextVersion.cs b/src/Text/Def/TextData/Model/ITextVersion.cs
new file mode 100644
index 0000000..a0664b1
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ITextVersion.cs
@@ -0,0 +1,139 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// Describes a version of an <see cref="ITextBuffer"/>. Each application of an <see cref="ITextEdit"/> to a text buffer
+ /// generates a new ITextVersion.
+ /// </summary>
+ public interface ITextVersion
+ {
+ /// <summary>
+ /// Gets the next <see cref="ITextVersion"/>. Returns null if and only if this is the most recent version of its text buffer.
+ /// </summary>
+ ITextVersion Next { get; }
+
+ /// <summary>
+ /// Gets the length in characters of this <see cref="ITextVersion"/>.
+ /// </summary>
+ int Length { get; }
+
+ /// <summary>
+ /// Gets the text changes that produce the next version. Returns null if and only if this is the most recent version of its text buffer.
+ /// </summary>
+ INormalizedTextChangeCollection Changes { get; }
+
+ /// <summary>
+ /// Creates a <see cref="ITrackingPoint"/> against this version.
+ /// </summary>
+ /// <param name="position">The position of the point.</param>
+ /// <param name="trackingMode">The tracking mode of the point.</param>
+ /// <returns>A non-null <see cref="ITrackingPoint"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than the length of this version.</exception>
+ ITrackingPoint CreateTrackingPoint(int position, PointTrackingMode trackingMode);
+
+ /// <summary>
+ /// Creates a <see cref="ITrackingPoint"/> against this version.
+ /// </summary>
+ /// <param name="position">The position of the point.</param>
+ /// <param name="trackingMode">The tracking mode of the point.</param>
+ /// <param name="trackingFidelity">The tracking fidelity of the point.</param>
+ /// <returns>A non-null <see cref="ITrackingPoint"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than the length of the snapshot.</exception>
+ /// <remarks>This text point reprises its previous position when visiting a version that was created by undo or redo.</remarks>
+ ITrackingPoint CreateTrackingPoint(int position, PointTrackingMode trackingMode, TrackingFidelityMode trackingFidelity);
+
+ /// <summary>
+ /// Creates a <see cref="ITrackingSpan"/> against this version.
+ /// </summary>
+ /// <param name="span">The span of text in this snapshot that the <see cref="ITrackingSpan"/> should represent.</param>
+ /// <param name="trackingMode">How the <see cref="ITrackingSpan"/> will react to changes at its boundaries.</param>
+ /// <returns>A non-null <see cref="ITrackingSpan"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="span"/>.End is greater than the length of this version, or
+ /// <paramref name="trackingMode"/> is equal to <see cref="SpanTrackingMode.Custom"/>.</exception>
+ ITrackingSpan CreateTrackingSpan(Span span, SpanTrackingMode trackingMode);
+
+ /// <summary>
+ /// Creates a <see cref="ITrackingSpan"/> against this version.
+ /// </summary>
+ /// <param name="span">The span of text in this snapshot that the <see cref="ITrackingSpan"/> should represent.</param>
+ /// <param name="trackingMode">How the <see cref="ITrackingSpan"/> will react to changes at its boundaries.</param>
+ /// <param name="trackingFidelity">The tracking fidelity of the span.</param>
+ /// <returns>A non-null <see cref="ITrackingSpan"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="span"/>.End is greater than <see cref="Length"/>, or
+ /// <paramref name="trackingMode"/> is equal to <see cref="SpanTrackingMode.Custom"/>.</exception>
+ ITrackingSpan CreateTrackingSpan(Span span, SpanTrackingMode trackingMode, TrackingFidelityMode trackingFidelity);
+
+ /// <summary>
+ /// Creates a <see cref="ITrackingSpan"/> against this version.
+ /// </summary>
+ /// <param name="start">The starting position of the <see cref="ITrackingSpan"/> in this version.</param>
+ /// <param name="length">The length of the <see cref="ITrackingSpan"/> in this version.</param>
+ /// <param name="trackingMode">How the <see cref="ITrackingSpan"/> will react to changes at its boundaries.</param>
+ /// <returns>A non-null <see cref="ITrackingSpan"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> is negative or greater than the length of this version, or
+ /// <paramref name="length"/> is negative, or <paramref name="start"/> + <paramref name="length"/>
+ /// is less than <paramref name="start"/>, or
+ /// <paramref name="trackingMode"/> is equal to <see cref="SpanTrackingMode.Custom"/>.</exception>
+ ITrackingSpan CreateTrackingSpan(int start, int length, SpanTrackingMode trackingMode);
+
+ /// <summary>
+ /// Creates a <see cref="ITrackingSpan"/> against this version.
+ /// </summary>
+ /// <param name="start">The starting position of the <see cref="ITrackingSpan"/> in this snapshot.</param>
+ /// <param name="length">The length of the <see cref="ITrackingSpan"/> in this snapshot.</param>
+ /// <param name="trackingMode">How the <see cref="ITrackingSpan"/> will react to changes at its boundaries.</param>
+ /// <param name="trackingFidelity">The tracking fidelity mode.</param>
+ /// <returns>A non-null <see cref="ITrackingSpan"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> is negative or greater than <see cref="Length"/>, or
+ /// <paramref name="length"/> is negative, or <paramref name="start"/> + <paramref name="length"/>
+ /// is less than <paramref name="start"/>, or
+ /// <paramref name="trackingMode"/> is equal to <see cref="SpanTrackingMode.Custom"/>.</exception>
+ ITrackingSpan CreateTrackingSpan(int start, int length, SpanTrackingMode trackingMode, TrackingFidelityMode trackingFidelity);
+
+ /// <summary>
+ /// Creates a custom <see cref="ITrackingSpan"/> against this version.
+ /// </summary>
+ /// <param name="span">The span of text in this snapshot that the <see cref="ITrackingSpan"/> should represent.</param>
+ /// <param name="trackingFidelity">The tracking fidelity of the span.</param>
+ /// <param name="customState">Client-defined state associated with the span.</param>
+ /// <param name="behavior">The custom tracking behavior.</param>
+ /// <returns>A non-null <see cref="ITrackingSpan"/>.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="span"/>.End is greater than <see cref="Length"/>.</exception>
+ ITrackingSpan CreateCustomTrackingSpan(Span span, TrackingFidelityMode trackingFidelity, object customState, CustomTrackToVersion behavior);
+
+ /// <summary>
+ /// The <see cref="ITextBuffer"/> to which this <see cref="ITextVersion"/> applies.
+ /// </summary>
+ ITextBuffer TextBuffer { get; }
+
+ /// <summary>
+ /// The version number for this version. It is used for comparisons between versions of the same buffer.
+ /// </summary>
+ int VersionNumber { get; }
+
+ /// <summary>
+ /// Gets the oldest version number for which all text changes between that version and this version have
+ /// been canceled out by corresponding undo/redo operations.
+ /// </summary>
+ /// <remarks>
+ /// If ReiteratedVersionNumber is not equal to <see cref="VersionNumber" />, then for every
+ /// <see cref="ITextChange" /> not originated by an undo operation between ReiteratedVersionNumber and VersionNumber, there is a
+ /// corresponding <see cref="ITextChange"/> originated by an undo operation that cancels it out. So the contents of the two
+ /// versions are necessarily identical.
+ ///<para>
+ /// Setting this property correctly is the responsibility of the undo system; aside from this
+ /// property, the text buffer and related classes are unaware of undo and redo.
+ /// </para>
+ /// <para>
+ /// Note that the <see cref="ITextVersion"/> objects created through <see cref="ITextBuffer.ChangeContentType"/>
+ /// have no text changes and will therefore keep the ReiteratedVersionNumber of the
+ /// previous version.
+ /// </para>
+ /// </remarks>
+ int ReiteratedVersionNumber { get; }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/ITrackingPoint.cs b/src/Text/Def/TextData/Model/ITrackingPoint.cs
new file mode 100644
index 0000000..4c5c216
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ITrackingPoint.cs
@@ -0,0 +1,65 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// A tracking position in an <see cref="ITextBuffer"/>.
+ /// </summary>
+ public interface ITrackingPoint
+ {
+ /// <summary>
+ /// The <see cref="ITextBuffer"/> to which this point refers.
+ /// </summary>
+ ITextBuffer TextBuffer { get; }
+
+ /// <summary>
+ /// Determines whether the tracking point shifts or remains stationary when insertions occur at its position.
+ /// </summary>
+ PointTrackingMode TrackingMode { get; }
+
+ /// <summary>
+ /// Determines how the tracking point behaves when moving to a previous version or when
+ /// encountering versions that are replications of previous versions (due to undo or redo).
+ /// </summary>
+ TrackingFidelityMode TrackingFidelity { get; }
+
+ /// <summary>
+ /// Maps the tracking point to a particular snapshot of its <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="snapshot">The snapshot to which to map the tracking point.</param>
+ /// <returns></returns>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshot"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="snapshot"/> is not a snapshot of <see cref="ITextBuffer"/>.</exception>
+ SnapshotPoint GetPoint(ITextSnapshot snapshot);
+
+ /// <summary>
+ /// The position of the tracking point in the specified <see cref="ITextSnapshot"/>.
+ /// </summary>
+ /// <param name="snapshot">The snapshot to which to map the position.</param>
+ /// <returns>An integer position in the given snapshot.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshot"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="snapshot"/> is not a snapshot of <see cref="TextBuffer"/>.</exception>
+ int GetPosition(ITextSnapshot snapshot);
+
+ /// <summary>
+ /// The position of the tracking point in the specified <see cref="ITextVersion"/>.
+ /// </summary>
+ /// <param name="version">The version to which to map the position.</param>
+ /// <returns>An integer position in the given version.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="version"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="version"/> is not a version of <see cref="TextBuffer"/>.</exception>
+ int GetPosition(ITextVersion version);
+
+ /// <summary>
+ /// Maps this tracking point to the specified snapshot and gets the character at that position.
+ /// </summary>
+ /// <param name="snapshot">The snapshot to which to map the position.</param>
+ /// <returns>The character at the specified position.</returns>
+ /// <exception cref="ArgumentOutOfRangeException">This ITrackingPoint denotes the end position of the snapshot.</exception>
+ char GetCharacter(ITextSnapshot snapshot);
+ }
+
+}
diff --git a/src/Text/Def/TextData/Model/ITrackingSpan.cs b/src/Text/Def/TextData/Model/ITrackingSpan.cs
new file mode 100644
index 0000000..6fb3e6d
--- /dev/null
+++ b/src/Text/Def/TextData/Model/ITrackingSpan.cs
@@ -0,0 +1,75 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// A span of text in an <see cref="ITextBuffer"/> that grows or shrinks
+ /// with changes to the text buffer. The span may be empty.
+ /// </summary>
+ public interface ITrackingSpan
+ {
+ /// <summary>
+ /// The <see cref="ITextBuffer"/> to which this tracking span refers.
+ /// </summary>
+ ITextBuffer TextBuffer { get; }
+
+ /// <summary>
+ /// The <see cref="TrackingMode"/> of this tracking span, which determines how it behaves when insertions occur at its edges.
+ /// </summary>
+ SpanTrackingMode TrackingMode { get; }
+
+ /// <summary>
+ /// The <see cref="TrackingFidelityMode"/> of the tracking span, which determines how it behaves when moving to a previous version or when
+ /// encountering versions that are replications of previous versions (due to undo or redo).
+ /// </summary>
+ TrackingFidelityMode TrackingFidelity { get; }
+
+ /// <summary>
+ /// Maps the tracking span to a particular snapshot of its text buffer.
+ /// </summary>
+ /// <param name="snapshot">The snapshot to which to map the tracking span.</param>
+ /// <returns></returns>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshot"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="snapshot"/> is not a snapshot of <see cref="TextBuffer"/>.</exception>
+ SnapshotSpan GetSpan(ITextSnapshot snapshot);
+
+ /// <summary>
+ /// Maps the TrackingSpan to a particular version of its text buffer.
+ /// </summary>
+ /// <param name="version">The version to which to map the tracking span.</param>
+ /// <returns></returns>
+ /// <exception cref="ArgumentNullException"><paramref name="version"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="version"/> is not a version of <see cref="TextBuffer"/>.</exception>
+ Span GetSpan(ITextVersion version);
+
+ /// <summary>
+ /// Maps the tracking span to a particular snapshot of its text buffer and gets the text it designates.
+ /// </summary>
+ /// <param name="snapshot">The snapshot to which to map the tracking span.</param>
+ /// <returns>The contents of the tracking span in the specified text snapshot.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshot"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="snapshot"/> is not a snapshot of <see cref="TextBuffer"/>.</exception>
+ string GetText(ITextSnapshot snapshot);
+
+ /// <summary>
+ /// Maps the start of the tracking span to a particular snapshot of its text buffer.
+ /// </summary>
+ /// <param name="snapshot">The snapshot to which to map the start point.</param>
+ /// <returns>A <see cref="SnapshotPoint"/> of the provided snapshot.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshot"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="snapshot"/> is not a snapshot of <see cref="TextBuffer"/>.</exception>
+ SnapshotPoint GetStartPoint(ITextSnapshot snapshot);
+
+ /// <summary>
+ /// Maps the end of the tracking span to a particular snapshot of its text buffer.
+ /// </summary>
+ /// <param name="snapshot">The snapshot to which to map the end point.</param>
+ /// <returns>A <see cref="SnapshotPoint"/> of the provided snapshot.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshot"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="snapshot"/> is not a snapshot of <see cref="TextBuffer"/>.</exception>
+ SnapshotPoint GetEndPoint(ITextSnapshot snapshot);
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Microsoft.VisualStudio.Text.Model.Overview.mht b/src/Text/Def/TextData/Model/Microsoft.VisualStudio.Text.Model.Overview.mht
new file mode 100644
index 0000000..0a1bd8b
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Microsoft.VisualStudio.Text.Model.Overview.mht
@@ -0,0 +1,4612 @@
+MIME-Version: 1.0
+Content-Type: multipart/related; boundary="----=_NextPart_01C91992.81DAA780"
+
+This document is a Single File Web Page, also known as a Web Archive file. If you are seeing this message, your browser or editor doesn't support Web Archive files. Please download a browser that supports Web Archive, such as Windows® Internet Explorer®.
+
+------=_NextPart_01C91992.81DAA780
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Model.Overview.htm
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/html; charset="us-ascii"
+
+<html xmlns:v=3D"urn:schemas-microsoft-com:vml"
+xmlns:o=3D"urn:schemas-microsoft-com:office:office"
+xmlns:w=3D"urn:schemas-microsoft-com:office:word"
+xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml"
+xmlns=3D"http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=3DContent-Type content=3D"text/html; charset=3Dus-ascii">
+<meta name=3DProgId content=3DWord.Document>
+<meta name=3DGenerator content=3D"Microsoft Word 12">
+<meta name=3DOriginator content=3D"Microsoft Word 12">
+<link rel=3DFile-List
+href=3D"Microsoft.VisualStudio.Text.Model.Overview_files/filelist.xml">
+<title>Text Model Subsystem</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Subject>VisualStudio Shell</o:Subject>
+ <o:Author>Vijaye Raji</o:Author>
+ <o:LastAuthor>Ameen Tayyebi</o:LastAuthor>
+ <o:Revision>4</o:Revision>
+ <o:TotalTime>124</o:TotalTime>
+ <o:LastPrinted>2005-05-26T01:48:00Z</o:LastPrinted>
+ <o:Created>2008-03-27T17:40:00Z</o:Created>
+ <o:LastSaved>2008-09-18T20:28:00Z</o:LastSaved>
+ <o:Pages>3</o:Pages>
+ <o:Words>3195</o:Words>
+ <o:Characters>18216</o:Characters>
+ <o:Company>Microsoft Corporation</o:Company>
+ <o:Lines>151</o:Lines>
+ <o:Paragraphs>42</o:Paragraphs>
+ <o:CharactersWithSpaces>21369</o:CharactersWithSpaces>
+ <o:Version>12.00</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]-->
+<link rel=3DthemeData
+href=3D"Microsoft.VisualStudio.Text.Model.Overview_files/themedata.thmx">
+<link rel=3DcolorSchemeMapping
+href=3D"Microsoft.VisualStudio.Text.Model.Overview_files/colorschememapping=
+.xml">
+<!--[if gte mso 9]><xml>
+ <w:WordDocument>
+ <w:TrackMoves>false</w:TrackMoves>
+ <w:TrackFormatting/>
+ <w:PunctuationKerning/>
+ <w:ValidateAgainstSchemas/>
+ <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
+ <w:IgnoreMixedContent>false</w:IgnoreMixedContent>
+ <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
+ <w:DoNotPromoteQF/>
+ <w:LidThemeOther>EN-US</w:LidThemeOther>
+ <w:LidThemeAsian>X-NONE</w:LidThemeAsian>
+ <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
+ <w:Compatibility>
+ <w:BreakWrappedTables/>
+ <w:SnapToGridInCell/>
+ <w:WrapTextWithPunct/>
+ <w:UseAsianBreakRules/>
+ <w:DontGrowAutofit/>
+ <w:SplitPgBreakAndParaMark/>
+ <w:DontVertAlignCellWithSp/>
+ <w:DontBreakConstrainedForcedTables/>
+ <w:DontVertAlignInTxbx/>
+ <w:Word11KerningPairs/>
+ <w:CachedColBalance/>
+ </w:Compatibility>
+ <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
+ <m:mathPr>
+ <m:mathFont m:val=3D"Cambria Math"/>
+ <m:brkBin m:val=3D"before"/>
+ <m:brkBinSub m:val=3D"&#45;-"/>
+ <m:smallFrac m:val=3D"off"/>
+ <m:dispDef/>
+ <m:lMargin m:val=3D"0"/>
+ <m:rMargin m:val=3D"0"/>
+ <m:defJc m:val=3D"centerGroup"/>
+ <m:wrapIndent m:val=3D"1440"/>
+ <m:intLim m:val=3D"subSup"/>
+ <m:naryLim m:val=3D"undOvr"/>
+ </m:mathPr></w:WordDocument>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:LatentStyles DefLockedState=3D"false" DefUnhideWhenUsed=3D"false"
+ DefSemiHidden=3D"false" DefQFormat=3D"false" DefPriority=3D"1"
+ LatentStyleCount=3D"267">
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+Normal"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+heading 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+heading 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+heading 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+heading 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 7"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 8"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 9"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"footnote text"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"annotation text"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+caption"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"footnote referenc=
+e"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"annotation refere=
+nce"/>
+ <w:LsdException Locked=3D"false" QFormat=3D"true" Name=3D"Title"/>
+ <w:LsdException Locked=3D"false" QFormat=3D"true" Name=3D"Subtitle"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Hyperlink"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+Strong"/>
+ <w:LsdException Locked=3D"false" QFormat=3D"true" Name=3D"Emphasis"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"HTML Top of Form"=
+/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"HTML Bottom of Fo=
+rm"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Normal (Web)"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Normal Table"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"annotation subjec=
+t"/>
+ <w:LsdException Locked=3D"false" Priority=3D"99" Name=3D"No List"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Outline List 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Outline List 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Outline List 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Simple 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Simple 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Simple 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Classic 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Classic 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Classic 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Classic 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Colorful 1"=
+/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Colorful 2"=
+/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Colorful 3"=
+/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 7"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 8"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 7"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 8"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table 3D effects =
+1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table 3D effects =
+2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table 3D effects =
+3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Contemporar=
+y"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Elegant"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Professiona=
+l"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Subtle 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Subtle 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Web 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Web 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Web 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Balloon Text"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Theme"/>
+ <w:LsdException Locked=3D"false" Priority=3D"99" SemiHidden=3D"true"
+ Name=3D"Placeholder Text"/>
+ <w:LsdException Locked=3D"false" Priority=3D"2" QFormat=3D"true" Name=3D"=
+No Spacing"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"99" SemiHidden=3D"true" Name=
+=3D"Revision"/>
+ <w:LsdException Locked=3D"false" Priority=3D"34" QFormat=3D"true"
+ Name=3D"List Paragraph"/>
+ <w:LsdException Locked=3D"false" Priority=3D"29" QFormat=3D"true" Name=3D=
+"Quote"/>
+ <w:LsdException Locked=3D"false" Priority=3D"30" QFormat=3D"true"
+ Name=3D"Intense Quote"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"19" QFormat=3D"true"
+ Name=3D"Subtle Emphasis"/>
+ <w:LsdException Locked=3D"false" Priority=3D"21" QFormat=3D"true"
+ Name=3D"Intense Emphasis"/>
+ <w:LsdException Locked=3D"false" Priority=3D"31" QFormat=3D"true"
+ Name=3D"Subtle Reference"/>
+ <w:LsdException Locked=3D"false" Priority=3D"32" QFormat=3D"true"
+ Name=3D"Intense Reference"/>
+ <w:LsdException Locked=3D"false" Priority=3D"33" QFormat=3D"true" Name=3D=
+"Book Title"/>
+ <w:LsdException Locked=3D"false" Priority=3D"37" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" Name=3D"Bibliography"/>
+ <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"TOC Heading"/>
+ </w:LatentStyles>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+ @font-face
+ {font-family:SimSun;
+ panose-1:2 1 6 0 3 1 1 1 1 1;
+ mso-font-alt:\5B8B\4F53;
+ mso-font-charset:134;
+ mso-generic-font-family:auto;
+ mso-font-pitch:variable;
+ mso-font-signature:3 680460288 22 0 262145 0;}
+@font-face
+ {font-family:PMingLiU;
+ panose-1:2 2 5 0 0 0 0 0 0 0;
+ mso-font-alt:\65B0\7D30\660E\9AD4;
+ mso-font-charset:136;
+ mso-generic-font-family:roman;
+ mso-font-pitch:variable;
+ mso-font-signature:-1610611969 684719354 22 0 1048577 0;}
+@font-face
+ {font-family:"Cambria Math";
+ panose-1:2 4 5 3 5 4 6 3 2 4;
+ mso-font-charset:1;
+ mso-generic-font-family:roman;
+ mso-font-format:other;
+ mso-font-pitch:variable;
+ mso-font-signature:0 0 0 0 0 0;}
+@font-face
+ {font-family:Calibri;
+ panose-1:2 15 5 2 2 2 4 3 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:-1610611985 1073750139 0 0 159 0;}
+@font-face
+ {font-family:Tahoma;
+ panose-1:2 11 6 4 3 5 4 4 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:-520082689 -1073717157 41 0 66047 0;}
+@font-face
+ {font-family:"Trebuchet MS";
+ panose-1:2 11 6 3 2 2 2 2 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:647 0 0 0 159 0;}
+@font-face
+ {font-family:Verdana;
+ panose-1:2 11 6 4 3 5 4 4 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:-1593833729 1073750107 16 0 415 0;}
+@font-face
+ {font-family:"Lucida Console";
+ panose-1:2 11 6 9 4 5 4 2 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:modern;
+ mso-font-pitch:fixed;
+ mso-font-signature:-2147482993 6144 0 0 31 0;}
+@font-face
+ {font-family:Consolas;
+ panose-1:2 11 6 9 2 2 4 3 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:modern;
+ mso-font-pitch:fixed;
+ mso-font-signature:-1610611985 1073750091 0 0 159 0;}
+@font-face
+ {font-family:"\@SimSun";
+ panose-1:2 1 6 0 3 1 1 1 1 1;
+ mso-font-charset:134;
+ mso-generic-font-family:auto;
+ mso-font-pitch:variable;
+ mso-font-signature:3 680460288 22 0 262145 0;}
+@font-face
+ {font-family:"\@PMingLiU";
+ panose-1:2 2 5 0 0 0 0 0 0 0;
+ mso-font-charset:136;
+ mso-generic-font-family:roman;
+ mso-font-pitch:variable;
+ mso-font-signature:-1610611969 684719354 22 0 1048577 0;}
+ /* Style Definitions */
+ p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-parent:"";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+h1
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-link:"Heading 1 Char";
+ mso-style-next:Normal;
+ margin-top:6.0pt;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-line-height-alt:14.0pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:1;
+ font-size:20.0pt;
+ mso-bidi-font-size:16.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:minor-fareast;
+ mso-bidi-font-family:Arial;
+ color:#666699;
+ mso-font-kerning:16.0pt;
+ font-weight:normal;
+ mso-bidi-font-weight:bold;}
+h2
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-parent:"";
+ mso-style-link:"Heading 2 Char";
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ mso-outline-level:2;
+ font-size:14.0pt;
+ font-family:"Trebuchet MS","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:minor-fareast;
+ mso-bidi-font-family:Arial;
+ color:#5F5F5F;
+ letter-spacing:2.0pt;}
+h3
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-parent:"Heading 4";
+ mso-style-link:"Heading 3 Char";
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:3;
+ font-size:14.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:minor-fareast;
+ color:#FF6600;
+ font-weight:normal;
+ mso-bidi-font-weight:bold;}
+h4
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-link:"Heading 4 Char";
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:4;
+ font-size:11.0pt;
+ mso-bidi-font-size:14.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:minor-fareast;
+ mso-bidi-font-family:"Times New Roman";
+ color:olive;}
+p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText
+ {mso-style-unhide:no;
+ mso-style-link:"Footnote Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoCommentText, li.MsoCommentText, div.MsoCommentText
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-link:"Comment Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoHeader, li.MsoHeader, div.MsoHeader
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-link:"Header Char";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.25in right 6.5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoFooter, li.MsoFooter, div.MsoFooter
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-link:"Footer Char";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.25in right 6.5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoCaption, li.MsoCaption, div.MsoCaption
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ font-weight:bold;}
+span.MsoFootnoteReference
+ {mso-style-unhide:no;
+ vertical-align:super;}
+span.MsoCommentReference
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-ansi-font-size:8.0pt;
+ mso-bidi-font-size:8.0pt;}
+p.MsoListBullet, li.MsoListBullet, div.MsoListBullet
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.25in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l3 level1 lfo1;
+ tab-stops:list .25in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBulletCxSpFirst, li.MsoListBulletCxSpFirst, div.MsoListBulletCxSpF=
+irst
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.25in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l3 level1 lfo1;
+ tab-stops:list .25in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBulletCxSpMiddle, li.MsoListBulletCxSpMiddle, div.MsoListBulletCxS=
+pMiddle
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.25in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l3 level1 lfo1;
+ tab-stops:list .25in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBulletCxSpLast, li.MsoListBulletCxSpLast, div.MsoListBulletCxSpLast
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.25in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l3 level1 lfo1;
+ tab-stops:list .25in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet2, li.MsoListBullet2, div.MsoListBullet2
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l2 level1 lfo2;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet2CxSpFirst, li.MsoListBullet2CxSpFirst, div.MsoListBullet2Cx=
+SpFirst
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l2 level1 lfo2;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet2CxSpMiddle, li.MsoListBullet2CxSpMiddle, div.MsoListBullet2=
+CxSpMiddle
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l2 level1 lfo2;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet2CxSpLast, li.MsoListBullet2CxSpLast, div.MsoListBullet2CxSp=
+Last
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l2 level1 lfo2;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet3, li.MsoListBullet3, div.MsoListBullet3
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.75in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l1 level1 lfo3;
+ tab-stops:list .75in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet3CxSpFirst, li.MsoListBullet3CxSpFirst, div.MsoListBullet3Cx=
+SpFirst
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.75in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l1 level1 lfo3;
+ tab-stops:list .75in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet3CxSpMiddle, li.MsoListBullet3CxSpMiddle, div.MsoListBullet3=
+CxSpMiddle
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.75in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l1 level1 lfo3;
+ tab-stops:list .75in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet3CxSpLast, li.MsoListBullet3CxSpLast, div.MsoListBullet3CxSp=
+Last
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.75in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l1 level1 lfo3;
+ tab-stops:list .75in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListNumber2, li.MsoListNumber2, div.MsoListNumber2
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l0 level1 lfo4;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListNumber2CxSpFirst, li.MsoListNumber2CxSpFirst, div.MsoListNumber2Cx=
+SpFirst
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l0 level1 lfo4;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListNumber2CxSpMiddle, li.MsoListNumber2CxSpMiddle, div.MsoListNumber2=
+CxSpMiddle
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l0 level1 lfo4;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListNumber2CxSpLast, li.MsoListNumber2CxSpLast, div.MsoListNumber2CxSp=
+Last
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l0 level1 lfo4;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+a:link, span.MsoHyperlink
+ {mso-style-unhide:no;
+ color:blue;
+ text-decoration:underline;
+ text-underline:single;}
+a:visited, span.MsoHyperlinkFollowed
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ color:purple;
+ mso-themecolor:followedhyperlink;
+ text-decoration:underline;
+ text-underline:single;}
+p.MsoCommentSubject, li.MsoCommentSubject, div.MsoCommentSubject
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-parent:"Comment Text";
+ mso-style-link:"Comment Subject Char";
+ mso-style-next:"Comment Text";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ font-weight:bold;}
+p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-link:"Balloon Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:8.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";}
+p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Verdana","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParag=
+raphCxSpFirst
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Verdana","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListPar=
+agraphCxSpMiddle
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Verdana","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagra=
+phCxSpLast
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Verdana","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoQuote, li.MsoQuote, div.MsoQuote
+ {mso-style-priority:29;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-link:"Quote Char";
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:black;
+ font-style:italic;}
+span.Heading1Char
+ {mso-style-name:"Heading 1 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 1";
+ mso-ansi-font-size:20.0pt;
+ mso-bidi-font-size:16.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-ascii-font-family:Tahoma;
+ mso-hansi-font-family:Tahoma;
+ mso-bidi-font-family:Arial;
+ color:#666699;
+ mso-font-kerning:16.0pt;
+ mso-bidi-font-weight:bold;}
+span.Heading2Char
+ {mso-style-name:"Heading 2 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 2";
+ mso-ansi-font-size:13.0pt;
+ mso-bidi-font-size:13.0pt;
+ font-family:"Cambria","serif";
+ mso-ascii-font-family:Cambria;
+ mso-ascii-theme-font:major-latin;
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:major-fareast;
+ mso-hansi-font-family:Cambria;
+ mso-hansi-theme-font:major-latin;
+ mso-bidi-font-family:"Times New Roman";
+ mso-bidi-theme-font:major-bidi;
+ color:#4F81BD;
+ mso-themecolor:accent1;
+ font-weight:bold;}
+span.Heading4Char
+ {mso-style-name:"Heading 4 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 4";
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:14.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-ascii-font-family:Tahoma;
+ mso-hansi-font-family:Tahoma;
+ mso-bidi-font-family:Tahoma;
+ color:olive;
+ mso-ansi-language:EN-US;
+ mso-fareast-language:EN-US;
+ mso-bidi-language:AR-SA;
+ font-weight:bold;}
+span.Heading3Char
+ {mso-style-name:"Heading 3 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 3";
+ mso-ansi-font-size:14.0pt;
+ mso-bidi-font-size:14.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-ascii-font-family:Tahoma;
+ mso-hansi-font-family:Tahoma;
+ mso-bidi-font-family:Tahoma;
+ color:#FF6600;
+ mso-ansi-language:EN-US;
+ mso-fareast-language:EN-US;
+ mso-bidi-language:AR-SA;
+ mso-bidi-font-weight:bold;}
+span.FootnoteTextChar
+ {mso-style-name:"Footnote Text Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Footnote Text";
+ mso-ansi-font-size:11.0pt;}
+span.CommentTextChar
+ {mso-style-name:"Comment Text Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Comment Text";}
+span.HeaderChar
+ {mso-style-name:"Header Char";
+ mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Header;
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;}
+span.FooterChar
+ {mso-style-name:"Footer Char";
+ mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Footer;
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;}
+span.CommentSubjectChar
+ {mso-style-name:"Comment Subject Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-parent:"Comment Text Char";
+ mso-style-link:"Comment Subject";
+ font-weight:bold;}
+span.BalloonTextChar
+ {mso-style-name:"Balloon Text Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Balloon Text";
+ mso-ansi-font-size:8.0pt;
+ mso-bidi-font-size:8.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-ascii-font-family:Tahoma;
+ mso-hansi-font-family:Tahoma;
+ mso-bidi-font-family:Tahoma;}
+span.QuoteChar
+ {mso-style-name:"Quote Char";
+ mso-style-priority:29;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Quote;
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ color:black;
+ font-style:italic;}
+p.Heading0, li.Heading0, div.Heading0
+ {mso-style-name:"Heading 0";
+ mso-style-unhide:no;
+ mso-style-parent:"Heading 1";
+ margin-top:6.0pt;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-line-height-alt:14.0pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:1;
+ font-size:28.0pt;
+ mso-bidi-font-size:16.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:Arial;
+ color:#006699;
+ mso-font-kerning:16.0pt;
+ mso-bidi-font-weight:bold;}
+p.SubHeading, li.SubHeading, div.SubHeading
+ {mso-style-name:SubHeading;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:maroon;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+span.CodeCharChar
+ {mso-style-name:"Code Char Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Code;
+ mso-ansi-font-size:9.0pt;
+ mso-bidi-font-size:9.0pt;
+ font-family:"Lucida Console";
+ mso-ascii-font-family:"Lucida Console";
+ mso-hansi-font-family:"Lucida Console";
+ mso-no-proof:yes;}
+p.Code, li.Code, div.Code
+ {mso-style-name:Code;
+ mso-style-unhide:no;
+ mso-style-link:"Code Char Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ mso-layout-grid-align:none;
+ text-autospace:none;
+ font-size:9.0pt;
+ font-family:"Lucida Console";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ mso-no-proof:yes;}
+span.NoteChar
+ {mso-style-name:"Note Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Note;
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ background:#F3F3F3;
+ font-style:italic;
+ mso-bidi-font-style:normal;}
+p.Note, li.Note, div.Note
+ {mso-style-name:Note;
+ mso-style-unhide:no;
+ mso-style-link:"Note Char";
+ margin-top:0in;
+ margin-right:.2in;
+ margin-bottom:12.0pt;
+ margin-left:.2in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ background:#F3F3F3;
+ border:none;
+ mso-border-top-alt:.5pt;
+ mso-border-left-alt:.5pt;
+ mso-border-bottom-alt:1.5pt;
+ mso-border-right-alt:1.5pt;
+ mso-border-color-alt:windowtext;
+ mso-border-style-alt:solid;
+ padding:0in;
+ mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ font-style:italic;
+ mso-bidi-font-style:normal;}
+p.Style2, li.Style2, div.Style2
+ {mso-style-name:Style2;
+ mso-style-unhide:no;
+ mso-style-parent:"";
+ mso-style-next:Normal;
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ background:#F9FFF3;
+ border:none;
+ mso-border-top-alt:.5pt;
+ mso-border-left-alt:.5pt;
+ mso-border-bottom-alt:1.5pt;
+ mso-border-right-alt:1.5pt;
+ mso-border-color-alt:windowtext;
+ mso-border-style-alt:solid;
+ padding:0in;
+ mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt;
+ font-size:9.0pt;
+ font-family:Consolas;
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ mso-no-proof:yes;}
+p.Style3, li.Style3, div.Style3
+ {mso-style-name:Style3;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ background:#F5FAF4;
+ mso-layout-grid-align:none;
+ text-autospace:none;
+ border:none;
+ mso-border-alt:solid windowtext 1.0pt;
+ padding:0in;
+ mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt;
+ mso-border-shadow:yes;
+ font-size:9.0pt;
+ font-family:Consolas;
+ mso-fareast-font-family:PMingLiU;
+ mso-bidi-font-family:"Times New Roman";
+ mso-fareast-language:ZH-CN;
+ mso-no-proof:yes;}
+span.DescriptionTextChar
+ {mso-style-name:"Description Text Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Description Text";}
+p.DescriptionText, li.DescriptionText, div.DescriptionText
+ {mso-style-name:"Description Text";
+ mso-style-unhide:no;
+ mso-style-link:"Description Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.25in;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.Issue, li.Issue, div.Issue
+ {mso-style-name:Issue;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan lines-together;
+ border:none;
+ mso-border-alt:solid navy 1.5pt;
+ padding:0in;
+ mso-padding-alt:1.0pt 1.0pt 1.0pt 1.0pt;
+ mso-border-shadow:yes;
+ font-size:10.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";
+ color:red;
+ font-style:italic;
+ mso-bidi-font-style:normal;}
+p.msolistparagraph0, li.msolistparagraph0, div.msolistparagraph0
+ {mso-style-name:msolistparagraph;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";}
+p.msolistparagraph0CxSpFirst, li.msolistparagraph0CxSpFirst, div.msolistpar=
+agraph0CxSpFirst
+ {mso-style-name:msolistparagraphCxSpFirst;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";}
+p.msolistparagraph0CxSpMiddle, li.msolistparagraph0CxSpMiddle, div.msolistp=
+aragraph0CxSpMiddle
+ {mso-style-name:msolistparagraphCxSpMiddle;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";}
+p.msolistparagraph0CxSpLast, li.msolistparagraph0CxSpLast, div.msolistparag=
+raph0CxSpLast
+ {mso-style-name:msolistparagraphCxSpLast;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";}
+.MsoChpDefault
+ {mso-style-type:export-only;
+ mso-default-props:yes;
+ font-size:10.0pt;
+ mso-ansi-font-size:10.0pt;
+ mso-bidi-font-size:10.0pt;
+ mso-ascii-font-family:Calibri;
+ mso-hansi-font-family:Calibri;}
+ /* Page Definitions */
+ @page
+ {mso-footnote-separator:url("Microsoft.VisualStudio.Text.Model.Overview_fi=
+les/header.htm") fs;
+ mso-footnote-continuation-separator:url("Microsoft.VisualStudio.Text.Model=
+.Overview_files/header.htm") fcs;
+ mso-endnote-separator:url("Microsoft.VisualStudio.Text.Model.Overview_file=
+s/header.htm") es;
+ mso-endnote-continuation-separator:url("Microsoft.VisualStudio.Text.Model.=
+Overview_files/header.htm") ecs;}
+@page Section1
+ {size:8.5in 11.0in;
+ margin:1.0in 1.25in 1.0in 1.25in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+ /* List Definitions */
+ @list l0
+ {mso-list-id:-129;
+ mso-list-type:simple;
+ mso-list-template-ids:-1739002844;}
+@list l0:level1
+ {mso-level-style-link:"List Number 2";
+ mso-level-tab-stop:.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l1
+ {mso-list-id:-126;
+ mso-list-type:simple;
+ mso-list-template-ids:-1045901690;}
+@list l1:level1
+ {mso-level-number-format:bullet;
+ mso-level-style-link:"List Bullet 3";
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.75in;
+ mso-level-number-position:left;
+ margin-left:.75in;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l2
+ {mso-list-id:-125;
+ mso-list-type:simple;
+ mso-list-template-ids:-1069260336;}
+@list l2:level1
+ {mso-level-number-format:bullet;
+ mso-level-style-link:"List Bullet 2";
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l3
+ {mso-list-id:-119;
+ mso-list-type:simple;
+ mso-list-template-ids:1390696726;}
+@list l3:level1
+ {mso-level-number-format:bullet;
+ mso-level-style-link:"List Bullet";
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.25in;
+ mso-level-number-position:left;
+ margin-left:.25in;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l4
+ {mso-list-id:361705730;
+ mso-list-type:hybrid;
+ mso-list-template-ids:-1564313072 67698689 67698691 67698693 67698689 6769=
+8691 67698693 67698689 67698691 67698693;}
+@list l4:level1
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l4:level2
+ {mso-level-tab-stop:1.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level3
+ {mso-level-tab-stop:1.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level4
+ {mso-level-tab-stop:2.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level5
+ {mso-level-tab-stop:2.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level6
+ {mso-level-tab-stop:3.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level7
+ {mso-level-tab-stop:3.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level8
+ {mso-level-tab-stop:4.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level9
+ {mso-level-tab-stop:4.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5
+ {mso-list-id:737099002;
+ mso-list-type:hybrid;
+ mso-list-template-ids:497705626 67698689 67698691 67698693 67698689 676986=
+91 67698693 67698689 67698691 67698693;}
+@list l5:level1
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:none;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l5:level2
+ {mso-level-tab-stop:1.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level3
+ {mso-level-tab-stop:1.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level4
+ {mso-level-tab-stop:2.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level5
+ {mso-level-tab-stop:2.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level6
+ {mso-level-tab-stop:3.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level7
+ {mso-level-tab-stop:3.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level8
+ {mso-level-tab-stop:4.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level9
+ {mso-level-tab-stop:4.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+ol
+ {margin-bottom:0in;}
+ul
+ {margin-bottom:0in;}
+-->
+</style>
+<!--[if gte mso 10]>
+<style>
+ /* Style Definitions */
+ table.MsoNormalTable
+ {mso-style-name:"Table Normal";
+ mso-tstyle-rowband-size:0;
+ mso-tstyle-colband-size:0;
+ mso-style-noshow:yes;
+ mso-style-priority:99;
+ mso-style-qformat:yes;
+ mso-style-parent:"";
+ mso-padding-alt:0in 5.4pt 0in 5.4pt;
+ mso-para-margin:0in;
+ mso-para-margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Calibri","sans-serif";}
+table.MsoTableGrid
+ {mso-style-name:"Table Grid";
+ mso-tstyle-rowband-size:0;
+ mso-tstyle-colband-size:0;
+ mso-style-unhide:no;
+ border:solid windowtext 1.0pt;
+ mso-border-alt:solid windowtext .5pt;
+ mso-padding-alt:0in 5.4pt 0in 5.4pt;
+ mso-border-insideh:.5pt solid windowtext;
+ mso-border-insidev:.5pt solid windowtext;
+ mso-para-margin:0in;
+ mso-para-margin-bottom:.0001pt;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Calibri","sans-serif";}
+</style>
+<![endif]--><!--[if gte mso 9]><xml>
+ <o:shapedefaults v:ext=3D"edit" spidmax=3D"3074"/>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <o:shapelayout v:ext=3D"edit">
+ <o:idmap v:ext=3D"edit" data=3D"1"/>
+ </o:shapelayout></xml><![endif]-->
+</head>
+
+<body lang=3DEN-US link=3Dblue vlink=3Dpurple style=3D'tab-interval:.5in'>
+
+<div class=3DSection1>
+
+<p class=3DHeading0>Text Model Subsystem</p>
+
+<div style=3D'mso-element:para-border-div;border:none;border-bottom:solid w=
+indowtext 1.0pt;
+mso-border-bottom-alt:solid windowtext .75pt;padding:0in 0in 1.0pt 0in'>
+
+<p class=3DMsoNormal style=3D'border:none;mso-border-bottom-alt:solid windo=
+wtext .75pt;
+padding:0in;mso-padding-alt:0in 0in 1.0pt 0in'><o:p>&nbsp;</o:p></p>
+
+</div>
+
+<h1 style=3D'margin-top:24.0pt;margin-right:0in;margin-bottom:10.0pt;margin=
+-left:
+.3in;text-indent:-.3in;line-height:normal;tab-stops:list .3in'><a
+name=3D"_Toc76978452"></a><a name=3D"_Toc151974416"></a><a name=3D"_Toc1519=
+73942"></a><a
+name=3D"_Toc149118079"></a><a name=3D"_Toc149118215"></a><a name=3D"_Toc149=
+118380"></a><a
+name=3D"_Toc149118641"></a><a name=3D"_Toc151873508"></a><a name=3D"_Toc151=
+873650"></a><a
+name=3D"_Toc151974258"></a><a name=3D"_Toc153684427"></a><a name=3D"_Toc151=
+892155"></a><a
+name=3D"_Toc151886240"></a><a name=3D"_Toc151886043"></a><a name=3D"_Toc153=
+700829"></a><a
+name=3D"_Toc151442559"></a><a name=3D"_Toc155080032"><span style=3D'mso-boo=
+kmark:
+_Toc151442559'><span style=3D'mso-bookmark:_Toc153700829'><span style=3D'ms=
+o-bookmark:
+_Toc151886043'><span style=3D'mso-bookmark:_Toc151886240'><span style=3D'ms=
+o-bookmark:
+_Toc151892155'><span style=3D'mso-bookmark:_Toc153684427'><span style=3D'ms=
+o-bookmark:
+_Toc151974258'><span style=3D'mso-bookmark:_Toc151873650'><span style=3D'ms=
+o-bookmark:
+_Toc151873508'><span style=3D'mso-bookmark:_Toc149118641'><span style=3D'ms=
+o-bookmark:
+_Toc149118380'><span style=3D'mso-bookmark:_Toc149118215'><span style=3D'ms=
+o-bookmark:
+_Toc149118079'><span style=3D'mso-bookmark:_Toc151973942'><span style=3D'ms=
+o-bookmark:
+_Toc151974416'><span style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso=
+-fareast-font-family:
+"Times New Roman"'>Overview</span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></a>=
+<span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></h1>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>This document describes the core concep=
+ts and
+public types of the <i>Text Model</i><i style=3D'mso-bidi-font-style:normal=
+'>
+Subsystem</i>.<span style=3D'mso-spacerun:yes'>&nbsp; </span>The Text Model
+Subsystem provides services and public types to manipulate sequences of Uni=
+code
+characters.</span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>The Text Model Subsystem comprises two
+separate areas that are described in greater detail below:</span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></p>
+
+<p class=3DMsoListParagraphCxSpFirst style=3D'text-indent:-.25in;mso-list:l=
+5 level1 lfo5'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><![if !supportLists]><span
+style=3D'font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-fa=
+mily:
+Symbol'><span style=3D'mso-list:Ignore'>&middot;<span style=3D'font:7.0pt "=
+Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span></span><![endif]>Basic Text Manipulation</span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></p>
+
+<p class=3DMsoListParagraphCxSpLast style=3D'text-indent:-.25in;mso-list:l5=
+ level1 lfo5'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><![if !supportLists]><span
+style=3D'font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-fa=
+mily:
+Symbol'><span style=3D'mso-list:Ignore'>&middot;<span style=3D'font:7.0pt "=
+Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span></span><![endif]>Text Projection</span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></p>
+
+<h1 style=3D'margin-top:24.0pt;margin-right:0in;margin-bottom:10.0pt;margin=
+-left:
+.3in;text-indent:-.3in;line-height:normal;tab-stops:list .3in'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><a
+name=3D"_Toc155080033"><span style=3D'mso-fareast-font-family:"Times New Ro=
+man"'>Basic
+Text Manipulation</span></a></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></h1>
+
+<h2 style=3D'margin-top:20.0pt;margin-right:0in;margin-bottom:10.0pt;margin=
+-left:
+.4in;text-indent:-.4in;page-break-after:avoid;tab-stops:list .4in'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><a
+name=3D"_Toc155080034"><span style=3D'mso-fareast-font-family:"Times New Ro=
+man"'>ITextBuffer,
+IText</span></a></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Snapshot, and
+ITextSnapshotLine<o:p></o:p></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></h=
+2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>The fundamental interface of the Text M=
+odel is
+<b>ITextBuffer</b>, which represents a sequence of Unicode characters encod=
+ed
+using UTF-16(</span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span><a
+style=3D'mso-footnote-id:ftn1' href=3D"#_ftn1" name=3D"_ftnref1" title=3D""=
+><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-special-character:footnote'><![if !supportFootnotes]><span
+style=3D'font-size:11.0pt;mso-bidi-font-size:12.0pt;font-family:"Calibri","=
+sans-serif";
+mso-fareast-font-family:"Times New Roman";mso-bidi-font-family:"Times New R=
+oman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA'=
+>[1]</span><![endif]></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></a><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'>)
+(that is, using the same encoding used by the String type in the .Net
+platform). Frequently a TextBuffer will be backed by a document, but this is
+not required and a TextBuffer can be used for manipulating any text. The <i=
+>Text
+Document</i> subsystem is responsible for keeping track of the association
+between documents and TextBuffers.</span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>During its lifetime, a TextBuffer proce=
+eds
+through one or more versions; a new version is generated each time the buff=
+er
+is edited (see below). Associated with each version is an immutable <b>ITex=
+tSnapshot</b>
+that can be used to examine the contents of that version of the text buffer=
+. <i>As
+long as a reference is held to a snapshot, it can continue to be used to
+examine the text of its version on any thread and without taking locks, eve=
+n as
+the TextBuffer continues to change.</i> </span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>The content of a TextSnapshot can be
+addressed as a sequence of characters or as a sequence of lines; characters=
+ and
+lines are both indexed starting at zero. The empty TextSnapshot contains ze=
+ro
+characters and one empty line. A line is delimited by any valid Unicode line
+break character sequence, or by the beginning or end of the buffer. Line br=
+eak
+characters are explicitly represented in the TextSnapshot, and the line bre=
+aks
+in a TextSnapshot need not all be the same.</span></span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>A single line of text is described by a=
+n <b>ITextSnapshotLine
+</b>object, which can be obtained from a TextBuffer for a particular line
+number or for a particular character position (in which case the returned l=
+ine
+is the line containing the character at that position).</span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>Associated with each TextBuffer is a <i=
+>ContentType;</i>
+this property is used throughout the text system to determine the kinds of
+operations that are available on the TextBuffer. See the descriptions of the
+Classification and Adornment subsystems for more details. The default
+ContentType is simply &#8220;text&#8221;.</span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>A TextBuffer maintains a property bag by
+virtue of its implementation of the <b>IPropertyOwner </b>interface. Objects
+placed in the <b>Properties </b>collection are easily reachable from the
+TextBuffer, and, because the reference from the TextBuffer is not weak, will
+remain alive as long as the TextBuffer does, unless they are explicitly rem=
+oved
+from the collection. </span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></p>
+
+<h2 style=3D'margin-top:20.0pt;margin-right:0in;margin-bottom:10.0pt;margin=
+-left:
+.4in;text-indent:-.4in;page-break-after:avoid;tab-stops:list .4in'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><a
+name=3D"_Toc155080035"></a><a name=3D"_Documents_and_Folders"></a><span
+style=3D'mso-bookmark:_Toc155080035'><span style=3D'mso-fareast-font-family=
+:"Times New Roman"'>Span
+and NormalizedSpanCollection</span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'> <o:p></o:p></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>The type <b>Span</b> represents an inte=
+ger
+interval of nonnegative length. Just as an integer is used in the Text API =
+to
+refer to a character position in a TextSnapshot, a span is used represent a
+fixed span of text in a TextSnapshot. The Start<b> </b>(lower bound) and Le=
+ngth<b>
+</b>of a span must be nonnegative. The End property of a Span is equal to t=
+he
+sum of its Start and Length; thus, when applied to a TextBuffer, the Span
+describes an open interval on the right&#8212;it does <i>not </i>include the
+character indexed by the End property. For example, the span with Start 5 a=
+nd
+Length 3 has End 8 and includes the characters at positions 5, 6, and 7. By
+convention, this span is written like this: &#8220;[5..8)&#8221;
+(alternatively, it can be written showing the start and length separated by=
+ a
+comma, viz.: &#8220;[5,3]&#8221;). Notice that Span constructors that take =
+two
+integer arguments expect the start and length, not the start and end. A span
+may have zero length.<b style=3D'mso-bidi-font-weight:normal'> <o:p></o:p><=
+/b></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>Two spans are said to <i style=3D'mso-b=
+idi-font-style:
+normal'>intersect </i>if they have any positions in common, including the E=
+nd
+position. Thus the intersection of [3, 5) and [2, 7) is [3, 5) and the
+intersection of [3, 5) and [5, 7) is [5, 5) (an empty span).</span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>Two spans are said to <i style=3D'mso-b=
+idi-font-style:
+normal'>overlap </i>if they have positions in common, excluding the End
+position. This means that an empty span never overlaps any other span and t=
+he
+overlap of two spans is never empty.</span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>Some operations result in a list of Spa=
+ns; it
+is easier to process such a list if it has certain properties. In particula=
+r, a
+<i>normalized </i>list of Spans is ordered by the Start properties of the
+spans, and overlapping or abutting spans are merged. For example, given the=
+ set
+of spans [5..9), [0..1), [3..6), [9..10), the normalized list of spans is
+[0..1), [3..10). These semantics are embodied in the <b>NormalizedSpanColle=
+ction</b>
+type (that is, its spans are ordered by their Start property, and they do n=
+ot
+overlap or abut). This type supports computing the union, intersection,
+overlap, and set difference of two NormalizedSpanCollections.</span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></p>
+
+<h2 style=3D'margin-top:20.0pt;margin-right:0in;margin-bottom:10.0pt;margin=
+-left:
+.4in;text-indent:-.4in;page-break-after:avoid;tab-stops:list .4in'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><a
+name=3D"_Toc155080036"><span style=3D'mso-fareast-font-family:"Times New Ro=
+man"'>SnapshotPoint,
+SnapshotSpan, and NormalizedSnapshotSpanCollection<o:p></o:p></span></a></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1550800=
+36'>The <b
+style=3D'mso-bidi-font-weight:normal'>SnapshotPoint </b>struct is an immuta=
+ble
+type that represents a character position in a particular snapshot. The
+position is guaranteed to lie between zero and the length of the snapshot (=
+when
+it takes its maximal value the position addresses the greatest position at
+which an insertion could take place &#8211; one position past the last
+character in the snapshot).</span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1550800=
+36'>The <b
+style=3D'mso-bidi-font-weight:normal'>SnapshotSpan </b>struct is an immutab=
+le
+type that represents a span of text in a particular snapshot. Its End posit=
+ion
+is guaranteed to lie between zero and the length of the snapshot.</span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1550800=
+36'>The <b
+style=3D'mso-bidi-font-weight:normal'>NormalizedSnapshotSpanCollection </b>=
+is
+very similar to the <b style=3D'mso-bidi-font-weight:normal'>NormalizedSpan=
+Collection
+</b>described previously, except that it consists of SnapshotSpans, all from
+the same snapshot. </span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1550800=
+36'>A
+live object of any of these types holds a reference to the snapshot in ques=
+tion
+and prevents it from being garbage collected.</span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></p>
+
+<h2 style=3D'margin-top:20.0pt;margin-right:0in;margin-bottom:10.0pt;margin=
+-left:
+.4in;text-indent:-.4in;page-break-after:avoid;tab-stops:list .4in'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc155080036'><span style=3D'mso-fareast-font-family=
+:"Times New Roman"'>ITextEdit,
+EditOptions, TextVersion and Text change notifications</span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>The content of a TextBuffer can be chan=
+ged
+using an <b>ITextEdit</b> object. Creating such an object using one of the
+CreateEdit() methods of ITextBuffer initiates a text transaction consisting=
+ of
+zero or more edits, each of which is modeled as a replacement of some span =
+of
+text in the buffer by a string. The coordinates and content of each edit are
+expressed in terms of the state of the current snapshot of the buffer when =
+the
+transaction was started; the TextEdit object is responsible for adjusting t=
+he
+coordinates of edits that are affected by other edits in the same transacti=
+on.
+For example, consider a TextBuffer containing the string
+&#8220;abcdefghij&#8221; and a transaction containing two edits, where the
+first edit replaces the two character span at [2..4) with &#8220;X&#8221; a=
+nd
+the second replaces the three character span at [6..9) with &#8220;Y&#8221;.
+The result is &#8220;abXefYj&#8221;. Notice that the coordinates for the se=
+cond
+edit were computed with respect to the contents of the buffer at the beginn=
+ing
+of the transaction, that is, before the first edit was applied. For a second
+example, consider a TextBuffer containing the string &#8220;abcd&#8221; and=
+ a
+transaction containing two edits, where the first edit inserts &#8220;X&#82=
+21;
+at position 3 and the second deletes 2 characters starting at position 2; t=
+he
+result is &#8220;abX&#8221;.</span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>When the TextEdit object is committed by
+calling its <b>Apply</b> method, the changes to the buffer become effective=
+. If
+there was at least one non-vacuous edit performed, a new <b>TextVersion</b>=
+ is
+created, a new <b>ITextSnapshot </b>is created, and a single <b>Changed</b>
+event is raised.</span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>Only one TextEdit object can be instant=
+iated
+for a TextBuffer at any time, and all TextEdits must be performed on the th=
+read
+that owns the TextBuffer (if ownership has been claimed). A TextEdit can be=
+ abandoned
+by calling its <b>Cancel</b> or <b>Dispose</b> method.</span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>ITextBuffer also provides <b>Insert</b>=
+, <b>Delete</b>,
+and <b>Replace</b> convenience methods similar to those found on the ITextE=
+dit
+interface; calling these has the same effect as creating an ITextEdit objec=
+t,
+making the similar call, and then applying the singleton edit.</span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>As mentioned above, each non-vacuous ch=
+ange
+to a TextBuffer results in a new version of the TextBuffer, described by a
+TextVersion object. There is a distinct TextSnapshot for each TextVersion.
+Whereas snapshots capture the complete state of the TextBuffer after each e=
+dit
+transaction, TextVersions incrementally describe the changes that lead from=
+ one
+snapshot to the next. From a snapshot you can navigate to the corresponding=
+ <b>TextVersion</b>
+that in turn refers to a <b>NormalizedTextChangeCollection</b>. This collec=
+tion
+describes the changes that, when applied to the snapshot, will result in the
+subsequent snapshot (the normalized collection is therefore always null for=
+ the
+most recent version of the TextBuffer). Each TextChange in the normalized
+collection contains the character position of the change, the replaced stri=
+ng,
+and the replacement string (the former is empty for a simple insertion and =
+the
+latter is empty for a simple deletion).</span></span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>The <b style=3D'mso-bidi-font-weight:no=
+rmal'>EditOptions
+</b>enumeration type describes options that alter the behavior of TextEdit
+objects. The <b style=3D'mso-bidi-font-weight:normal'>ComputeMinimalChange =
+</b>option
+specifies that, for a text replacement, the editor should compute the minim=
+al
+set of edits required to accomplish the replacement and break the replaceme=
+nt
+down into that set. For example, if the string &#8220;ABCD&#8221; at positi=
+on 0
+is replaced by &#8220;ABC&#8221; and this edit is specified, the TextVersion
+that is created will show a simple insertion of &#8220;D&#8221; at position=
+ 3.</span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></p>
+
+<h2 style=3D'margin-top:20.0pt;margin-right:0in;margin-bottom:10.0pt;margin=
+-left:
+.4in;text-indent:-.4in;page-break-after:avoid;tab-stops:list .4in'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><a
+name=3D"_Toc155080038"></a><a name=3D"_Content_Type"></a><span style=3D'mso=
+-bookmark:
+_Toc155080038'><span style=3D'mso-fareast-font-family:"Times New Roman"'>IT=
+rackingPoint
+and ITrackingSpan</span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>An <b>ITrackingPoint</b> denotes a part=
+icular
+position in a particular TextBuffer. If the buffer is edited so as to cause=
+ the
+character at the denoted position to shift, the TrackingPoint shifts along =
+with
+it. Thus if a TrackingPoint refers to position 10 in a buffer and 5 charact=
+ers
+are inserted at the beginning of the buffer, the TrackingPoint for the
+resulting snapshot will then refer to position 15. If an insertion happens =
+at
+precisely the position denoted by the TtrackingPoint, its behavior is
+determined by its <b style=3D'mso-bidi-font-weight:normal'>PointT<span
+style=3D'mso-bidi-font-weight:bold'>rackingMode</span></b>, which can be ei=
+ther <b>Positive
+</b>or <b>Negative</b>. If the tracking mode is positive, the TrackingPoint
+will refer to the same character, now at the end of the insertion; if the
+tracking mode is negative, the TrackingPoint will refer to the first insert=
+ed
+character at the original position. If the character at the position denote=
+d by
+a TrackingPoint is deleted, the TrackingPoint shifts to the point of the
+deletion and refers to the first character that following the deleted range.
+For example, if a TrackingPoint refers to the character at position 5 and t=
+hen
+the characters at positions 3 through 6 are deleted, the TrackingPoint will
+refer to the character at position 3. To obtain the position of a
+TrackingPoint, you must specify the TextSnapshot of interest. </span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>An <b>ITrackingSpan</b> is a similar ob=
+ject
+that denotes a range of characters instead of a single position, and whose
+behavior is conditioned by its <b>SpanTrackingMode</b>. If the SpanTracking=
+Mode
+is <b>EdgeInclusive</b>, the TrackingSpan grows to incorporate text inserte=
+d at
+its edges; if the SpanTrackingMode is <b>EdgeExclusive</b>, the TrackingSpan
+does not incorporate text inserted at its edges. Two other SpanTrackingModes
+are less frequently used: in <b style=3D'mso-bidi-font-weight:normal'>EdgeN=
+egative</b>
+mode both ends points behave like Negative tracking text points; in <b
+style=3D'mso-bidi-font-weight:normal'>EdgePositive </b>mode both end points
+behave like Positive tracking text points. These modes are most useful
+respectively at the beginning and end of a buffer.</span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>The position of a TrackingPoint or the =
+Span
+of a TrackingSpan can be obtained for any snapshot of the TextBuffer to whi=
+ch
+they belong. TrackingPoints and TrackingSpans may be safely referenced from=
+ any
+thread.</span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>In addition to the tracking modes descr=
+ibed
+above, <b style=3D'mso-bidi-font-weight:normal'>TrackingFidelityMode </b>is=
+ used
+to control the behavior of tracking points and spans. Each of the fidelity
+modes is explained below in terms of text points; the start and end points =
+of
+text spans behave individually in the same way. In the discussion below, th=
+e <i>origin</i>
+version of a point is the version against which it was created (that is, the
+origin version is the TextVersion object on which the factory method for the
+point was called). The <i>cached </i>version is the largest version number
+against which the </span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'font-family:Consolas;color:#00B0F0'>GetPosition</span> method has =
+been
+called. Tracking behavior is described with respect to the <i>target</i>
+version, the version against which the GetPosition method is called. Tracki=
+ng
+fidelity modes affect the behavior of </span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+<span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'font-family:Consolas;color:#00B0F0'>GetPosition</span> depending o=
+n the
+relative ordering of the origin, cached, and target versions.</span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></p>
+
+<h3><span style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:=
+_Toc153700829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Forward<o:p></o:p></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></h3>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>When the target version is greater than=
+ or
+equal to the cached version, the point tracks forward as expected. When the
+cached version is greater than the origin version, and the target version
+number is between the two, </span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'font-family:Consolas;color:#00B0F0'>GetPosition</span> may give
+unexpected results. For example, consider a buffer containing the string
+&#8220;0123&#8221; and a </span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'font-family:Consolas;color:#00B0F0'>Positive</span> tracking point=
+ at
+position 2. Now suppose the substring &#8220;12&#8221; is deleted, leaving
+&#8220;03&#8221;, and the position of the point is queried; it will have the
+value 1. If the position of the point is subsequently queried for the previ=
+ous version,
+it will have the value 3 rather than 2. This is because the forward fidelity
+mode simply reverses edits when moving backwards in version space from the
+cached version to the target version. In this case, the deletion of
+&#8220;12&#8221; is reversed (becomes an insertion at position 1), and beca=
+use
+the point is </span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'font-family:Consolas;color:#00B0F0'>Positive</span> tracking, it
+advances two positions. In this mode, the information that the point was
+previously in the middle of the deleted substring is lost.</span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin=
+'><o:p></o:p></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>Because they do not force historical
+information to be retained, forward tracking points are the most space
+efficient. Typically they should be used only when points are not shared am=
+ong
+several clients, because queries by one client that are not known to another
+client may cause unexpected results. Still, it is anticipated that this
+fidelity mode will be the most commonly used. It is especially advantageous=
+ to
+use this mode if large numbers of spans are being created, say, one for each
+node in an AST.</span></span></span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>Forward is the default tracking fidelit=
+y for
+both points and spans. </span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></p>
+
+<h3><span style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:=
+_Toc153700829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Backward<o:p></o:p></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></h3>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>The point tracks forward as expected, a=
+nd
+when the target version is less than the cached version, </span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'font-family:Consolas;color:#00B0F0'>GetPosition</span> always give=
+s the
+same answer. When the target version is less than the origin version, it
+behaves like a Forward tracking point (but there is no history to remember =
+in
+this case).</span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin=
+'><o:p></o:p></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>Backward tracking points require the
+retention of more historical information and are therefore less space effic=
+ient
+than forward tracking points. Therefore, Backward tracking points should on=
+ly
+be used for short-lived objects; typically they are used in situations where
+some derived model may temporarily be out of sync with the text buffer by a=
+ few
+versions, and it is necessary to map both forward and backward with complete
+fidelity. </span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></p>
+
+<h3><span style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:=
+_Toc153700829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>UndoRedo<o:p></o:p></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></h3>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>The point behaves like a forward tracki=
+ng
+point unless it is mapped to a reiterated version (a version that is the re=
+sult
+of an undo or redo operation). In the latter case, </span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'font-family:Consolas;color:#00B0F0'>GetPosition</span> is guarante=
+ed to
+return the same result it would have for the version being reiterated. Of
+course, if the target version is earlier than the origin version, the point=
+ has
+no history to reiterate, and it behaves like a Forward tracking point. </sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin=
+'><o:p></o:p></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>For example, consider a buffer containi=
+ng
+&#8220;012345&#8221; and a positive tracking point at position 2. Now suppo=
+se
+the string &#8220;123&#8221; is deleted. Getting the position of the point =
+at
+this juncture returns the value 1. Now suppose the deletion is undone and <=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'font-family:Consolas;color:#00B0F0'>GetPosition</span> is called. A
+positive tracking point that does not have UndoRedo fidelity would return t=
+he
+position 3, since the undo appears to be a simple insertion. A point having
+UndoRedo fidelity returns position 2.</span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>Like Backward tracking points, UndoRedo
+tracking points require retention of more historical information and should
+only be used if absolutely required. </span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/p>
+
+<h2 style=3D'margin-top:20.0pt;margin-right:0in;margin-bottom:10.0pt;margin=
+-left:
+.4in;text-indent:-.4in;page-break-after:avoid;tab-stops:list .4in'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><a
+name=3D"_Toc155080039"></a><a name=3D"_Obtaining_Documents_and"></a><a
+name=3D"_Reading_and_Writing"></a><span style=3D'mso-bookmark:_Toc155080039=
+'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>IReadOnlyRegion and </s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>IReadOnlyRegionEdit<o:p=
+></o:p></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>Individual spans of text in a TextBuffe=
+r may
+be marked as read only, with each designated by an <b>IReadOnlyRegion</b>.
+Attempts to modify the text in a read only region have no effect. Each
+TextBuffer can create an <b style=3D'mso-bidi-font-weight:normal'>IReadOnly=
+RegionEdit</b>
+which can be used to create and remove <b>IReadOnlyRegion</b>s on that buff=
+er.
+The IReadOnlyRegionEdit object is similar to an ITextEdit object&#8212;it m=
+ust
+by applied to have effect, and each non-vacuous edit generates a new version
+and snapshot of the text buffer. The behavior of a ReadOnlyRegion at its
+boundaries is determined by its <b>EdgeInsertionMode</b>.</span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></p>
+
+<h2 style=3D'margin-top:20.0pt;margin-right:0in;margin-bottom:10.0pt;margin=
+-left:
+.4in;text-indent:-.4in;page-break-after:avoid;tab-stops:list .4in'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><a
+name=3D"_Toc155080040"><span style=3D'mso-fareast-font-family:"Times New Ro=
+man"'>ITextBufferFactory</span></a></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span><sp=
+an
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Service<o:p></o:p></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>TextBuffers are created using the <b>IT=
+extBufferFactoryService</b>,
+which allows creation of an empty TextBuffer or a TextBuffer initialized fr=
+om a
+string or System.IO.<b>TextReader</b>.</span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</p>
+
+<h1 style=3D'margin-top:24.0pt;margin-right:0in;margin-bottom:10.0pt;margin=
+-left:
+.3in;text-indent:-.3in;line-height:normal;tab-stops:list .3in'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><a
+name=3D"_Toc155080041"><span style=3D'mso-fareast-font-family:"Times New Ro=
+man"'>Text
+Projection</span></a></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></h1>
+
+<h2 style=3D'margin-top:20.0pt;margin-right:0in;margin-bottom:10.0pt;margin=
+-left:
+.4in;text-indent:-.4in;page-break-after:avoid;tab-stops:list .4in'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><a
+name=3D"_Toc155080042"><span style=3D'mso-fareast-font-family:"Times New Ro=
+man"'>IProjectionBuffer</span></a></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>An
+<b>IProjectionBuffer</b> is a specialized TextBuffer that does not actually
+store text; rather, it presents a projection of text drawn from one or more
+other TextBuffers. In particular, a ProjectionBuffer is specified by an ord=
+ered
+sequence of ITrackingSpans known as <i style=3D'mso-bidi-font-style:normal'=
+>Source
+Spans</i>; it presents the contents of these spans as a contiguous sequence=
+ of
+characters. The TextBuffers from which the source spans are drawn are called
+the <i style=3D'mso-bidi-font-style:normal'>Source Buffers. </i>A client of=
+ the
+ProjectionBuffer need not be aware that it is different from an ordinary
+TextBuffer and so can be insulated from the fact that the text it presents =
+is
+virtualized (on the other hand it may well be aware of the presence of a
+ProjectionBuffer).<o:p></o:p></span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>The
+ProjectionBuffer listens to text change events on the source buffers. Whene=
+ver
+the text in a source span changes, the ProjectionBuffer maps the changed te=
+xt
+coordinates into its own coordinates and raises appropriate text change eve=
+nts.
+For example, consider source buffers A and B with contents as shown below,<=
+o:p></o:p></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></p>
+
+<div style=3D'mso-element:para-border-div;border:solid windowtext 1.0pt;
+mso-border-alt:solid windowtext .5pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
+background:#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
+
+<p class=3DCode style=3D'background:#E5E5E5;mso-shading:windowtext;mso-patt=
+ern:
+gray-10 auto;border:none;mso-border-alt:solid windowtext .5pt;padding:0in;
+mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><span style=3D'mso-bookmark:_Toc15=
+1442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'><span
+style=3D'mso-spacerun:yes'>&nbsp;&nbsp; </span>01234<o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></p>
+
+<p class=3DCode style=3D'background:#E5E5E5;mso-shading:windowtext;mso-patt=
+ern:
+gray-10 auto;border:none;mso-border-alt:solid windowtext .5pt;padding:0in;
+mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><span style=3D'mso-bookmark:_Toc15=
+1442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>A:
+ABCDE<o:p></o:p></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></p>
+
+<p class=3DCode style=3D'background:#E5E5E5;mso-shading:windowtext;mso-patt=
+ern:
+gray-10 auto;border:none;mso-border-alt:solid windowtext .5pt;padding:0in;
+mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><span style=3D'mso-bookmark:_Toc15=
+1442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'><o:p>&nbsp;</o:p></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></p>
+
+<p class=3DCode style=3D'background:#E5E5E5;mso-shading:windowtext;mso-patt=
+ern:
+gray-10 auto;border:none;mso-border-alt:solid windowtext .5pt;padding:0in;
+mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><span style=3D'mso-bookmark:_Toc15=
+1442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'><span
+style=3D'mso-spacerun:yes'>&nbsp;&nbsp; </span>01234<o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></p>
+
+<p class=3DCode style=3D'background:#E5E5E5;mso-shading:windowtext;mso-patt=
+ern:
+gray-10 auto;border:none;mso-border-alt:solid windowtext .5pt;padding:0in;
+mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><span style=3D'mso-bookmark:_Toc15=
+1442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>B:
+vwxyz<o:p></o:p></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></p>
+
+</div>
+
+<p class=3DMsoNormal style=3D'margin-bottom:0in;margin-bottom:.0001pt'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'font-family:"Verdana","sans-serif";mso-fareast-font-family:SimSun'=
+><o:p>&nbsp;</o:p></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>and
+suppose ProjectionBuffer P is formed from two text spans, one comprising al=
+l of
+buffer A and the other all of buffer B. P has these contents:<o:p></o:p></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></p>
+
+<div style=3D'mso-element:para-border-div;border:solid windowtext 1.0pt;
+mso-border-alt:solid windowtext .5pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
+background:#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
+
+<p class=3DCode style=3D'background:#E5E5E5;mso-shading:windowtext;mso-patt=
+ern:
+gray-10 auto;border:none;mso-border-alt:solid windowtext .5pt;padding:0in;
+mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><span style=3D'mso-bookmark:_Toc15=
+1442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'><span
+style=3D'mso-spacerun:yes'>&nbsp;&nbsp; </span>0123456789<o:p></o:p></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></p>
+
+<p class=3DCode style=3D'background:#E5E5E5;mso-shading:windowtext;mso-patt=
+ern:
+gray-10 auto;border:none;mso-border-alt:solid windowtext .5pt;padding:0in;
+mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><span style=3D'mso-bookmark:_Toc15=
+1442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>P:
+ABCDEvwxyz<o:p></o:p></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></p>
+
+</div>
+
+<p class=3DMsoNormal style=3D'margin-bottom:0in;margin-bottom:.0001pt'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'font-family:"Courier New";mso-fareast-font-family:SimSun;mso-bidi-=
+font-family:
+"Times New Roman"'><o:p>&nbsp;</o:p></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>If
+the substring &#8220;xy&#8221; is deleted from buffer B (at position 2), P =
+will
+raise an event indicating that the characters at positions 7 and 8 were
+deleted. </span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'font-family:"Verdana","sans-serif";mso-fareast-font-family:SimSun'=
+><o:p></o:p></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>The</span>
+ProjectionBuffer can also be edited directly; it propagates edits to the
+appropriate source buffers. For example, if a string is inserted into the P=
+ at
+position 6, the insertion will be propagated to B at position 1.</span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:SimSun'><o:p></o:p></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>There
+are certain restrictions on the source spans that contribute to a
+ProjectionBuffer:<o:p></o:p></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></p>
+
+<ul style=3D'margin-top:0in' type=3Ddisc>
+ <li class=3DMsoNormal style=3D'margin-bottom:6.0pt;line-height:normal;mso-=
+list:
+ l4 level1 lfo6;tab-stops:list .5in'><span style=3D'mso-bookmark:_Toc15=
+1442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-fa=
+mily:
+ SimSun'>Source spans may not be overlapping (more precisely, a single
+ location in a projection buffer cannot map to more than one location in
+ any source buffer, and a single location in a source buffer cannot map=
+ to
+ more than one location in a projection buffer). <o:p></o:p></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></li>
+ <li class=3DMsoNormal style=3D'margin-bottom:6.0pt;line-height:normal;mso-=
+list:
+ l4 level1 lfo6;tab-stops:list .5in'><span style=3D'mso-bookmark:_Toc15=
+1442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-fa=
+mily:
+ SimSun'>In order to more easily prevent overlapping source spans, a so=
+urce
+ span may be EdgeInclusive only if it covers an entire TextBuffer.
+ EdgeNegative spans may only be used at the beginning of a source buffe=
+r,
+ and EdgePositive spans at the end of a source buffer. There is no
+ restriction on EdgeExclusive source spans.<o:p></o:p></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></li>
+ <li class=3DMsoNormal style=3D'margin-bottom:6.0pt;line-height:normal;mso-=
+list:
+ l4 level1 lfo6;tab-stops:list .5in'><span style=3D'mso-bookmark:_Toc15=
+1442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-fa=
+mily:
+ SimSun'>No circularities are permitted in the source buffer relationsh=
+ip.<o:p></o:p></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></li>
+</ul>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>In
+addition to garden variety insertion, deletion, and replacement of character
+strings, ProjectionBuffers support insertion, deletion, and replacement of
+source spans. These source span changes cause ordinary text change events t=
+o be
+raised as if the text contained in the spans had itself been inserted, dele=
+ted,
+or replaced. In the example above, if the first source span were deleted, t=
+he
+ProjectionBuffer would raise an event indicating that the characters ABCDE =
+had
+been deleted.<o:p></o:p></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>Read only regions created for a
+ProjectionBuffer apply only at the level of the projection, prohibiting cha=
+nges
+to the affected text through that buffer. They do not prevent the same text
+from being changed in the source buffer. Thus read only regions do not
+guarantee immutability of text unless applied to a non-projection buffer.</=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>Events
+are raised when the set of source buffers for a projection buffer changes a=
+nd
+when the set of source spans changes.<o:p></o:p></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>ProjectionBuffers
+are created using the <b>IProjectionBufferFactory </b>service.<o:p></o:p></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></p>
+
+<h3 style=3D'margin-top:15.0pt;margin-right:0in;margin-bottom:6.0pt;margin-=
+left:
+.5in;text-indent:-.5in;line-height:normal;tab-stops:list .5in'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><a
+name=3D"_Toc155080043"><span style=3D'mso-fareast-font-family:"Times New Ro=
+man"'>Boundary
+Conditions</span></a></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc155080043'></span><span style=3D'mso-bookmark:_To=
+c151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'><o:p></o:p></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></h3>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun'>In
+the example above, if an insertion is made into ProjectionBuffer P at posit=
+ion
+5, the intent could be that the text should be inserted into TextBuffer A at
+position 5, or it could be that it should be inserted into TextBuffer B at
+position 0 (or it could be that the insertion string should be split between
+the two source buffers). To resolve such ambiguities, the creator of the
+ProjectionBuffer may optionally supply an object that implements the <b>IPr=
+ojectionEditResolver</b>
+interface. <o:p></o:p></span></span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><i style=3D'mso-bidi-font-style:normal'=
+><span
+style=3D'mso-fareast-font-family:SimSun'>TODO: literal source spans.<o:p></=
+o:p></span></i></span></span></span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:=
+_Toc153700829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:SimSun'>IProjectionSnapshot and PositionAf=
+finity<o:p></o:p></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><i style=3D'mso-bidi-font-style:normal'=
+><span
+style=3D'mso-fareast-font-family:SimSun'>TODO: point mapping, affinity, span
+mapping<o:p></o:p></span></i></span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><b style=3D'mso-bidi-font-weight:normal=
+'><span
+style=3D'mso-fareast-font-family:SimSun'>IProjectionSnapshot </span></b></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-fareast-font-family:SimSun'>is a specialization of ITextSnapsh=
+ot. It
+can be used to examine the source snapshot spans that contribute to a
+particular snapshot of a projection buffer, and also to map positions from =
+the
+projection buffer to its sources and vice versa.<o:p></o:p></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></p>
+
+<h2 style=3D'margin-top:20.0pt;margin-right:0in;margin-bottom:10.0pt;margin=
+-left:
+.4in;text-indent:-.4in;page-break-after:avoid;tab-stops:list .4in'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><a
+name=3D"_Toc155080044"><span style=3D'mso-fareast-font-family:"Times New Ro=
+man"'>IBufferGraph</span></a></span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc155080044'></span><span style=3D'mso-bookmark:_To=
+c151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+SimSun;
+mso-bidi-font-style:italic'><o:p></o:p></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc151442559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'>The<b> IBufferGraph</b> interface facil=
+itates
+mapping positions across a graph of ProjectionBuffers. The graph is defined=
+ by
+the <i>top buffer, </i>which can be any text buffer. If it is a
+ProjectionBuffer, the graph will be nontrivial. IBufferGraph supports mappi=
+ng
+from a point in the top buffer to a point in a particular source buffer, or
+from a span in the top buffer to a set of spans in a particular source buff=
+er.
+Similarly, it can map a point or span from a source buffer to a point in the
+top buffer. Buffer graphs are created using the <b>IBufferGraphFactoryServi=
+ce</b><span
+style=3D'mso-bidi-font-weight:bold'>.</span> </span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></p>
+
+<h2><span style=3D'mso-fareast-font-family:"Times New Roman"'>IMappingPoint=
+ and
+IMappingSpan<o:p></o:p></span></h2>
+
+</div>
+
+<div style=3D'mso-element:footnote-list'><![if !supportFootnotes]><br clear=
+=3Dall>
+
+<hr align=3Dleft size=3D1 width=3D"33%">
+
+<![endif]>
+
+<div style=3D'mso-element:footnote' id=3Dftn1>
+
+<p class=3DMsoFootnoteText><a style=3D'mso-footnote-id:ftn1' href=3D"#_ftnr=
+ef1"
+name=3D"_ftn1" title=3D""><span style=3D'mso-special-character:footnote'><!=
+[if !supportFootnotes]><span
+style=3D'font-size:11.0pt;mso-bidi-font-size:10.0pt;font-family:"Calibri","=
+sans-serif";
+mso-fareast-font-family:"Times New Roman";mso-bidi-font-family:"Times New R=
+oman";
+mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA'=
+>[1]</span><![endif]></span></a>
+The TextBuffer does not guarantee that its contents are a valid Unicode
+sequence; it expects its clients to create only legal sequences. Text model
+clients should not fail if presented with illegal sequences (for example,
+surrogate characters without an appropriate paired surrogate).</p>
+
+</div>
+
+</div>
+
+</body>
+
+</html>
+
+------=_NextPart_01C91992.81DAA780
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Model.Overview_files/themedata.thmx
+Content-Transfer-Encoding: base64
+Content-Type: application/vnd.ms-officetheme
+
+UEsDBBQABgAIAAAAIQCCirwT+gAAABwCAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbKyRy2rDMBBF
+94X+g9C22HK6KKXYzqJJd30s0g8Y5LEtao+ENAnJ33fsuFC6CC10IxBizpl7Va6P46AOGJPzVOlV
+XmiFZH3jqKv0++4pu9cqMVADgyes9AmTXtfXV+XuFDApmaZU6Z45PBiTbI8jpNwHJHlpfRyB5Ro7
+E8B+QIfmtijujPXESJzxxNB1+SoLRNegeoPILzCKx7Cg8Pv5DCSAmAtYq8czYVqi0hDC4CywRDAH
+an7oM9+2zmLj7X4UaT6DF9jNBDO/XGD1P+ov5wZb2A+stkfp4lx/xCH9LdtSay6Tc/7Uu5AuGC6X
+t7Rh5r+tPwEAAP//AwBQSwMEFAAGAAgAAAAhAKXWp+fAAAAANgEAAAsAAABfcmVscy8ucmVsc4SP
+z2rDMAyH74W9g9F9UdLDGCV2L6WQQy+jfQDhKH9oIhvbG+vbT8cGCrsIhKTv96k9/q6L+eGU5yAW
+mqoGw+JDP8to4XY9v3+CyYWkpyUIW3hwhqN727VfvFDRozzNMRulSLYwlRIPiNlPvFKuQmTRyRDS
+SkXbNGIkf6eRcV/XH5ieGeA2TNP1FlLXN2Cuj6jJ/7PDMMyeT8F/ryzlRQRuN5RMaeRioagv41O9
+kKhlqtQe0LW4+db9AQAA//8DAFBLAwQUAAYACAAAACEAa3mWFoMAAACKAAAAHAAAAHRoZW1lL3Ro
+ZW1lL3RoZW1lTWFuYWdlci54bWwMzE0KwyAQQOF9oXeQ2TdjuyhFYrLLrrv2AEOcGkHHoNKf29fl
+44M3zt8U1ZtLDVksnAcNimXNLoi38Hwspxuo2kgcxSxs4ccV5ul4GMm0jRPfSchzUX0j1ZCFrbXd
+INa1K9Uh7yzdXrkkaj2LR1fo0/cp4kXrKyYKAjj9AQAA//8DAFBLAwQUAAYACAAAACEAlrWt4pYG
+AABQGwAAFgAAAHRoZW1lL3RoZW1lL3RoZW1lMS54bWzsWU9v2zYUvw/YdyB0b2MndhoHdYrYsZst
+TRvEboceaYmW2FCiQNJJfRva44ABw7phhxXYbYdhW4EW2KX7NNk6bB3Qr7BHUpLFWF6SNtiKrT4k
+Evnj+/8eH6mr1+7HDB0SISlP2l79cs1DJPF5QJOw7d0e9i+teUgqnASY8YS0vSmR3rWN99+7itdV
+RGKCYH0i13Hbi5RK15eWpA/DWF7mKUlgbsxFjBW8inApEPgI6MZsablWW12KMU08lOAYyN4aj6lP
+0FCT9DZy4j0Gr4mSesBnYqBJE2eFwQYHdY2QU9llAh1i1vaAT8CPhuS+8hDDUsFE26uZn7e0cXUJ
+r2eLmFqwtrSub37ZumxBcLBseIpwVDCt9xutK1sFfQNgah7X6/W6vXpBzwCw74OmVpYyzUZ/rd7J
+aZZA9nGedrfWrDVcfIn+ypzMrU6n02xlsliiBmQfG3P4tdpqY3PZwRuQxTfn8I3OZre76uANyOJX
+5/D9K63Vhos3oIjR5GAOrR3a72fUC8iYs+1K+BrA12oZfIaCaCiiS7MY80QtirUY3+OiDwANZFjR
+BKlpSsbYhyju4ngkKNYM8DrBpRk75Mu5Ic0LSV/QVLW9D1MMGTGj9+r596+eP0XHD54dP/jp+OHD
+4wc/WkLOqm2chOVVL7/97M/HH6M/nn7z8tEX1XhZxv/6wye//Px5NRDSZybOiy+f/PbsyYuvPv39
+u0cV8E2BR2X4kMZEopvkCO3zGBQzVnElJyNxvhXDCNPyis0klDjBmksF/Z6KHPTNKWaZdxw5OsS1
+4B0B5aMKeH1yzxF4EImJohWcd6LYAe5yzjpcVFphR/MqmXk4ScJq5mJSxu1jfFjFu4sTx7+9SQp1
+Mw9LR/FuRBwx9xhOFA5JQhTSc/yAkArt7lLq2HWX+oJLPlboLkUdTCtNMqQjJ5pmi7ZpDH6ZVukM
+/nZss3sHdTir0nqLHLpIyArMKoQfEuaY8TqeKBxXkRzimJUNfgOrqErIwVT4ZVxPKvB0SBhHvYBI
+WbXmlgB9S07fwVCxKt2+y6axixSKHlTRvIE5LyO3+EE3wnFahR3QJCpjP5AHEKIY7XFVBd/lbobo
+d/ADTha6+w4ljrtPrwa3aeiINAsQPTMR2pdQqp0KHNPk78oxo1CPbQxcXDmGAvji68cVkfW2FuJN
+2JOqMmH7RPldhDtZdLtcBPTtr7lbeJLsEQjz+Y3nXcl9V3K9/3zJXZTPZy20s9oKZVf3DbYpNi1y
+vLBDHlPGBmrKyA1pmmQJ+0TQh0G9zpwOSXFiSiN4zOq6gwsFNmuQ4OojqqJBhFNosOueJhLKjHQo
+UcolHOzMcCVtjYcmXdljYVMfGGw9kFjt8sAOr+jh/FxQkDG7TWgOnzmjFU3grMxWrmREQe3XYVbX
+Qp2ZW92IZkqdw61QGXw4rxoMFtaEBgRB2wJWXoXzuWYNBxPMSKDtbvfe3C3GCxfpIhnhgGQ+0nrP
++6hunJTHirkJgNip8JE+5J1itRK3lib7BtzO4qQyu8YCdrn33sRLeQTPvKTz9kQ6sqScnCxBR22v
+1VxuesjHadsbw5kWHuMUvC51z4dZCBdDvhI27E9NZpPlM2+2csXcJKjDNYW1+5zCTh1IhVRbWEY2
+NMxUFgIs0Zys/MtNMOtFKWAj/TWkWFmDYPjXpAA7uq4l4zHxVdnZpRFtO/ualVI+UUQMouAIjdhE
+7GNwvw5V0CegEq4mTEXQL3CPpq1tptzinCVd+fbK4Ow4ZmmEs3KrUzTPZAs3eVzIYN5K4oFulbIb
+5c6vikn5C1KlHMb/M1X0fgI3BSuB9oAP17gCI52vbY8LFXGoQmlE/b6AxsHUDogWuIuFaQgquEw2
+/wU51P9tzlkaJq3hwKf2aYgEhf1IRYKQPShLJvpOIVbP9i5LkmWETESVxJWpFXtEDgkb6hq4qvd2
+D0UQ6qaaZGXA4E7Gn/ueZdAo1E1OOd+cGlLsvTYH/unOxyYzKOXWYdPQ5PYvRKzYVe16szzfe8uK
+6IlZm9XIswKYlbaCVpb2rynCObdaW7HmNF5u5sKBF+c1hsGiIUrhvgfpP7D/UeEz+2VCb6hDvg+1
+FcGHBk0Mwgai+pJtPJAukHZwBI2THbTBpElZ02atk7ZavllfcKdb8D1hbC3ZWfx9TmMXzZnLzsnF
+izR2ZmHH1nZsoanBsydTFIbG+UHGOMZ80ip/deKje+DoLbjfnzAlTTDBNyWBofUcmDyA5LcczdKN
+vwAAAP//AwBQSwMEFAAGAAgAAAAhAA3RkJ+2AAAAGwEAACcAAAB0aGVtZS90aGVtZS9fcmVscy90
+aGVtZU1hbmFnZXIueG1sLnJlbHOEj00KwjAUhPeCdwhvb9O6EJEm3YjQrdQDhOQ1DTY/JFHs7Q2u
+LAguh2G+mWm7l53JE2My3jFoqhoIOumVcZrBbbjsjkBSFk6J2TtksGCCjm837RVnkUsoTSYkUigu
+MZhyDidKk5zQilT5gK44o49W5CKjpkHIu9BI93V9oPGbAXzFJL1iEHvVABmWUJr/s/04GolnLx8W
+Xf5RQXPZhQUoosbM4CObqkwEylu6usTfAAAA//8DAFBLAQItABQABgAIAAAAIQCCirwT+gAAABwC
+AAATAAAAAAAAAAAAAAAAAAAAAABbQ29udGVudF9UeXBlc10ueG1sUEsBAi0AFAAGAAgAAAAhAKXW
+p+fAAAAANgEAAAsAAAAAAAAAAAAAAAAAKwEAAF9yZWxzLy5yZWxzUEsBAi0AFAAGAAgAAAAhAGt5
+lhaDAAAAigAAABwAAAAAAAAAAAAAAAAAFAIAAHRoZW1lL3RoZW1lL3RoZW1lTWFuYWdlci54bWxQ
+SwECLQAUAAYACAAAACEAlrWt4pYGAABQGwAAFgAAAAAAAAAAAAAAAADRAgAAdGhlbWUvdGhlbWUv
+dGhlbWUxLnhtbFBLAQItABQABgAIAAAAIQAN0ZCftgAAABsBAAAnAAAAAAAAAAAAAAAAAJsJAAB0
+aGVtZS90aGVtZS9fcmVscy90aGVtZU1hbmFnZXIueG1sLnJlbHNQSwUGAAAAAAUABQBdAQAAlgoA
+AAAA
+
+------=_NextPart_01C91992.81DAA780
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Model.Overview_files/colorschememapping.xml
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/xml
+
+<?xml version=3D"1.0" encoding=3D"UTF-8" standalone=3D"yes"?>
+<a:clrMap xmlns:a=3D"http://schemas.openxmlformats.org/drawingml/2006/main"=
+ bg1=3D"lt1" tx1=3D"dk1" bg2=3D"lt2" tx2=3D"dk2" accent1=3D"accent1" accent=
+2=3D"accent2" accent3=3D"accent3" accent4=3D"accent4" accent5=3D"accent5" a=
+ccent6=3D"accent6" hlink=3D"hlink" folHlink=3D"folHlink"/>
+------=_NextPart_01C91992.81DAA780
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Model.Overview_files/header.htm
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/html; charset="us-ascii"
+
+<html xmlns:v=3D"urn:schemas-microsoft-com:vml"
+xmlns:o=3D"urn:schemas-microsoft-com:office:office"
+xmlns:w=3D"urn:schemas-microsoft-com:office:word"
+xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml"
+xmlns=3D"http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=3DContent-Type content=3D"text/html; charset=3Dus-ascii">
+<meta name=3DProgId content=3DWord.Document>
+<meta name=3DGenerator content=3D"Microsoft Word 12">
+<meta name=3DOriginator content=3D"Microsoft Word 12">
+<link id=3DMain-File rel=3DMain-File
+href=3D"../Microsoft.VisualStudio.Text.Model.Overview.htm">
+<![if IE]>
+<base
+href=3D"file:///C:\515CB117\Microsoft.VisualStudio.Text.Model.Overview_file=
+s\header.htm"
+id=3D"webarch_temp_base_tag">
+<![endif]>
+</head>
+
+<body lang=3DEN-US link=3Dblue vlink=3Dpurple>
+
+<div style=3D'mso-element:footnote-separator' id=3Dfs>
+
+<p class=3DMsoNormal><span style=3D'mso-special-character:footnote-separato=
+r'><![if !supportFootnotes]>
+
+<hr align=3Dleft size=3D1 width=3D"33%">
+
+<![endif]></span></p>
+
+</div>
+
+<div style=3D'mso-element:footnote-continuation-separator' id=3Dfcs>
+
+<p class=3DMsoNormal><span style=3D'mso-special-character:footnote-continua=
+tion-separator'><![if !supportFootnotes]>
+
+<hr align=3Dleft size=3D1>
+
+<![endif]></span></p>
+
+</div>
+
+<div style=3D'mso-element:endnote-separator' id=3Des>
+
+<p class=3DMsoNormal><span style=3D'mso-special-character:footnote-separato=
+r'><![if !supportFootnotes]>
+
+<hr align=3Dleft size=3D1 width=3D"33%">
+
+<![endif]></span></p>
+
+</div>
+
+<div style=3D'mso-element:endnote-continuation-separator' id=3Decs>
+
+<p class=3DMsoNormal><span style=3D'mso-special-character:footnote-continua=
+tion-separator'><![if !supportFootnotes]>
+
+<hr align=3Dleft size=3D1>
+
+<![endif]></span></p>
+
+</div>
+
+</body>
+
+</html>
+
+------=_NextPart_01C91992.81DAA780
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Model.Overview_files/filelist.xml
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/xml; charset="utf-8"
+
+<xml xmlns:o=3D"urn:schemas-microsoft-com:office:office">
+ <o:MainFile HRef=3D"../Microsoft.VisualStudio.Text.Model.Overview.htm"/>
+ <o:File HRef=3D"themedata.thmx"/>
+ <o:File HRef=3D"colorschememapping.xml"/>
+ <o:File HRef=3D"header.htm"/>
+ <o:File HRef=3D"filelist.xml"/>
+</xml>
+------=_NextPart_01C91992.81DAA780--
diff --git a/src/Text/Def/TextData/Model/NormalizedSnapshotSpanCollection.cs b/src/Text/Def/TextData/Model/NormalizedSnapshotSpanCollection.cs
new file mode 100644
index 0000000..57ba5dd
--- /dev/null
+++ b/src/Text/Def/TextData/Model/NormalizedSnapshotSpanCollection.cs
@@ -0,0 +1,1188 @@
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+
+ /// <summary>
+ /// A read-only collection of <see cref="SnapshotSpan"/> objects, all from the same snapshot.
+ /// </summary>
+ /// <remarks>
+ /// The snapshot spans are sorted by start position,
+ /// with adjacent and overlapping spans combined.
+ /// </remarks>
+ public sealed class NormalizedSnapshotSpanCollection : IList<SnapshotSpan>, ICollection<SnapshotSpan>, IEnumerable<SnapshotSpan>, IList, ICollection, IEnumerable
+ {
+ // imitate platform implementation of ReadOnlyCollection. Methods that write throw NotSupportException, and use explicit
+ // interface implementation to keep them from being easily called or participating in intellisense.
+
+ #region State and Construction
+
+ // To save space and reduce allocations, we do not create an inner NormalizedSpanCollection if this collection is
+ // of size zero or one. If this.snapshot is null, the collection has size zero. If this.snapshot is nonnull and
+ // this.spans is null, the collection is size one and this.span contains its single element (this accounts for
+ // over 95% of the instances of this class). If this.spans is nonnull, the collection is size two or greater.
+ // We can't do this by subclassing because of backward compatibility with the concrete constructor.
+
+ private ITextSnapshot snapshot;
+ private NormalizedSpanCollection spans;
+ private Span span;
+
+ public readonly static NormalizedSnapshotSpanCollection Empty = new NormalizedSnapshotSpanCollection();
+
+ /// <summary>
+ /// Initializes an empty <see cref="NormalizedSnapshotSpanCollection"/>.
+ /// </summary>
+ public NormalizedSnapshotSpanCollection()
+ {
+ // empty collection, signalled by this.snapshot == null
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="NormalizedSnapshotSpanCollection"/> with a single element.
+ /// </summary>
+ /// <param name="span">The sole member of the collection.</param>
+ /// <exception cref="ArgumentException"><paramref name="span"/> is not initialized.</exception>
+ public NormalizedSnapshotSpanCollection(SnapshotSpan span)
+ {
+ if (span.Snapshot == null)
+ {
+ throw new ArgumentException(Strings.UninitializedSnapshotSpan);
+ }
+ this.snapshot = span.Snapshot;
+ this.span = span;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="NormalizedSnapshotSpanCollection"/> from a <see cref="NormalizedSpanCollection"/> and a <see cref="ITextSnapshot"/>.
+ /// </summary>
+ /// <param name="snapshot">The <see cref="ITextSnapshot"/> to apply to <paramref name="spans"/>.</param>
+ /// <param name="spans">The normalized spans.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshot"/> or <paramref name="spans"/> is null.</exception>
+ /// <exception cref="ArgumentException">The spans in <paramref name="spans"/> extend beyond the end of <paramref name="snapshot"/>.</exception>
+ public NormalizedSnapshotSpanCollection(ITextSnapshot snapshot, NormalizedSpanCollection spans)
+ {
+ if (snapshot == null)
+ {
+ throw new ArgumentNullException("snapshot");
+ }
+ if (spans == null)
+ {
+ throw new ArgumentNullException("spans");
+ }
+ if (spans.Count > 0 && spans[spans.Count - 1].End > snapshot.Length)
+ {
+ throw new ArgumentException(Strings.SpansBeyondEnd);
+ }
+ if (spans.Count == 1)
+ {
+ this.snapshot = snapshot;
+ this.span = spans[0];
+ }
+ else if (spans.Count > 1)
+ {
+ this.snapshot = snapshot;
+ this.spans = spans;
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="NormalizedSnapshotSpanCollection"/> from a list of <see cref="Span"/>s and a <see cref="ITextSnapshot"/>.
+ /// </summary>
+ /// <param name="snapshot">The <see cref="ITextSnapshot"/> to apply to <paramref name="spans"/>.</param>
+ /// <param name="spans">An arbitrary set of <see cref="Span"/> objects.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshot"/> or <paramref name="spans"/> is null.</exception>
+ /// <exception cref="ArgumentException">The spans in <paramref name="spans"/> extend beyond the end of <paramref name="snapshot"/>.</exception>
+ public NormalizedSnapshotSpanCollection(ITextSnapshot snapshot, IEnumerable<Span> spans)
+ {
+ if (snapshot == null)
+ {
+ throw new ArgumentNullException("snapshot");
+ }
+ if (spans == null)
+ {
+ throw new ArgumentNullException("spans");
+ }
+
+ using (IEnumerator<Span> spanEnumerator = spans.GetEnumerator())
+ {
+ if (!spanEnumerator.MoveNext())
+ {
+ // empty collection
+ }
+ else
+ {
+ this.snapshot = snapshot;
+ Span span = spanEnumerator.Current;
+ if (!spanEnumerator.MoveNext())
+ {
+ // length one
+ this.span = span;
+ if (span.End > snapshot.Length)
+ {
+ throw new ArgumentException(Strings.SpansBeyondEnd);
+ }
+ }
+ else
+ {
+ // length at least two
+ this.spans = new NormalizedSpanCollection(spans);
+ if (this.spans[this.spans.Count - 1].End > snapshot.Length)
+ {
+ throw new ArgumentException(Strings.SpansBeyondEnd);
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="NormalizedSnapshotSpanCollection"/> from a list of <see cref="Span"/>s and a <see cref="ITextSnapshot"/>.
+ /// </summary>
+ /// <param name="snapshot">The <see cref="ITextSnapshot"/> to apply to <paramref name="spans"/>.</param>
+ /// <param name="spans">An arbitrary set of <see cref="Span"/> objects.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshot"/> or <paramref name="spans"/> is null.</exception>
+ /// <exception cref="ArgumentException">The spans in <paramref name="spans"/> extend beyond the end of <paramref name="snapshot"/>.</exception>
+ public NormalizedSnapshotSpanCollection(ITextSnapshot snapshot, IList<Span> spans)
+ {
+ if (snapshot == null)
+ {
+ throw new ArgumentNullException("snapshot");
+ }
+ if (spans == null)
+ {
+ throw new ArgumentNullException("spans");
+ }
+
+ if (spans.Count == 0)
+ {
+ // empty collection
+ }
+ else
+ {
+ this.snapshot = snapshot;
+ if (spans.Count == 1)
+ {
+ // length one
+ this.span = spans[0];
+ if (this.span.End > snapshot.Length)
+ {
+ throw new ArgumentException(Strings.SpansBeyondEnd);
+ }
+ }
+ else
+ {
+ // length at least two
+ this.spans = new NormalizedSpanCollection(spans);
+ if (this.spans[this.spans.Count - 1].End > snapshot.Length)
+ {
+ throw new ArgumentException(Strings.SpansBeyondEnd);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="NormalizedSnapshotSpanCollection"/> from a list of <see cref="SnapshotSpan"/> objects.
+ /// </summary>
+ /// <param name="snapshotSpans">An arbitrary set of <see cref="SnapshotSpan"/> objects.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshotSpans"/> is null.</exception>
+ /// <exception cref="ArgumentException">A <see cref="SnapshotSpan"/> is uninitialized, or it
+ /// does not refer to the same <see cref="ITextSnapshot"/> as the other snapshot spans, or it refers to an uninitialized <see cref="ITextSnapshot"/>.</exception>
+ public NormalizedSnapshotSpanCollection(IEnumerable<SnapshotSpan> snapshotSpans)
+ {
+ if (snapshotSpans == null)
+ {
+ throw new ArgumentNullException("snapshotSpans");
+ }
+
+ using (IEnumerator<SnapshotSpan> spanEnumerator = snapshotSpans.GetEnumerator())
+ {
+ if (!spanEnumerator.MoveNext())
+ {
+ // empty
+ }
+ else
+ {
+ SnapshotSpan firstSpan = spanEnumerator.Current;
+ this.snapshot = firstSpan.Snapshot;
+ if (!spanEnumerator.MoveNext())
+ {
+ // length one
+ this.span = firstSpan.Span;
+ }
+ else
+ {
+ // length at least two
+ bool alreadyNormalized = true;
+ List<Span> spans = new List<Span>();
+ Span currentSpan = firstSpan.Span;
+ spans.Add(currentSpan);
+ int lastEnd = currentSpan.End;
+ do
+ {
+ SnapshotSpan snapshotSpan = spanEnumerator.Current;
+ if (snapshotSpan.Snapshot != this.snapshot)
+ {
+ if (snapshotSpan.Snapshot == null)
+ {
+ throw new ArgumentException(Strings.UninitializedSnapshotSpan);
+ }
+ else
+ {
+ throw new ArgumentException(Strings.InvalidSnapshot);
+ }
+ }
+ currentSpan = snapshotSpan.Span;
+ spans.Add(currentSpan);
+ if (currentSpan.Start <= lastEnd)
+ {
+ alreadyNormalized = false;
+ }
+ lastEnd = currentSpan.End;
+ } while (spanEnumerator.MoveNext()) ;
+ this.spans = alreadyNormalized
+ ? NormalizedSpanCollection.CreateFromNormalizedSpans(spans)
+ : new NormalizedSpanCollection(spans);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="NormalizedSnapshotSpanCollection"/> from a list of <see cref="SnapshotSpan"/> objects.
+ /// </summary>
+ /// <param name="snapshotSpans">An arbitrary set of <see cref="SnapshotSpan"/> objects.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshotSpans"/> is null.</exception>
+ /// <exception cref="ArgumentException">A <see cref="SnapshotSpan"/> is uninitialized, or it
+ /// does not refer to the same <see cref="ITextSnapshot"/> as the other snapshot spans, or it refers to an uninitialized <see cref="ITextSnapshot"/>.</exception>
+ public NormalizedSnapshotSpanCollection(IList<SnapshotSpan> snapshotSpans)
+ {
+ // TODO: possibly eliminate based on slight usage?
+ if (snapshotSpans == null)
+ {
+ throw new ArgumentNullException("snapshotSpans");
+ }
+
+ if (snapshotSpans.Count == 0)
+ {
+ // empty collection
+ }
+ else
+ {
+ this.snapshot = snapshotSpans[0].Snapshot;
+ if (this.snapshot == null)
+ {
+ throw new ArgumentException(Strings.UninitializedSnapshotSpan);
+ }
+ if (snapshotSpans.Count == 1)
+ {
+ // length one
+ this.span = snapshotSpans[0].Span;
+ }
+ else
+ {
+ // length at least two
+ bool alreadyNormalized = true;
+ List<Span> spans = new List<Span>(snapshotSpans.Count);
+ Span currentSpan = snapshotSpans[0].Span;
+ spans.Add(currentSpan);
+ int lastEnd = currentSpan.End;
+ for (int s = 1; s < snapshotSpans.Count; ++s)
+ {
+ if (snapshotSpans[s].Snapshot != this.snapshot)
+ {
+ if (snapshotSpans[s].Snapshot == null)
+ {
+ throw new ArgumentException(Strings.UninitializedSnapshotSpan);
+ }
+ else
+ {
+ throw new ArgumentException(Strings.InvalidSnapshot);
+ }
+ }
+ currentSpan = snapshotSpans[s].Span;
+ spans.Add(currentSpan);
+ if (currentSpan.Start <= lastEnd)
+ {
+ alreadyNormalized = false;
+ }
+ lastEnd = currentSpan.End;
+ }
+ this.spans = alreadyNormalized
+ ? NormalizedSpanCollection.CreateFromNormalizedSpans(spans)
+ : new NormalizedSpanCollection(spans);
+ }
+ }
+ }
+
+ public NormalizedSnapshotSpanCollection(ITextSnapshot snapshot, Span span)
+ {
+ if (snapshot == null)
+ {
+ throw new ArgumentNullException("snapshot");
+ }
+
+ if (span.End > snapshot.Length)
+ {
+ throw new ArgumentException(Strings.SpansBeyondEnd);
+ }
+
+ this.snapshot = snapshot;
+ this.span = span;
+ }
+ #endregion
+
+ public NormalizedSnapshotSpanCollection CloneAndTrackTo(ITextSnapshot targetSnapshot, SpanTrackingMode mode)
+ {
+ if (targetSnapshot == null)
+ {
+ throw new ArgumentNullException("targetSnapshot");
+ }
+ if (mode < SpanTrackingMode.EdgeExclusive || mode > SpanTrackingMode.Custom)
+ {
+ throw new ArgumentOutOfRangeException("mode");
+ }
+
+ if (this.snapshot == null)
+ {
+ return NormalizedSnapshotSpanCollection.Empty;
+ }
+ else if (targetSnapshot.TextBuffer != this.snapshot.TextBuffer)
+ {
+ throw new ArgumentException("this.Snapshot and targetSnapshot must be from the same ITextBuffer");
+ }
+ else if (this.snapshot == targetSnapshot)
+ {
+ return this;
+ }
+ else if (this.spans == null)
+ {
+ Span targetSpan = targetSnapshot.Version.VersionNumber > this.snapshot.Version.VersionNumber
+ ? Tracking.TrackSpanForwardInTime(mode, this.span, this.snapshot.Version, targetSnapshot.Version)
+ : Tracking.TrackSpanBackwardInTime(mode, this.span, this.snapshot.Version, targetSnapshot.Version);
+
+ return new NormalizedSnapshotSpanCollection(targetSnapshot, targetSpan);
+ }
+ else
+ {
+ var targetSpans = new Span[this.spans.Count];
+ for (int i = 0; (i < this.spans.Count); ++i)
+ {
+ targetSpans[i] = targetSnapshot.Version.VersionNumber > this.snapshot.Version.VersionNumber
+ ? Tracking.TrackSpanForwardInTime(mode, this.spans[i], this.snapshot.Version, targetSnapshot.Version)
+ : Tracking.TrackSpanBackwardInTime(mode, this.spans[i], this.snapshot.Version, targetSnapshot.Version);
+ }
+
+ return new NormalizedSnapshotSpanCollection(targetSnapshot, targetSpans);
+ }
+ }
+
+ #region Implicit Conversion
+ /// <summary>
+ /// Converts the specified <see cref="NormalizedSnapshotSpanCollection"/> to a <see cref="NormalizedSpanCollection"/>.
+ /// </summary>
+ /// <param name="spans">The collection to convert.</param>
+ /// <returns>A <see cref="NormalizedSpanCollection"/> containing the corresponding normalized collection of <see cref="Span"/> objects.</returns>
+ public static implicit operator NormalizedSpanCollection(NormalizedSnapshotSpanCollection spans)
+ {
+ if (spans == null)
+ {
+ return null;
+ }
+ else if (spans.spans != null)
+ {
+ // length greater than one
+ return spans.spans;
+ }
+ else if (spans.snapshot != null)
+ {
+ // length one
+ return new NormalizedSpanCollection(spans.span);
+ }
+ else
+ {
+ // length zero;
+ return NormalizedSpanCollection.Empty;
+ }
+ }
+ #endregion
+
+ #region Set Operations
+ /// <summary>
+ /// Computes the union of two snapshot span collections and normalizes the result.
+ /// </summary>
+ /// <param name="left">The first <see cref="NormalizedSnapshotSpanCollection"/>.</param>
+ /// <param name="right">The second <see cref="NormalizedSnapshotSpanCollection"/>.</param>
+ /// <returns>The normalized union of the input collections.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> is null.</exception>
+ /// <exception cref="ArgumentException">The collections refer to different snapshots.</exception>
+ public static NormalizedSnapshotSpanCollection Union(NormalizedSnapshotSpanCollection left, NormalizedSnapshotSpanCollection right)
+ {
+ if (left == null)
+ {
+ throw new ArgumentNullException("left");
+ }
+ if (right == null)
+ {
+ throw new ArgumentNullException("right");
+ }
+
+ if (left.Count == 0)
+ {
+ return right;
+ }
+ if (right.Count == 0)
+ {
+ return left;
+ }
+
+ if (left.snapshot != right.snapshot)
+ {
+ throw new ArgumentException(Strings.MismatchedSnapshots);
+ }
+
+ NormalizedSpanCollection leftSpans = left.spans ?? new NormalizedSpanCollection(left.span);
+ NormalizedSpanCollection rightSpans = right.spans ?? new NormalizedSpanCollection(right.span);
+
+ return new NormalizedSnapshotSpanCollection(left[0].Snapshot, NormalizedSpanCollection.Union(leftSpans, rightSpans));
+ }
+
+ /// <summary>
+ /// Computes the overlap of two normalized snapshot span collections and normalizes the result.
+ /// </summary>
+ /// <param name="left">The first <see cref="NormalizedSnapshotSpanCollection"/>.</param>
+ /// <param name="right">The second <see cref="NormalizedSnapshotSpanCollection"/></param>
+ /// <returns>The normalized set of overlapping snapshot spans.</returns>
+ /// <remarks>Empty SnapshotSpans never overlap any other SnapshotSpan.</remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> is null.</exception>
+ /// <exception cref="ArgumentException">The input collections refer to different snapshots.</exception>
+ public static NormalizedSnapshotSpanCollection Overlap(NormalizedSnapshotSpanCollection left, NormalizedSnapshotSpanCollection right)
+ {
+ if (left == null)
+ {
+ throw new ArgumentNullException("left");
+ }
+ if (right == null)
+ {
+ throw new ArgumentNullException("right");
+ }
+
+ if (left.Count == 0)
+ {
+ return left;
+ }
+ if (right.Count == 0)
+ {
+ return right;
+ }
+
+ if (left.snapshot != right.snapshot)
+ {
+ throw new ArgumentException(Strings.MismatchedSnapshots);
+ }
+
+ NormalizedSpanCollection leftSpans = left.spans ?? new NormalizedSpanCollection(left.span);
+ NormalizedSpanCollection rightSpans = right.spans ?? new NormalizedSpanCollection(right.span);
+
+ return new NormalizedSnapshotSpanCollection(left[0].Snapshot, NormalizedSpanCollection.Overlap(leftSpans, rightSpans));
+ }
+
+ /// <summary>
+ /// Computes the intersection of two normalized snapshot span collections and normalizes the result.
+ /// </summary>
+ /// <param name="left">The first <see cref="NormalizedSnapshotSpanCollection"/>.</param>
+ /// <param name="right">The second<see cref="NormalizedSnapshotSpanCollection"/>.</param>
+ /// <returns>The normalized set of intersecting spans.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> is null.</exception>
+ /// <exception cref="ArgumentException">The collections refer to different snapshots.</exception>
+ public static NormalizedSnapshotSpanCollection Intersection(NormalizedSnapshotSpanCollection left, NormalizedSnapshotSpanCollection right)
+ {
+ if (left == null)
+ {
+ throw new ArgumentNullException("left");
+ }
+ if (right == null)
+ {
+ throw new ArgumentNullException("right");
+ }
+
+ if (left.Count == 0)
+ {
+ return left;
+ }
+ if (right.Count == 0)
+ {
+ return right;
+ }
+
+ if (left.snapshot != right.snapshot)
+ {
+ throw new ArgumentException(Strings.MismatchedSnapshots);
+ }
+
+ NormalizedSpanCollection leftSpans = left.spans ?? new NormalizedSpanCollection(left.span);
+ NormalizedSpanCollection rightSpans = right.spans ?? new NormalizedSpanCollection(right.span);
+
+ return new NormalizedSnapshotSpanCollection(left[0].Snapshot, NormalizedSpanCollection.Intersection(leftSpans, rightSpans));
+ }
+
+ /// <summary>
+ /// Computes the difference between two normalized snapshot span collections and normalizes the result.
+ /// </summary>
+ /// <param name="left">The collection from which to subtract <paramref name="right"/>.</param>
+ /// <param name="right">The collection to subtract from <paramref name="left"/>.</param>
+ /// <returns>The normalized set difference.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> is null.</exception>
+ /// <exception cref="ArgumentException">The input collections refer to different snapshots.</exception>
+ public static NormalizedSnapshotSpanCollection Difference(NormalizedSnapshotSpanCollection left, NormalizedSnapshotSpanCollection right)
+ {
+ if (left == null)
+ {
+ throw new ArgumentNullException("left");
+ }
+ if (right == null)
+ {
+ throw new ArgumentNullException("right");
+ }
+
+ if (left.Count == 0)
+ {
+ return left;
+ }
+ if (right.Count == 0)
+ {
+ return left;
+ }
+
+ if (left.snapshot != right.snapshot)
+ {
+ throw new ArgumentException(Strings.MismatchedSnapshots);
+ }
+
+ NormalizedSpanCollection leftSpans = left.spans ?? new NormalizedSpanCollection(left.span);
+ NormalizedSpanCollection rightSpans = right.spans ?? new NormalizedSpanCollection(right.span);
+
+ return new NormalizedSnapshotSpanCollection(left[0].Snapshot, NormalizedSpanCollection.Difference(leftSpans, rightSpans));
+ }
+
+ /// <summary>
+ /// Determines whether this collection overlaps with another normalized snapshot span collection.
+ /// </summary>
+ /// <param name="set">The collection.</param>
+ /// <returns><c>true</c> if the collections refer to the same snapshot and their spans overlap, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="set"/> is null.</exception>
+ /// <exception cref="ArgumentException">The collections refer to different snapshots.</exception>
+ public bool OverlapsWith(NormalizedSnapshotSpanCollection set)
+ {
+ if (set == null)
+ {
+ throw new ArgumentNullException("set");
+ }
+ else if (set.Count == 0 || this.Count == 0)
+ {
+ return false;
+ }
+ else if (set.snapshot != this.snapshot)
+ {
+ throw new ArgumentException(Strings.MismatchedSnapshots);
+ }
+ else
+ {
+ NormalizedSpanCollection thisSpans = this.spans ?? new NormalizedSpanCollection(this.span);
+ return thisSpans.OverlapsWith(set);
+ }
+ }
+
+ /// <summary>
+ /// Determines whether this collection overlaps with a snapshot span.
+ /// </summary>
+ /// <param name="span">The snapshot span to test.</param>
+ /// <returns><c>true</c> if the collection and the span refer to the same snapshot and their spans overlap, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentException">The collection and the span refer to different snapshots.</exception>
+ public bool OverlapsWith(SnapshotSpan span)
+ {
+ if (this.snapshot == null)
+ {
+ // we are size zero
+ return false;
+ }
+ else if (span.Snapshot != this.snapshot)
+ {
+ throw new ArgumentException(Strings.MismatchedSnapshots);
+ }
+ else if (this.spans != null)
+ {
+ return this.spans.OverlapsWith(span.Span);
+ }
+ else
+ {
+ return this.span.OverlapsWith(span.Span);
+ }
+ }
+
+ /// <summary>
+ /// Determines whether this collection intersects with another normalized snapshot span collection.
+ /// </summary>
+ /// <param name="set">The colllection.</param>
+ /// <returns><c>true</c> if the collections intersect, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="set"/> is null.</exception>
+ /// <exception cref="ArgumentException">The input collections refer to different snapshots.</exception>
+ public bool IntersectsWith(NormalizedSnapshotSpanCollection set)
+ {
+ if (set == null)
+ {
+ throw new ArgumentNullException("set");
+ }
+ else if (set.Count == 0 || this.Count == 0)
+ {
+ return false;
+ }
+ else if (set.snapshot != this.snapshot)
+ {
+ throw new ArgumentException(Strings.MismatchedSnapshots);
+ }
+ else
+ {
+ NormalizedSpanCollection thisSpans = this.spans ?? new NormalizedSpanCollection(this.span);
+ return thisSpans.IntersectsWith(set);
+ }
+ }
+
+ /// <summary>
+ /// Determines whether this collection overlaps with a snapshot span.
+ /// </summary>
+ /// <param name="span">The snapshot span to test.</param>
+ /// <returns><c>true</c> if the collection and the span refer to the same snapshot and their spans overlap, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentException">The collection and the span refer to different snapshots.</exception>
+ public bool IntersectsWith(SnapshotSpan span)
+ {
+ if (this.snapshot == null)
+ {
+ // we are size zero
+ return false;
+ }
+ else if (span.Snapshot != this.snapshot)
+ {
+ throw new ArgumentException(Strings.MismatchedSnapshots);
+ }
+ else if (this.spans != null)
+ {
+ return this.spans.IntersectsWith(span);
+ }
+ else
+ {
+ return this.span.IntersectsWith(span.Span);
+ }
+ }
+ #endregion
+
+ #region IList<SnapshotSpan> Members
+
+ /// <summary>
+ /// Gets the index of the specified <see cref="SnapshotSpan"/>.
+ /// </summary>
+ /// <param name="item">The <see cref="SnapshotSpan"/>.</param>
+ /// <returns>The index of the snapshot span.</returns>
+ public int IndexOf(SnapshotSpan item)
+ {
+ if (this.snapshot == item.Snapshot)
+ {
+ if (this.spans != null)
+ {
+ return this.spans.IndexOf(item.Span);
+ }
+ else if (this.snapshot != null && this.span == item.Span)
+ {
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+ /// <summary>
+ /// Inserts a snapshot span into the list. This method throws a <see cref="NotSupportedException"/>.
+ /// </summary>
+ /// <param name="index">The location at which to insert the snapshot span.</param>
+ /// <param name="item">The snapshot span to insert.</param>
+ void IList<SnapshotSpan>.Insert(int index, SnapshotSpan item)
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Removes a snapshot span at the specified location. This method throws a <see cref="NotSupportedException"/>.
+ /// </summary>
+ /// <param name="index">The location at which to remove the snapshot span.</param>
+ void IList<SnapshotSpan>.RemoveAt(int index)
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Gets the snapshot span at the specified location. The setter throws a <see cref="NotSupportedException"/>.
+ /// </summary>
+ /// <param name="index">The location at which to get the snapshot span.</param>
+ /// <returns>The snapshot span.</returns>
+ public SnapshotSpan this[int index]
+ {
+ get
+ {
+ if (this.spans != null)
+ {
+ return new SnapshotSpan(this.snapshot, this.spans[index]);
+ }
+ else if (this.snapshot != null && index == 0)
+ {
+ return new SnapshotSpan(this.snapshot, this.span);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException("index");
+ }
+ }
+ set
+ {
+ throw new NotSupportedException();
+ }
+ }
+
+ #endregion
+
+ #region ICollection<SnapshotSpan> Members
+
+ /// <summary>
+ /// Adds a snapshot span to the collection. This method throws a <see cref="NotSupportedException"/>.
+ /// </summary>
+ /// <param name="item">The snapshot span.</param>
+ void ICollection<SnapshotSpan>.Add(SnapshotSpan item)
+ {
+ throw new NotSupportedException();
+ }
+
+
+ /// <summary>
+ /// Clears the collection. This method throws a <see cref="NotSupportedException"/>.
+ /// </summary>
+ void ICollection<SnapshotSpan>.Clear()
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Determines whether the collection contains the specified snapshot span.
+ /// </summary>
+ /// <param name="item">The snapshot span.</param>
+ /// <returns><c>true</c> if the collection contains the snapshot span, otherwise <c>false</c>.</returns>
+ public bool Contains(SnapshotSpan item)
+ {
+ if (this.spans != null)
+ {
+ return item.Snapshot == this.snapshot && this.spans.Contains(item);
+ }
+ else if (this.snapshot == null)
+ {
+ return false;
+ }
+ else
+ {
+ return item.Snapshot == this.snapshot && item.Span == this.span;
+ }
+ }
+
+ /// <summary>
+ /// Copies the collection to an array of snapshot spans at the specified location.
+ /// </summary>
+ /// <param name="array">The array of snapshot spans.</param>
+ /// <param name="arrayIndex">The location to which to copy the snapshot spans.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="array"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="arrayIndex"/> is negative or greater than the array length,
+ /// or the number of spans in the collection is greater than the length of the array minus the array index.</exception>
+ public void CopyTo(SnapshotSpan[] array, int arrayIndex)
+ {
+ if (array == null)
+ {
+ throw new ArgumentNullException("array");
+ }
+ if (arrayIndex < 0 || arrayIndex > array.Length || this.Count > array.Length - arrayIndex)
+ {
+ throw new ArgumentOutOfRangeException("arrayIndex");
+ }
+ if (this.spans != null)
+ {
+ for (int s = 0; s < this.spans.Count; ++s)
+ {
+ array[arrayIndex++] = new SnapshotSpan(this.snapshot, this.spans[s]);
+ }
+ }
+ else if (this.snapshot != null)
+ {
+ array[arrayIndex] = new SnapshotSpan(this.snapshot, this.span);
+ }
+ }
+
+ /// <summary>
+ /// Gets the number of spans in the collection.
+ /// </summary>
+ public int Count
+ {
+ get
+ {
+ if (this.spans != null)
+ {
+ return this.spans.Count;
+ }
+ else
+ {
+ return this.snapshot == null ? 0 : 1;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Determines whether the collection is read-only. Always returns <c>true</c>.
+ /// </summary>
+ bool ICollection<SnapshotSpan>.IsReadOnly
+ {
+ get { return true; }
+ }
+
+ /// <summary>
+ /// Removes the specified span from the collection. This method throws a <see cref="NotSupportedException"/>.
+ /// </summary>
+ /// <param name="item">The snapshot span.</param>
+ /// <returns><c>true</c> if it was possible to remove the span.</returns>
+ bool ICollection<SnapshotSpan>.Remove(SnapshotSpan item)
+ {
+ throw new NotSupportedException();
+ }
+
+ #endregion
+
+ #region IEnumerable<SnapshotSpan> Members
+
+ /// <summary>
+ /// Gets an enumerator for the collection.
+ /// </summary>
+ /// <returns>The enumerator.</returns>
+ public IEnumerator<SnapshotSpan> GetEnumerator()
+ {
+ if (this.spans != null)
+ {
+ foreach (Span span in this.spans)
+ {
+ yield return new SnapshotSpan(this.snapshot, span);
+ }
+ }
+ else if (this.snapshot != null)
+ {
+ yield return new SnapshotSpan(this.snapshot, this.span);
+ }
+ }
+
+ #endregion
+
+ #region IEnumerable Members
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ if (this.spans != null)
+ {
+ foreach (Span span in this.spans)
+ {
+ yield return new SnapshotSpan(this.snapshot, span);
+ }
+ }
+ else if (this.snapshot != null)
+ {
+ yield return new SnapshotSpan(this.snapshot, this.span);
+ }
+ }
+
+ #endregion
+
+ #region IList Members
+
+ /// <summary>
+ /// Adds an object to the list. This method throws a <see cref="NotSupportedException"/>.
+ /// </summary>
+ /// <param name="value">The object to add.</param>
+ /// <returns>The location at which the object was added.</returns>
+ int IList.Add(object value)
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Clears the list. This method throws a <see cref="NotSupportedException"/>.
+ /// </summary>
+ void IList.Clear()
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Determines whether the collection contains the specified snapshot span.
+ /// </summary>
+ /// <param name="value">The snapshot span.</param>
+ /// <returns><c>true</c> if the snapshot span is contained in the collection, otherwise <c>false</c>.</returns>
+ public bool Contains(object value)
+ {
+ if (value is SnapshotSpan)
+ {
+ SnapshotSpan val = (SnapshotSpan)value;
+ if (this.spans != null)
+ {
+ return this.snapshot == val.Snapshot && this.spans.Contains(val.Span);
+ }
+ else if (this.snapshot == null)
+ {
+ return false;
+ }
+ else
+ {
+ return this.snapshot == val.Snapshot && this.span == val.Span;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Gets the index of the specified snapshot span.
+ /// </summary>
+ /// <param name="value">The snapshot span.</param>
+ /// <returns>The location of the snapshot span.</returns>
+ public int IndexOf(object value)
+ {
+ if (value is SnapshotSpan)
+ {
+ SnapshotSpan val = (SnapshotSpan)value;
+ if (this.snapshot == val.Snapshot)
+ {
+ if (this.spans != null)
+ {
+ return this.spans.IndexOf(val.Span);
+ }
+ else if (this.snapshot != null && this.span == val.Span)
+ {
+ return 0;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /// <summary>
+ /// Inserts a snapshot span into the list at the specified location. This method throws a <see cref="NotSupportedException"/>.
+ /// </summary>
+ /// <param name="index">The location.</param>
+ /// <param name="value">The snapshot span.</param>
+ void IList.Insert(int index, object value)
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Determines whether the collection is of fixed size. Always returns <c>true</c>.
+ /// </summary>
+ bool IList.IsFixedSize
+ {
+ get { return true; }
+ }
+
+ /// <summary>
+ /// Removes the specified snapshot span. This method throws a <see cref="NotSupportedException"/>.
+ /// </summary>
+ /// <param name="value">The snapshot span.</param>
+ void IList.Remove(object value)
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Removes a snapshot span at the specified location. This method throws a <see cref="NotSupportedException"/>.
+ /// </summary>
+ /// <param name="index">The location.</param>
+ void IList.RemoveAt(int index)
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Gets the snapshot span at the specified location. The setter throws a <see cref="NotSupportedException"/>.
+ /// </summary>
+ /// <param name="index">The location.</param>
+ /// <returns>The snapshot span.</returns>
+ object IList.this[int index]
+ {
+ get
+ {
+ if (this.spans != null)
+ {
+ return new SnapshotSpan(this.snapshot, this.spans[index]);
+ }
+ else if (this.snapshot != null && index == 0)
+ {
+ return new SnapshotSpan(this.snapshot, this.span);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException("index");
+ }
+ }
+ set
+ {
+ throw new NotSupportedException();
+ }
+ }
+
+ #endregion
+
+ #region ICollection Members
+
+ /// <summary>
+ /// Copies the snapshot spans in this collection to the specified array, starting at the specified index.
+ /// </summary>
+ /// <param name="array">The array.</param>
+ /// <param name="index">The location at which to start copying.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="array"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is negative, or greater than
+ /// the length of the array, or the number of spans is greater than the length of the array less the index.</exception>
+ /// <exception cref="ArgumentException"><paramref name="array"/> is not one-dimensional.</exception>
+ public void CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
+ throw new ArgumentNullException("array");
+ }
+ if (index < 0 || index > array.Length || this.Count > array.Length - index)
+ {
+ throw new ArgumentOutOfRangeException("index");
+ }
+ if (array.Rank != 1)
+ {
+ throw new ArgumentException(Strings.ArrayRankNotOne);
+ }
+ if (this.spans != null)
+ {
+ for (int s = 0; s < this.spans.Count; ++s)
+ {
+ array.SetValue(new SnapshotSpan(this.snapshot, this.spans[s]), index++);
+ }
+ }
+ else if (this.snapshot != null)
+ {
+ array.SetValue(new SnapshotSpan(this.snapshot, this.span), index);
+ }
+ }
+
+ /// <summary>
+ /// Determines whether this collection is read-only. This property always returns <c>true</c>.
+ /// </summary>
+ bool IList.IsReadOnly
+ {
+ get { return true; }
+ }
+
+ /// <summary>
+ /// Determines whether this collection is synchronized.
+ /// </summary>
+ bool ICollection.IsSynchronized
+ {
+ get { return true; }
+ }
+
+ /// <summary>
+ /// Gets an object that can be used to synchronize access to this collection.
+ /// </summary>
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ return this.spans != null ? (this.spans as IList).SyncRoot : this;
+ }
+ }
+
+ #endregion
+
+ #region Operators and Overrides
+ /// <summary>
+ /// Determines whether two <see cref="NormalizedSnapshotSpanCollection"/> objects are the same.
+ /// </summary>
+ /// <param name="left">The first collection.</param>
+ /// <param name="right">The second collection.</param>
+ /// <returns><c>true</c> if the two sets are the same, otherwise <c>false</c>.</returns>
+ public static bool operator ==(NormalizedSnapshotSpanCollection left, NormalizedSnapshotSpanCollection right)
+ {
+ if (object.ReferenceEquals(left, right))
+ {
+ return true;
+ }
+ if (object.ReferenceEquals(left, null) || object.ReferenceEquals(right, null))
+ {
+ return false;
+ }
+
+ if (left.Count != right.Count)
+ {
+ return false;
+ }
+
+ for (int i = 0; i < left.Count; ++i)
+ {
+ if (left[i] != right[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="NormalizedSnapshotSpanCollection"/> are different..
+ /// </summary>
+ /// <param name="left">The first collection.</param>
+ /// <param name="right">The second collection.</param>
+ /// <returns><c>true</c> if the two collections are different.</returns>
+ public static bool operator !=(NormalizedSnapshotSpanCollection left, NormalizedSnapshotSpanCollection right)
+ {
+ return !(left == right);
+ }
+
+ /// <summary>
+ /// Gets a hash code for the collection.
+ /// </summary>
+ /// <returns>A 32-bit hash code associated with the collection.</returns>
+ public override int GetHashCode()
+ {
+ return this.spans != null ? this.spans.GetHashCode() : this.span.GetHashCode();
+ }
+
+ /// <summary>
+ /// Determines whether two snapshot span collections are equal
+ /// </summary>
+ /// <param name="obj">The second collection.</param>
+ /// <returns><c>true</c> if the two collections are equal, otherwise <c>false</c>.</returns>
+ public override bool Equals(object obj)
+ {
+ NormalizedSnapshotSpanCollection set = obj as NormalizedSnapshotSpanCollection;
+
+ return this == set;
+ }
+
+ /// <summary>
+ /// Converts the spans to a string..
+ /// </summary>
+ /// <returns>The string representation.</returns>
+ public override string ToString()
+ {
+ return this.spans != null ? this.spans.ToString() : this.span.ToString();
+ }
+ #endregion
+
+ }
+}
diff --git a/src/Text/Def/TextData/Model/NormalizedSpanCollection.cs b/src/Text/Def/TextData/Model/NormalizedSpanCollection.cs
new file mode 100644
index 0000000..2447742
--- /dev/null
+++ b/src/Text/Def/TextData/Model/NormalizedSpanCollection.cs
@@ -0,0 +1,632 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using System.Text;
+ using System.Diagnostics;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+
+ /// <summary>
+ /// A collection of spans that are sorted by start position, with adjacent and overlapping spans combined.
+ /// </summary>
+ public class NormalizedSpanCollection : ReadOnlyCollection<Span>
+ {
+ public readonly static NormalizedSpanCollection Empty = new NormalizedSpanCollection();
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="NormalizedSpanCollection"/> that is empty.
+ /// </summary>
+ public NormalizedSpanCollection()
+ : base(new List<Span>(0))
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="NormalizedSpanCollection"/> that contains the specified span.
+ /// </summary>
+ /// <param name="span">Span contained by the span set.</param>
+ public NormalizedSpanCollection(Span span)
+ : base(ListFromSpan(span))
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="NormalizedSpanCollection"/> that contains the specified list of spans.
+ /// </summary>
+ /// <param name="spans">The spans to be added.</param>
+ /// <remarks>
+ /// <para>The list of spans will be sorted and normalized (overlapping and adjoining spans will be combined).</para>
+ /// <para>This constructor runs in O(N log N) time, where N = spans.Count.</para></remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="spans"/> is null.</exception>
+ public NormalizedSpanCollection(IEnumerable<Span> spans)
+ : base(NormalizedSpanCollection.NormalizeSpans(spans))
+ {
+ //NormalizeSpans will throw if spans == null.
+ }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="NormalizedSpanCollection"/> that contains the specified (already
+ /// normalized) list of spans.
+ /// </summary>
+ /// <param name="spans">The spans to be added.</param>
+ /// <param name="ignored">This parameter is present just to give this constructor a different signature that
+ /// is used to indicate the input spans are already normalized.</param>
+ /// <remarks>
+ /// <para>This constructor runs in O(N) time, where N = spans.Count.</para></remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="normalizedSpans"/> is null.</exception>
+ /// <remarks>This constructor is private so as not to expose the misleading <paramref name="ignored"/> parameter.</remarks>
+ private NormalizedSpanCollection(IList<Span> normalizedSpans, bool ignored)
+ : base(normalizedSpans)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new instance of <see cref="NormalizedSpanCollection"/> from a list of <see cref="Span"/>s that are
+ /// already normalized. For internal use only.
+ /// </summary>
+ /// <param name="alreadyNormalizedSpans"></param>
+ /// <returns></returns>
+ internal static NormalizedSpanCollection CreateFromNormalizedSpans(IList<Span> alreadyNormalizedSpans)
+ {
+ return new NormalizedSpanCollection(alreadyNormalizedSpans, true);
+ }
+
+ /// <summary>
+ /// Finds the union of two span sets.
+ /// </summary>
+ /// <param name="left">
+ /// The first span set.
+ /// </param>
+ /// <param name="right">
+ /// The second span set.
+ /// </param>
+ /// <returns>
+ /// The new span set that corresponds to the union of <paramref name="left"/> and <paramref name="right"/>.
+ /// </returns>
+ /// <remarks>This operator runs in O(N+M) time where N = left.Count, M = right.Count.</remarks>
+ /// <exception cref="ArgumentNullException">Either <paramref name="left"/> or <paramref name="right"/> is null.</exception>
+ public static NormalizedSpanCollection Union(NormalizedSpanCollection left, NormalizedSpanCollection right)
+ {
+ if (left == null)
+ {
+ throw new ArgumentNullException("left");
+ }
+ if (right == null)
+ {
+ throw new ArgumentNullException("right");
+ }
+
+ if (left.Count == 0)
+ {
+ return right;
+ }
+ if (right.Count == 0)
+ {
+ return left;
+ }
+
+ List<Span> spans = new List<Span>();
+
+ int index1 = 0;
+ int index2 = 0;
+
+ int start = -1;
+ int end = int.MaxValue;
+ while ((index1 < left.Count) && (index2 < right.Count))
+ {
+ Span span1 = left[index1];
+ Span span2 = right[index2];
+
+ if (span1.Start < span2.Start)
+ {
+ NormalizedSpanCollection.UpdateSpanUnion(span1, spans, ref start, ref end);
+ ++index1;
+ }
+ else
+ {
+ NormalizedSpanCollection.UpdateSpanUnion(span2, spans, ref start, ref end);
+ ++index2;
+ }
+ }
+ while (index1 < left.Count)
+ {
+ NormalizedSpanCollection.UpdateSpanUnion(left[index1], spans, ref start, ref end);
+ ++index1;
+ }
+ while (index2 < right.Count)
+ {
+ NormalizedSpanCollection.UpdateSpanUnion(right[index2], spans, ref start, ref end);
+ ++index2;
+ }
+
+ if (end != int.MaxValue)
+ {
+ spans.Add(Span.FromBounds(start, end));
+ }
+
+ return CreateFromNormalizedSpans(spans);
+ }
+
+ /// <summary>
+ /// Findx the overlap of two span sets.
+ /// </summary>
+ /// <param name="left">The first span set.</param>
+ /// <param name="right">The second span set.</param>
+ /// <returns>The new span set that corresponds to the overlap of <paramref name="left"/> and <paramref name="right"/>.</returns>
+ /// <remarks>This operator runs in O(N+M) time where N = left.Count, M = right.Count.</remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> is null.</exception>
+ public static NormalizedSpanCollection Overlap(NormalizedSpanCollection left, NormalizedSpanCollection right)
+ {
+ if (left == null)
+ {
+ throw new ArgumentNullException("left");
+ }
+ if (right == null)
+ {
+ throw new ArgumentNullException("right");
+ }
+
+ if (left.Count == 0)
+ {
+ return left;
+ }
+ if (right.Count == 0)
+ {
+ return right;
+ }
+
+ List<Span> spans = new List<Span>();
+ for (int index1 = 0, index2 = 0; (index1 < left.Count) && (index2 < right.Count); )
+ {
+ Span span1 = left[index1];
+ Span span2 = right[index2];
+
+ if (span1.OverlapsWith(span2))
+ {
+ spans.Add(span1.Overlap(span2).Value);
+ }
+
+ if (span1.End < span2.End)
+ {
+ ++index1;
+ }
+ else if (span1.End == span2.End)
+ {
+ ++index1; ++index2;
+ }
+ else
+ {
+ ++index2;
+ }
+ }
+
+ return CreateFromNormalizedSpans(spans);
+ }
+
+ /// <summary>
+ /// Finds the intersection of two span sets.
+ /// </summary>
+ /// <param name="left">The first span set.</param>
+ /// <param name="right">The second span set.</param>
+ /// <returns>The new span set that corresponds to the intersection of <paramref name="left"/> and <paramref name="right"/>.</returns>
+ /// <remarks>This operator runs in O(N+M) time where N = left.Count, M = right.Count.</remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="left"/> is null.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="right"/> is null.</exception>
+ public static NormalizedSpanCollection Intersection(NormalizedSpanCollection left, NormalizedSpanCollection right)
+ {
+ if (left == null)
+ {
+ throw new ArgumentNullException("left");
+ }
+ if (right == null)
+ {
+ throw new ArgumentNullException("right");
+ }
+
+ if (left.Count == 0)
+ {
+ return left;
+ }
+ if (right.Count == 0)
+ {
+ return right;
+ }
+
+ List<Span> spans = new List<Span>();
+ for (int index1 = 0, index2 = 0; (index1 < left.Count) && (index2 < right.Count) ;)
+ {
+ Span span1 = left[index1];
+ Span span2 = right[index2];
+
+ if (span1.IntersectsWith(span2))
+ {
+ spans.Add(span1.Intersection(span2).Value);
+ }
+
+ if (span1.End < span2.End)
+ {
+ ++index1;
+ }
+ else
+ {
+ ++index2;
+ }
+ }
+
+ return CreateFromNormalizedSpans(spans);
+ }
+
+ /// <summary>
+ /// Finds the difference between two sets. The difference is defined as everything in the first span set that is not in the second span set.
+ /// </summary>
+ /// <param name="left">The first span set.</param>
+ /// <param name="right">The second span set.</param>
+ /// <returns>The new span set that corresponds to the difference between <paramref name="left"/> and <paramref name="right"/>.</returns>
+ /// <remarks>
+ /// Empty spans in the second set do not affect the first set at all. This method returns empty spans in the first set that are not contained by any set in
+ /// the second set.
+ /// </remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="left"/> is null.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="right"/> is null.</exception>
+ public static NormalizedSpanCollection Difference(NormalizedSpanCollection left, NormalizedSpanCollection right)
+ {
+ if (left == null)
+ {
+ throw new ArgumentNullException("left");
+ }
+ if (right == null)
+ {
+ throw new ArgumentNullException("right");
+ }
+
+ if (left.Count == 0)
+ {
+ return left;
+ }
+ if (right.Count == 0)
+ {
+ return left;
+ }
+
+ List<Span> spans = new List<Span>();
+
+ int index1 = 0;
+ int index2 = 0;
+ int lastEnd = -1;
+ do
+ {
+ Span span1 = left[index1];
+ Span span2 = right[index2];
+
+ if ((span2.Length == 0) || (span1.Start >= span2.End))
+ {
+ ++index2;
+ }
+ else if (span1.End <= span2.Start)
+ {
+ //lastEnd is set to the end of the previously encountered intersecting span from right when
+ //it ended before the end of span1 (so it must still be less than the end of span1).
+ Debug.Assert(lastEnd < span1.End);
+ spans.Add(Span.FromBounds(Math.Max(lastEnd, span1.Start), span1.End));
+ ++index1;
+ }
+ else
+ {
+ // The spans intersect, so add anything from span1 that extends to the left of span2.
+ if (span1.Start < span2.Start)
+ {
+ //lastEnd is set to the end of the previously encountered intersecting span on span2, so it must
+ //be less than the start of the current span on span2.
+ Debug.Assert(lastEnd < span2.Start);
+ spans.Add(Span.FromBounds(Math.Max(lastEnd, span1.Start), span2.Start));
+ }
+
+ if (span1.End < span2.End)
+ {
+ ++index1;
+ }
+ else if (span1.End == span2.End)
+ {
+ //Both spans ended at the same place so we're done with both.
+ ++index1; ++index2;
+ }
+ else
+ {
+ //span2 ends before span1, so keep track of where it ended so that we don't try to add
+ //the excluded portion the next time we add a span.
+ lastEnd = span2.End;
+ ++index2;
+ }
+ }
+ }
+ while ((index1 < left.Count) && (index2 < right.Count));
+
+ while (index1 < left.Count)
+ {
+ Span span1 = left[index1++];
+ spans.Add(Span.FromBounds(Math.Max(lastEnd, span1.Start), span1.End));
+ }
+
+ return CreateFromNormalizedSpans(spans);
+ }
+
+ /// <summary>
+ /// Determines whether two span sets are the same.
+ /// </summary>
+ /// <param name="left">The first set.</param>
+ /// <param name="right">The second set.</param>
+ /// <returns><c>true</c> if the two sets are equivalent, otherwise <c>false</c>.</returns>
+ public static bool operator ==(NormalizedSpanCollection left, NormalizedSpanCollection right)
+ {
+ if (object.ReferenceEquals(left, right))
+ return true;
+ if (object.ReferenceEquals(left, null) || object.ReferenceEquals(right, null))
+ return false;
+
+ if (left.Count != right.Count)
+ return false;
+
+ for (int i = 0; (i < left.Count); ++i)
+ if (left[i] != right[i])
+ return false;
+
+ return true;
+ }
+
+ /// <summary>
+ /// Determines whether two span sets are not the same.
+ /// </summary>
+ /// <param name="left">The first set.</param>
+ /// <param name="right">The second set.</param>
+ /// <returns><c>true</c> if the two sets are not equivalent, otherwise <c>false</c>.</returns>
+ public static bool operator !=(NormalizedSpanCollection left, NormalizedSpanCollection right)
+ {
+ return !(left == right);
+ }
+
+ /// <summary>
+ /// Determines whether this span set overlaps with another span set.
+ /// </summary>
+ /// <param name="set">The span set to test.</param>
+ /// <returns><c>true</c> if the span sets overlap, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="set"/> is null.</exception>
+ public bool OverlapsWith(NormalizedSpanCollection set)
+ {
+ if (set == null)
+ {
+ throw new ArgumentNullException("set");
+ }
+
+ for (int index1 = 0, index2 = 0; (index1 < this.Count) && (index2 < set.Count) ;)
+ {
+ Span span1 = this[index1];
+ Span span2 = set[index2];
+
+ if (span1.OverlapsWith(span2))
+ {
+ return true;
+ }
+
+ if (span1.End < span2.End)
+ {
+ ++index1;
+ }
+ else if (span1.End == span2.End)
+ {
+ ++index1; ++index2;
+ }
+ else
+ {
+ ++index2;
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Determines whether this span set overlaps with another span.
+ /// </summary>
+ /// <param name="span">The span to test.</param>
+ /// <returns><c>true</c> if this span set overlaps with the given span, otherwise <c>false</c>.</returns>
+ public bool OverlapsWith(Span span)
+ {
+ // TODO: binary search
+ for (int index = 0; index < this.Count; ++index)
+ {
+ if (this[index].OverlapsWith(span))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Determines wheher this span set intersects with another span set.
+ /// </summary>
+ /// <param name="set">Set to test.</param>
+ /// <returns><c>true</c> if the span sets intersect, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="set"/> is null.</exception>
+ public bool IntersectsWith(NormalizedSpanCollection set)
+ {
+ if (set == null)
+ {
+ throw new ArgumentNullException("set");
+ }
+
+ for (int index1 = 0, index2 = 0; (index1 < this.Count) && (index2 < set.Count); )
+ {
+ Span span1 = this[index1];
+ Span span2 = set[index2];
+
+ if (span1.IntersectsWith(span2))
+ {
+ return true;
+ }
+
+ if (span1.End < span2.End)
+ {
+ ++index1;
+ }
+ else
+ {
+ ++index2;
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Determines wheher this span set intersects with another span.
+ /// </summary>
+ /// <param name="set">The span to test.</param>
+ /// <returns><c>true</c> if this span set intersects with the given span, otherwise <c>false</c>.</returns>
+ public bool IntersectsWith(Span span)
+ {
+ // TODO: binary search
+ for (int index = 0; index < this.Count; ++index)
+ {
+ if (this[index].IntersectsWith(span))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ #region Overridden methods and operators
+
+ /// <summary>
+ /// Gets a unique hash code for the span set.
+ /// </summary>
+ /// <returns>A 32-bit hash code associated with the set.</returns>
+ public override int GetHashCode()
+ {
+ int hc = 0;
+ foreach (Span s in this)
+ hc ^= s.GetHashCode();
+
+ return hc;
+ }
+
+ /// <summary>
+ /// Determines whether this span set is the same as another object.
+ /// </summary>
+ /// <param name="obj">The object to test.</param>
+ /// <returns><c>true</c> if the two objects are equal, otherwise <c>false</c>.</returns>
+ public override bool Equals(object obj)
+ {
+ NormalizedSpanCollection set = obj as NormalizedSpanCollection;
+
+ return this == set;
+ }
+
+ /// <summary>
+ /// Provides a string representation of the set.
+ /// </summary>
+ /// <returns>Thetring representation of the set.</returns>
+ public override string ToString()
+ {
+ StringBuilder value = new StringBuilder("{");
+ foreach (Span s in this)
+ value.Append(s.ToString());
+ value.Append("}");
+
+ return value.ToString();
+ }
+
+ #endregion // Overridden methods and operators
+
+ #region Private Helpers
+ private static IList<Span> ListFromSpan(Span span)
+ {
+ IList<Span> list = new List<Span>(1);
+ list.Add(span);
+ return list;
+ }
+
+ private static void UpdateSpanUnion(Span span, IList<Span> spans, ref int start, ref int end)
+ {
+ if (end < span.Start)
+ {
+ spans.Add(Span.FromBounds(start, end));
+
+ start = -1;
+ end = int.MaxValue;
+ }
+
+ if (end == int.MaxValue)
+ {
+ start = span.Start;
+ end = span.End;
+ }
+ else
+ {
+ end = Math.Max(end, span.End);
+ }
+ }
+
+ private class SpanStartComparer : IComparer<Span>
+ {
+ public int Compare(Span s1, Span s2) { return s1.Start.CompareTo(s2.Start); }
+
+ public static readonly IComparer<Span> Default = new SpanStartComparer();
+ }
+
+ private static IList<Span> NormalizeSpans(IEnumerable<Span> spans)
+ {
+ if (spans == null)
+ {
+ throw new ArgumentNullException("spans");
+ }
+
+ List<Span> sorted = new List<Span>(spans);
+ if (sorted.Count <= 1)
+ {
+ return sorted;
+ }
+ else
+ {
+ sorted.Sort(SpanStartComparer.Default);
+
+ int oldIndex = 0;
+ int oldStart = sorted[0].Start;
+ int oldEnd = sorted[0].End;
+ for (int index = 1; (index < sorted.Count); ++index)
+ {
+ int newStart = sorted[index].Start;
+ int newEnd = sorted[index].End;
+ if (oldEnd < newStart)
+ {
+ sorted[oldIndex++] = Span.FromBounds(oldStart, oldEnd);
+ oldStart = newStart;
+ oldEnd = newEnd;
+ }
+ else
+ {
+ oldEnd = Math.Max(oldEnd, newEnd);
+ }
+ }
+ sorted[oldIndex++] = Span.FromBounds(oldStart, oldEnd);
+
+ sorted.RemoveRange(oldIndex, sorted.Count - oldIndex);
+
+ //Only call TrimExcess() if the list is large enough that the memory saved is worth the cost
+ //of another allocation.
+ if (sorted.Capacity > 10)
+ sorted.TrimExcess();
+
+ return sorted;
+ }
+ }
+ #endregion // Private Helpers
+ }
+}
diff --git a/src/Text/Def/TextData/Model/PointTrackingMode.cs b/src/Text/Def/TextData/Model/PointTrackingMode.cs
new file mode 100644
index 0000000..7c0a72d
--- /dev/null
+++ b/src/Text/Def/TextData/Model/PointTrackingMode.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Represents tracking modes for <see cref="ITrackingPoint"/> objects.
+ /// </summary>
+ public enum PointTrackingMode
+ {
+ /// <summary>
+ /// With this setting, a point tracks toward the end of the document, so that an
+ /// insertion at the current position pushes the point to the end of the inserted text.
+ /// If a replacement contains the point, it will end up at the end of the replacement text.
+ /// </summary>
+ Positive,
+
+ /// <summary>
+ /// With this setting, a point tracks toward the beginning of the document,
+ /// so that an insertion at the current position leaves the point unaffected. If a
+ /// replacement contains the point, it will end up at the beginning of the replacement text.
+ /// </summary>
+ Negative
+ }
+}
diff --git a/src/Text/Def/TextData/Model/PositionAffinity.cs b/src/Text/Def/TextData/Model/PositionAffinity.cs
new file mode 100644
index 0000000..7ab1b9f
--- /dev/null
+++ b/src/Text/Def/TextData/Model/PositionAffinity.cs
@@ -0,0 +1,22 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Describes whether a position in a <see cref="ITextBuffer"/> that can be thought of as
+ /// lying between two characters is coupled to the preceding character or the following character.
+ /// </summary>
+ public enum PositionAffinity
+ {
+ /// <summary>
+ /// The position is coupled to with the preceding character.
+ /// </summary>
+ Predecessor,
+
+ /// <summary>
+ /// The position is coupled to the following character.
+ /// </summary>
+ Successor
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Model/PreContentChangedEventArgs.cs b/src/Text/Def/TextData/Model/PreContentChangedEventArgs.cs
new file mode 100644
index 0000000..3dd4faf
--- /dev/null
+++ b/src/Text/Def/TextData/Model/PreContentChangedEventArgs.cs
@@ -0,0 +1,36 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+
+ /// <summary>
+ /// Information provided before content changes.
+ /// </summary>
+ public class PreContentChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the text snapshot before the change.
+ /// </summary>
+ public ITextSnapshot BeforeSnapshot { get; private set; }
+
+ /// <summary>
+ /// Gets the collection of changes.
+ /// </summary>
+ public INormalizedTextChangeCollection Changes { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="PreContentChangedEventArgs"/>.
+ /// </summary>
+ /// <param name="beforeSnapshot">A text snapshot before the change.</param>
+ /// <param name="changes">The collection of changes.</param>
+ public PreContentChangedEventArgs(ITextSnapshot beforeSnapshot, INormalizedTextChangeCollection changes)
+ {
+ this.BeforeSnapshot = beforeSnapshot;
+ this.Changes = changes;
+ }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/ElisionBufferOptions.cs b/src/Text/Def/TextData/Model/Projection/ElisionBufferOptions.cs
new file mode 100644
index 0000000..2a398d2
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/ElisionBufferOptions.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+
+ /// <summary>
+ /// Options that apply to an <see cref="IElisionBuffer"/>s.
+ /// </summary>
+ [Flags]
+ public enum ElisionBufferOptions
+ {
+ /// <summary>
+ /// No special treatment.
+ /// </summary>
+ None = 0x00,
+
+ /// <summary>
+ /// When mapping spans, include hidden text between the start point and the end point.
+ /// </summary>
+ FillInMappingMode = 0x01
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/ElisionSourceSpansChangedEventArgs.cs b/src/Text/Def/TextData/Model/Projection/ElisionSourceSpansChangedEventArgs.cs
new file mode 100644
index 0000000..265709c
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/ElisionSourceSpansChangedEventArgs.cs
@@ -0,0 +1,78 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Provides data about an edit transaction on a <see cref="IElisionBuffer"/> in which the set of hidden source spans has changed.
+ /// </summary>
+ public class ElisionSourceSpansChangedEventArgs : TextContentChangedEventArgs
+ {
+ private NormalizedSpanCollection elidedSpans;
+ private NormalizedSpanCollection expandedSpans;
+
+ /// <summary>
+ /// Initialize a new instance of an <see cref="ElisionSourceSpansChangedEventArgs"/> object.
+ /// </summary>
+ /// <param name="beforeSnapshot">The most recent <see cref="IProjectionSnapshot"/> before the change occurred.</param>
+ /// <param name="afterSnapshot">The <see cref="IProjectionSnapshot"/> immediately after the change occurred.</param>
+ /// <param name="elidedSpans">Zero or more source spans that were hidden.</param>
+ /// <param name="expandedSpans">Zero or more source spans that were expanded.</param>
+ /// <param name="sourceToken">An arbitrary object associated with this change.</param>
+ /// <exception cref="ArgumentNullException">One of <paramref name="beforeSnapshot"/>, <paramref name="afterSnapshot"/>,
+ /// <paramref name="elidedSpans"/>, or <paramref name="expandedSpans"/> is null.</exception>
+ public ElisionSourceSpansChangedEventArgs(IProjectionSnapshot beforeSnapshot,
+ IProjectionSnapshot afterSnapshot,
+ NormalizedSpanCollection elidedSpans,
+ NormalizedSpanCollection expandedSpans,
+ object sourceToken)
+ : base(beforeSnapshot, afterSnapshot, EditOptions.None, sourceToken)
+ {
+ if (elidedSpans == null)
+ {
+ throw new ArgumentNullException("elidedSpans");
+ }
+ if (expandedSpans == null)
+ {
+ throw new ArgumentNullException("expandedSpans");
+ }
+ this.elidedSpans = elidedSpans;
+ this.expandedSpans = expandedSpans;
+ }
+
+ /// <summary>
+ /// The set of source spans that were inserted into the <see cref="IProjectionBuffer"/> by this edit transaction.
+ /// </summary>
+ public NormalizedSpanCollection ElidedSpans
+ {
+ get { return this.elidedSpans; }
+ }
+
+ /// <summary>
+ /// The set of source spans that were deleted from the <see cref="IProjectionBuffer"/> by this edit transaction.
+ /// </summary>
+ public NormalizedSpanCollection ExpandedSpans
+ {
+ get { return this.expandedSpans; }
+ }
+
+ /// <summary>
+ /// The state of the <see cref="IProjectionBuffer"/> before the change occurred.
+ /// </summary>
+ public new IProjectionSnapshot Before
+ {
+ get { return (IProjectionSnapshot)base.Before; }
+ }
+
+ /// <summary>
+ /// The state of the <see cref="IProjectionBuffer"/> after the change.
+ /// </summary>
+ public new IProjectionSnapshot After
+ {
+ get { return (IProjectionSnapshot)base.After; }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Model/Projection/GraphBufferContentTypeChangedEventArgs.cs b/src/Text/Def/TextData/Model/Projection/GraphBufferContentTypeChangedEventArgs.cs
new file mode 100644
index 0000000..8d7178f
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/GraphBufferContentTypeChangedEventArgs.cs
@@ -0,0 +1,67 @@
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Provides data about a change of <see cref="IContentType"/> on a member of a <see cref="IBufferGraph"/>.
+ /// </summary>
+ public class GraphBufferContentTypeChangedEventArgs : EventArgs
+ {
+ private ITextBuffer textBuffer;
+ private IContentType beforeContentType;
+ private IContentType afterContentType;
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="GraphBufferContentTypeChangedEventArgs"/> with the specified
+ /// text buffer and the old and new content types.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> whose <see cref="IContentType"/> has changed.</param>
+ /// <param name="beforeContentType">The <see cref="IContentType"/> before the change.</param>
+ /// <param name="afterContentType">The <see cref="IContentType"/> after the change.</param>
+ /// <exception cref="ArgumentNullException">One of <paramref name="textBuffer"/>, <paramref name="beforeContentType"/>,
+ /// or <paramref name="afterContentType"/> is null.</exception>
+ public GraphBufferContentTypeChangedEventArgs(ITextBuffer textBuffer, IContentType beforeContentType, IContentType afterContentType)
+ {
+ if (textBuffer == null)
+ {
+ throw new ArgumentNullException("textBuffer");
+ }
+ if (beforeContentType == null)
+ {
+ throw new ArgumentNullException("beforeContentType");
+ }
+ if (afterContentType == null)
+ {
+ throw new ArgumentNullException("afterContentType");
+ }
+ this.textBuffer = textBuffer;
+ this.beforeContentType = beforeContentType;
+ this.afterContentType = afterContentType;
+ }
+
+ /// <summary>
+ /// The <see cref="ITextBuffer"/> whose <see cref="IContentType"/> has changed.
+ /// </summary>
+ public ITextBuffer TextBuffer
+ {
+ get { return this.textBuffer; }
+ }
+
+ /// <summary>
+ /// The <see cref="IContentType"/> before the change.
+ /// </summary>
+ public IContentType BeforeContentType
+ {
+ get { return this.beforeContentType; }
+ }
+
+ /// <summary>
+ /// The <see cref="IContentType"/> after the change.
+ /// </summary>
+ public IContentType AfterContentType
+ {
+ get { return this.afterContentType; }
+ }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/GraphBuffersChangedEventArgs.cs b/src/Text/Def/TextData/Model/Projection/GraphBuffersChangedEventArgs.cs
new file mode 100644
index 0000000..638b6d2
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/GraphBuffersChangedEventArgs.cs
@@ -0,0 +1,51 @@
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+
+ /// <summary>
+ /// Information provided when a <see cref="ITextBuffer"/> is added or removed from a <see cref="IBufferGraph"/>.
+ /// </summary>
+ public class GraphBuffersChangedEventArgs : EventArgs
+ {
+ private ReadOnlyCollection<ITextBuffer> addedBuffers;
+ private ReadOnlyCollection<ITextBuffer> removedBuffers;
+ /// <summary>
+ /// Initializes a new instance of <see cref="GraphBuffersChangedEventArgs"/> with the provided buffers.
+ /// </summary>
+ /// <param name="addedBuffers">The list of buffers that were added.</param>
+ /// <param name="removedBuffers">The list of buffers that were removed.</param>
+ /// <exception cref="ArgumentNullException">Either <paramref name="addedBuffers"/> or <paramref name="removedBuffers"/>
+ /// is null.</exception>
+ public GraphBuffersChangedEventArgs(IList<ITextBuffer> addedBuffers, IList<ITextBuffer> removedBuffers)
+ {
+ if (addedBuffers == null)
+ {
+ throw new ArgumentNullException("addedBuffers");
+ }
+ if (removedBuffers == null)
+ {
+ throw new ArgumentNullException("removedBuffers");
+ }
+ this.addedBuffers = new ReadOnlyCollection<ITextBuffer>(addedBuffers);
+ this.removedBuffers = new ReadOnlyCollection<ITextBuffer>(removedBuffers);
+ }
+
+ /// <summary>
+ /// The list of <see cref="ITextBuffer"/> objects that have been added to the <see cref="IBufferGraph"/>.
+ /// </summary>
+ public ReadOnlyCollection<ITextBuffer> AddedBuffers
+ {
+ get { return this.addedBuffers; }
+ }
+
+ /// <summary>
+ /// The list of <see cref="ITextBuffer"/> objects that have been removed from the <see cref="IBufferGraph"/>.
+ /// </summary>
+ public ReadOnlyCollection<ITextBuffer> RemovedBuffers
+ {
+ get { return this.removedBuffers; }
+ }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/IBufferGraph.cs b/src/Text/Def/TextData/Model/Projection/IBufferGraph.cs
new file mode 100644
index 0000000..ed71847
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/IBufferGraph.cs
@@ -0,0 +1,259 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+
+ /// <summary>
+ /// Represents a graph of <see cref="ITextBuffer"/> objects. The
+ /// top level text buffer might or might not be a <see cref="IProjectionBuffer"/>.
+ /// </summary>
+ public interface IBufferGraph
+ {
+ /// <summary>
+ /// Gets the top text buffer in the buffer graph.
+ /// </summary>
+ ITextBuffer TopBuffer { get; }
+
+ /// <summary>
+ /// Finds all the <see cref="ITextBuffer"/> objects in the graph that match the specified predicate.
+ /// </summary>
+ /// <param name="match">The predicate used for matching.</param>
+ /// <returns>A non-null but possibly empty collection of <see cref="ITextBuffer"/> objects.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="match"/> is null.</exception>
+ Collection<ITextBuffer> GetTextBuffers(Predicate<ITextBuffer> match);
+
+ /// <summary>
+ /// Creates a new <see cref="IMappingPoint"/> with the specified snapshot point and tracking mode.
+ /// </summary>
+ /// <param name="point">A <see cref="SnapshotPoint"/> in one of the buffers of the graph.</param>
+ /// <param name="trackingMode">How to track the point.</param>
+ /// <returns>A <see cref="IMappingPoint"/> that can track within its buffer and map within the graph.</returns>
+ IMappingPoint CreateMappingPoint(SnapshotPoint point, PointTrackingMode trackingMode);
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="IMappingSpan"/>.
+ /// </summary>
+ /// <param name="span">A <see cref="SnapshotSpan"/> in one of the buffers of the graph.</param>
+ /// <param name="trackingMode">How to track the span.</param>
+ /// <returns>A <see cref="IMappingSpan"/> that can track within its buffer and map within the graph.</returns>
+ IMappingSpan CreateMappingSpan(SnapshotSpan span, SpanTrackingMode trackingMode);
+
+ /// <summary>
+ /// Maps a position in the graph to the corresponding position in a buffer lower in the graph. Source buffers are considered to be lower than
+ /// the projection buffers that consume them.
+ /// </summary>
+ /// <param name="position">The position in a buffer in the graph.</param>
+ /// <param name="trackingMode">How <paramref name="position"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="targetBuffer">The buffer to which to map the <paramref name="position"/>.</param>
+ /// <param name="affinity">
+ /// If the mapping is ambiguous (the position is on a source span seam), determines
+ /// whether the mapping should target the position immediately after the preceding
+ /// character or immediately before the following character in the top buffer.
+ /// This setting has no effect if the mapping is unambiguous.</param>
+ /// <returns>A point in a snapshot of the target buffer, or null if <paramref name="position"/> is not in this graph or does not map to
+ /// the target buffer with the given affinity.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="position"/>.Snapshot or <paramref name="targetBuffer"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="PointTrackingMode"/>, or
+ /// <paramref name="affinity"/> is not a valid <see cref="PositionAffinity"/>.</exception>
+ SnapshotPoint? MapDownToBuffer(SnapshotPoint position, PointTrackingMode trackingMode, ITextBuffer targetBuffer, PositionAffinity affinity);
+
+ /// <summary>
+ /// Maps a position in the graph to the corresponding position in a snapshot lower in the graph. Source buffers are considered to be lower than
+ /// the projection buffers that consume them.
+ /// </summary>
+ /// <param name="position">The position in a buffer in the graph.</param>
+ /// <param name="trackingMode">How <paramref name="position"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="targetSnapshot">The buffer to which to map the <paramref name="position"/>.</param>
+ /// <param name="affinity">
+ /// If the mapping is ambiguous (the position is on a source span seam), determines
+ /// whether the mapping should target the position immediately after the preceding
+ /// character or immediately before the following character in the top buffer.
+ /// This setting has no effect if the mapping is unambiguous.</param>
+ /// <returns>A point in a snapshot of the target buffer, or null if <paramref name="position"/> is not in this graph or does not map to the
+ /// target buffer with the given affinity.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="position"/>.Snapshot or <paramref name="targetSnapshot"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="PointTrackingMode"/>, or
+ /// <paramref name="affinity"/> is not a valid <see cref="PositionAffinity"/>.</exception>
+ SnapshotPoint? MapDownToSnapshot(SnapshotPoint position, PointTrackingMode trackingMode, ITextSnapshot targetSnapshot, PositionAffinity affinity);
+
+ /// <summary>
+ /// Maps a position in the graph to a position in a matching buffer that is lower in the graph. Source buffers are
+ /// considered to be lower than the projection buffers that consume them.
+ /// </summary>
+ /// <param name="position">The position in a buffer in the graph.</param>
+ /// <param name="trackingMode">How <paramref name="position"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="match">The predicate that identifies the target buffer.</param>
+ /// <param name="affinity">
+ /// If the mapping is ambiguous (the position is on a source span seam), determines
+ /// whether the mapping should target the position immediately after the preceding
+ /// character or immediately before the following character in the top buffer.
+ /// This setting has no effect if the mapping is unambiguous.</param>
+ /// <returns>A point in a snapshot of the target buffer, or null if <paramref name="position"/> does not map down to any buffer
+ /// selected by <paramref name="match"/>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="position"/>.Snapshot or <paramref name="match"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="PointTrackingMode"/>, or
+ /// <paramref name="affinity"/> is not a valid <see cref="PositionAffinity"/>.</exception>
+ /// <remarks>The <paramref name="match"/> predicate is called on each text buffer in the buffer graph until it
+ /// returns <c>true</c>. The predicate will not be called again.</remarks>
+ SnapshotPoint? MapDownToFirstMatch(SnapshotPoint position, PointTrackingMode trackingMode, Predicate<ITextSnapshot> match, PositionAffinity affinity);
+
+ /// <summary>
+ /// Maps a position in some buffer in the graph to a position in a matching buffer that is lower in the graph and to which an
+ /// insertion would be routed. Source buffers are considered to be lower than the projection buffers that consume them.
+ /// </summary>
+ /// <param name="position">the position in a buffer in the graph.</param>
+ /// <param name="trackingMode">How <paramref name="position"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="match">The predicate that identifies the target buffer.</param>
+ /// <returns>A point in a snapshot of some source buffer, or null if <paramref name="position"/> is not in this graph or does not
+ /// map down to any buffer selected by <paramref name="match"/>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="position"/>.Snapshot or <paramref name="match"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="PointTrackingMode"/>.</exception>
+ SnapshotPoint? MapDownToInsertionPoint(SnapshotPoint position, PointTrackingMode trackingMode, Predicate<ITextSnapshot> match);
+
+ /// <summary>
+ /// Maps a snapshot span in some buffer in the graph to a sequence of zero or more spans in a buffer that is lower in the graph.
+ /// Source buffers are considered to be lower than the projection buffers that consume them.
+ /// </summary>
+ /// <param name="span">The span that is to be mapped.</param>
+ /// <param name="trackingMode">How <paramref name="span"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="targetBuffer">The buffer to which to map the span.</param>
+ /// <returns>A collection of zero or more snapshot spans in the target buffer to which the span maps.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/>.Snapshot or <paramref name="targetBuffer"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="SpanTrackingMode"/>.</exception>
+ NormalizedSnapshotSpanCollection MapDownToBuffer(SnapshotSpan span, SpanTrackingMode trackingMode, ITextBuffer targetBuffer);
+
+ /// <summary>
+ /// Maps a snapshot span in some buffer in the graph to a sequence of zero or more spans in a buffer that is lower in the graph.
+ /// Source buffers are considered to be lower than the projection buffers that consume them.
+ /// </summary>
+ /// <param name="span">The span that is to be mapped.</param>
+ /// <param name="trackingMode">How <paramref name="span"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="targetSnapshot">The buffer to which to map the span.</param>
+ /// <returns>A collection of zero or more snapshot spans in the target buffer to which the span maps.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/>.Snapshot or <paramref name="targetSnapshot"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="SpanTrackingMode"/>.</exception>
+ NormalizedSnapshotSpanCollection MapDownToSnapshot(SnapshotSpan span, SpanTrackingMode trackingMode, ITextSnapshot targetSnapshot);
+
+ /// <summary>
+ /// Maps a snapshot span in some buffer in the graph to a sequence of zero or more spans in some source snapshot selected by a predicate.
+ /// </summary>
+ /// <param name="span">The span that is to be mapped.</param>
+ /// <param name="trackingMode">How <paramref name="span"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="match">The predicate that identifies the target buffer.</param>
+ /// <returns>A collection of zero or more snapshot spans in the target buffer to which the topSpan maps.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/>.Snapshot or <paramref name="match"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="SpanTrackingMode"/>.</exception>
+ /// <remarks><paramref name="match"/> is called on each text buffer in the buffer graph until it
+ /// returns <c>true</c>. The predicate will not be called again.</remarks>
+ NormalizedSnapshotSpanCollection MapDownToFirstMatch(SnapshotSpan span, SpanTrackingMode trackingMode, Predicate<ITextSnapshot> match);
+
+ /// <summary>
+ /// Maps a position in the current snapshot of some buffer that is a member of the buffer graph to a snapshot of some buffer.
+ /// </summary>
+ /// <param name="point">A point in some buffer in the <see cref="IBufferGraph"/>.</param>
+ /// <param name="trackingMode">How <paramref name="point"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="affinity">
+ /// If the mapping is ambiguous (the position is on a source span seam), determines
+ /// whether the mapping should target the position immediately after the preceding
+ /// character or immediately before the following character in the top buffer.
+ /// This setting has no effect if the mapping is unambiguous.</param>
+ /// <param name="targetBuffer">The buffer to which to map.</param>
+ /// <returns>The corresponding position in a snapshot of the target buffer, or null if the position does not map to the target buffer
+ /// using this graph.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="point"/>.Snapshot is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="PointTrackingMode"/>, or
+ /// <paramref name="affinity"/> is not a valid <see cref="PositionAffinity"/>.</exception>
+ SnapshotPoint? MapUpToBuffer(SnapshotPoint point, PointTrackingMode trackingMode, PositionAffinity affinity, ITextBuffer targetBuffer);
+
+ /// <summary>
+ /// Maps a position in the current snapshot of some buffer that is a member of the buffer graph to specified snapshot.
+ /// </summary>
+ /// <param name="point">A point in some buffer in the <see cref="IBufferGraph"/>.</param>
+ /// <param name="trackingMode">How <paramref name="point"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="affinity">
+ /// If the mapping is ambiguous (the position is on a source span seam), determines
+ /// whether the mapping should target the position immediately after the preceding
+ /// character or immediately before the following character in the top buffer.
+ /// This setting has no effect if the mapping is unambiguous.</param>
+ /// <param name="targetSnapshot">The snapshot to which to map.</param>
+ /// <returns>The corresponding position in <paramref name="targetSnapshot"/>, or null if the position does not map to <paramref name="targetSnapshot"/>
+ /// using this graph.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="point"/>.Snapshot is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="PointTrackingMode"/>, or
+ /// <paramref name="affinity"/> is not a valid <see cref="PositionAffinity"/>.</exception>
+ SnapshotPoint? MapUpToSnapshot(SnapshotPoint point, PointTrackingMode trackingMode, PositionAffinity affinity, ITextSnapshot targetSnapshot);
+
+ /// <summary>
+ /// Maps a position in the current snapshot of some buffer that is a member of the buffer graph to a snapshot of some buffer
+ /// that is selected by a predicate.
+ /// </summary>
+ /// <param name="point">A point in some buffer in the <see cref="IBufferGraph"/>.</param>
+ /// <param name="trackingMode">How <paramref name="point"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="affinity">
+ /// If the mapping is ambiguous (the position is on a source span seam), determines
+ /// whether the mapping should target the position immediately after the preceding
+ /// character or immediately before the following character in the top buffer.
+ /// This setting has no effect if the mapping is unambiguous.</param>
+ /// <param name="match">The predicate that identifies the target buffer.</param>
+ /// <remarks><paramref name="match"/> is called for each text buffer in the buffer graph until it
+ /// returns <c>true</c>. The predicate will not be called again.</remarks>
+ /// <returns>The corresponding position in a snapshot of the matching buffer, or null if does not map to the matching buffer using
+ /// this graph.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="point"/>.Snapshot or <paramref name="match"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="PointTrackingMode"/>, or
+ /// <paramref name="affinity"/> is not a valid <see cref="PositionAffinity"/>.</exception>
+ SnapshotPoint? MapUpToFirstMatch(SnapshotPoint point, PointTrackingMode trackingMode, Predicate<ITextSnapshot> match, PositionAffinity affinity);
+
+ /// <summary>
+ /// Maps a span in the current snapshot of some buffer that is a member of the buffer graph to a sequence of spans in a snapshot of
+ /// a designated buffer.
+ /// </summary>
+ /// <param name="span">A span in some buffer in the <see cref="IBufferGraph"/>.</param>
+ /// <param name="trackingMode">How <paramref name="span"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="targetBuffer">The buffer to which to map.</param>
+ /// <returns>A collection of zero or more snapshot spans in <paramref name="targetBuffer"/> to which the span maps using this graph.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/>.Snapshot is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="SpanTrackingMode"/>.</exception>
+ NormalizedSnapshotSpanCollection MapUpToBuffer(SnapshotSpan span, SpanTrackingMode trackingMode, ITextBuffer targetBuffer);
+
+ /// <summary>
+ /// Maps a span in the current snapshot of some buffer that is a member of the buffer graph to a sequence of spans in a snapshot of
+ /// a designated buffer.
+ /// </summary>
+ /// <param name="span">A span in some buffer in the <see cref="IBufferGraph"/>.</param>
+ /// <param name="trackingMode">How <paramref name="span"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="targetSnapshot">The snapshot to which to map.</param>
+ /// <returns>A collection of zero or more snapshot spans in <paramref name="targetSnapshot"/> to which the span maps using this graph.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/>.Snapshot is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="SpanTrackingMode"/>.</exception>
+ NormalizedSnapshotSpanCollection MapUpToSnapshot(SnapshotSpan span, SpanTrackingMode trackingMode, ITextSnapshot targetSnapshot);
+
+ /// <summary>
+ /// Maps a span in the current snapshot of some buffer that is a member of the buffer graph up to a sequence of spans in a snapshot of
+ /// some buffer that is selected by a predicate.
+ /// </summary>
+ /// <param name="span">A span in some buffer in the IBufferGraph.</param>
+ /// <param name="trackingMode">How <paramref name="span"/> is tracked to the current snapshot if necessary.</param>
+ /// <param name="match">The predicate that identifies the target buffer.</param>
+ /// <returns>A collection of zero or more snapshot spans in the buffer selected by <paramref name="match"/>.</returns>
+ /// <remarks><paramref name="match"/> is called on each text buffer in the graph until it
+ /// returns <c>true</c>. The predicate will not be called again.</remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/>.Snapshot or <paramref name="match"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="trackingMode"/> is not a valid <see cref="SpanTrackingMode"/>.</exception>
+ NormalizedSnapshotSpanCollection MapUpToFirstMatch(SnapshotSpan span, SpanTrackingMode trackingMode, Predicate<ITextSnapshot> match);
+
+ /// <summary>
+ /// Occurs when the set of <see cref="ITextBuffer"/> objects in the buffer graph changes.
+ /// </summary>
+ event EventHandler<GraphBuffersChangedEventArgs> GraphBuffersChanged;
+
+ /// <summary>
+ /// Occurs when the <see cref="Microsoft.VisualStudio.Utilities.IContentType"/> of any <see cref="ITextBuffer"/> in the buffer graph changes.
+ /// </summary>
+ event EventHandler<GraphBufferContentTypeChangedEventArgs> GraphBufferContentTypeChanged;
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/IBufferGraphFactoryService.cs b/src/Text/Def/TextData/Model/Projection/IBufferGraphFactoryService.cs
new file mode 100644
index 0000000..7a64169
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/IBufferGraphFactoryService.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+
+ /// <summary>
+ /// Creates a buffer graph from a graph of <see cref="ITextBuffer"/> objects created by projection.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IBufferGraphFactoryService factory = null;
+ /// </remarks>
+ public interface IBufferGraphFactoryService
+ {
+ /// <summary>
+ /// Initializes a new instance of an <see cref="IBufferGraph"/> for the specified <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> for which to create the <see cref="IBufferGraph"/>.</param>
+ /// <returns>The <see cref="IBufferGraph"/>.</returns>
+ /// <exception cref="ArgumentNullException"> if <paramref name="textBuffer"/> is null.</exception>
+ IBufferGraph CreateBufferGraph(ITextBuffer textBuffer);
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/IElisionBuffer.cs b/src/Text/Def/TextData/Model/Projection/IElisionBuffer.cs
new file mode 100644
index 0000000..fa5e889
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/IElisionBuffer.cs
@@ -0,0 +1,74 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+
+ /// <summary>
+ /// A restricted projection buffer that has exactly one source buffer. Spans from the source buffer
+ /// must appear in the same order in the projection buffer as in the source buffer.
+ /// </summary>
+ /// <remarks>
+ /// The source spans of an elision buffer are all <see cref="SpanTrackingMode.EdgeInclusive"/>. Consequently,
+ /// if all of the contents of a source span are deleted, and later an insertion is made at the location of that span
+ /// in the source buffer, the insertion will appear in the elision buffer.
+ /// </remarks>
+ public interface IElisionBuffer : IProjectionBufferBase
+ {
+ /// <summary>
+ /// Gets the source buffer of this elision buffer.
+ /// </summary>
+ ITextBuffer SourceBuffer { get; }
+
+ /// <summary>
+ /// Gets the current snapshot of this elision buffer.
+ /// </summary>
+ new IElisionSnapshot CurrentSnapshot { get; }
+
+ /// <summary>
+ /// Hides the text designated by <paramref name="spansToElide"/>.
+ /// </summary>
+ /// <param name="spansToElide">The spans of text to hide with respect to the current snapshot of the source buffer.
+ /// It is not an error if some of the designated text is already hidden. These spans are converted to EdgeExclusive
+ /// tracking spans.</param>
+ /// <returns>A newly generated snapshot.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="spansToElide"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">The end of the final span in <paramref name="spansToElide"/> is greater
+ /// than <see cref="SourceBuffer"/>.CurrentSnapshot.Length.</exception>
+ IProjectionSnapshot ElideSpans(NormalizedSpanCollection spansToElide);
+
+ /// <summary>
+ /// Expands the text specified by <paramref name="spansToExpand"/>.
+ /// </summary>
+ /// <param name="spansToExpand">The spans of text to expand, with respect to the current snapshot of the source buffer.
+ /// It is not an error if some of the designated text is already expanded.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="spansToExpand"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">The end of the final spans in <paramref name="spansToExpand"/> is greater
+ /// than <see cref="SourceBuffer"/>.CurrentSnapshot.Length.</exception>
+ IProjectionSnapshot ExpandSpans(NormalizedSpanCollection spansToExpand);
+
+ /// <summary>
+ /// Modifies the exposed text by hiding <paramref name="spansToElide"/> and then expanding <paramref name="spansToExpand"/>
+ /// in a single transaction.
+ /// </summary>
+ /// <param name="spansToElide">The spans of text to hide with respect to the current snapshot of the source buffer.
+ /// It is not an error if some of the designated text is already hidden. These spans are converted to EdgeExclusive
+ /// tracking spans. This parameter may be null.</param>
+ /// <param name="spansToExpand">The spans of text to expand, with respect to the current snapshot of the source buffer.
+ /// It is not an error if some of the designated text is already expanded. This parameter may be null.</param>
+ /// <exception cref="ArgumentOutOfRangeException">The end of the final spans in <paramref name="spansToElide"/> or
+ /// <paramref name="spansToExpand"/> is greater than <see cref="SourceBuffer"/>.CurrentSnapshot.Length.</exception>
+ IProjectionSnapshot ModifySpans(NormalizedSpanCollection spansToElide, NormalizedSpanCollection spansToExpand);
+
+ /// <summary>
+ /// Gets the <see cref="ElisionBufferOptions"/> in effect for this <see cref="IElisionBuffer"/>.
+ /// </summary>
+ ElisionBufferOptions Options { get; }
+
+ /// <summary>
+ /// Occurs when the set of hidden spans changes.
+ /// </summary>
+ event EventHandler<ElisionSourceSpansChangedEventArgs> SourceSpansChanged;
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/IElisionSnapshot.cs b/src/Text/Def/TextData/Model/Projection/IElisionSnapshot.cs
new file mode 100644
index 0000000..5ed1481
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/IElisionSnapshot.cs
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+ using System.Collections.ObjectModel;
+
+ /// <summary>
+ /// A snapshot from an <see cref="IElisionBuffer"/> object.
+ /// </summary>
+ public interface IElisionSnapshot : IProjectionSnapshot
+ {
+ /// <summary>
+ /// Gets the <see cref="IElisionBuffer"/> of which this is a snapshot.
+ /// </summary>
+ /// <remarks>
+ /// This property always returns the same elision buffer, but that elision buffer is not itself immutable.
+ /// </remarks>
+ new IElisionBuffer TextBuffer { get; }
+
+ /// <summary>
+ /// Gets the text snapshot on which this elision snapshot is based.
+ /// </summary>
+ ITextSnapshot SourceSnapshot { get; }
+
+ /// <summary>
+ /// Maps from a snapshot point in the source buffer to the corresponding point in the elision snapshot.
+ /// If the source buffer position is not exposed in the elision snapshot, returns the nearest point that is
+ /// exposed. If nothing is exposed, returns position zero.
+ /// </summary>
+ /// <param name="point">The snapshot point in a source buffer to map.</param>
+ /// <returns>A position in the elision snapshot.</returns>
+ /// <exception cref="ArgumentException"><paramref name="point"/> does not belong to the source snapshot of this elision snapshot.</exception>
+ SnapshotPoint MapFromSourceSnapshotToNearest(SnapshotPoint point);
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/IProjectionBuffer.cs b/src/Text/Def/TextData/Model/Projection/IProjectionBuffer.cs
new file mode 100644
index 0000000..d2151f4
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/IProjectionBuffer.cs
@@ -0,0 +1,109 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// A text buffer that contains projections of other text buffers, composed
+ /// of a list of tracking spans of those buffers. The buffers that contribute to
+ /// the projection buffer are called source buffers, and the tracking spans that describe
+ /// the contributed regions are called source spans.
+ /// </summary>
+ public interface IProjectionBuffer : IProjectionBufferBase
+ {
+ #region Span Editing
+ /// <summary>
+ /// Inserts a tracking span into the list of source spans.
+ /// </summary>
+ /// <param name="position">The position at which to insert <paramref name="spanToInsert"/>.</param>
+ /// <param name="spanToInsert">The span to insert.</param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than SpanCount.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="spanToInsert"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="spanToInsert"/> would cause any duplicated projection.</exception>
+ /// <exception cref="ArgumentException"><paramref name="spanToInsert"/> is EdgeInclusive and does not cover its entire buffer,
+ /// or is EdgePositive and does not abut the end of its buffer, or is EdgeNegative and does not abut the beginning of its
+ /// buffer.
+ /// These checks are not performed if the projection buffer was created with the PermissiveEdgeInclusiveSourceSpans option.</exception>
+ /// <exception cref="ArgumentException">Adding the TextBuffer containing <paramref name="spanToInsert"/> would create a cycle
+ /// among a set of projection buffers by virtue of the SourceBuffer relationship.</exception>
+ IProjectionSnapshot InsertSpan(int position, ITrackingSpan spanToInsert);
+
+ /// <summary>
+ /// Inserts a literal string into the list of SourceSpans.
+ /// </summary>
+ /// <param name="position">The position at which to insert <paramref name="literalSpanToInsert"/>.</param>
+ /// <param name="literalSpanToInsert">The string to insert.</param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than SpanCount.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="literalSpanToInsert"/> is null.
+ /// These checks are not performed if the projection buffer was created with the PermissiveEdgeInclusiveSourceSpans option.</exception>
+ IProjectionSnapshot InsertSpan(int position, string literalSpanToInsert);
+
+ /// <summary>
+ /// Inserts a list of <see cref="ITrackingSpan"/> objects and/or literal strings into the list of source spans in the order in which they appear in the list.
+ /// </summary>
+ /// <param name="position">The position at which to insert the spans.</param>
+ /// <param name="spansToInsert">The list of spans to insert.</param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than SpanCount.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="spansToInsert"/> is null or a span in that list is null.</exception>
+ /// <exception cref="ArgumentException">An element of <parmref name="spansToInsert"/> is neither an <see cref="ITrackingSpan"/> nor a string.</exception>
+ /// <exception cref="ArgumentException">A span in <paramref name="spansToInsert"/> would cause a duplicated projection.</exception>
+ /// <exception cref="ArgumentException">A tracking span in <paramref name="spansToInsert"/> is EdgeInclusive and does not cover its entire buffer,
+ /// or is EdgePositive and does not abut the end of its buffer, or is EdgeNegative and does not abut the beginning of its
+ /// buffer.
+ /// These checks are not performed if the projection buffer was created with the PermissiveEdgeInclusiveSourceSpans option.</exception>
+ /// <exception cref="ArgumentException">Adding one of the text buffers containing any of the <paramref name="spansToInsert"/> would
+ /// create a cycle among a set of projection vuffers by virtue of the SourceBuffer relationship.</exception>
+ IProjectionSnapshot InsertSpans(int position, IList<object> spansToInsert);
+
+ /// <summary>
+ /// Deletes a sequence of source spans from the projection buffer.
+ /// </summary>
+ /// <param name="position">The position at which to begin deleting spans.</param>
+ /// <param name="spansToDelete">The number of spans to delete.</param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than SpanCount.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="spansToDelete"/> is less than zero or
+ /// <paramref name="position"/> + <paramref name="spansToDelete"/> is greater than SpanCount.</exception>
+ IProjectionSnapshot DeleteSpans(int position, int spansToDelete);
+
+ /// <summary>
+ /// Replaces a sequence of source spans with a new list of <see cref="ITrackingSpan"/> objects and/or literal strings.
+ /// </summary>
+ /// <param name="position">The position at which to begin replacing spans.</param>
+ /// <param name="spansToReplace">The number of spans to replace.</param>
+ /// <param name="spansToInsert">The new spans to insert.</param>
+ /// <param name="options">Options to apply to the span edit.</param>
+ /// <param name="editTag">An arbitrary object that will be associated with this edit transaction.</param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than SpanCount.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="spansToReplace"/> is less than zero or <paramref name="position"/> + <paramref name="spansToReplace"/>
+ /// is greater than SpanCount.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="spansToInsert"/> is null or a span in the list are null.</exception>
+ /// <exception cref="ArgumentException">An element of <parmref name="spansToInsert"/> is neither an <see cref="ITrackingSpan"/> nor a string.</exception>
+ /// <exception cref="ArgumentException">A span in <paramref name="spansToInsert"/> would cause a duplicated projection.</exception>
+ /// <exception cref="ArgumentException">A tracking span in <paramref name="spansToInsert"/> is EdgeInclusive and does not cover its entire buffer,
+ /// or is EdgePositive and does not abut the end of its buffer, or is EdgeNegative and does not abut the beginning of its
+ /// buffer.
+ /// These checks are not performed if the projection buffer was created with the PermissiveEdgeInclusiveSourceSpans option.</exception>
+ /// <exception cref="ArgumentException">Adding a text buffer containing one of the <paramref name="spansToInsert"/> would
+ /// create a cycle among a set of projection buffers by virtue of the SourceBuffer relationship.</exception>
+ IProjectionSnapshot ReplaceSpans(int position, int spansToReplace, IList<object> spansToInsert, EditOptions options, object editTag);
+ #endregion
+
+ /// <summary>
+ /// Raised when source spans are added or deleted. It is not raised when
+ /// the contents of a source span change, for example when a source span becomes empty. When
+ /// a nonempty span is added or deleted, the <see cref="SourceBuffersChanged"/> event will be raised first.
+ /// The sequence of events is: 1) SourceBuffersChanged, 2) SourceSpansChanged, 3) ITextBuffer.Changed.
+ /// The <see cref="SourceSpansChanged"/> event is raised first).
+ /// </summary>
+ event EventHandler<ProjectionSourceSpansChangedEventArgs> SourceSpansChanged;
+
+ /// <summary>
+ /// Raised when source buffers are added or deleted by virtue of the addition or deletion
+ /// of source spans. This event is raised before the <see cref="SourceSpansChanged"/> event is raised.
+ /// </summary>
+ event EventHandler<ProjectionSourceBuffersChangedEventArgs> SourceBuffersChanged;
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/IProjectionBufferBase.cs b/src/Text/Def/TextData/Model/Projection/IProjectionBufferBase.cs
new file mode 100644
index 0000000..d6eaba2
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/IProjectionBufferBase.cs
@@ -0,0 +1,76 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+ using System.Collections.Generic;
+
+ //TODO: rename IProjectionBuffer when ready for API changes
+
+ /// <summary>
+ /// A text buffer that contains projections of other text buffers, composed
+ /// of a list of text spans of those buffers. The other buffers that contribute to
+ /// the projection buffer are called source buffers, and the text spans that describe
+ /// the contributed regions are called source spans.
+ /// </summary>
+ public interface IProjectionBufferBase : ITextBuffer
+ {
+ /// <summary>
+ /// The current snapshot of the contents of the projection buffer.
+ /// </summary>
+ /// <returns></returns>
+ new IProjectionSnapshot CurrentSnapshot { get; }
+
+ /// <summary>
+ /// The set of <see cref="ITextBuffer"/> objects that directly contribute to the projection buffer.
+ /// </summary>
+ IList<ITextBuffer> SourceBuffers { get; }
+
+ #region Editing shortcuts
+ /// <summary>
+ /// Inserts the given <paramref name="text"/> at the specified <paramref name="position"/> in the <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="position">The buffer position at which the first character of the text will appear.</param>
+ /// <param name="text">The text to be inserted.</param>
+ /// <remarks>
+ /// This is a shortcut for creating a new <see cref="ITextEdit"/> object, using it to insert the text, and then applying it. If the insertion
+ /// fails on account of a read-only region, the snapshot returned will be the same as the current snapshot of the buffer before
+ /// the attempted insertion.
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than the length of the buffer.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="text"/> is null.</exception>
+ /// <exception cref="InvalidOperationException">A TextEdit is currently active.</exception>
+ new IProjectionSnapshot Insert(int position, string text);
+
+ /// <summary>
+ /// Deletes a span of characters from the buffer.
+ /// </summary>
+ /// <param name="deleteSpan">The span of characters to delete.</param>
+ /// <remarks>
+ /// This is a shortcut for creating a new <see cref="ITextEdit"/> object, using it to delete the text, and then applying it. If the deletion
+ /// fails on account of a read-only region, the snapshot returned will be the same as the current snapshot of the buffer before
+ /// the attempted deletion.
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="deleteSpan"/>.The end of the span is greater than the length of the buffer.</exception>
+ /// <exception cref="InvalidOperationException">A TextEdit is currently active.</exception>
+ new IProjectionSnapshot Delete(Span deleteSpan);
+
+ /// <summary>
+ /// Replaces a span of characters with different text. This is equivalent to first deleting the text to be replaced and then
+ /// inserting the new text.
+ /// </summary>
+ /// <param name="replaceSpan">The span of characters to replace.</param>
+ /// <param name="replaceWith">The new text.</param>
+ /// <remarks>
+ /// This is a shortcut for creating a new <see cref="ITextEdit"/> object, using it to replace the text, and then applying it. If the replacement
+ /// fails on account of a read-only region, the snapshot returned will be the same as the current snapshot of the buffer before
+ /// the attempted replacement.
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="replaceSpan"/>.The end of the span is greater than the length of the buffer.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="replaceWith"/>is null.</exception>
+ /// <exception cref="InvalidOperationException">A TextEdit is currently active.</exception>
+ new IProjectionSnapshot Replace(Span replaceSpan, string replaceWith);
+ #endregion
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/IProjectionBufferFactoryService.cs b/src/Text/Def/TextData/Model/Projection/IProjectionBufferFactoryService.cs
new file mode 100644
index 0000000..8ffc9f0
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/IProjectionBufferFactoryService.cs
@@ -0,0 +1,96 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Used to create projection buffers.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IProjectionBufferFactoryService factory = null;
+ /// </remarks>
+ public interface IProjectionBufferFactoryService
+ {
+ /// <summary>
+ /// The default content type for projection buffers.
+ /// </summary>
+ IContentType ProjectionContentType { get; }
+
+ /// <summary>
+ /// Creates an <see cref="IProjectionBuffer"/> object with a specified <see cref="IContentType"/> and
+ /// the specified list of <see cref="ITrackingSpan"/> objects and/or literal strings.
+ /// </summary>
+ /// <param name="projectionEditResolver">The conflict resolver for this <see cref="IProjectionBuffer"/>. May be null.</param>
+ /// <param name="sourceSpans">The initial set of source spans for the <see cref="IProjectionBuffer"/>.</param>
+ /// <param name="options">Options for this buffer.</param>
+ /// <param name="contentType">The <see cref="IContentType"/> for the new <see cref="IProjectionBuffer"/>.</param>
+ /// <returns>A non-null projection buffer.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sourceSpans"/> or any of its elements is null.</exception>
+ /// <exception cref="ArgumentException">An element of <paramref name="sourceSpans"/> is neither a string nor an <see cref="ITrackingSpan"/>.</exception>
+ /// <exception cref="ArgumentException">A tracking span in <paramref name="sourceSpans"/> is EdgeInclusive and does not cover its entire buffer,
+ /// or is EdgePositive and does not abut the end of its buffer, or is EdgeNegative and does not abut the beginning of its
+ /// buffer.
+ /// These checks are not performed if the projection buffer was created with the PermissiveEdgeInclusiveSourceSpans option.</exception>
+ /// <exception cref="ArgumentException">Some of the tracking spans in <paramref name="sourceSpans"/> overlap.</exception>
+ IProjectionBuffer CreateProjectionBuffer(IProjectionEditResolver projectionEditResolver,
+ IList<object> sourceSpans,
+ ProjectionBufferOptions options,
+ IContentType contentType);
+
+ /// <summary>
+ /// Creates an <see cref="IProjectionBuffer"/> object with the default projection <see cref="IContentType"/> and
+ /// the specified list of source spans.
+ /// </summary>
+ /// <param name="projectionEditResolver">The conflict resolver for this <see cref="IProjectionBuffer"/>. May be null.</param>
+ /// <param name="sourceSpans">The initial set of source spans for the <see cref="IProjectionBuffer"/>.</param>
+ /// <param name="options">Options for this buffer.</param>
+ /// <returns>A non-null projection buffer.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="sourceSpans"/> or any of its elements is null.</exception>
+ /// <exception cref="ArgumentException">An element of <paramref name="sourceSpans"/> is neither a string nor an <see cref="ITrackingSpan"/>.</exception>
+ /// <exception cref="ArgumentException">A tracking spans in <paramref name="sourceSpans"/> is EdgeInclusive and does not cover its entire buffer,
+ /// or is EdgePositive and does not abut the end of its buffer, or is EdgeNegative and does not abut the beginning of its
+ /// buffer.</exception>
+ /// <exception cref="ArgumentException">Any of the tracking spans in <paramref name="sourceSpans"/> overlap.</exception>
+ IProjectionBuffer CreateProjectionBuffer(IProjectionEditResolver projectionEditResolver,
+ IList<object> sourceSpans,
+ ProjectionBufferOptions options);
+
+ /// <summary>
+ /// Create an elision buffer initialized to expose the provided list of snapshot spans from a single source buffer.
+ /// </summary>
+ /// <param name="projectionEditResolver">The conflict resolver for this <see cref="IProjectionBuffer"/>. May be null.</param>
+ /// <param name="exposedSpans">The set of spans (from a single source buffer) that are initially exposed in the elision buffer.</param>
+ /// <param name="options">Options for this buffer.</param>
+ /// <param name="contentType">The <see cref="IContentType"/> for the new <see cref="IElisionBuffer"/>.</param>
+ /// <returns>A non-null elision buffer.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="contentType"/> is null.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="exposedSpans"/> is null.</exception>
+ IElisionBuffer CreateElisionBuffer(IProjectionEditResolver projectionEditResolver,
+ NormalizedSnapshotSpanCollection exposedSpans,
+ ElisionBufferOptions options,
+ IContentType contentType);
+
+ /// <summary>
+ /// Create an ElisionBuffer with the default projection <see cref="IContentType"/> and initialized to the provided list of snapshot spans from
+ /// a single source buffer.
+ /// </summary>
+ /// <param name="projectionEditResolver">The conflict resolver for this <see cref="IProjectionBuffer"/>. May be null.</param>
+ /// <param name="exposedSpans">The set of spans (from a single source buffer) that are initially exposed in the elision buffer.</param>
+ /// <param name="options">Options for this buffer.</param>
+ /// <returns>A non-null elision buffer.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="exposedSpans"/> is null.</exception>
+ IElisionBuffer CreateElisionBuffer(IProjectionEditResolver projectionEditResolver,
+ NormalizedSnapshotSpanCollection exposedSpans,
+ ElisionBufferOptions options);
+
+ /// <summary>
+ /// Raised when any <see cref="IProjectionBuffer"/> or <see cref="IElisionBuffer"/> is created.
+ /// </summary>
+ event EventHandler<TextBufferCreatedEventArgs> ProjectionBufferCreated;
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/IProjectionEditResolver.cs b/src/Text/Def/TextData/Model/Projection/IProjectionEditResolver.cs
new file mode 100644
index 0000000..e224213
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/IProjectionEditResolver.cs
@@ -0,0 +1,63 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+
+ /// <summary>
+ /// Allows the creator of a projection buffer to control behavior of certain edits to the buffer.
+ /// </summary>
+ public interface IProjectionEditResolver
+ {
+ /// <summary>
+ /// When text is inserted into the projection buffer at <paramref name="projectionInsertionPoint"/>, determine how many characters
+ /// of the <paramref name="insertionText"/> are to be inserted into the source buffer at each source insertion point.
+ /// If length of the <paramref name="sourceInsertionPoints"/> is greater than two, all but the first and last snapshot point will denote
+ /// the boundary of an empty source span.
+ /// </summary>
+ /// <remarks>
+ /// This call is made while an edit is in progress, so any attempt to change the projection buffer or its sources during
+ /// this call will fail.
+ /// </remarks>
+ /// <param name="projectionInsertionPoint">The insertion point in the <see cref="IProjectionBuffer"/>.</param>
+ /// <param name="sourceInsertionPoints">The list of insertion points in the source buffers (of length two or more).</param>
+ /// <param name="insertionText">The text to be split between the insertion points.</param>
+ /// <param name="insertionSizes">Filled in by the callee; the number of characters in the <paramref name="insertionText"/> to be inserted into the corresponding source insertion point.</param>
+ void FillInInsertionSizes(SnapshotPoint projectionInsertionPoint,
+ ReadOnlyCollection<SnapshotPoint> sourceInsertionPoints,
+ string insertionText,
+ IList<int> insertionSizes);
+
+ /// <summary>
+ /// When text at <paramref name="projectionReplacementSpan"/> is replaced in a projection buffer, determine how many characters
+ /// of the <paramref name="insertionText"/> are to be inserted into the source buffer at each source insertion point (which are
+ /// the Start points of the <paramref name="sourceReplacementSpans"/>).
+ /// </summary>
+ /// <remarks>
+ /// This call is made while an edit is in progress, so any attempt to change the projection buffer or its sources during
+ /// this call will fail.
+ /// </remarks>
+ /// <param name="projectionReplacementSpan">The span of text that is to be replaced in the <see cref="IProjectionBuffer"/>.</param>
+ /// <param name="sourceReplacementSpans">The spans of text that are to be replaced in the source buffers (of length two or more).</param>
+ /// <param name="insertionText">The text to be split among the replacement spans.</param>
+ /// <param name="insertionSizes">Filled in by the callee; the number of characters in the <paramref name="insertionText"/> to
+ /// be inserted into the corresponding source replacement span.</param>
+ void FillInReplacementSizes(SnapshotSpan projectionReplacementSpan,
+ ReadOnlyCollection<SnapshotSpan> sourceReplacementSpans,
+ string insertionText,
+ IList<int> insertionSizes);
+
+ /// <summary>
+ /// When a position in the projection buffer lies on a source buffer seam, determine which source insertion
+ /// point would receive a typical insertion.
+ /// </summary>
+ /// <param name="projectionInsertionPoint">The insertion point in the <see cref="IProjectionBuffer"/>.</param>
+ /// <param name="sourceInsertionPoints">The list of insertion points in the source buffers (of length two or more).</param>
+ /// <returns>An integer between 0 and <paramref name="sourceInsertionPoints"/>.Length - 1.</returns>
+ int GetTypicalInsertionPosition(SnapshotPoint projectionInsertionPoint,
+ ReadOnlyCollection<SnapshotPoint> sourceInsertionPoints);
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/IProjectionSnapshot.cs b/src/Text/Def/TextData/Model/Projection/IProjectionSnapshot.cs
new file mode 100644
index 0000000..81c413e
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/IProjectionSnapshot.cs
@@ -0,0 +1,150 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+ using System.Collections.ObjectModel;
+
+ /// <summary>
+ /// An immutable text snapshot that represents a state of an <see cref="IProjectionBuffer"/>.
+ /// This snapshot contains projections of other text snapshots, described
+ /// by a list of tracking spans from those buffers. Every modification of a projection buffer
+ /// or one of its source buffers generates a new projection snapshot.
+ /// </summary>
+ public interface IProjectionSnapshot : ITextSnapshot
+ {
+ /// <summary>
+ /// Gets the <see cref="IProjectionBufferBase"/> of which this is a snapshot.
+ /// </summary>
+ /// <remarks>
+ /// This property always returns the same projection buffer, but the projection buffer is not itself immutable.
+ /// </remarks>
+ new IProjectionBufferBase TextBuffer { get; }
+
+ /// <summary>
+ /// Gets the number of source spans in the projection snapshot.
+ /// </summary>
+ int SpanCount { get; }
+
+ /// <summary>
+ /// Gets the set of one or more text snapshots that contribute source spans to this projection snapshot.
+ /// The ordering of the list is arbitrary. It does not contain duplicates.
+ /// </summary>
+ ReadOnlyCollection<ITextSnapshot> SourceSnapshots { get; }
+
+ /// <summary>
+ /// Gets the snapshot of the specified text buffer that corresponds to this snapshot.
+ /// </summary>
+ /// <param name="textBuffer"></param>
+ /// <returns>The snapshot of the text buffer. Returns null if <paramref name="textBuffer"/> is not a text buffer of this projection buffer.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="textBuffer"/> is null.</exception>
+ ITextSnapshot GetMatchingSnapshot(ITextBuffer textBuffer);
+
+ /// <summary>
+ /// Gets a read-only collection of source snapshot spans starting at the specified span index.
+ /// The <paramref name="startSpanIndex"/> is an index into the collection of source spans, not into the characters
+ /// in the text buffer.
+ /// </summary>
+ /// <param name="startSpanIndex">The position at which to start getting snapshot spans.</param>
+ /// <param name="count">The number of spans to get.</param>
+ /// <returns>A read-only collection of <see cref="SnapshotSpan"/> objects that are sources of the projection snapshot.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="startSpanIndex"/> is less than zero or greater than SpanCount.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than zero or <paramref name="count"/> plus <paramref name="startSpanIndex"/>
+ /// is greater than SpanCount.</exception>
+ ReadOnlyCollection<SnapshotSpan> GetSourceSpans(int startSpanIndex, int count);
+
+ /// <summary>
+ /// Gets all the source spans for the projection snapshot.
+ /// </summary>
+ /// <returns>A read-only collection of source spans of the projection snapshot, listed in the order they have in the projection snapshot.
+ /// The collection may be empty.</returns>
+ ReadOnlyCollection<SnapshotSpan> GetSourceSpans();
+
+ /// <summary>
+ /// Maps a position in the projection snapshot to the corresponding position in a source snapshot.
+ /// </summary>
+ /// <param name="position">The position in the projection snapshot .</param>
+ /// <param name="affinity">
+ /// If the mapping is ambiguous (the position lies on a source span seam), this parameter affects the mapping as follows:
+ /// if <paramref name="affinity"/> is <see cref="PositionAffinity.Predecessor"/>, the mapping targets
+ /// the position immediately after the preceding character in the projection buffer; if <paramref name="affinity"/> is
+ /// <see cref="PositionAffinity.Successor"/>, the mapping targets the position immediately before the following character
+ /// in the projection buffer. This parameter has no effect if the mapping is unambiguous.</param>
+ /// <returns>A snapshot point in one of the source snapshots.</returns>
+ /// <remarks>
+ /// In general, a source span seam occurs at the end of a source span of nonzero length
+ /// and the beginning of a source span of nonzero length, and
+ /// coincides with zero or more source spans of zero length.
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than or equal to the length of the snapshot.</exception>
+ /// <exception cref="InvalidOperationException">The projection snapshot has no source spans.</exception>
+ SnapshotPoint MapToSourceSnapshot(int position, PositionAffinity affinity);
+
+ /// <summary>
+ /// Maps a position in the projection snapshot to the corresponding position in one or more source snapshots.
+ /// </summary>
+ /// <param name="position">The position in the projection snapshot.</param>
+ /// <returns>A read-only collection of snapshot points to which the position maps. This collection contains one snapshot point unless the position lies
+ /// on a source span seam, in which case it can contain two or more points.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than or equal to the length of the snapshot.</exception>
+ /// <remarks>
+ /// In general, a source span seam occurs at the end of a source span of nonzero length
+ /// and the beginning of a source span of nonzero length, and
+ /// coincides with zero or more source spans of zero length. Every span on a seam
+ /// has a point in the result collection.
+ /// </remarks>
+ ReadOnlyCollection<SnapshotPoint> MapToSourceSnapshots(int position);
+
+ /// <summary>
+ /// Maps a position in the projection snapshot to the corresponding position in a source snapshot. If the mapping
+ /// is ambiguous (occurs on a source span seam), see <see cref="IProjectionEditResolver.GetTypicalInsertionPosition"/>
+ /// to choose a source buffer.
+ /// </summary>
+ /// <param name="position">The position in the projection snapshot.</param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than or equal to the length of the snapshot.</exception>
+ SnapshotPoint MapToSourceSnapshot(int position);
+
+ /// <summary>
+ /// Maps from a snapshot point in one of the source snapshots to the corresponding position in the projection snapshot.
+ /// </summary>
+ /// <param name="point">The snapshot point in a source buffer.</param>
+ /// <param name="affinity">
+ /// If the mapping is ambiguous (the position lies between two source spans), this parameter affects the mapping as follows:
+ /// if <paramref name="affinity"/> is <see cref="PositionAffinity.Predecessor"/>, the mapping targets
+ /// the position immediately after the preceding character in the projection buffer; if <paramref name="affinity"/> is
+ /// <see cref="PositionAffinity.Successor"/>, the mapping targets the position immediately before the following character
+ /// in the projection buffer. This parameter has no effect if the mapping is unambiguous.</param>
+ /// <returns>A position in the projection snapshot, or null if the source point does not correspond
+ /// to text belonging to a span that is a member of the projection snapshot.</returns>
+ /// <remarks>
+ /// In general, a source span seam occurs at the end of a source span of nonzero length
+ /// and the beginning of a source span of nonzero length, and
+ /// coincides with zero or more source spans of zero length. Every span on a seam
+ /// has a point in the result collection.
+ /// </remarks>
+ /// <exception cref="ArgumentException"><paramref name="point"/> does not belong to a source snapshot of this projection snapshot.</exception>
+ SnapshotPoint? MapFromSourceSnapshot(SnapshotPoint point, PositionAffinity affinity);
+
+ /// <summary>
+ /// Maps a span of the current projection snapshot to a list of snapshot spans belonging to source
+ /// snapshots. The resulting spans will be ordered by the order of their appearance in the projection.
+ /// </summary>
+ /// <param name="span">The span in the projection snapshot.</param>
+ /// <returns>A non-empty list of snapshot spans.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="span"/> is not valid for this buffer.</exception>
+ /// <remarks>If a null span occurs on a source span seam, it may map to more than one null source span.</remarks>
+ ReadOnlyCollection<SnapshotSpan> MapToSourceSnapshots(Span span);
+
+ /// <summary>
+ /// Maps a snapshot span of a source buffer to a list of spans of the projection snapshot.
+ /// The resulting ordered list may be empty, contain a single element, or contain multiple elements.
+ /// </summary>
+ /// <param name="span">The snapshot span in a source buffer to map.</param>
+ /// <returns>A non-null list of spans. The list will be empty if none of the positions in <paramref name="span"/> are projected by a source span
+ /// of the projection snapshot. This list is <b>not</b> normalized; the spans will be ordered by their original position in the
+ /// source snapshot, not their position in the projection snapshot. Adjacent spans are not coalesced.</returns>
+ /// <exception cref="ArgumentException"><paramref name="span"/> does not belong to a source buffer of this projection buffer.</exception>
+ ReadOnlyCollection<Span> MapFromSourceSnapshot(SnapshotSpan span);
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/IProjectionSnapshot2.cs b/src/Text/Def/TextData/Model/Projection/IProjectionSnapshot2.cs
new file mode 100644
index 0000000..beb08c0
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/IProjectionSnapshot2.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+using System;
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ public interface IProjectionSnapshot2 : IProjectionSnapshot
+ {
+ /// <summary>
+ /// Computes the snapshot of <paramref name="targetBuffer"/> that is a contributor to this snapshot. If
+ /// <paramref name="targetBuffer"/> is not in the source closure of this snapshot, return null.
+ /// </summary>
+ /// <exception cref="ArgumentNullException"> if <paramref name="targetBuffer"/> is null.</exception>
+ ITextSnapshot GetMatchingSnapshotInClosure(ITextBuffer targetBuffer);
+
+ /// <summary>
+ /// For each snapshot in the source closure of this snapshot, call the <paramref name="match"/> predicate on the
+ /// corresponding text buffer, and return the first source snapshot for which it returns true. The order in which the
+ /// source snapshots are visited is undefined.
+ /// </summary>
+ /// <exception cref="ArgumentNullException"> if <paramref name="match"/> is null.</exception>
+ ITextSnapshot GetMatchingSnapshotInClosure(Predicate<ITextBuffer> match);
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/ProjectionBufferOptions.cs b/src/Text/Def/TextData/Model/Projection/ProjectionBufferOptions.cs
new file mode 100644
index 0000000..f6fe8e7
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/ProjectionBufferOptions.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+
+ /// <summary>
+ /// Represents the options that apply to <see cref="IProjectionBuffer"/> objects.
+ /// </summary>
+ [Flags]
+ public enum ProjectionBufferOptions
+ {
+ /// <summary>
+ /// No special treatment.
+ /// </summary>
+ None = 0x00,
+
+ /// <summary>
+ /// Do not perform certain consistency checks on edge-inclusive source spans.
+ /// </summary>
+ /// <remarks>
+ /// See <see cref="IProjectionBuffer"/> for details.
+ /// </remarks>
+ PermissiveEdgeInclusiveSourceSpans = 0x01,
+
+ /// <summary>
+ /// Allow source spans that are string literals to be edited.
+ /// </summary>
+ WritableLiteralSpans = 0x02
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/ProjectionSourceBuffersChangedEventArgs.cs b/src/Text/Def/TextData/Model/Projection/ProjectionSourceBuffersChangedEventArgs.cs
new file mode 100644
index 0000000..f646b20
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/ProjectionSourceBuffersChangedEventArgs.cs
@@ -0,0 +1,72 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+
+ /// <summary>
+ /// Provides information for an edit transaction on a <see cref="IProjectionBuffer"/> in which the set of source <see cref="ITextBuffer"/> objects has changed.
+ /// </summary>
+ public class ProjectionSourceBuffersChangedEventArgs : ProjectionSourceSpansChangedEventArgs
+ {
+ private IList<ITextBuffer> addedBuffers;
+ private IList<ITextBuffer> removedBuffers;
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="ProjectionSourceBuffersChangedEventArgs"/> object.
+ /// </summary>
+ /// <param name="beforeSnapshot">The most recent <see cref="IProjectionSnapshot"/> before the change occurred.</param>
+ /// <param name="afterSnapshot">The <see cref="IProjectionSnapshot"/> immediately after the change occurred.</param>
+ /// <param name="insertedSpans">Zero or more source spans that were inserted into the <see cref="IProjectionBuffer"/>.</param>
+ /// <param name="deletedSpans">Zero or more source spans that were deleted from the <see cref="IProjectionBuffer"/>.</param>
+ /// <param name="spanPosition">The position in the list of source spans at which the buffer changes occurred.</param>
+ /// <param name="addedBuffers">The list of added source <see cref="ITextBuffer"/> objects.</param>
+ /// <param name="removedBuffers">The list of removed source <see cref="ITextBuffer"/> objects.</param>
+ /// <param name="options">The edit options that were applied to this change.</param>
+ /// <param name="editTag">An arbitrary object associated with this change.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="insertedSpans"/> is null.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="deletedSpans"/> is null.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="addedBuffers"/> or <paramref name="removedBuffers"/> is null.</exception>
+ public ProjectionSourceBuffersChangedEventArgs(IProjectionSnapshot beforeSnapshot,
+ IProjectionSnapshot afterSnapshot,
+ IList<ITrackingSpan> insertedSpans,
+ IList<ITrackingSpan> deletedSpans,
+ int spanPosition,
+ IList<ITextBuffer> addedBuffers,
+ IList<ITextBuffer> removedBuffers,
+ EditOptions options,
+ object editTag)
+ : base(beforeSnapshot, afterSnapshot, insertedSpans, deletedSpans, spanPosition, options, editTag)
+ {
+ if (addedBuffers == null)
+ {
+ throw new ArgumentNullException("addedBuffers");
+ }
+ if (removedBuffers == null)
+ {
+ throw new ArgumentNullException("removedBuffers");
+ }
+ this.addedBuffers = addedBuffers;
+ this.removedBuffers = removedBuffers;
+ }
+
+ /// <summary>
+ /// The source buffers that were added to the projection buffer.
+ /// </summary>
+ public ReadOnlyCollection<ITextBuffer> AddedBuffers
+ {
+ get { return new ReadOnlyCollection<ITextBuffer>(this.addedBuffers); }
+ }
+
+ /// <summary>
+ /// The source buffers that were removed and no longer contribute spans to the projection buffer.
+ /// </summary>
+ public ReadOnlyCollection<ITextBuffer> RemovedBuffers
+ {
+ get { return new ReadOnlyCollection<ITextBuffer>(this.removedBuffers); }
+ }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Projection/ProjectionSourceSpansChangedEventArgs.cs b/src/Text/Def/TextData/Model/Projection/ProjectionSourceSpansChangedEventArgs.cs
new file mode 100644
index 0000000..064fead
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Projection/ProjectionSourceSpansChangedEventArgs.cs
@@ -0,0 +1,93 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Projection
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+
+ /// <summary>
+ /// Provides information for an edit transaction on a <see cref="IProjectionBuffer"/> in which the set of source <see cref="ITrackingSpan"/> objects has changed.
+ /// </summary>
+ public class ProjectionSourceSpansChangedEventArgs : TextContentChangedEventArgs
+ {
+ private ReadOnlyCollection<ITrackingSpan> insertedSpans;
+ private ReadOnlyCollection<ITrackingSpan> deletedSpans;
+ private int spanPosition;
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="ProjectionSourceSpansChangedEventArgs"/>.
+ /// </summary>
+ /// <param name="beforeSnapshot">The most recent <see cref="IProjectionSnapshot"/> before the change occurred.</param>
+ /// <param name="afterSnapshot">The <see cref="IProjectionSnapshot"/> immediately after the change occurred.</param>
+ /// <param name="insertedSpans">Zero or more source spans that were inserted into the <see cref="IProjectionBuffer"/>.</param>
+ /// <param name="deletedSpans">Zero or more source spans that were deleted from the <see cref="IProjectionBuffer"/>.</param>
+ /// <param name="spanPosition">The position at which the span changes occurred.</param>
+ /// <param name="options">The edit options that were applied to this change.</param>
+ /// <param name="editTag">An arbitrary object associated with this change.</param>
+ /// <exception cref="ArgumentNullException">One of the parameters: <paramref name="beforeSnapshot"/>, <paramref name="afterSnapshot"/>,
+ /// <paramref name="insertedSpans"/>, or <paramref name="deletedSpans"/>is null.</exception>
+ public ProjectionSourceSpansChangedEventArgs(IProjectionSnapshot beforeSnapshot,
+ IProjectionSnapshot afterSnapshot,
+ IList<ITrackingSpan> insertedSpans,
+ IList<ITrackingSpan> deletedSpans,
+ int spanPosition,
+ EditOptions options,
+ object editTag)
+ : base(beforeSnapshot, afterSnapshot, options, editTag)
+ {
+ if (insertedSpans == null)
+ {
+ throw new ArgumentNullException("insertedSpans");
+ }
+ if (deletedSpans == null)
+ {
+ throw new ArgumentNullException("deletedSpans");
+ }
+ this.insertedSpans = new ReadOnlyCollection<ITrackingSpan>(insertedSpans);
+ this.deletedSpans = new ReadOnlyCollection<ITrackingSpan>(deletedSpans);
+ this.spanPosition = spanPosition;
+ }
+
+ /// <summary>
+ /// The position in the list of source spans at which the change occurred.
+ /// </summary>
+ public int SpanPosition
+ {
+ get { return this.spanPosition; }
+ }
+
+ /// <summary>
+ /// The set of source spans that were inserted into the <see cref="IProjectionBuffer"/> by this edit transaction.
+ /// </summary>
+ public ReadOnlyCollection<ITrackingSpan> InsertedSpans
+ {
+ get { return this.insertedSpans; }
+ }
+
+ /// <summary>
+ /// The set of source spans that were deleted from the <see cref="IProjectionBuffer"/> by this edit transaction.
+ /// </summary>
+ public ReadOnlyCollection<ITrackingSpan> DeletedSpans
+ {
+ get { return this.deletedSpans; }
+ }
+
+ /// <summary>
+ /// The state of the <see cref="IProjectionBuffer"/> before the change occurred.
+ /// </summary>
+ public new IProjectionSnapshot Before
+ {
+ get { return (IProjectionSnapshot)base.Before; }
+ }
+
+ /// <summary>
+ /// The state of the <see cref="IProjectionBuffer"/> after the change occurred.
+ /// </summary>
+ public new IProjectionSnapshot After
+ {
+ get { return (IProjectionSnapshot)base.After; }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Model/SnapshotPoint.cs b/src/Text/Def/TextData/Model/SnapshotPoint.cs
new file mode 100644
index 0000000..1c470f7
--- /dev/null
+++ b/src/Text/Def/TextData/Model/SnapshotPoint.cs
@@ -0,0 +1,304 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// An immutable text position in a particular text snapshot.
+ /// </summary>
+ public struct SnapshotPoint : IComparable<SnapshotPoint>
+ {
+ // Member must match order in the ctor, otherwise the COM tool gets confused.
+ private ITextSnapshot snapshot;
+ private int position;
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="SnapshotPoint"/> with respect to a particular snapshot and position.
+ /// </summary>
+ /// <param name="snapshot">The <see cref="ITextSnapshot"> that contains the new point.</see></param>
+ /// <param name="position">The position of the point.</param>
+ public SnapshotPoint(ITextSnapshot snapshot, int position)
+ {
+ if (snapshot == null)
+ {
+ throw new ArgumentNullException("snapshot");
+ }
+ if (position < 0 || position > snapshot.Length)
+ {
+ throw new ArgumentOutOfRangeException("position");
+ }
+ this.snapshot = snapshot;
+ this.position = position;
+ }
+
+ /// <summary>
+ /// Gets the position of the point.
+ /// </summary>
+ /// <value>A non-negative integer less than or equal to the length of the snapshot.</value>
+ public int Position
+ {
+ get { return this.position; }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="ITextSnapshot"/> to which this snapshot point refers.
+ /// </summary>
+ public ITextSnapshot Snapshot
+ {
+ get { return this.snapshot; }
+ }
+
+ /// <summary>
+ /// Implicitly converts the snapshot point to an integer equal to the position of the snapshot point in the snapshot.
+ /// </summary>
+ public static implicit operator int(SnapshotPoint snapshotPoint)
+ {
+ return snapshotPoint.Position;
+ }
+
+ /// <summary>
+ /// The <see cref="ITextSnapshotLine"/> containing this snapshot point.
+ /// </summary>
+ /// <returns></returns>
+ public ITextSnapshotLine GetContainingLine()
+ {
+ return this.snapshot.GetLineFromPosition(this.position);
+ }
+
+ /// <summary>
+ /// Gets the character at the position of this snapshot point.
+ /// </summary>
+ /// <returns>The character at the position of this snapshot point.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"> if the position of this point is equal to the length of the snapshot.</exception>
+ public char GetChar()
+ {
+ return this.snapshot[this.position];
+ }
+
+ /// <summary>
+ /// Translates this snapshot Point to a different snapshot of the same <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="targetSnapshot">The snapshot to which to translate.</param>
+ /// <param name="trackingMode">The <see cref="PointTrackingMode"/> to use in the translation.</param>
+ /// <returns>A new snapshot point that has been mapped to the requested snapshot.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="targetSnapshot"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="targetSnapshot"/> does not refer to the same <see cref="ITextBuffer"/> as this snapshot point.</exception>
+ public SnapshotPoint TranslateTo(ITextSnapshot targetSnapshot, PointTrackingMode trackingMode)
+ {
+ if (targetSnapshot == this.snapshot)
+ {
+ return this;
+ }
+ else
+ {
+ if (targetSnapshot == null)
+ {
+ throw new ArgumentNullException("targetSnapshot");
+ }
+ if (targetSnapshot.TextBuffer != this.snapshot.TextBuffer)
+ {
+ throw new ArgumentException(Strings.InvalidSnapshot);
+ }
+
+ int targetPosition = targetSnapshot.Version.VersionNumber > this.snapshot.Version.VersionNumber
+ ? Tracking.TrackPositionForwardInTime(trackingMode, this.position, this.snapshot.Version, targetSnapshot.Version)
+ : Tracking.TrackPositionBackwardInTime(trackingMode, this.position, this.snapshot.Version, targetSnapshot.Version);
+
+ return new SnapshotPoint(targetSnapshot, targetPosition);
+ }
+ }
+
+ /// <summary>
+ /// Serves as a hash function for this type.
+ /// </summary>
+ public override int GetHashCode()
+ {
+ return (this.snapshot != null) ? (this.position.GetHashCode() ^ this.snapshot.GetHashCode()) : 0;
+ }
+
+ /// <summary>
+ /// Converts this snapshot point to a string, or to the string "uninit" if the <see cref="ITextSnapshot"/> is null.
+ /// </summary>
+ public override string ToString()
+ {
+ if (this.snapshot == null)
+ {
+ return "uninit";
+ }
+ else
+ {
+ string tag;
+ this.Snapshot.TextBuffer.Properties.TryGetProperty<string>("tag", out tag);
+ return string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0}_v{1}_{2}_'{3}'",
+ tag ?? "?",
+ this.Snapshot.Version.VersionNumber,
+ this.position,
+ position == this.Snapshot.Length ? "<end>" : this.Snapshot.GetText(position, 1));
+ }
+ }
+
+ /// <summary>
+ /// Determines whether this snapshot point is the same as a second snapshot point.
+ /// </summary>
+ public override bool Equals(object obj)
+ {
+ if (obj is SnapshotPoint)
+ {
+ SnapshotPoint other = (SnapshotPoint)obj;
+ return other == this;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Creates a new snapshot point at the specified offset from this point.
+ /// </summary>
+ /// <param name="offset">The offset of the new point.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The new point is less than zero or greater than Snapshot.Length.
+ /// </exception>
+ public SnapshotPoint Add(int offset)
+ {
+ return new SnapshotPoint(this.Snapshot, this.Position + offset);
+ }
+
+ /// <summary>
+ /// Creates a new snapshot point at the specified negative offset from this point.
+ /// </summary>
+ /// <param name="offset">The offset of the new point.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The new point is less than zero or greater than Snapshot.Length.
+ /// </exception>
+ public SnapshotPoint Subtract(int offset)
+ {
+ return Add(-offset);
+ }
+
+ /// <summary>
+ /// Computes the offset between this snapshot point and another snapshot point.
+ /// </summary>
+ /// <param name="other">The point from which to compute the offset.</param>
+ /// <exception cref="ArgumentException">The two points do not belong to the same
+ /// snapshot.</exception>
+ /// <returns>The offset between the two points, equivalent to other.Position -
+ /// this.Position.</returns>
+ public int Difference(SnapshotPoint other)
+ {
+ return other - this;
+ }
+
+ #region Operator overloads
+
+ /// <summary>
+ /// Decrements the position of a snapshot point.
+ /// </summary>
+ /// <param name="point">The point from which to calculate the new position.</param>
+ /// <param name="offset">The offset of the new point.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The new point is less than zero
+ /// or greater than Snapshot.Length.
+ /// </exception>
+ public static SnapshotPoint operator -(SnapshotPoint point, int offset)
+ {
+ return point.Add(-offset);
+ }
+
+ /// <summary>
+ /// Computes the offset between two <see cref="SnapshotPoint"/> objects.
+ /// </summary>
+ /// <param name="start">The starting point.</param>
+ /// <param name="other">The point from which to compute the offset.</param>
+ /// <exception cref="ArgumentException">The two points do not belong to the same
+ /// snapshot.</exception>
+ /// <returns>The offset between the two points, equivalent to start.Position -
+ /// other.Position.</returns>
+ /// <remarks>The following should always be true:
+ /// start == other + (start - other).</remarks>
+ public static int operator -(SnapshotPoint start, SnapshotPoint other)
+ {
+ if (start.Snapshot != other.Snapshot)
+ {
+ throw new ArgumentException(Strings.InvalidSnapshotPoint);
+ }
+
+ return start.Position - other.Position;
+ }
+
+ /// <summary>
+ /// Determines whether this snapshot point is the same as a second snapshot point.
+ /// </summary>
+ public static bool operator ==(SnapshotPoint left, SnapshotPoint right)
+ {
+ return left.Snapshot == right.Snapshot && left.Position == right.Position;
+ }
+
+ /// <summary>
+ /// Determines whether this snapshot point is different from a second snapshot point.
+ /// </summary>
+ public static bool operator !=(SnapshotPoint left, SnapshotPoint right)
+ {
+ return !(left == right);
+ }
+
+ /// <summary>
+ /// Increments the position of a snapshot point.
+ /// </summary>
+ /// <param name="point">The point from which to calculate the new position.</param>
+ /// <param name="offset">The offset of the new point.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// The new point is less than zero
+ /// or greater than Snapshot.Length.
+ /// </exception>
+ public static SnapshotPoint operator +(SnapshotPoint point, int offset)
+ {
+ return point.Add(offset);
+ }
+
+ /// <summary>
+ /// Determines whether the position of one snapshot point is greater than the position of a second snapshot point.
+ /// </summary>
+ /// <returns><c>true</c> if the first position is greater than the second position, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentException">The two points do not belong to the same snapshot.</exception>
+ public static bool operator >(SnapshotPoint left, SnapshotPoint right)
+ {
+ return left.CompareTo(right) > 0;
+ }
+
+ /// <summary>
+ /// Determine if the position of the left point is less than the position of the right point.
+ /// </summary>
+ /// <returns><c>true</c> if left.Position is greater than right.Position, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentException">The two points do not belong to the same snapshot.</exception>
+ public static bool operator <(SnapshotPoint left, SnapshotPoint right)
+ {
+ return left.CompareTo(right) < 0;
+ }
+
+ #endregion
+
+ #region IComparable<SnapshotPoint>
+ /// <summary>
+ /// Determines whether this snapshot is the same as a second snapshot point.
+ /// </summary>
+ /// <param name="other">The snapshot point to which to compare.</param>
+ /// <returns>A negative integer if the position of this snapshot point occurs before the second snapshot point,
+ /// a positive integer if the position of this snapshot point occurs before the second snapshot point, and
+ /// zero if the positions are the same.</returns>
+ public int CompareTo(SnapshotPoint other)
+ {
+ if (this.Snapshot != other.Snapshot)
+ {
+ throw new ArgumentException(Strings.InvalidSnapshotPoint);
+ }
+
+ return this.position.CompareTo(other.position);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Text/Def/TextData/Model/SnapshotSpan.cs b/src/Text/Def/TextData/Model/SnapshotSpan.cs
new file mode 100644
index 0000000..0b2749b
--- /dev/null
+++ b/src/Text/Def/TextData/Model/SnapshotSpan.cs
@@ -0,0 +1,496 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// An immutable text span in a particular text snapshot.
+ /// </summary>
+ public struct SnapshotSpan
+ {
+ #region Private Members
+
+ // Member must match order in the ctor, otherwise the COM tool gets confused.
+ private SnapshotPoint start;
+ private int length;
+
+ #endregion // Private Members
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="SnapshotSpan"/> with the specified snapshot and span.
+ /// </summary>
+ /// <param name="snapshot">The <see cref="ITextSnapshot"/> on which to base the snapshot span.</param>
+ /// <param name="span">The span of the snapshot span.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshot"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="span"/>.End is greater than <paramref name="snapshot"/>.Length.</exception>
+ public SnapshotSpan(ITextSnapshot snapshot, Span span)
+ {
+ if (snapshot == null)
+ {
+ throw new ArgumentNullException("snapshot");
+ }
+ if (span.End > snapshot.Length)
+ {
+ throw new ArgumentOutOfRangeException("span");
+ }
+
+ this.start = new SnapshotPoint(snapshot, span.Start);
+ this.length = span.Length;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="SnapshotSpan"/> with the specified snapshot, start point, and length.
+ /// </summary>
+ /// <param name="snapshot">The text snapshot on which to base the snapshot span.</param>
+ /// <param name="start">The starting point of the snapshot span.</param>
+ /// <param name="length">The length of the snapshot span.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="snapshot"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> is negative or greater than <paramref name="snapshot"/>.Length, or
+ /// <paramref name="length"/> is negative or <paramref name="start"/> + <paramref name="length"/> is greater than
+ /// <paramref name="snapshot"/>.Length.</exception>
+ public SnapshotSpan(ITextSnapshot snapshot, int start, int length)
+ : this(snapshot, new Span(start, length))
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="SnapshotSpan"/> from two <see cref="SnapshotPoint"/> objects.
+ /// </summary>
+ /// <param name="start">The start point.</param>
+ /// <param name="end">The end point, which must be from the same <see cref="ITextSnapshot"/>
+ /// as the start point.</param>
+ /// <exception cref="ArgumentException">The snapshot points belong to different
+ /// <see cref="ITextSnapshot"/> objects.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">The end point comes before the start
+ /// point.</exception>
+ public SnapshotSpan(SnapshotPoint start, SnapshotPoint end)
+ {
+ if (start.Snapshot == null || end.Snapshot == null)
+ {
+ throw new ArgumentException(Strings.UninitializedSnapshotPoint);
+ }
+ if (start.Snapshot != end.Snapshot)
+ {
+ throw new ArgumentException(Strings.MismatchedSnapshotPoints);
+ }
+ if (end.Position < start.Position)
+ {
+ throw new ArgumentOutOfRangeException("end");
+ }
+
+ this.start = start;
+ this.length = (end - start);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="SnapshotSpan"/> from an existing <see cref="SnapshotPoint"/> and a specified length.
+ /// </summary>
+ /// <param name="start">The starting snapshot point.</param>
+ /// <param name="length">The length of the span.</param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is negative or
+ /// <paramref name="start"/> + <paramref name="length"/> is greater than the length of the snapshot.
+ /// </exception>
+ public SnapshotSpan(SnapshotPoint start, int length)
+ {
+ if (length < 0 ||
+ start.Position + length > start.Snapshot.Length)
+ {
+ throw new ArgumentOutOfRangeException("length");
+ }
+
+ this.start = start;
+ this.length = length;
+ }
+
+ /// <summary>
+ /// Implicitly converts a snapshot span to a span.
+ /// </summary>
+ public static implicit operator Span(SnapshotSpan snapshotSpan)
+ {
+ return snapshotSpan.Span;
+ }
+
+ /// <summary>
+ /// The <see cref="ITextSnapshot"/> to which this snapshot span refers.
+ /// </summary>
+ public ITextSnapshot Snapshot
+ {
+ get { return this.start.Snapshot; }
+ }
+
+ /// <summary>
+ /// The text contained by this snapshot span.
+ /// </summary>
+ /// <returns>A non-null string.</returns>
+ public string GetText()
+ {
+ return this.Snapshot.GetText(this.Span);
+ }
+
+ /// <summary>
+ /// Translates this snapshot span to a different snapshot of the same <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="targetSnapshot">The snapshot to which to translate.</param>
+ /// <param name="spanTrackingMode">The <see cref="SpanTrackingMode"/> to use in the translation.</param>
+ /// <returns>A new snapshot span.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="targetSnapshot"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="targetSnapshot"/> does not refer to the same <see cref="ITextBuffer"/> as this snapshot span.</exception>
+ public SnapshotSpan TranslateTo(ITextSnapshot targetSnapshot, SpanTrackingMode spanTrackingMode)
+ {
+ if (targetSnapshot == this.Snapshot)
+ {
+ return this;
+ }
+ else
+ {
+ if (targetSnapshot == null)
+ {
+ throw new ArgumentNullException("targetSnapshot");
+ }
+ if (targetSnapshot.TextBuffer != this.Start.Snapshot.TextBuffer)
+ {
+ throw new ArgumentException(Strings.InvalidSnapshot);
+ }
+
+ Span targetSpan = targetSnapshot.Version.VersionNumber > this.Snapshot.Version.VersionNumber
+ ? Tracking.TrackSpanForwardInTime(spanTrackingMode, Span, this.Snapshot.Version, targetSnapshot.Version)
+ : Tracking.TrackSpanBackwardInTime(spanTrackingMode, Span, this.Snapshot.Version, targetSnapshot.Version);
+
+ return new SnapshotSpan(targetSnapshot, targetSpan);
+ }
+ }
+
+ #region Reimplementation of Span methods and properties
+
+ /// <summary>
+ /// Gets the span covered by the snapshot span.
+ /// </summary>
+ public Span Span
+ {
+ get { return new Span(start, length); }
+ }
+
+ /// <summary>
+ /// Gets the starting index of the snapshot span.
+ /// </summary>
+ public SnapshotPoint Start
+ {
+ get
+ {
+ return start;
+ }
+ }
+
+ /// <summary>
+ /// Gets the end of the snapshot span. The span is open-ended on the right side, which is to say
+ /// that Start + Length = End.
+ /// </summary>
+ public SnapshotPoint End
+ {
+ get
+ {
+ return start + length;
+ }
+ }
+
+ /// <summary>
+ /// Gets the length of the span, which is always non-negative.
+ /// </summary>
+ public int Length
+ {
+ get { return this.length; }
+ }
+
+ /// <summary>
+ /// Determines whether or not this span is empty.
+ /// </summary>
+ /// <value><c>true</c> if the length of the span is zero, otherwise <c>false</c>.</value>
+ public bool IsEmpty
+ {
+ get { return this.Length == 0; }
+ }
+
+ /// <summary>
+ /// Determines whether the position lies within the span.
+ /// </summary>
+ /// <param name="position">
+ /// The position to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the position is greater than or equal to parameter span.Start and strictly less than parameter span.End, otherwise <c>false</c>.
+ /// </returns>
+ public bool Contains(int position)
+ {
+ return this.Span.Contains(position);
+ }
+
+ /// <summary>
+ /// Determines whether a given <see cref="SnapshotPoint"/> lies within the span.
+ /// </summary>
+ /// <param name="point">
+ /// The point to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the position is greater than or equal to parameter span.Start and strictly less than parameter span.End, otherwise <c>false</c>.
+ /// </returns>
+ public bool Contains(SnapshotPoint point)
+ {
+ this.EnsureSnapshot(point.Snapshot);
+
+ return this.Span.Contains(point.Position);
+ }
+
+ /// <summary>
+ /// Determines whether <paramref name="simpleSpan"/> falls completely within this span.
+ /// </summary>
+ /// <param name="simpleSpan">
+ /// The span to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the specified span falls completely within this span, otherwise <c>false</c>.
+ /// </returns>
+ public bool Contains(Span simpleSpan)
+ {
+ return this.Span.Contains(simpleSpan);
+ }
+
+ /// <summary>
+ /// Determines whether <paramref name="snapshotSpan"/> falls completely within this span.
+ /// </summary>
+ /// <param name="snapshotSpan">
+ /// The span to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the specified span falls completely within this span, otherwise <c>false</c>.
+ /// </returns>
+ public bool Contains(SnapshotSpan snapshotSpan)
+ {
+ this.EnsureSnapshot(snapshotSpan.Snapshot);
+
+ return this.Span.Contains(snapshotSpan.Span);
+ }
+
+ /// <summary>
+ /// Determines whether <paramref name="simpleSpan"/> overlaps this span. Two spans are considered to overlap if they have positions in common and are not empty.
+ /// Empty spans do not overlap with any other span.
+ /// </summary>
+ /// <param name="simpleSpan">
+ /// The span to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the spans overlap, otherwise <c>false</c>.
+ /// </returns>
+ public bool OverlapsWith(Span simpleSpan)
+ {
+ return this.Span.OverlapsWith(simpleSpan);
+ }
+
+ /// <summary>
+ /// Determines whether <paramref name="snapshotSpan"/> overlaps this span.
+ /// Two spans are considered to overlap if they have positions in common and are not empty. Empty spans do not overlap with any other span.
+ /// </summary>
+ /// <param name="snapshotSpan">
+ /// The span to check for overlap.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the spans overlap, otherwise <c>false</c>.
+ /// </returns>
+ public bool OverlapsWith(SnapshotSpan snapshotSpan)
+ {
+ this.EnsureSnapshot(snapshotSpan.Snapshot);
+
+ return this.Span.OverlapsWith(snapshotSpan.Span);
+ }
+
+ /// <summary>
+ /// Returns the overlap with the given span, or null if there is no overlap.
+ /// </summary>
+ /// <param name="simpleSpan">The span to check.</param>
+ /// <returns>The overlap of the spans, or null if the overlap is empty.</returns>
+ public SnapshotSpan? Overlap(Span simpleSpan)
+ {
+ Span? overlap = this.Span.Overlap(simpleSpan);
+
+ if (overlap != null)
+ {
+ return new SnapshotSpan(this.Snapshot, overlap.Value);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Returns the overlap with the given <see cref="SnapshotSpan"/>, or null if there is no overlap.
+ /// </summary>
+ /// <param name="snapshotSpan">The span to check.</param>
+ /// <exception cref="ArgumentException"><paramref name="snapshotSpan"/> does not refer to the same
+ /// <see cref="ITextSnapshot"/> as this snapshot span.</exception>
+ /// <returns>The overlap of the spans, or null if the overlap is empty.</returns>
+ public SnapshotSpan? Overlap(SnapshotSpan snapshotSpan)
+ {
+ this.EnsureSnapshot(snapshotSpan.Snapshot);
+
+ return this.Overlap(snapshotSpan.Span);
+ }
+
+ /// <summary>
+ /// Determines whether <paramref name="simpleSpan"/> intersects this span. Two spans are considered to
+ /// intersect if they have positions in common, or if the end of one span
+ /// coincides with the start of the other span, and neither is empty.
+ /// </summary>
+ /// <param name="simpleSpan">
+ /// The span to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the spans intersect, otherwise <c>false</c>.
+ /// </returns>
+ public bool IntersectsWith(Span simpleSpan)
+ {
+ return this.Span.IntersectsWith(simpleSpan);
+ }
+
+ /// <summary>
+ /// Determines whether <paramref name="snapshotSpan"/> intersects this span. Two spans are considered to
+ /// intersect if they have positions in common, or the end of one span
+ /// coincides with the start of the other span, and neither is empty.
+ /// </summary>
+ /// <param name="snapshotSpan">
+ /// The span to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the spans intersect, otherwise <c>false</c>.
+ /// </returns>
+ public bool IntersectsWith(SnapshotSpan snapshotSpan)
+ {
+ this.EnsureSnapshot(snapshotSpan.Snapshot);
+
+ return this.Span.IntersectsWith(snapshotSpan.Span);
+ }
+
+ /// <summary>
+ /// Computes the intersection with the given span, or null if there is no intersection.
+ /// </summary>
+ /// <param name="simpleSpan">
+ /// The span to check.
+ /// </param>
+ /// <returns>
+ /// The intersection of the spans, or null if the intersection is empty.
+ /// </returns>
+ public SnapshotSpan? Intersection(Span simpleSpan)
+ {
+ Span? intersection = this.Span.Intersection(simpleSpan);
+
+ if (intersection != null)
+ {
+ return new SnapshotSpan(this.Snapshot, intersection.Value);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Computes the intersection with the given <see cref="SnapshotSpan"/>, or null if there is no intersection.
+ /// </summary>
+ /// <param name="snapshotSpan">
+ /// The span to check.
+ /// </param>
+ /// <exception cref="ArgumentException"><paramref name="snapshotSpan"/> does not refer to the same snapshot. </exception>
+ /// <returns>
+ /// The intersection of the spans, or null if the intersection is empty.
+ /// </returns>
+ public SnapshotSpan? Intersection(SnapshotSpan snapshotSpan)
+ {
+ this.EnsureSnapshot(snapshotSpan.Snapshot);
+
+ return this.Intersection(snapshotSpan.Span);
+ }
+
+ #endregion // Reimplementation of Span methods and properties
+
+ #region Overridden methods and operators
+
+ /// <summary>
+ /// Serves as a hash function for this type.
+ /// </summary>
+ public override int GetHashCode()
+ {
+ return (this.Snapshot != null) ? (this.Span.GetHashCode() ^ this.Snapshot.GetHashCode()) : 0;
+ }
+
+ /// <summary>
+ /// Converts this snapshot span to a string, or to the string "uninit" if the <see cref="ITextSnapshot"/> is null.
+ /// </summary>
+ public override string ToString()
+ {
+ if (this.Snapshot == null)
+ {
+ return "uninit";
+ }
+ else
+ {
+ string tag;
+ this.Snapshot.TextBuffer.Properties.TryGetProperty<string>("tag", out tag);
+ return string.Format(System.Globalization.CultureInfo.CurrentCulture,
+ "{0}_v{1}_{2}_'{3}'",
+ tag ?? "?",
+ this.Snapshot.Version.VersionNumber,
+ this.Span.ToString(),
+ this.Length < 40
+ ? this.GetText()
+ : this.Snapshot.GetText(this.Start, 40));
+ }
+ }
+
+ /// <summary>
+ /// Determines whether two snapshot spans are the same.
+ /// </summary>
+ public override bool Equals(object obj)
+ {
+ if (obj is SnapshotSpan)
+ {
+ SnapshotSpan other = (SnapshotSpan)obj;
+ return other == this;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Determines whether two snapshot spans are the same.
+ /// </summary>
+ public static bool operator ==(SnapshotSpan left, SnapshotSpan right)
+ {
+ return left.Snapshot == right.Snapshot && left.Span == right.Span;
+ }
+
+ /// <summary>
+ /// Determines whether two snapshot spans are different.
+ /// </summary>
+ public static bool operator !=(SnapshotSpan left, SnapshotSpan right)
+ {
+ return !(left == right);
+ }
+
+ #endregion // Overridden methods and operators
+
+ #region Private helpers
+
+ private void EnsureSnapshot(ITextSnapshot requestedSnapshot)
+ {
+ if (this.Snapshot != requestedSnapshot)
+ {
+ throw new ArgumentException(Strings.InvalidSnapshotSpan);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Text/Def/TextData/Model/SnapshotSpanEventArgs.cs b/src/Text/Def/TextData/Model/SnapshotSpanEventArgs.cs
new file mode 100644
index 0000000..45cc11b
--- /dev/null
+++ b/src/Text/Def/TextData/Model/SnapshotSpanEventArgs.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// Provides information for events that report changes affecting a span of text.
+ /// </summary>
+ public class SnapshotSpanEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the <see cref="SnapshotSpan"/>.
+ /// </summary>
+ public SnapshotSpan Span { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="SnapshotSpanEventArgs"/> with the specified <see cref="SnapshotSpan" />.
+ /// </summary>
+ /// <param name="span">The <see cref="SnapshotSpan" />.</param>
+ public SnapshotSpanEventArgs(SnapshotSpan span)
+ {
+ Span = span;
+ }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Span.cs b/src/Text/Def/TextData/Model/Span.cs
new file mode 100644
index 0000000..2583882
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Span.cs
@@ -0,0 +1,264 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// An immutable integer interval that describes a range of values from <see cref="Start"/> to <see cref="End"/> that is closed on
+ /// the left and open on the right: [Start .. End). A zpan is usually applied to an <see cref="ITextSnapshot"/> to denote a span of text,
+ /// but it is independent of any particular text buffer or snapshot.
+ /// </summary>
+ public struct Span
+ {
+ #region Private Members
+
+ private int start, length;
+
+ #endregion // Private Members
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="Span"/> with the given start point and length.
+ /// </summary>
+ /// <param name="start">
+ /// The starting point of the span.
+ /// </param>
+ /// <param name="length">
+ /// The length of the span.
+ /// </param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> or <paramref name="length"/> is less than zero, or
+ /// start + length is greater than the length of the text snapshot.</exception>
+ public Span(int start, int length)
+ {
+ if (start < 0)
+ {
+ throw new ArgumentOutOfRangeException("start");
+ }
+ if (start + length < start)
+ {
+ throw new ArgumentOutOfRangeException("length");
+ }
+ this.start = start;
+ this.length = length;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="Span"/> with the given start and end positions.
+ /// </summary>
+ /// <param name="start">The start position of the new span.</param>
+ /// <param name="end">The end position of the new Span.</param>
+ /// <returns>The new span.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> is less than zero, or
+ /// <paramref name="end"/> is less than <paramref name="start"/>.</exception>
+ public static Span FromBounds(int start, int end)
+ {
+ // We don't need to check arguments, as the Span constructor will check for us.
+ return new Span(start, end - start);
+ }
+
+ #region Public Properties
+
+ /// <summary>
+ /// The starting index of the span.
+ /// </summary>
+ public int Start
+ {
+ get { return this.start; }
+ }
+
+ /// <summary>
+ /// The end of the span. The span is open-ended on the right side, which is to say
+ /// that Start + Length = End.
+ /// </summary>
+ public int End
+ {
+ get { return this.start + this.length; }
+ }
+
+ /// <summary>
+ /// The length of the span, which is always non-negative.
+ /// </summary>
+ public int Length
+ {
+ get { return this.length; }
+ }
+
+ /// <summary>
+ /// Determines whether or not this span is empty.
+ /// </summary>
+ /// <value><c>true</c> if the length of the span is zero, otherwise <c>false</c>.</value>
+ public bool IsEmpty
+ {
+ get { return (this.Length == 0); }
+ }
+
+ #endregion // Public Properties
+
+ #region Public Methods
+
+ /// <summary>
+ /// Determines whether the position lies within the span.
+ /// </summary>
+ /// <param name="position">
+ /// The position to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the position is greater than or equal to Start and strictly less
+ /// than End, otherwise <c>false</c>.
+ /// </returns>
+ public bool Contains(int position)
+ {
+ return (position >= this.start && position < this.End);
+ }
+
+ /// <summary>
+ /// Determines whether <paramref name="span"/> falls completely within this span.
+ /// </summary>
+ /// <param name="span">
+ /// The span to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the specified span falls completely within this span, otherwise <c>false</c>.
+ /// </returns>
+ public bool Contains(Span span)
+ {
+ return (span.start >= this.start && span.End <= this.End);
+ }
+
+ /// <summary>
+ /// Determines whether <paramref name="span"/> overlaps this span. Two spans are considered to overlap
+ /// if they have positions in common and neither is empty. Empty spans do not overlap with any
+ /// other span.
+ /// </summary>
+ /// <param name="span">
+ /// The span to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the spans overlap, otherwise <c>false</c>.
+ /// </returns>
+ public bool OverlapsWith(Span span)
+ {
+ int overlapStart = Math.Max(this.Start, span.Start);
+ int overlapEnd = Math.Min(this.End, span.End);
+
+ return overlapStart < overlapEnd;
+ }
+
+ /// <summary>
+ /// Returns the overlap with the given span, or null if there is no overlap.
+ /// </summary>
+ /// <param name="span">
+ /// The span to check.
+ /// </param>
+ /// <returns>
+ /// The overlap of the spans, or null if the overlap is empty.
+ /// </returns>
+ public Span? Overlap(Span span)
+ {
+ int overlapStart = Math.Max(this.Start, span.Start);
+ int overlapEnd = Math.Min(this.End, span.End);
+
+ if (overlapStart < overlapEnd)
+ {
+ return Span.FromBounds(overlapStart, overlapEnd);
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Determines whether <paramref name="span"/> intersects this span. Two spans are considered to
+ /// intersect if they have positions in common or the end of one span
+ /// coincides with the start of the other span.
+ /// </summary>
+ /// <param name="span">
+ /// The span to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the spans intersect, otherwise <c>false</c>.
+ /// </returns>
+ public bool IntersectsWith(Span span)
+ {
+ return (span.Start <= this.End && span.End >= this.Start);
+ }
+
+ /// <summary>
+ /// Returns the intersection with the given span, or null if there is no intersection.
+ /// </summary>
+ /// <param name="span">
+ /// The span to check.
+ /// </param>
+ /// <returns>
+ /// The intersection of the spans, or null if the intersection is empty.
+ /// </returns>
+ public Span? Intersection(Span span)
+ {
+ int intersectStart = Math.Max(this.Start, span.Start);
+ int intersectEnd = Math.Min(this.End, span.End);
+
+ if (intersectStart <= intersectEnd)
+ {
+ return Span.FromBounds(intersectStart, intersectEnd);
+ }
+
+ return null;
+ }
+
+ #endregion // Public Methods
+
+ #region Overridden methods and operators
+
+ /// <summary>
+ /// Provides a string representation of the span.
+ /// </summary>
+ public override string ToString()
+ {
+ return string.Format(System.Globalization.CultureInfo.InvariantCulture,
+ "[{0}..{1})", this.start, this.start + this.length);
+ }
+
+ /// <summary>
+ /// Provides a hash function for the type.
+ /// </summary>
+ public override int GetHashCode()
+ {
+ return (Length.GetHashCode() ^ Start.GetHashCode());
+ }
+
+ /// <summary>
+ /// Determines whether two spans are the same.
+ /// </summary>
+ /// <param name="obj">The object to compare.</param>
+ public override bool Equals(object obj)
+ {
+ if (obj is Span)
+ {
+ Span other = (Span)obj;
+ return other.start == this.start && other.length == this.length;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Determines whether two spans are the same
+ /// </summary>
+ public static bool operator ==(Span left, Span right)
+ {
+ return left.start == right.start && left.length == right.length;
+ }
+
+ /// <summary>
+ /// Determines whether two spans are different.
+ /// </summary>
+ public static bool operator !=(Span left, Span right)
+ {
+ return !(left == right);
+ }
+
+ #endregion // Overridden methods and operators
+ }
+}
diff --git a/src/Text/Def/TextData/Model/SpanTrackingMode.cs b/src/Text/Def/TextData/Model/SpanTrackingMode.cs
new file mode 100644
index 0000000..114c90f
--- /dev/null
+++ b/src/Text/Def/TextData/Model/SpanTrackingMode.cs
@@ -0,0 +1,44 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Represents tracking modes for <see cref="ITrackingSpan"/> objects.
+ /// </summary>
+ public enum SpanTrackingMode
+ {
+ /// <summary>
+ /// The leading edge of the span is positive tracking (insertions push the current position towards the end)
+ /// and the trailing edge is negative tracking (insertions push the current position towards the start).
+ /// The span will not expand when text changes occur at the span boundaries. For example,
+ /// if an EdgeExclusive Span has Start position 3, and a single character is inserted at position 3,
+ /// the Span will then have Start position 4 and its length will be unchanged.
+ /// </summary>
+ EdgeExclusive,
+
+ /// <summary>
+ /// The leading edge of the span is negative tracking (insertions push the current position toward the start)
+ /// and the trailing edge is positive tracking (insertions push the current position toward the end).
+ /// The span will expand when text changes occur at the span boundaries. For example,
+ /// if an EdgeInclusive Span has Start position 3, and a single character is inserted at position 3,
+ /// the Span will then have Start position 3 and its length will be increased by one.
+ /// </summary>
+ EdgeInclusive,
+
+ /// <summary>
+ /// Both edges of the span are positive tracking (insertions push the current position toward the end).
+ /// </summary>
+ EdgePositive,
+
+ /// <summary>
+ /// Both edges of the span are negative tracking (insertions push the current position toward the start).
+ /// </summary>
+ EdgeNegative,
+
+ /// <summary>
+ /// Custom client-determined tracking behavior.
+ /// </summary>
+ Custom
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Model/TextBufferCreatedEventArgs.cs b/src/Text/Def/TextData/Model/TextBufferCreatedEventArgs.cs
new file mode 100644
index 0000000..a521dd9
--- /dev/null
+++ b/src/Text/Def/TextData/Model/TextBufferCreatedEventArgs.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// Provides information about a newly created <see cref="ITextBuffer"/>.
+ /// </summary>
+ public class TextBufferCreatedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// The newly created <see cref="ITextBuffer"/>.
+ /// </summary>
+ public ITextBuffer TextBuffer { get; private set; }
+
+ /// <summary>
+ /// Constructs a <see cref="TextBufferCreatedEventArgs"/>.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> which was created.</param>
+ public TextBufferCreatedEventArgs(ITextBuffer textBuffer)
+ {
+ if (textBuffer == null)
+ {
+ throw new ArgumentNullException("textBuffer");
+ }
+ TextBuffer = textBuffer;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Model/TextContentChangedEventArgs.cs b/src/Text/Def/TextData/Model/TextContentChangedEventArgs.cs
new file mode 100644
index 0000000..a6439d1
--- /dev/null
+++ b/src/Text/Def/TextData/Model/TextContentChangedEventArgs.cs
@@ -0,0 +1,55 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// Provides information about an edit transaction on an <see cref="ITextBuffer"/>.
+ /// </summary>
+ public class TextContentChangedEventArgs : TextSnapshotChangedEventArgs
+ {
+ #region Private Members and Construction
+
+ private EditOptions options;
+
+ /// <summary>
+ /// Initializes an new instance of <see cref="TextContentChangedEventArgs"/> for a Change event.
+ /// </summary>
+ /// <param name="beforeSnapshot">The most recent <see cref="ITextSnapshot"/> before the change occurred.</param>
+ /// <param name="afterSnapshot">The <see cref="ITextSnapshot"/> immediately after the change occurred.</param>
+ /// <param name="options">Edit options that were applied to this change.</param>
+ /// <param name="editTag">An arbitrary object associated with this change.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="beforeSnapshot"/> or
+ /// <paramref name="afterSnapshot"/> or
+ /// <paramref name="options"/> is null.</exception>
+ public TextContentChangedEventArgs(ITextSnapshot beforeSnapshot,
+ ITextSnapshot afterSnapshot,
+ EditOptions options,
+ Object editTag) : base(beforeSnapshot, afterSnapshot, editTag)
+ {
+ this.options = options;
+ }
+ #endregion // Private Members and Construction
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the set of changes that occurred.
+ /// </summary>
+ public INormalizedTextChangeCollection Changes
+ {
+ get { return this.Before.Version.Changes; }
+ }
+
+ /// <summary>
+ /// Gets the edit options that were applied to this change.
+ /// </summary>
+ public EditOptions Options
+ {
+ get { return this.options; }
+ }
+ #endregion
+ }
+}
diff --git a/src/Text/Def/TextData/Model/TextContentChangingEventArgs.cs b/src/Text/Def/TextData/Model/TextContentChangingEventArgs.cs
new file mode 100644
index 0000000..ac4b31d
--- /dev/null
+++ b/src/Text/Def/TextData/Model/TextContentChangingEventArgs.cs
@@ -0,0 +1,75 @@
+using System;
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Provides information about an upcoming edit transaction on a <see cref="ITextBuffer"/>
+ /// </summary>
+ public class TextContentChangingEventArgs : EventArgs
+ {
+ private Action<TextContentChangingEventArgs> cancelAction;
+
+ /// <summary>
+ /// Determines whether the edit transaction has been canceled.
+ /// </summary>
+ public bool Canceled { get; private set; }
+
+ /// <summary>
+ /// The most recent <see cref="ITextSnapshot"/> before the change.
+ /// </summary>
+ public ITextSnapshot Before { get; private set; }
+
+ /// <summary>
+ /// Gets an arbitrary object provided by the initiator of the changes.
+ /// </summary>
+ public object EditTag { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="TextContentChangingEventArgs"/> to be passed during a Changing event.
+ /// </summary>
+ /// <param name="beforeSnapshot">The most recent <see cref="ITextSnapshot"/> before the change.</param>
+ /// <param name="editTag">An arbitrary object associated with this change.</param>
+ /// <param name="cancelAction">The action to execute when <see cref="Cancel"/> is called. Invoked at most once.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="beforeSnapshot"/> is null.</exception>
+ public TextContentChangingEventArgs(ITextSnapshot beforeSnapshot, object editTag, Action<TextContentChangingEventArgs> cancelAction)
+ {
+ if (beforeSnapshot == null)
+ {
+ throw new ArgumentNullException("beforeSnapshot");
+ }
+
+ Canceled = false;
+ Before = beforeSnapshot;
+ EditTag = editTag;
+
+ this.cancelAction = cancelAction;
+ }
+
+ /// <summary>
+ /// Cancels the edit transaction.
+ /// </summary>
+ public void Cancel()
+ {
+ if (!Canceled)
+ {
+ Canceled = true;
+
+ if (cancelAction != null)
+ {
+ cancelAction(this);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="ITextVersion"/> associated with <see cref="Before"/>.
+ /// </summary>
+ public ITextVersion BeforeVersion
+ {
+ get
+ {
+ return Before.Version;
+ }
+ }
+ }
+}
diff --git a/src/Text/Def/TextData/Model/TextSnapshotChangedEventArgs.cs b/src/Text/Def/TextData/Model/TextSnapshotChangedEventArgs.cs
new file mode 100644
index 0000000..1d060c7
--- /dev/null
+++ b/src/Text/Def/TextData/Model/TextSnapshotChangedEventArgs.cs
@@ -0,0 +1,88 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// Provides information about a transaction on a <see cref="ITextBuffer"/>
+ /// that causes a new <see cref="ITextSnapshot"/> to be generated.
+ /// </summary>
+ public abstract class TextSnapshotChangedEventArgs : EventArgs
+ {
+ #region Private Members and Construction
+
+ private ITextSnapshot before;
+ private ITextSnapshot after;
+ private Object editTag;
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="TextSnapshotChangedEventArgs"/> for a Change event.
+ /// </summary>
+ /// <param name="beforeSnapshot">The most recent <see cref="ITextSnapshot"/> before the change occurred.</param>
+ /// <param name="afterSnapshot">The <see cref="ITextSnapshot"/> immediately after the change occurred.</param>
+ /// <param name="editTag">An arbitrary object associated with this change.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="beforeSnapshot"/> or <paramref name="afterSnapshot"/> is null.</exception>
+ protected TextSnapshotChangedEventArgs(ITextSnapshot beforeSnapshot,
+ ITextSnapshot afterSnapshot,
+ object editTag)
+ {
+ if (beforeSnapshot == null)
+ {
+ throw new ArgumentNullException("beforeSnapshot");
+ }
+ if (afterSnapshot == null)
+ {
+ throw new ArgumentNullException("afterSnapshot");
+ }
+ this.before = beforeSnapshot;
+ this.after = afterSnapshot;
+ this.editTag = editTag;
+ }
+ #endregion // Private Members and Construction
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the state of the <see cref="ITextBuffer"/> before the change occurred.
+ /// </summary>
+ public ITextSnapshot Before
+ {
+ get { return this.before; }
+ }
+
+ /// <summary>
+ /// Gets the state of the <see cref="ITextBuffer"/> after the change.
+ /// </summary>
+ public ITextSnapshot After
+ {
+ get { return this.after; }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="ITextVersion"/> associated with <see cref="Before"/>.
+ /// </summary>
+ public ITextVersion BeforeVersion
+ {
+ get { return this.before.Version; }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="ITextVersion"/>n associated with <see cref="After"/>.
+ /// </summary>
+ public ITextVersion AfterVersion
+ {
+ get { return this.after.Version; }
+ }
+
+ /// <summary>
+ /// Gets an arbitrary object provided by the initiator of the changes.
+ /// </summary>
+ public Object EditTag
+ {
+ get { return this.editTag; }
+ }
+ #endregion
+ }
+}
diff --git a/src/Text/Def/TextData/Model/TextSnapshotToTextReader.cs b/src/Text/Def/TextData/Model/TextSnapshotToTextReader.cs
new file mode 100644
index 0000000..380c44f
--- /dev/null
+++ b/src/Text/Def/TextData/Model/TextSnapshotToTextReader.cs
@@ -0,0 +1,177 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using System.IO;
+ using System.Diagnostics;
+
+ /// <summary>
+ /// Provides a <see cref="TextReader"/> facade over a text snapshot.
+ /// </summary>
+ public sealed class TextSnapshotToTextReader : TextReader
+ {
+ #region TextReader methods
+ /// <summary>
+ /// Closes the reader and releases any associated system resources.
+ /// </summary>
+ public override void Close()
+ {
+ _currentPosition = -1;
+ base.Close();
+ }
+
+ /// <summary>
+ /// Releases all resources used by the reader.
+ /// </summary>
+ /// <param name="disposing">Whether to release managed resources.</param>
+ protected override void Dispose(bool disposing)
+ {
+ _currentPosition = -1;
+ base.Dispose(disposing);
+ }
+
+ /// <summary>
+ /// Returns the next character without changing the state of the reader or the
+ /// character source.
+ /// </summary>
+ /// <returns>The next character to be read, or -1 if no more characters are available or the stream does not support seeking.</returns>
+ /// <exception cref="ObjectDisposedException">The reader is closed.</exception>
+ public override int Peek()
+ {
+ if (_currentPosition == -1)
+ throw new ObjectDisposedException("TextSnapshotToTextReader");
+
+ return (_currentPosition == _snapshot.Length) ? -1 : (int)(_snapshot[_currentPosition]);
+ }
+
+ /// <summary>
+ /// Reads the next character from the input stream and advances the character
+ /// position by one character.
+ /// </summary>
+ /// <returns>The next character from the input stream, or -1 if no more characters are available.</returns>
+ /// <exception cref="ObjectDisposedException">The reader is closed.</exception>
+ public override int Read()
+ {
+ if (_currentPosition == -1)
+ throw new ObjectDisposedException("TextSnapshotToTextReader");
+
+ return (_currentPosition == _snapshot.Length) ? -1 : (int)(_snapshot[_currentPosition++]);
+ }
+
+ /// <summary>
+ /// Reads the specified number of characters from the current stream and writes the
+ /// data to the buffer, beginning at the specified location.
+ /// </summary>
+ /// <param name="buffer">When this method returns, contains the specified character array from the current source.</param>
+ /// <param name="index">The place in buffer at which to begin writing.</param>
+ /// <param name="count">The maximum number of characters to read.</param>
+ /// <returns>The number of characters that have been read. The number will be less than
+ /// or equal to <paramref name="count"/>, depending on whether the data is available within the
+ /// stream. This method returns zero if called when no more characters are left to read.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> or <paramref name="count"/> is negative, or
+ /// the buffer length minus index is less than <paramref name="count"/>.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">The reader is closed.</exception>
+ public override int Read(char[] buffer, int index, int count)
+ {
+ if (_currentPosition == -1)
+ throw new ObjectDisposedException("TextSnapshotToTextReader");
+ if (buffer == null)
+ throw new ArgumentNullException("buffer");
+ if (index < 0)
+ throw new ArgumentOutOfRangeException("index");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count");
+ if (((index + count) < 0) || ((index + count) > buffer.Length))
+ throw new ArgumentOutOfRangeException("count");
+
+ int charactersToRead = System.Math.Min(_snapshot.Length - _currentPosition, count);
+ _snapshot.CopyTo(_currentPosition, buffer, index, charactersToRead);
+ _currentPosition += charactersToRead;
+
+ return charactersToRead;
+ }
+
+ /// <summary>
+ /// Reads a maximum of <paramref name="count"/> characters from the current stream and writes the
+ /// data to buffer, beginning at index.
+ /// </summary>
+ /// <param name="buffer">When this method returns, contains the specified character array from the current source.</param>
+ /// <param name="index">The place in buffer at which to begin writing.</param>
+ /// <param name="count">The maximum number of characters to read.</param>
+ /// <returns>The number of characters that have been read. The number will be less than
+ /// or equal to <paramref name="count"/>, depending on whether the data is available within the
+ /// stream. This method returns zero if called when no more characters are left to read.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> or <paramref name="count"/> is negative, or
+ /// the buffer length minus index is less than <paramref name="count"/>.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException">The reader is closed.</exception>
+ public override int ReadBlock(char[] buffer, int index, int count)
+ {
+ return Read(buffer, index, count);
+ }
+
+ /// <summary>Reads a line of characters from the current stream and returns the data as a string.</summary>
+ /// <returns>The next line from the input stream, or null if all characters have been read.</returns>
+ /// <exception cref="ObjectDisposedException">The <see cref="TextReader"/> is closed.</exception>
+ public override string ReadLine()
+ {
+ if (_currentPosition == -1)
+ throw new ObjectDisposedException("TextSnapshotToTextReader");
+
+ if (_readLastLine)
+ return null;
+
+ ITextSnapshotLine line = _snapshot.GetLineFromPosition(_currentPosition);
+
+ //Handle the case where the current position is between a \r\n without crashing (but returning an empty string instead).
+ string text = (line.End > _currentPosition)
+ ? _snapshot.GetText(_currentPosition, line.End - _currentPosition)
+ : string.Empty;
+
+ _currentPosition = line.EndIncludingLineBreak;
+
+ if (_currentPosition == _snapshot.Length)
+ {
+ //Do not read the last line in the buffer unless it contains some text.
+ _readLastLine = true;
+ }
+
+ return text;
+ }
+
+ /// <summary>Reads all the characters from the current position to the end of the reader and returns them as a string.</summary>
+ /// <returns>A string containing all the characters from the current position to the end of the reader.</returns>
+ /// <exception cref="ObjectDisposedException">The <see cref="TextReader"/> is closed.</exception>
+ public override string ReadToEnd()
+ {
+ if (_currentPosition == -1)
+ throw new ObjectDisposedException("TextSnapshotToTextReader");
+
+ string text = _snapshot.GetText(_currentPosition, _snapshot.Length - _currentPosition);
+ _currentPosition = _snapshot.Length;
+
+ return text;
+ }
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="TextSnapshotToTextReader"/> with the specified text snapshot.
+ /// </summary>
+ /// <param name="textSnapshot">The <see cref="ITextSnapshot"/> to expose as a reader.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="textSnapshot"/> is null.</exception>
+ public TextSnapshotToTextReader(ITextSnapshot textSnapshot)
+ {
+ if (textSnapshot == null)
+ throw new ArgumentNullException("textSnapshot");
+
+ _snapshot = textSnapshot;
+ }
+
+ ITextSnapshot _snapshot;
+ int _currentPosition;
+ bool _readLastLine;
+ }
+}
diff --git a/src/Text/Def/TextData/Model/Tracking.cs b/src/Text/Def/TextData/Model/Tracking.cs
new file mode 100644
index 0000000..8c94cff
--- /dev/null
+++ b/src/Text/Def/TextData/Model/Tracking.cs
@@ -0,0 +1,378 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Microsoft.VisualStudio.Text
+{
+ public static class Tracking
+ {
+ /// <summary>
+ /// Track a position forward in time using forward fidelity.
+ /// </summary>
+ public static int TrackPositionForwardInTime(PointTrackingMode trackingMode,
+ int currentPosition,
+ ITextVersion currentVersion,
+ ITextVersion targetVersion)
+ {
+ if (trackingMode < PointTrackingMode.Positive || trackingMode > PointTrackingMode.Negative)
+ {
+ throw new ArgumentOutOfRangeException("trackingMode");
+ }
+ if (currentVersion == null)
+ {
+ throw new ArgumentNullException("currentVersion");
+ }
+ if (targetVersion == null)
+ {
+ throw new ArgumentNullException("targetVersion");
+ }
+ if (targetVersion.TextBuffer != currentVersion.TextBuffer)
+ {
+ throw new ArgumentException("currentVersion and targetVersion must be from the same ITextBuffer");
+ }
+ if (targetVersion.VersionNumber < currentVersion.VersionNumber)
+ {
+ throw new ArgumentOutOfRangeException("targetVersion");
+ }
+ if (currentPosition < 0 || currentPosition > currentVersion.Length)
+ {
+ throw new ArgumentOutOfRangeException("currentPosition");
+ }
+
+ // track forward in time
+ while (currentVersion != targetVersion)
+ {
+ int changeCount = currentVersion.Changes.Count;
+
+ // perform binary search over the old text (deleted) ranges
+ int lo = 0;
+ int hi = changeCount - 1;
+ while (lo <= hi)
+ {
+ int mid = (lo + hi) / 2;
+ ITextChange textChange = currentVersion.Changes[mid];
+ if (currentPosition < textChange.OldPosition)
+ {
+ hi = mid - 1;
+ }
+ else if (currentPosition > textChange.OldEnd)
+ {
+ lo = mid + 1;
+ }
+ else
+ {
+ // currentPosition lies within or on the edge of
+ // text deleted by the change
+ if (IsOpaque(textChange))
+ {
+ int offset = currentPosition - textChange.OldPosition;
+
+ if (offset > 0)
+ {
+ if ((offset >= textChange.OldLength) || (offset >= textChange.NewLength))
+ {
+ offset = textChange.NewLength;
+ }
+ else if (ShouldOffsetEndpointOfChange(textChange, offset, isForwardTracking: true))
+ {
+ // Shift offset to the front of the \r\n
+ --offset;
+ }
+ }
+
+ currentPosition = textChange.NewPosition + offset;
+ }
+ else
+ {
+ if (trackingMode == PointTrackingMode.Positive)
+ {
+ currentPosition = textChange.NewEnd;
+ }
+ else
+ {
+ currentPosition = textChange.NewPosition;
+ }
+ }
+ break;
+ }
+ }
+
+ if (hi < lo)
+ {
+ // currentPosition is outside all changes.
+ Debug.Assert(hi == lo - 1);
+ if (lo > 0)
+ {
+ // currentPosition is to the right of Changes[hi]
+ ITextChange textChange = currentVersion.Changes[hi];
+ currentPosition += (textChange.NewEnd - textChange.OldEnd);
+ }
+ }
+
+ currentVersion = currentVersion.Next;
+ }
+
+ Debug.Assert(currentPosition >= 0 && currentPosition <= currentVersion.Length);
+ return currentPosition;
+ }
+
+ /// <summary>
+ /// Returns true if endpoint of a change lands in between a \r\n sequence and so needs to be offsetted.
+ /// </summary>
+ private static bool ShouldOffsetEndpointOfChange(ITextChange textChange, int offset, bool isForwardTracking)
+ {
+ var textChange3 = textChange as ITextChange3;
+ if (isForwardTracking)
+ {
+ if (textChange3 == null)
+ {
+ Debug.Fail("ITextChange implementation unexpectedly doesn't implement ITextChange3.");
+ return (textChange.NewText[offset] == '\n') && (textChange.NewText[offset - 1] == '\r') &&
+ // Don't let the translated point land in-between a \r\n (unless it started there)
+ ((textChange.OldText[offset] != '\n') || (textChange.OldText[offset - 1] != '\r'));
+ }
+
+ // We want to avoid a situation where, when translating a point across an opaque change,
+ // we have it land in the middle of a \r\n (this can break the elision buffer if the point in
+ // question is the endpoint of an elided span).
+ // This test basically says that if a point lands between a \r\n in the new snapshot but didn’t
+ // start between a \r\n in the old snapshot, we will offset it by one to avoid the problem.
+ return (textChange3.GetNewTextAt(offset) == '\n') && (textChange3.GetNewTextAt(offset - 1) == '\r') &&
+ // Don't let the translated point land in-between a \r\n (unless it started there)
+ ((textChange3.GetOldTextAt(offset) != '\n') || (textChange3.GetOldTextAt(offset - 1) != '\r'));
+ }
+ else
+ {
+ // Backward in time tracking
+
+ if (textChange3 == null)
+ {
+ Debug.Fail("ITextChange implementation unexpectedly doesn't implement ITextChange3.");
+ return (textChange.OldText[offset] == '\n') && (textChange.OldText[offset - 1] == '\r') &&
+ // Don't let the translated point land in-between a \r\n (unless it started there)
+ ((textChange.NewText[offset] != '\n') || (textChange.NewText[offset - 1] != '\r'));
+ }
+
+ return (textChange3.GetOldTextAt(offset) == '\n') && (textChange3.GetOldTextAt(offset - 1) == '\r') &&
+ // Don't let the translated point land in-between a \r\n (unless it started there)
+ ((textChange3.GetNewTextAt(offset) != '\n') || (textChange3.GetNewTextAt(offset - 1) != '\r'));
+ }
+ }
+
+ /// <summary>
+ /// Track a position backward in time using forward fidelity.
+ /// </summary>
+ public static int TrackPositionBackwardInTime(PointTrackingMode trackingMode,
+ int currentPosition,
+ ITextVersion currentVersion,
+ ITextVersion targetVersion)
+ {
+ if (trackingMode < PointTrackingMode.Positive || trackingMode > PointTrackingMode.Negative)
+ {
+ throw new ArgumentOutOfRangeException("trackingMode");
+ }
+ if (currentVersion == null)
+ {
+ throw new ArgumentNullException("currentVersion");
+ }
+ if (targetVersion == null)
+ {
+ throw new ArgumentNullException("targetVersion");
+ }
+ if (targetVersion.TextBuffer != currentVersion.TextBuffer)
+ {
+ throw new ArgumentException("currentVersion and targetVersion must be from the same ITextBuffer");
+ }
+ if (targetVersion.VersionNumber > currentVersion.VersionNumber)
+ {
+ throw new ArgumentOutOfRangeException("targetVersion");
+ }
+ if (currentPosition < 0 || currentPosition > currentVersion.Length)
+ {
+ throw new ArgumentOutOfRangeException("currentPosition");
+ }
+
+ // track backwards in time
+ IList<ITextChange>[] textChangesStack = new IList<ITextChange>[currentVersion.VersionNumber - targetVersion.VersionNumber];
+ int top = 0;
+ {
+ ITextVersion roverVersion = targetVersion;
+ while (roverVersion != currentVersion)
+ {
+ textChangesStack[top++] = roverVersion.Changes;
+ roverVersion = roverVersion.Next;
+ }
+ }
+
+ while (top > 0)
+ {
+ IList<ITextChange> textChanges = textChangesStack[--top];
+
+ // perform binary search over the old text (deleted) ranges
+ int lo = 0;
+ int hi = textChanges.Count - 1;
+ while (lo <= hi)
+ {
+ int mid = (lo + hi) / 2;
+ ITextChange textChange = textChanges[mid];
+ if (currentPosition < textChange.NewPosition)
+ {
+ hi = mid - 1;
+ }
+ else if (currentPosition > textChange.NewEnd)
+ {
+ lo = mid + 1;
+ }
+ else
+ {
+ // currentPosition lies within or on the edge of
+ // text deleted by the change
+ if (IsOpaque(textChange))
+ {
+ int offset = currentPosition - textChange.NewPosition;
+
+ if (offset > 0)
+ {
+ if ((offset >= textChange.OldLength) || (offset >= textChange.NewLength))
+ {
+ offset = textChange.OldLength;
+ }
+ else if (ShouldOffsetEndpointOfChange(textChange, offset, isForwardTracking: false))
+ {
+ // Shift offset to the front of the \r\n
+ --offset;
+ }
+ }
+
+ currentPosition = textChange.OldPosition + offset;
+ }
+ else
+ {
+ if (trackingMode == PointTrackingMode.Positive)
+ {
+ currentPosition = textChange.OldEnd;
+ }
+ else
+ {
+ currentPosition = textChange.OldPosition;
+ }
+ }
+ break;
+ }
+ }
+
+ if (hi < lo)
+ {
+ // currentPosition is outside all changes.
+ Debug.Assert(hi == lo - 1);
+ if (lo > 0)
+ {
+ // currentPosition is to the right of Changes[hi]
+ ITextChange textChange = textChanges[hi];
+ currentPosition += (textChange.OldEnd - textChange.NewEnd);
+ }
+ }
+ }
+
+ return currentPosition;
+ }
+
+ /// <summary>
+ /// Track a span forward in time using forward fidelity.
+ /// </summary>
+ public static Span TrackSpanForwardInTime(SpanTrackingMode trackingMode, Span span, ITextVersion currentVersion, ITextVersion targetVersion)
+ {
+ if (trackingMode < SpanTrackingMode.EdgeExclusive || trackingMode > SpanTrackingMode.Custom)
+ {
+ throw new ArgumentOutOfRangeException("trackingMode");
+ }
+ if (currentVersion == null)
+ {
+ throw new ArgumentNullException("currentVersion");
+ }
+ if (targetVersion == null)
+ {
+ throw new ArgumentNullException("targetVersion");
+ }
+ if (targetVersion.TextBuffer != currentVersion.TextBuffer)
+ {
+ throw new ArgumentException("currentVersion and targetVersion must be from the same ITextBuffer");
+ }
+ if (span.End > currentVersion.Length)
+ {
+ throw new ArgumentOutOfRangeException("span");
+ }
+ if (targetVersion.VersionNumber < currentVersion.VersionNumber)
+ {
+ throw new ArgumentOutOfRangeException("targetVersion");
+ }
+
+ int resultStart =
+ TrackPositionForwardInTime
+ ((trackingMode == SpanTrackingMode.EdgeExclusive || trackingMode == SpanTrackingMode.EdgePositive)
+ ? PointTrackingMode.Positive
+ : PointTrackingMode.Negative, span.Start, currentVersion, targetVersion);
+
+ int resultEnd =
+ TrackPositionForwardInTime
+ ((trackingMode == SpanTrackingMode.EdgeExclusive || trackingMode == SpanTrackingMode.EdgeNegative)
+ ? PointTrackingMode.Negative
+ : PointTrackingMode.Positive, span.End, currentVersion, targetVersion);
+
+ return Span.FromBounds(resultStart, System.Math.Max(resultStart, resultEnd));
+ }
+
+ /// <summary>
+ /// Track a span backward in time using forward fidelity.
+ /// </summary>
+ public static Span TrackSpanBackwardInTime(SpanTrackingMode trackingMode, Span span, ITextVersion currentVersion, ITextVersion targetVersion)
+ {
+ if (trackingMode < SpanTrackingMode.EdgeExclusive || trackingMode > SpanTrackingMode.Custom)
+ {
+ throw new ArgumentOutOfRangeException("trackingMode");
+ }
+ if (currentVersion == null)
+ {
+ throw new ArgumentNullException("currentVersion");
+ }
+ if (targetVersion == null)
+ {
+ throw new ArgumentNullException("targetVersion");
+ }
+ if (targetVersion.TextBuffer != currentVersion.TextBuffer)
+ {
+ throw new ArgumentException("currentVersion and targetVersion must be from the same ITextBuffer");
+ }
+ if (span.End > currentVersion.Length)
+ {
+ throw new ArgumentOutOfRangeException("span");
+ }
+ if (targetVersion.VersionNumber > currentVersion.VersionNumber)
+ {
+ throw new ArgumentOutOfRangeException("targetVersion");
+ }
+
+ int resultStart =
+ TrackPositionBackwardInTime
+ ((trackingMode == SpanTrackingMode.EdgeExclusive || trackingMode == SpanTrackingMode.EdgePositive)
+ ? PointTrackingMode.Positive
+ : PointTrackingMode.Negative,
+ span.Start, currentVersion, targetVersion);
+
+ int resultEnd =
+ TrackPositionBackwardInTime
+ ((trackingMode == SpanTrackingMode.EdgeExclusive || trackingMode == SpanTrackingMode.EdgeNegative)
+ ? PointTrackingMode.Negative
+ : PointTrackingMode.Positive,
+ span.End, currentVersion, targetVersion);
+
+ return Span.FromBounds(resultStart, System.Math.Max(resultStart, resultEnd));
+ }
+
+ private static bool IsOpaque(ITextChange textChange)
+ {
+ ITextChange2 tc2 = textChange as ITextChange2;
+ return tc2 != null && tc2.IsOpaque;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextData/Model/TrackingFidelityMode.cs b/src/Text/Def/TextData/Model/TrackingFidelityMode.cs
new file mode 100644
index 0000000..5e42b25
--- /dev/null
+++ b/src/Text/Def/TextData/Model/TrackingFidelityMode.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ /// <summary>
+ /// Represents special tracking behaviors for <see cref="ITrackingPoint"/> and <see cref="ITrackingSpan"/> objects.
+ /// </summary>
+ public enum TrackingFidelityMode
+ {
+ /// <summary>
+ /// When moving back to a previous version (either by explicitly
+ /// moving to that version or by undo or redo operations), the result may be different from the result
+ /// that was originally given for that version. This mode is suitable for most purposes,
+ /// and is the most space-efficient mode.
+ /// </summary>
+ Forward,
+
+ /// <summary>
+ /// When mapping back to a previous version, the result is the same as the result from
+ /// mapping forward from the origin version. This mode should be used only
+ /// for short-lived points and spans.
+ /// </summary>
+ Backward,
+
+ /// <summary>
+ /// When mapping to a version that is the result of undo
+ /// or redo operations, the result will be the same as the result from mapping forward to the
+ /// version of which the undo or redo is a reiteration. This mode is more
+ /// expensive than <see cref="Forward"/> in both space and time and should be used only
+ /// if necessary.
+ /// </summary>
+ UndoRedo
+ }
+}
diff --git a/src/Text/Def/TextData/Strings.Designer.cs b/src/Text/Def/TextData/Strings.Designer.cs
new file mode 100644
index 0000000..685568f
--- /dev/null
+++ b/src/Text/Def/TextData/Strings.Designer.cs
@@ -0,0 +1,171 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.11002.0
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Microsoft.VisualStudio.Text {
+ 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 Strings {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Strings() {
+ }
+
+ /// <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("Microsoft.VisualStudio.Text.Strings", typeof(Strings).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 The array is not one-dimensional..
+ /// </summary>
+ internal static string ArrayRankNotOne {
+ get {
+ return ResourceManager.GetString("ArrayRankNotOne", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to Circularity detected in text buffer version..
+ /// </summary>
+ internal static string CircularityInBufferVersion {
+ get {
+ return ResourceManager.GetString("CircularityInBufferVersion", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The specified ITextSnapshot doesn&apos;t belong to the correct TextBuffer..
+ /// </summary>
+ internal static string InvalidSnapshot {
+ get {
+ return ResourceManager.GetString("InvalidSnapshot", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The specified SnapshotPoint is on a different ITextSnapshot than this SnapshotPoint..
+ /// </summary>
+ internal static string InvalidSnapshotPoint {
+ get {
+ return ResourceManager.GetString("InvalidSnapshotPoint", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The specified SnapshotPoint or SnapshotSpan is on a different ITextSnapshot than this SnapshotSpan..
+ /// </summary>
+ internal static string InvalidSnapshotSpan {
+ get {
+ return ResourceManager.GetString("InvalidSnapshotSpan", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The specified SnapshotPoints belong to different ITextSnapshots..
+ /// </summary>
+ internal static string MismatchedSnapshotPoints {
+ get {
+ return ResourceManager.GetString("MismatchedSnapshotPoints", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The collections refer to different snapshots..
+ /// </summary>
+ internal static string MismatchedSnapshots {
+ get {
+ return ResourceManager.GetString("MismatchedSnapshots", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The TextVersions do not belong to the same TextBuffer..
+ /// </summary>
+ internal static string MismatchedVersions {
+ get {
+ return ResourceManager.GetString("MismatchedVersions", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The specified NormalizedSnapshotSpanCollection extends beyond the end of the TextSnapshot..
+ /// </summary>
+ internal static string SpansBeyondEnd {
+ get {
+ return ResourceManager.GetString("SpansBeyondEnd", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The SnapshotPoint is not initialized..
+ /// </summary>
+ internal static string UninitializedSnapshotPoint {
+ get {
+ return ResourceManager.GetString("UninitializedSnapshotPoint", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The SnapshotSpan is not initialized..
+ /// </summary>
+ internal static string UninitializedSnapshotSpan {
+ get {
+ return ResourceManager.GetString("UninitializedSnapshotSpan", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to The specified TextVersion does not belong to the specified TextBuffer..
+ /// </summary>
+ internal static string VersionDoesNotBelongToBuffer {
+ get {
+ return ResourceManager.GetString("VersionDoesNotBelongToBuffer", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/src/Text/Def/TextData/Strings.resx b/src/Text/Def/TextData/Strings.resx
new file mode 100644
index 0000000..0d3870e
--- /dev/null
+++ b/src/Text/Def/TextData/Strings.resx
@@ -0,0 +1,156 @@
+<?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="CircularityInBufferVersion" xml:space="preserve">
+ <value>Circularity detected in text buffer version.</value>
+ </data>
+ <data name="VersionDoesNotBelongToBuffer" xml:space="preserve">
+ <value>The specified TextVersion does not belong to the specified TextBuffer.</value>
+ </data>
+ <data name="InvalidSnapshot" xml:space="preserve">
+ <value>The specified ITextSnapshot doesn't belong to the correct TextBuffer.</value>
+ </data>
+ <data name="InvalidSnapshotSpan" xml:space="preserve">
+ <value>The specified SnapshotPoint or SnapshotSpan is on a different ITextSnapshot than this SnapshotSpan.</value>
+ </data>
+ <data name="MismatchedVersions" xml:space="preserve">
+ <value>The TextVersions do not belong to the same TextBuffer.</value>
+ </data>
+ <data name="UninitializedSnapshotPoint" xml:space="preserve">
+ <value>The SnapshotPoint is not initialized.</value>
+ </data>
+ <data name="UninitializedSnapshotSpan" xml:space="preserve">
+ <value>The SnapshotSpan is not initialized.</value>
+ </data>
+ <data name="MismatchedSnapshots" xml:space="preserve">
+ <value>The collections refer to different snapshots.</value>
+ </data>
+ <data name="SpansBeyondEnd" xml:space="preserve">
+ <value>The specified NormalizedSnapshotSpanCollection extends beyond the end of the TextSnapshot.</value>
+ </data>
+ <data name="ArrayRankNotOne" xml:space="preserve">
+ <value>The array is not one-dimensional.</value>
+ </data>
+ <data name="InvalidSnapshotPoint" xml:space="preserve">
+ <value>The specified SnapshotPoint is on a different ITextSnapshot than this SnapshotPoint.</value>
+ </data>
+ <data name="MismatchedSnapshotPoints" xml:space="preserve">
+ <value>The specified SnapshotPoints belong to different ITextSnapshots.</value>
+ </data>
+</root>
diff --git a/src/Text/Def/TextData/TextData.csproj b/src/Text/Def/TextData/TextData.csproj
new file mode 100644
index 0000000..a9eef46
--- /dev/null
+++ b/src/Text/Def/TextData/TextData.csproj
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="BuildProps">
+ <BuildPropsFile>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), Build.props))\Build.props</BuildPropsFile>
+ </PropertyGroup>
+ <Import Project="$(BuildPropsFile)" Condition="'$(BuildProps_Imported)'!='True' AND Exists('$(BuildPropsFile)') AND '$(VisualStudioDir)'==''" />
+ <Import Project="..\Platform.Settings.targets" />
+ <Import Project="$(PlatformPath)\Tools\Targets\Platform.Settings.Selector.targets" />
+ <PropertyGroup>
+ <AssemblyName>Microsoft.VisualStudio.Text.Data</AssemblyName>
+ <RootNamespace>Microsoft.VisualStudio.Text</RootNamespace>
+ <OutputPath>$(BinariesDirectory)\bin\$(BuildArchitecture)</OutputPath>
+ <OutputType>Library</OutputType>
+ <SignAssemblyAttribute>true</SignAssemblyAttribute>
+ <UseVsVersion>true</UseVsVersion>
+ <AssemblyAttributeClsCompliant>true</AssemblyAttributeClsCompliant>
+ <GenerateAssemblyRefs>true</GenerateAssemblyRefs>
+ <NoWarn>649;436;$(NoWarn)</NoWarn>
+ <GeneratedModuleId>Microsoft.VisualStudio.Text.Data</GeneratedModuleId>
+ <GeneratedModuleVersion>$(VsAssemblyVersion)</GeneratedModuleVersion>
+ <BuildArchitecturesAllowed>$(BuildArchitecturesAllowed);amd64;arm</BuildArchitecturesAllowed>
+ </PropertyGroup>
+ <!-- IDE specific Information -->
+ <PropertyGroup>
+ <ProjectGuid>{80A00E91-51E5-471C-80BA-0D863987ECC7}</ProjectGuid>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="AssemblyInfo.cs" />
+ <Compile Include="Differencing\ContinueProcessingPredicate.cs" />
+ <Compile Include="Differencing\Deprecated\DetermineLocalityCallback.cs" />
+ <Compile Include="Differencing\Difference.cs" />
+ <Compile Include="Differencing\DifferenceType.cs" />
+ <Compile Include="Differencing\IDifferenceService.cs" />
+ <Compile Include="Differencing\IHierarchicalDifferenceCollection.cs" />
+ <Compile Include="Differencing\IDifferenceCollection.cs" />
+ <Compile Include="Differencing\Deprecated\IHierarchicalStringDifferenceService.cs" />
+ <Compile Include="Differencing\ITextDifferencingSelectorService.cs" />
+ <Compile Include="Differencing\ITextDifferencingService.cs" />
+ <Compile Include="Differencing\ITokenizedStringList.cs" />
+ <Compile Include="Differencing\Match.cs" />
+ <Compile Include="Differencing\StringDifferenceTypes.cs" />
+ <Compile Include="Differencing\StringDifferenceOptions.cs" />
+ <Compile Include="Differencing\WordSplitBehavior.cs" />
+ <Compile Include="Document\EncodingChangedEventArgs.cs" />
+ <Compile Include="Document\FileUtilities.cs" />
+ <Compile Include="Document\IEncodingDetector.cs" />
+ <Compile Include="Document\ITextDocument.cs" />
+ <Compile Include="Document\ITextDocumentFactoryService.cs" />
+ <Compile Include="Document\ReloadResult.cs" />
+ <Compile Include="Document\TextDocumentEventArgs.cs" />
+ <Compile Include="Document\TextDocumentFileActionEventArgs.cs" />
+ <Compile Include="FxCopSuppressions.cs" />
+ <Compile Include="Model\ContentTypeChangedEventArgs.cs" />
+ <Compile Include="Model\CustomTrackToVersion.cs" />
+ <Compile Include="Model\EdgeInsertionMode.cs" />
+ <Compile Include="Model\EditOptions.cs" />
+ <Compile Include="Model\IExtensionErrorHandler.cs" />
+ <Compile Include="Model\IExtensionPerformanceTracker.cs" />
+ <Compile Include="Model\IMappingPoint.cs" />
+ <Compile Include="Model\IMappingSpan.cs" />
+ <Compile Include="Model\INormalizedTextChangeCollection.cs" />
+ <Compile Include="Model\IPersistentSpan.cs" />
+ <Compile Include="Model\IPersistentSpanFactory.cs" />
+ <Compile Include="Model\IReadOnlyRegion.cs" />
+ <Compile Include="Model\IReadOnlyRegionEdit.cs" />
+ <Compile Include="Model\ITextBuffer.cs" />
+ <Compile Include="Model\ITextBufferEdit.cs" />
+ <Compile Include="Model\ITextBufferFactory.cs" />
+ <Compile Include="Model\ITextChange.cs" />
+ <Compile Include="Model\ITextChange2.cs" />
+ <Compile Include="Model\ITextChange3.cs" />
+ <Compile Include="Model\ITextEdit.cs" />
+ <Compile Include="Model\ITextSnapshot.cs" />
+ <Compile Include="Model\ITextSnapshotLine.cs" />
+ <Compile Include="Model\ITextVersion.cs" />
+ <Compile Include="Model\ITrackingPoint.cs" />
+ <Compile Include="Model\ITrackingSpan.cs" />
+ <Compile Include="Model\NormalizedSnapshotSpanCollection.cs" />
+ <Compile Include="Model\NormalizedSpanCollection.cs" />
+ <Compile Include="Model\PointTrackingMode.cs" />
+ <Compile Include="Model\PositionAffinity.cs" />
+ <Compile Include="Model\PreContentChangedEventArgs.cs" />
+ <Compile Include="Model\Projection\ElisionBufferOptions.cs" />
+ <Compile Include="Model\Projection\ElisionSourceSpansChangedEventArgs.cs" />
+ <Compile Include="Model\Projection\GraphBufferContentTypeChangedEventArgs.cs" />
+ <Compile Include="Model\Projection\GraphBuffersChangedEventArgs.cs" />
+ <Compile Include="Model\Projection\IBufferGraph.cs" />
+ <Compile Include="Model\Projection\IBufferGraphFactoryService.cs" />
+ <Compile Include="Model\Projection\IElisionBuffer.cs" />
+ <Compile Include="Model\Projection\IElisionSnapshot.cs" />
+ <Compile Include="Model\Projection\IProjectionBuffer.cs" />
+ <Compile Include="Model\Projection\IProjectionBufferBase.cs" />
+ <Compile Include="Model\Projection\IProjectionBufferFactoryService.cs" />
+ <Compile Include="Model\Projection\IProjectionEditResolver.cs" />
+ <Compile Include="Model\Projection\IProjectionSnapshot.cs" />
+ <Compile Include="Model\Projection\IProjectionSnapshot2.cs" />
+ <Compile Include="Model\Projection\ProjectionBufferOptions.cs" />
+ <Compile Include="Model\Projection\ProjectionSourceBuffersChangedEventArgs.cs" />
+ <Compile Include="Model\Projection\ProjectionSourceSpansChangedEventArgs.cs" />
+ <Compile Include="Model\DynamicReadOnlyRegionQuery.cs" />
+ <Compile Include="Model\SnapshotPoint.cs" />
+ <Compile Include="Model\SnapshotSpan.cs" />
+ <Compile Include="Model\SnapshotSpanEventArgs.cs" />
+ <Compile Include="Model\Span.cs" />
+ <Compile Include="Model\SpanTrackingMode.cs" />
+ <Compile Include="Model\TextBufferCreatedEventArgs.cs" />
+ <Compile Include="Model\TextContentChangedEventArgs.cs" />
+ <Compile Include="Model\TextContentChangingEventArgs.cs" />
+ <Compile Include="Model\TextSnapshotChangedEventArgs.cs" />
+ <Compile Include="Model\TextSnapshotToTextReader.cs" />
+ <Compile Include="Model\Tracking.cs" />
+ <Compile Include="Model\TrackingFidelityMode.cs" />
+ <Reference Include="System" />
+ <CopyFile Include="Model\Microsoft.VisualStudio.Text.Model.Overview.mht">
+ <DestFolder>$(SuiteBinPath)\PlatformOverviews</DestFolder>
+ <Visible>false</Visible>
+ </CopyFile>
+ <EmbeddedResource Include="Strings.resx">
+ <SubType>Designer</SubType>
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Strings.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <Compile Include="Strings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Strings.resx</DependentUpon>
+ </Compile>
+ <ProjectReference Include="..\..\..\Core\Def\CoreUtility.csproj">
+ <Project>{BA3DD7EC-3F13-4400-A3A9-96AD425B3369}</Project>
+ <Name>CoreUtility</Name>
+ </ProjectReference>
+ <None Include="Diagrams\*.cd" />
+ </ItemGroup>
+ <ItemGroup>
+ <PublishPartLinked Include="$(OutputPath)\$(AssemblyName).dll">
+ <Visibility>Inter</Visibility>
+ <FileType>Reference</FileType>
+ <DoNotCopyPDB>true</DoNotCopyPDB>
+ </PublishPartLinked>
+ </ItemGroup>
+ <!--Import the targets-->
+ <Import Project="$(PlatformPath)\Tools\Targets\Platform.Imports.targets" />
+ <PropertyGroup>
+ <CopyToSuiteBin>true</CopyToSuiteBin>
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/src/Text/Def/TextDef.fxcop b/src/Text/Def/TextDef.fxcop
new file mode 100644
index 0000000..735a40b
--- /dev/null
+++ b/src/Text/Def/TextDef.fxcop
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FxCopProject Version="1.32" Name="My FxCop Project">
+ <ProjectOptions>
+ <SharedProject>True</SharedProject>
+ <Stylesheet Apply="False">http://fxcop/xsl/1.32/FxCopReport.xsl</Stylesheet>
+ <SaveMessages>
+ <Project Status="Active, Excluded" NewOnly="False" />
+ <Report Status="Active" NewOnly="False" />
+ </SaveMessages>
+ <ProjectFile Compress="True" DefaultTargetCheck="True" DefaultRuleCheck="True" SaveByRuleGroup="" Deterministic="True" />
+ <EnableMultithreadedLoad>True</EnableMultithreadedLoad>
+ <EnableMultithreadedAnalysis>True</EnableMultithreadedAnalysis>
+ <SourceLookup>True</SourceLookup>
+ <AnalysisExceptionsThreshold>100</AnalysisExceptionsThreshold>
+ <RuleExceptionsThreshold>10</RuleExceptionsThreshold>
+ <Spelling Locale="en-us" />
+ <VersionAware>False</VersionAware>
+ <OverrideRuleVisibilities>False</OverrideRuleVisibilities>
+ <CustomDictionaries SearchFxCopDir="True" SearchUserProfile="True" SearchProjectDir="True" />
+ </ProjectOptions>
+ <Targets>
+ <AssemblyReferenceDirectories>
+ <Directory>%VSPATH%</Directory>
+ <Directory>%programfiles%\Reference Assemblies\Microsoft\WinFX\v3.0\</Directory>
+ <Directory>%windir%\WinFX\v3.0\WPF\</Directory>
+ </AssemblyReferenceDirectories>
+ <Target Name="%VSPATH%\Microsoft.VisualStudio.Data.Text.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="%VSPATH%\Microsoft.VisualStudio.Data.Text.Projection.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="%VSPATH%\Microsoft.VisualStudio.Logic.Text.Classification.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="%VSPATH%\Microsoft.VisualStudio.Logic.Text.Navigation.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="%VSPATH%\Microsoft.VisualStudio.Logic.Text.Undo.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="%VSPATH%\Microsoft.VisualStudio.UI.Text.Adornment.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="%VSPATH%\Microsoft.VisualStudio.UI.Text.AdornmentLibrary.Breakpoint.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="%VSPATH%/Microsoft.VisualStudio.UI.Text.AdornmentLibrary.TextMarker.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="%VSPATH%\Microsoft.VisualStudio.UI.Text.Wpf.AdornmentSurface.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="%VSPATH%\Microsoft.VisualStudio.UI.Text.Wpf.AdornmentSurfaceManager.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="%VSPATH%\Microsoft.VisualStudio.UI.Text.Wpf.Classification.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="%VSPATH%\Microsoft.VisualStudio.UI.Text.Wpf.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="%VSPATH%\Microsoft.VisualStudio.UI.Text.Wpf.InputBinding.dll" Analyze="True" AnalyzeAllChildren="True" />
+ <Target Name="$(ProjectDir)/../../../Output/debug/bin/Microsoft.VisualStudio.UI.Text.View.dll" Analyze="True" AnalyzeAllChildren="True" />
+ </Targets>
+ <Rules>
+ <RuleFiles>
+ <RuleFile Name="$(FxCopDir)\Rules\DesignRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\GlobalizationRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\InteroperabilityRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\MaintainabilityRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\MobilityRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\MSInternalRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\NamingRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\PerformanceRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\PortabilityRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\ReliabilityRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\SecurityRules.dll" Enabled="True" AllRulesEnabled="True" />
+ <RuleFile Name="$(FxCopDir)\Rules\UsageRules.dll" Enabled="True" AllRulesEnabled="True" />
+ </RuleFiles>
+ <Groups />
+ <Settings />
+ </Rules>
+ <FxCopReport Version="1.32" />
+</FxCopProject>
diff --git a/src/Text/Def/TextLogic/AssemblyInfo.cs b/src/Text/Def/TextLogic/AssemblyInfo.cs
new file mode 100644
index 0000000..d7ef5a3
--- /dev/null
+++ b/src/Text/Def/TextLogic/AssemblyInfo.cs
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+using System.Reflection;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+using System.Security.Permissions;
+
+//
+// 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: ComponentGuarantees(ComponentGuaranteesOptions.Stable)]
+
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+#pragma warning disable 618
+[assembly: SecurityPermission (SecurityAction.RequestMinimum, Flags = SecurityPermissionFlag.Execution)]
+#pragma warning restore 618
+[assembly: ReliabilityContract(Consistency.MayCorruptProcess, Cer.MayFail)]
diff --git a/src/Text/Def/TextLogic/Classification/ClassificationChangedEventArgs.cs b/src/Text/Def/TextLogic/Classification/ClassificationChangedEventArgs.cs
new file mode 100644
index 0000000..d1fbdcb
--- /dev/null
+++ b/src/Text/Def/TextLogic/Classification/ClassificationChangedEventArgs.cs
@@ -0,0 +1,34 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Classification
+{
+ using System;
+
+ /// <summary>
+ /// Provides information for the <see cref="IClassifier.ClassificationChanged"/> event.
+ /// </summary>
+ public class ClassificationChangedEventArgs : EventArgs
+ {
+ SnapshotSpan changeSpan;
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="ClassificationChangedEventArgs"/> object.
+ /// </summary>
+ /// <param name="changeSpan">
+ /// The span of the classification that changed.
+ /// </param>
+ public ClassificationChangedEventArgs(SnapshotSpan changeSpan)
+ {
+ this.changeSpan = changeSpan;
+ }
+
+ /// <summary>
+ /// Gets the span of the classification that changed.
+ /// </summary>
+ public SnapshotSpan ChangeSpan
+ {
+ get { return this.changeSpan; }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/Classification/ClassificationSpan.cs b/src/Text/Def/TextLogic/Classification/ClassificationSpan.cs
new file mode 100644
index 0000000..6b22864
--- /dev/null
+++ b/src/Text/Def/TextLogic/Classification/ClassificationSpan.cs
@@ -0,0 +1,54 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Classification
+{
+ using System;
+
+ /// <summary>
+ /// Describes a region of text by an <see cref="IClassificationType"/>.
+ /// </summary>
+ /// <remarks>
+ /// This class is immutable.
+ /// </remarks>
+ public class ClassificationSpan
+ {
+ SnapshotSpan span;
+ IClassificationType classification;
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="ClassificationSpan"/>.
+ /// </summary>
+ /// <param name="span">The span of text to which the classification applies.</param>
+ /// <param name="classification">
+ /// The classification type of the span.
+ /// </param>
+ /// <exception cref="ArgumentNullException"><paramref name="classification"/> is null.</exception>
+ public ClassificationSpan(SnapshotSpan span, IClassificationType classification)
+ {
+ if (classification == null)
+ {
+ throw new ArgumentNullException("classification");
+ }
+ this.span = span;
+ this.classification = classification;
+ }
+
+ /// <summary>
+ /// Gets the classification type of the text.
+ /// </summary>
+ public IClassificationType ClassificationType
+ {
+ get { return this.classification; }
+ }
+
+ /// <summary>
+ /// Gets the snapshot span of the classified text.
+ /// </summary>
+ public SnapshotSpan Span
+ {
+ get { return this.span; }
+ }
+
+ }
+}
diff --git a/src/Text/Def/TextLogic/Classification/ClassificationTypeAttribute.cs b/src/Text/Def/TextLogic/Classification/ClassificationTypeAttribute.cs
new file mode 100644
index 0000000..78a7add
--- /dev/null
+++ b/src/Text/Def/TextLogic/Classification/ClassificationTypeAttribute.cs
@@ -0,0 +1,57 @@
+// Copyright (C) Microsoft Corporation. All Rights Reserved.
+
+namespace Microsoft.VisualStudio.Text.Classification
+{
+ using System;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Used to declare the name for a logical classification
+ /// type and the name of a classification type from which it is derived.
+ /// </summary>
+ /// <remarks>
+ /// <para>This attribute is used to provide metadata for the <see cref="ClassificationTypeDefinition" /> MEF export.
+ /// The <see cref="IClassificationTypeRegistryService" /> service uses this to construct <see cref="IClassificationType"></see> objects.
+ /// </para>
+ /// <para>
+ /// This attribute can be stacked, so that a <see cref="IClassificationType"/> can multiply inherit from different base types.
+ /// </para>
+ /// </remarks>
+ /// <seealso cref="IClassificationType"/>
+ /// <seealso cref="IClassificationTypeRegistryService"/>
+ /// <seealso cref="ClassificationTypeDefinition"/>
+ public sealed class ClassificationTypeAttribute : MultipleBaseMetadataAttribute
+ {
+ private string _name;
+
+ /// <summary>
+ /// Gets or sets the name of this classification type.
+ /// </summary>
+ /// <remarks>
+ /// The name must be unique across all classification types. It cannot be null or
+ /// an empty string. Classification type names are case insensitive.
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">The value is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">The value is an empty string.</exception>
+ public string ClassificationTypeNames
+ {
+ get
+ {
+ return _name;
+ }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+ if (string.IsNullOrEmpty(value))
+ {
+ throw new ArgumentOutOfRangeException("value");
+ }
+
+ _name = value;
+ }
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Classification/ClassificationTypeDefinition.cs b/src/Text/Def/TextLogic/Classification/ClassificationTypeDefinition.cs
new file mode 100644
index 0000000..5db4ab4
--- /dev/null
+++ b/src/Text/Def/TextLogic/Classification/ClassificationTypeDefinition.cs
@@ -0,0 +1,25 @@
+// Copyright (C) Microsoft Corporation. All Rights Reserved.
+
+namespace Microsoft.VisualStudio.Text.Classification
+{
+ /// <summary>
+ /// Describes a data-only export for declaring classification types.
+ /// </summary>
+ /// <remarks>
+ /// Because you cannot subclass this type, you can use the [Export] attribute with no type.
+ /// </remarks>
+ /// <example>
+ /// internal sealed class Components
+ /// {
+ /// [Export]
+ /// [Name("keyword")] // required
+ /// [BaseDefinition("text")] // zero or more BaseDefinitions are allowed
+ /// internal ClassificationTypeDefinition keywordDefinition;
+ ///
+ /// { other components }
+ /// }
+ /// </example>
+ public sealed class ClassificationTypeDefinition
+ {
+ }
+}
diff --git a/src/Text/Def/TextLogic/Classification/IClassificationType.cs b/src/Text/Def/TextLogic/Classification/IClassificationType.cs
new file mode 100644
index 0000000..1275546
--- /dev/null
+++ b/src/Text/Def/TextLogic/Classification/IClassificationType.cs
@@ -0,0 +1,47 @@
+// ****************************************************************************
+// IClassificationType.cs
+// Copyright (C) Microsoft Corporation. All Rights Reserved.
+// ****************************************************************************
+
+namespace Microsoft.VisualStudio.Text.Classification
+{
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// The logical classification type of a span of text.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// All classification types are identified by a unique name.
+ /// The <see cref="IClassificationTypeRegistryService"></see> can return an <see cref="IClassificationType"/> object from this
+ /// unique name in order to allow clients to access additional information.
+ /// </para>
+ /// <para>
+ /// Classification types can multiply inherit by stacking <see cref="ClassificationTypeAttribute" /> attributes./>
+ /// </para>
+ /// </remarks>
+ public interface IClassificationType
+ {
+ /// <summary>
+ /// Gets the name of the classification type.
+ /// </summary>
+ /// <remarks>All classification types are identified by a unique name.
+ /// The <see cref="IClassificationTypeRegistryService"></see> can return an <see cref="IClassificationType"/> from this name.</remarks>
+ /// <value>This name is never <c>null</c>.</value>
+ string Classification { get; }
+
+ /// <summary>
+ /// Determines whether the current <see cref="IClassificationType"></see>
+ /// derives from the classification type named <paramref name="type"/>.
+ /// </summary>
+ /// <param name="type">The name of the base classification type.</param>
+ /// <returns><c>true</c> if the current classification type derives from the one identified by <paramref name="type"/>, otherwise <c>false</c>.</returns>
+ bool IsOfType(string type);
+
+ /// <summary>
+ /// Gets the classification types from which the current <see cref="IClassificationType"/> is derived.
+ /// </summary>
+ /// <value>This value is never <c>null</c>, though it may be the empty set.</value>
+ IEnumerable<IClassificationType> BaseTypes { get; }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Classification/IClassificationTypeRegistryService.cs b/src/Text/Def/TextLogic/Classification/IClassificationTypeRegistryService.cs
new file mode 100644
index 0000000..d7e18e9
--- /dev/null
+++ b/src/Text/Def/TextLogic/Classification/IClassificationTypeRegistryService.cs
@@ -0,0 +1,92 @@
+// ****************************************************************************
+// IClassificationTypeRegistryService.cs
+// Copyright (C) Microsoft Corporation. All Rights Reserved.
+// ****************************************************************************
+
+namespace Microsoft.VisualStudio.Text.Classification
+{
+ using System;
+ using System.Collections.Generic;
+ using System.ComponentModel.Composition;
+
+ /// <summary>
+ /// The service that maintains the collection of all known classification types.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IClassificationTypeRegistryService registry = null;
+ /// </remarks>
+ public interface IClassificationTypeRegistryService
+ {
+ /// <summary>
+ /// Gets the <see cref="IClassificationType"></see> object identified by the specified <paramref name="type"/>.
+ /// </summary>
+ /// <param name="type">
+ /// The name of the classification type.
+ /// </param>
+ /// <returns>
+ /// The classification type, <c>null</c> if there is no classification type of that name.
+ /// </returns>
+ IClassificationType GetClassificationType(string type);
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="IClassificationType"/> and adds it to the registry.
+ /// </summary>
+ /// <param name="type">The name of the classification type to create.</param>
+ /// <param name="baseTypes">The base types of the classification.</param>
+ /// <returns>A new <see cref="IClassificationType"/>.</returns>
+ /// <exception cref="InvalidOperationException"><paramref name="type"/> is already in the registry.</exception>
+ IClassificationType CreateClassificationType(string type, IEnumerable<IClassificationType> baseTypes);
+
+ /// <summary>
+ /// Creates an <see cref="IClassificationType"/> that persists only for the duration of
+ /// this session. This <see cref="IClassificationType"/> must inherit from at least one
+ /// <see cref="IClassificationType"/>.
+ /// </summary>
+ /// <param name="baseTypes">
+ /// The base types for this <see cref="IClassificationType"/>.
+ /// </param>
+ /// <returns>
+ /// A new <see cref="IClassificationType"/> that inherits from all of <paramref name="baseTypes"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="baseTypes"/> is null.</exception>
+ /// <exception cref="InvalidOperationException"><paramref name="baseTypes"/> has zero items.</exception>
+ /// <remarks>
+ /// <para>
+ /// This function is intended primarily to aid in the runtime display of overlapping classifications.
+ /// </para>
+ /// <para>
+ /// The classification names generated by this function are determined at run time and are subject to
+ /// change in future revisions. The only guarantee made is that if two transient <see cref="IClassificationType"/> objects
+ /// are created with the same base types, they will have the same classification name.
+ /// </para>
+ /// </remarks>
+ IClassificationType CreateTransientClassificationType(IEnumerable<IClassificationType> baseTypes);
+
+ /// <summary>
+ /// Creates an <see cref="IClassificationType"/> that persists only for the duration of
+ /// this session. This <see cref="IClassificationType"/> must inherit from at least one
+ /// <see cref="IClassificationType"/>.
+ /// </summary>
+ /// <param name="baseTypes">
+ /// The base types for this <see cref="IClassificationType"/>.
+ /// </param>
+ /// <returns>
+ /// A new <see cref="IClassificationType"/> which inherits from all <paramref name="baseTypes"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="baseTypes"/> is null.</exception>
+ /// <exception cref="InvalidOperationException"><paramref name="baseTypes"/> has zero items.</exception>
+ /// <remarks>
+ /// <para>
+ /// This function is intended primarily to aid in the runtime display of overlapping classifications.
+ /// </para>
+ ///
+ /// <para>
+ /// The classification names generated by this function are determined at run time and are subject to
+ /// change in future revisions. The only guarantee made is that if two transient <see cref="IClassificationType"/> objects
+ /// are created with the same base types, they will have the same classification name.
+ /// </para>
+ /// </remarks>
+ IClassificationType CreateTransientClassificationType(params IClassificationType[] baseTypes);
+ }
+}
diff --git a/src/Text/Def/TextLogic/Classification/IClassifier.cs b/src/Text/Def/TextLogic/Classification/IClassifier.cs
new file mode 100644
index 0000000..640281b
--- /dev/null
+++ b/src/Text/Def/TextLogic/Classification/IClassifier.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Classification
+{
+ using System;
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Assigns <see cref="IClassificationType"/> objects to the text in a <see cref="ITextBuffer"/>.
+ /// </summary>
+ public interface IClassifier
+ {
+ /// <summary>
+ /// Gets all the <see cref="ClassificationSpan"/> objects that intersect the given range of text.
+ /// </summary>
+ /// <param name="span">
+ /// The snapshot span.
+ /// </param>
+ /// <returns>
+ /// A list of <see cref="ClassificationSpan"/> objects that intersect with the given range.
+ /// </returns>
+ IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan span);
+
+ /// <summary>
+ /// Occurs when the classification of a span of text has changed.
+ /// </summary>
+ /// <remarks>
+ /// This event does not need to be raised for newly-inserted text.
+ /// However, it should be raised if any text other than that which was actually inserted has been reclassified.
+ /// It should also be raised if the deletion of text causes the remaining
+ /// text to be reclassified.</remarks>
+ event EventHandler<ClassificationChangedEventArgs> ClassificationChanged;
+ }
+}
diff --git a/src/Text/Def/TextLogic/Classification/IClassifierAggregatorService.cs b/src/Text/Def/TextLogic/Classification/IClassifierAggregatorService.cs
new file mode 100644
index 0000000..021c6f8
--- /dev/null
+++ b/src/Text/Def/TextLogic/Classification/IClassifierAggregatorService.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Classification
+{
+ /// <summary>
+ /// A service that returns an <see cref="IClassifier"/> that aggregates and normalizes all <see cref="IClassifier"/>
+ /// contributions for a <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <remarks>
+ /// <para>The normalized classifications produced by this aggregator are sorted and do not overlap. If a span of text
+ /// had multiple classifications based on the original classifier contributions, then in the normalized
+ /// classification it has a transient classification (<see cref="IClassificationTypeRegistryService"/>) that corresponds to
+ /// all of the original classifications.</para>
+ /// <para>Classifier aggregators are cached for each <see cref="ITextBuffer"/> object.</para>
+ /// </remarks>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IClassifierAggregatorService aggregator = null;
+ /// </remarks>
+ public interface IClassifierAggregatorService
+ {
+ /// <summary>
+ /// Gets the cached <see cref="IClassifier"/> for the given <see cref="ITextBuffer"/>.
+ /// If one does not exist, an <see cref="IClassifier"/> will be created and cached with the given <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> with which to retrieve/create the <see cref="IClassifier"/>.</param>
+ /// <returns>The cached <see cref="IClassifier"/>.</returns>
+ /// <exception cref="System.ArgumentNullException"><paramref name="textBuffer"/> is null.</exception>
+ IClassifier GetClassifier(ITextBuffer textBuffer);
+ }
+}
diff --git a/src/Text/Def/TextLogic/Classification/IClassifierProvider.cs b/src/Text/Def/TextLogic/Classification/IClassifierProvider.cs
new file mode 100644
index 0000000..b5f6696
--- /dev/null
+++ b/src/Text/Def/TextLogic/Classification/IClassifierProvider.cs
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Classification
+{
+ /// <summary>
+ /// Creates a classifier for a given <see cref="ITextBuffer" />.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be exported with the following attribute:
+ /// [Export(NameSource=typeof(IClassifierProvider))]
+ /// Component exporters must add at least one content type attribute to specify the
+ /// content types for which the component is valid.
+ /// </remarks>
+ public interface IClassifierProvider
+ {
+ /// <summary>
+ /// Gets a classifier for the given text buffer.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> to classify.</param>
+ /// <returns>A classifier for the text buffer, or null if the provider cannot do so in its current state.</returns>
+ IClassifier GetClassifier(ITextBuffer textBuffer);
+ }
+}
diff --git a/src/Text/Def/TextLogic/Classification/Microsoft.VisualStudio.Text.Classification.Overview.mht b/src/Text/Def/TextLogic/Classification/Microsoft.VisualStudio.Text.Classification.Overview.mht
new file mode 100644
index 0000000..3bbdf22
--- /dev/null
+++ b/src/Text/Def/TextLogic/Classification/Microsoft.VisualStudio.Text.Classification.Overview.mht
@@ -0,0 +1,3155 @@
+MIME-Version: 1.0
+Content-Type: multipart/related; boundary="----=_NextPart_01C89573.42B3B3B0"
+
+This document is a Single File Web Page, also known as a Web Archive file. If you are seeing this message, your browser or editor doesn't support Web Archive files. Please download a browser that supports Web Archive, such as Windows® Internet Explorer®.
+
+------=_NextPart_01C89573.42B3B3B0
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Classification.Overview.htm
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/html; charset="us-ascii"
+
+<html xmlns:v=3D"urn:schemas-microsoft-com:vml"
+xmlns:o=3D"urn:schemas-microsoft-com:office:office"
+xmlns:w=3D"urn:schemas-microsoft-com:office:word"
+xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml"
+xmlns=3D"http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=3DContent-Type content=3D"text/html; charset=3Dus-ascii">
+<meta name=3DProgId content=3DWord.Document>
+<meta name=3DGenerator content=3D"Microsoft Word 12">
+<meta name=3DOriginator content=3D"Microsoft Word 12">
+<link rel=3DFile-List
+href=3D"Microsoft.VisualStudio.Text.Classification.Overview_files/filelist.=
+xml">
+<title>Classification Subsystem</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Subject>VisualStudio Shell</o:Subject>
+ <o:Author>Vijaye Raji</o:Author>
+ <o:Template>VisualStudio SDK Overview.dot</o:Template>
+ <o:LastAuthor>Jack Tilford</o:LastAuthor>
+ <o:Revision>8</o:Revision>
+ <o:TotalTime>100</o:TotalTime>
+ <o:LastPrinted>2005-05-26T01:48:00Z</o:LastPrinted>
+ <o:Created>2007-01-05T22:45:00Z</o:Created>
+ <o:LastSaved>2008-04-03T17:12:00Z</o:LastSaved>
+ <o:Pages>1</o:Pages>
+ <o:Words>770</o:Words>
+ <o:Characters>4394</o:Characters>
+ <o:Company>Microsoft Corporation</o:Company>
+ <o:Lines>36</o:Lines>
+ <o:Paragraphs>10</o:Paragraphs>
+ <o:CharactersWithSpaces>5154</o:CharactersWithSpaces>
+ <o:Version>12.00</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]-->
+<link rel=3DthemeData
+href=3D"Microsoft.VisualStudio.Text.Classification.Overview_files/themedata=
+.thmx">
+<link rel=3DcolorSchemeMapping
+href=3D"Microsoft.VisualStudio.Text.Classification.Overview_files/colorsche=
+memapping.xml">
+<!--[if gte mso 9]><xml>
+ <w:WordDocument>
+ <w:Zoom>110</w:Zoom>
+ <w:TrackMoves>false</w:TrackMoves>
+ <w:TrackFormatting/>
+ <w:PunctuationKerning/>
+ <w:ValidateAgainstSchemas/>
+ <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
+ <w:IgnoreMixedContent>false</w:IgnoreMixedContent>
+ <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
+ <w:DoNotPromoteQF/>
+ <w:LidThemeOther>EN-US</w:LidThemeOther>
+ <w:LidThemeAsian>X-NONE</w:LidThemeAsian>
+ <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
+ <w:Compatibility>
+ <w:BreakWrappedTables/>
+ <w:SnapToGridInCell/>
+ <w:WrapTextWithPunct/>
+ <w:UseAsianBreakRules/>
+ <w:DontGrowAutofit/>
+ <w:SplitPgBreakAndParaMark/>
+ <w:DontVertAlignCellWithSp/>
+ <w:DontBreakConstrainedForcedTables/>
+ <w:DontVertAlignInTxbx/>
+ <w:Word11KerningPairs/>
+ <w:CachedColBalance/>
+ </w:Compatibility>
+ <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
+ <m:mathPr>
+ <m:mathFont m:val=3D"Cambria Math"/>
+ <m:brkBin m:val=3D"before"/>
+ <m:brkBinSub m:val=3D"&#45;-"/>
+ <m:smallFrac m:val=3D"off"/>
+ <m:dispDef/>
+ <m:lMargin m:val=3D"0"/>
+ <m:rMargin m:val=3D"0"/>
+ <m:defJc m:val=3D"centerGroup"/>
+ <m:wrapIndent m:val=3D"1440"/>
+ <m:intLim m:val=3D"subSup"/>
+ <m:naryLim m:val=3D"undOvr"/>
+ </m:mathPr></w:WordDocument>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:LatentStyles DefLockedState=3D"false" DefUnhideWhenUsed=3D"false"
+ DefSemiHidden=3D"false" DefQFormat=3D"false" DefPriority=3D"1"
+ LatentStyleCount=3D"267">
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+Normal"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+heading 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+heading 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+heading 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+heading 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 7"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 8"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 9"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"footnote text"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"annotation text"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+caption"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"footnote referenc=
+e"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"annotation refere=
+nce"/>
+ <w:LsdException Locked=3D"false" QFormat=3D"true" Name=3D"Title"/>
+ <w:LsdException Locked=3D"false" QFormat=3D"true" Name=3D"Subtitle"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Hyperlink"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+Strong"/>
+ <w:LsdException Locked=3D"false" QFormat=3D"true" Name=3D"Emphasis"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"HTML Top of Form"=
+/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"HTML Bottom of Fo=
+rm"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Normal (Web)"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Normal Table"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"annotation subjec=
+t"/>
+ <w:LsdException Locked=3D"false" Priority=3D"99" Name=3D"No List"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Outline List 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Outline List 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Outline List 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Simple 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Simple 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Simple 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Classic 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Classic 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Classic 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Classic 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Colorful 1"=
+/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Colorful 2"=
+/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Colorful 3"=
+/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 7"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 8"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 7"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 8"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table 3D effects =
+1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table 3D effects =
+2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table 3D effects =
+3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Contemporar=
+y"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Elegant"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Professiona=
+l"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Subtle 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Subtle 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Web 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Web 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Web 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Balloon Text"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Theme"/>
+ <w:LsdException Locked=3D"false" Priority=3D"99" SemiHidden=3D"true"
+ Name=3D"Placeholder Text"/>
+ <w:LsdException Locked=3D"false" Priority=3D"2" QFormat=3D"true" Name=3D"=
+No Spacing"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"99" SemiHidden=3D"true" Name=
+=3D"Revision"/>
+ <w:LsdException Locked=3D"false" Priority=3D"34" QFormat=3D"true"
+ Name=3D"List Paragraph"/>
+ <w:LsdException Locked=3D"false" Priority=3D"29" QFormat=3D"true" Name=3D=
+"Quote"/>
+ <w:LsdException Locked=3D"false" Priority=3D"30" QFormat=3D"true"
+ Name=3D"Intense Quote"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"19" QFormat=3D"true"
+ Name=3D"Subtle Emphasis"/>
+ <w:LsdException Locked=3D"false" Priority=3D"21" QFormat=3D"true"
+ Name=3D"Intense Emphasis"/>
+ <w:LsdException Locked=3D"false" Priority=3D"31" QFormat=3D"true"
+ Name=3D"Subtle Reference"/>
+ <w:LsdException Locked=3D"false" Priority=3D"32" QFormat=3D"true"
+ Name=3D"Intense Reference"/>
+ <w:LsdException Locked=3D"false" Priority=3D"33" QFormat=3D"true" Name=3D=
+"Book Title"/>
+ <w:LsdException Locked=3D"false" Priority=3D"37" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" Name=3D"Bibliography"/>
+ <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"TOC Heading"/>
+ </w:LatentStyles>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+ @font-face
+ {font-family:PMingLiU;
+ panose-1:2 2 5 0 0 0 0 0 0 0;
+ mso-font-alt:\65B0\7D30\660E\9AD4;
+ mso-font-charset:136;
+ mso-generic-font-family:roman;
+ mso-font-pitch:variable;
+ mso-font-signature:-1610611969 684719354 22 0 1048577 0;}
+@font-face
+ {font-family:"Cambria Math";
+ panose-1:2 4 5 3 5 4 6 3 2 4;
+ mso-font-charset:1;
+ mso-generic-font-family:roman;
+ mso-font-format:other;
+ mso-font-pitch:variable;
+ mso-font-signature:0 0 0 0 0 0;}
+@font-face
+ {font-family:Calibri;
+ panose-1:2 15 5 2 2 2 4 3 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:-1610611985 1073750139 0 0 159 0;}
+@font-face
+ {font-family:Tahoma;
+ panose-1:2 11 6 4 3 5 4 4 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:-520082689 -1073717157 41 0 66047 0;}
+@font-face
+ {font-family:Verdana;
+ panose-1:2 11 6 4 3 5 4 4 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:-1593833729 1073750107 16 0 415 0;}
+@font-face
+ {font-family:"Lucida Console";
+ panose-1:2 11 6 9 4 5 4 2 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:modern;
+ mso-font-pitch:fixed;
+ mso-font-signature:-2147482993 6144 0 0 31 0;}
+@font-face
+ {font-family:"Trebuchet MS";
+ panose-1:2 11 6 3 2 2 2 2 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:647 0 0 0 159 0;}
+@font-face
+ {font-family:Consolas;
+ panose-1:2 11 6 9 2 2 4 3 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:modern;
+ mso-font-pitch:fixed;
+ mso-font-signature:-1610611985 1073750091 0 0 159 0;}
+@font-face
+ {font-family:"\@PMingLiU";
+ panose-1:2 2 5 0 0 0 0 0 0 0;
+ mso-font-charset:136;
+ mso-generic-font-family:roman;
+ mso-font-pitch:variable;
+ mso-font-signature:-1610611969 684719354 22 0 1048577 0;}
+@font-face
+ {font-family:Georgia;
+ panose-1:2 4 5 2 5 4 5 2 3 3;
+ mso-font-charset:0;
+ mso-generic-font-family:roman;
+ mso-font-pitch:variable;
+ mso-font-signature:647 0 0 0 159 0;}
+ /* Style Definitions */
+ p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-parent:"";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+h1
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-link:"Heading 1 Char";
+ mso-style-next:Normal;
+ margin-top:6.0pt;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-line-height-alt:14.0pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:1;
+ font-size:20.0pt;
+ mso-bidi-font-size:16.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:minor-fareast;
+ mso-bidi-font-family:Arial;
+ color:#666699;
+ mso-font-kerning:16.0pt;
+ font-weight:normal;
+ mso-bidi-font-weight:bold;}
+h2
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-parent:"";
+ mso-style-link:"Heading 2 Char";
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ mso-outline-level:2;
+ font-size:14.0pt;
+ font-family:"Trebuchet MS","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:minor-fareast;
+ mso-bidi-font-family:Arial;
+ color:#5F5F5F;
+ letter-spacing:2.0pt;}
+h3
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-parent:"Heading 4";
+ mso-style-link:"Heading 3 Char";
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:3;
+ font-size:14.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:minor-fareast;
+ color:#FF6600;
+ font-weight:normal;
+ mso-bidi-font-weight:bold;}
+h4
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-link:"Heading 4 Char";
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:4;
+ font-size:11.0pt;
+ mso-bidi-font-size:14.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:minor-fareast;
+ mso-bidi-font-family:"Times New Roman";
+ color:olive;}
+p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText
+ {mso-style-unhide:no;
+ mso-style-link:"Footnote Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoCommentText, li.MsoCommentText, div.MsoCommentText
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-link:"Comment Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoHeader, li.MsoHeader, div.MsoHeader
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-link:"Header Char";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.25in right 6.5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoFooter, li.MsoFooter, div.MsoFooter
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-link:"Footer Char";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.25in right 6.5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoCaption, li.MsoCaption, div.MsoCaption
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ font-weight:bold;}
+span.MsoFootnoteReference
+ {mso-style-unhide:no;
+ vertical-align:super;}
+span.MsoCommentReference
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-ansi-font-size:8.0pt;
+ mso-bidi-font-size:8.0pt;}
+p.MsoListBullet, li.MsoListBullet, div.MsoListBullet
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.25in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l3 level1 lfo1;
+ tab-stops:list .25in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBulletCxSpFirst, li.MsoListBulletCxSpFirst, div.MsoListBulletCxSpF=
+irst
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.25in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l3 level1 lfo1;
+ tab-stops:list .25in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBulletCxSpMiddle, li.MsoListBulletCxSpMiddle, div.MsoListBulletCxS=
+pMiddle
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.25in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l3 level1 lfo1;
+ tab-stops:list .25in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBulletCxSpLast, li.MsoListBulletCxSpLast, div.MsoListBulletCxSpLast
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.25in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l3 level1 lfo1;
+ tab-stops:list .25in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet2, li.MsoListBullet2, div.MsoListBullet2
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l2 level1 lfo2;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet2CxSpFirst, li.MsoListBullet2CxSpFirst, div.MsoListBullet2Cx=
+SpFirst
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l2 level1 lfo2;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet2CxSpMiddle, li.MsoListBullet2CxSpMiddle, div.MsoListBullet2=
+CxSpMiddle
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l2 level1 lfo2;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet2CxSpLast, li.MsoListBullet2CxSpLast, div.MsoListBullet2CxSp=
+Last
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l2 level1 lfo2;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet3, li.MsoListBullet3, div.MsoListBullet3
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.75in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l1 level1 lfo3;
+ tab-stops:list .75in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet3CxSpFirst, li.MsoListBullet3CxSpFirst, div.MsoListBullet3Cx=
+SpFirst
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.75in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l1 level1 lfo3;
+ tab-stops:list .75in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet3CxSpMiddle, li.MsoListBullet3CxSpMiddle, div.MsoListBullet3=
+CxSpMiddle
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.75in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l1 level1 lfo3;
+ tab-stops:list .75in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet3CxSpLast, li.MsoListBullet3CxSpLast, div.MsoListBullet3CxSp=
+Last
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.75in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l1 level1 lfo3;
+ tab-stops:list .75in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListNumber2, li.MsoListNumber2, div.MsoListNumber2
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l0 level1 lfo4;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListNumber2CxSpFirst, li.MsoListNumber2CxSpFirst, div.MsoListNumber2Cx=
+SpFirst
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l0 level1 lfo4;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListNumber2CxSpMiddle, li.MsoListNumber2CxSpMiddle, div.MsoListNumber2=
+CxSpMiddle
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l0 level1 lfo4;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListNumber2CxSpLast, li.MsoListNumber2CxSpLast, div.MsoListNumber2CxSp=
+Last
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l0 level1 lfo4;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+a:link, span.MsoHyperlink
+ {mso-style-unhide:no;
+ color:blue;
+ text-decoration:underline;
+ text-underline:single;}
+a:visited, span.MsoHyperlinkFollowed
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ color:purple;
+ mso-themecolor:followedhyperlink;
+ text-decoration:underline;
+ text-underline:single;}
+p.MsoCommentSubject, li.MsoCommentSubject, div.MsoCommentSubject
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-parent:"Comment Text";
+ mso-style-link:"Comment Subject Char";
+ mso-style-next:"Comment Text";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ font-weight:bold;}
+p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-link:"Balloon Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:8.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";}
+p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Verdana","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParag=
+raphCxSpFirst
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Verdana","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListPar=
+agraphCxSpMiddle
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Verdana","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagra=
+phCxSpLast
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Verdana","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoQuote, li.MsoQuote, div.MsoQuote
+ {mso-style-priority:29;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-link:"Quote Char";
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:black;
+ font-style:italic;}
+span.Heading1Char
+ {mso-style-name:"Heading 1 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 1";
+ mso-ansi-font-size:20.0pt;
+ mso-bidi-font-size:16.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-ascii-font-family:Tahoma;
+ mso-hansi-font-family:Tahoma;
+ mso-bidi-font-family:Arial;
+ color:#666699;
+ mso-font-kerning:16.0pt;
+ mso-bidi-font-weight:bold;}
+span.Heading2Char
+ {mso-style-name:"Heading 2 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 2";
+ mso-ansi-font-size:13.0pt;
+ mso-bidi-font-size:13.0pt;
+ font-family:"Cambria","serif";
+ mso-ascii-font-family:Cambria;
+ mso-ascii-theme-font:major-latin;
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:major-fareast;
+ mso-hansi-font-family:Cambria;
+ mso-hansi-theme-font:major-latin;
+ mso-bidi-font-family:"Times New Roman";
+ mso-bidi-theme-font:major-bidi;
+ color:#4F81BD;
+ mso-themecolor:accent1;
+ font-weight:bold;}
+span.Heading4Char
+ {mso-style-name:"Heading 4 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 4";
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:14.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-ascii-font-family:Tahoma;
+ mso-hansi-font-family:Tahoma;
+ mso-bidi-font-family:Tahoma;
+ color:olive;
+ mso-ansi-language:EN-US;
+ mso-fareast-language:EN-US;
+ mso-bidi-language:AR-SA;
+ font-weight:bold;}
+span.Heading3Char
+ {mso-style-name:"Heading 3 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 3";
+ mso-ansi-font-size:14.0pt;
+ mso-bidi-font-size:14.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-ascii-font-family:Tahoma;
+ mso-hansi-font-family:Tahoma;
+ mso-bidi-font-family:Tahoma;
+ color:#FF6600;
+ mso-ansi-language:EN-US;
+ mso-fareast-language:EN-US;
+ mso-bidi-language:AR-SA;
+ mso-bidi-font-weight:bold;}
+span.FootnoteTextChar
+ {mso-style-name:"Footnote Text Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Footnote Text";
+ mso-ansi-font-size:11.0pt;}
+span.CommentTextChar
+ {mso-style-name:"Comment Text Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Comment Text";}
+span.HeaderChar
+ {mso-style-name:"Header Char";
+ mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Header;
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;}
+span.FooterChar
+ {mso-style-name:"Footer Char";
+ mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Footer;
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;}
+span.CommentSubjectChar
+ {mso-style-name:"Comment Subject Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-parent:"Comment Text Char";
+ mso-style-link:"Comment Subject";
+ font-weight:bold;}
+span.BalloonTextChar
+ {mso-style-name:"Balloon Text Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Balloon Text";
+ mso-ansi-font-size:8.0pt;
+ mso-bidi-font-size:8.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-ascii-font-family:Tahoma;
+ mso-hansi-font-family:Tahoma;
+ mso-bidi-font-family:Tahoma;}
+span.QuoteChar
+ {mso-style-name:"Quote Char";
+ mso-style-priority:29;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Quote;
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ color:black;
+ font-style:italic;}
+p.Heading0, li.Heading0, div.Heading0
+ {mso-style-name:"Heading 0";
+ mso-style-unhide:no;
+ mso-style-parent:"Heading 1";
+ margin-top:6.0pt;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-line-height-alt:14.0pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:1;
+ font-size:28.0pt;
+ mso-bidi-font-size:16.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:Arial;
+ color:#006699;
+ mso-font-kerning:16.0pt;
+ mso-bidi-font-weight:bold;}
+p.SubHeading, li.SubHeading, div.SubHeading
+ {mso-style-name:SubHeading;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:maroon;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+span.CodeCharChar
+ {mso-style-name:"Code Char Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Code;
+ mso-ansi-font-size:9.0pt;
+ mso-bidi-font-size:9.0pt;
+ font-family:"Lucida Console";
+ mso-ascii-font-family:"Lucida Console";
+ mso-hansi-font-family:"Lucida Console";
+ mso-no-proof:yes;}
+p.Code, li.Code, div.Code
+ {mso-style-name:Code;
+ mso-style-unhide:no;
+ mso-style-link:"Code Char Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ mso-layout-grid-align:none;
+ text-autospace:none;
+ font-size:9.0pt;
+ font-family:"Lucida Console";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ mso-no-proof:yes;}
+span.NoteChar
+ {mso-style-name:"Note Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Note;
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ background:#F3F3F3;
+ font-style:italic;
+ mso-bidi-font-style:normal;}
+p.Note, li.Note, div.Note
+ {mso-style-name:Note;
+ mso-style-unhide:no;
+ mso-style-link:"Note Char";
+ margin-top:0in;
+ margin-right:.2in;
+ margin-bottom:12.0pt;
+ margin-left:.2in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ background:#F3F3F3;
+ border:none;
+ mso-border-top-alt:.5pt;
+ mso-border-left-alt:.5pt;
+ mso-border-bottom-alt:1.5pt;
+ mso-border-right-alt:1.5pt;
+ mso-border-color-alt:windowtext;
+ mso-border-style-alt:solid;
+ padding:0in;
+ mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ font-style:italic;
+ mso-bidi-font-style:normal;}
+p.Style2, li.Style2, div.Style2
+ {mso-style-name:Style2;
+ mso-style-unhide:no;
+ mso-style-parent:"";
+ mso-style-next:Normal;
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ background:#F9FFF3;
+ border:none;
+ mso-border-top-alt:.5pt;
+ mso-border-left-alt:.5pt;
+ mso-border-bottom-alt:1.5pt;
+ mso-border-right-alt:1.5pt;
+ mso-border-color-alt:windowtext;
+ mso-border-style-alt:solid;
+ padding:0in;
+ mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt;
+ font-size:9.0pt;
+ font-family:Consolas;
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ mso-no-proof:yes;}
+p.Style3, li.Style3, div.Style3
+ {mso-style-name:Style3;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ background:#F5FAF4;
+ mso-layout-grid-align:none;
+ text-autospace:none;
+ border:none;
+ mso-border-alt:solid windowtext 1.0pt;
+ padding:0in;
+ mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt;
+ mso-border-shadow:yes;
+ font-size:9.0pt;
+ font-family:Consolas;
+ mso-fareast-font-family:PMingLiU;
+ mso-bidi-font-family:"Times New Roman";
+ mso-fareast-language:ZH-CN;
+ mso-no-proof:yes;}
+span.DescriptionTextChar
+ {mso-style-name:"Description Text Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Description Text";}
+p.DescriptionText, li.DescriptionText, div.DescriptionText
+ {mso-style-name:"Description Text";
+ mso-style-unhide:no;
+ mso-style-link:"Description Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.25in;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.Issue, li.Issue, div.Issue
+ {mso-style-name:Issue;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan lines-together;
+ border:none;
+ mso-border-alt:solid navy 1.5pt;
+ padding:0in;
+ mso-padding-alt:1.0pt 1.0pt 1.0pt 1.0pt;
+ mso-border-shadow:yes;
+ font-size:10.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";
+ color:red;
+ font-style:italic;
+ mso-bidi-font-style:normal;}
+p.msolistparagraph0, li.msolistparagraph0, div.msolistparagraph0
+ {mso-style-name:msolistparagraph;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";}
+p.msolistparagraph0CxSpFirst, li.msolistparagraph0CxSpFirst, div.msolistpar=
+agraph0CxSpFirst
+ {mso-style-name:msolistparagraphCxSpFirst;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";}
+p.msolistparagraph0CxSpMiddle, li.msolistparagraph0CxSpMiddle, div.msolistp=
+aragraph0CxSpMiddle
+ {mso-style-name:msolistparagraphCxSpMiddle;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";}
+p.msolistparagraph0CxSpLast, li.msolistparagraph0CxSpLast, div.msolistparag=
+raph0CxSpLast
+ {mso-style-name:msolistparagraphCxSpLast;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";}
+.MsoChpDefault
+ {mso-style-type:export-only;
+ mso-default-props:yes;
+ font-size:10.0pt;
+ mso-ansi-font-size:10.0pt;
+ mso-bidi-font-size:10.0pt;
+ mso-ascii-font-family:Calibri;
+ mso-hansi-font-family:Calibri;}
+ /* Page Definitions */
+ @page
+ {mso-footnote-separator:url("Microsoft.VisualStudio.Text.Classification.Ov=
+erview_files/header.htm") fs;
+ mso-footnote-continuation-separator:url("Microsoft.VisualStudio.Text.Class=
+ification.Overview_files/header.htm") fcs;
+ mso-endnote-separator:url("Microsoft.VisualStudio.Text.Classification.Over=
+view_files/header.htm") es;
+ mso-endnote-continuation-separator:url("Microsoft.VisualStudio.Text.Classi=
+fication.Overview_files/header.htm") ecs;}
+@page Section1
+ {size:8.5in 11.0in;
+ margin:1.0in 1.25in 1.0in 1.25in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+ /* List Definitions */
+ @list l0
+ {mso-list-id:-129;
+ mso-list-type:simple;
+ mso-list-template-ids:-1739002844;}
+@list l0:level1
+ {mso-level-style-link:"List Number 2";
+ mso-level-tab-stop:.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l1
+ {mso-list-id:-126;
+ mso-list-type:simple;
+ mso-list-template-ids:-1045901690;}
+@list l1:level1
+ {mso-level-number-format:bullet;
+ mso-level-style-link:"List Bullet 3";
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.75in;
+ mso-level-number-position:left;
+ margin-left:.75in;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l2
+ {mso-list-id:-125;
+ mso-list-type:simple;
+ mso-list-template-ids:-1069260336;}
+@list l2:level1
+ {mso-level-number-format:bullet;
+ mso-level-style-link:"List Bullet 2";
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l3
+ {mso-list-id:-119;
+ mso-list-type:simple;
+ mso-list-template-ids:1390696726;}
+@list l3:level1
+ {mso-level-number-format:bullet;
+ mso-level-style-link:"List Bullet";
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.25in;
+ mso-level-number-position:left;
+ margin-left:.25in;
+ text-indent:-.25in;
+ font-family:Symbol;}
+ol
+ {margin-bottom:0in;}
+ul
+ {margin-bottom:0in;}
+-->
+</style>
+<!--[if gte mso 10]>
+<style>
+ /* Style Definitions */
+ table.MsoNormalTable
+ {mso-style-name:"Table Normal";
+ mso-tstyle-rowband-size:0;
+ mso-tstyle-colband-size:0;
+ mso-style-noshow:yes;
+ mso-style-priority:99;
+ mso-style-qformat:yes;
+ mso-style-parent:"";
+ mso-padding-alt:0in 5.4pt 0in 5.4pt;
+ mso-para-margin:0in;
+ mso-para-margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Calibri","sans-serif";}
+table.MsoTableGrid
+ {mso-style-name:"Table Grid";
+ mso-tstyle-rowband-size:0;
+ mso-tstyle-colband-size:0;
+ mso-style-unhide:no;
+ border:solid windowtext 1.0pt;
+ mso-border-alt:solid windowtext .5pt;
+ mso-padding-alt:0in 5.4pt 0in 5.4pt;
+ mso-border-insideh:.5pt solid windowtext;
+ mso-border-insidev:.5pt solid windowtext;
+ mso-para-margin:0in;
+ mso-para-margin-bottom:.0001pt;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Calibri","sans-serif";}
+</style>
+<![endif]--><!--[if gte mso 9]><xml>
+ <o:shapedefaults v:ext=3D"edit" spidmax=3D"8194"/>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <o:shapelayout v:ext=3D"edit">
+ <o:idmap v:ext=3D"edit" data=3D"1"/>
+ </o:shapelayout></xml><![endif]-->
+</head>
+
+<body lang=3DEN-US link=3Dblue vlink=3Dpurple style=3D'tab-interval:.5in'>
+
+<div class=3DSection1>
+
+<p class=3DHeading0>Classification Subsystem</p>
+
+<div style=3D'mso-element:para-border-div;border:none;border-bottom:solid w=
+indowtext 1.0pt;
+mso-border-bottom-alt:solid windowtext .75pt;padding:0in 0in 1.0pt 0in'>
+
+<p class=3DMsoNormal style=3D'border:none;mso-border-bottom-alt:solid windo=
+wtext .75pt;
+padding:0in;mso-padding-alt:0in 0in 1.0pt 0in'><o:p>&nbsp;</o:p></p>
+
+</div>
+
+<h1><a name=3D"_Toc155080032"></a><a name=3D"_Toc151442559"></a><a
+name=3D"_Toc153700829"></a><a name=3D"_Toc151886043"></a><a name=3D"_Toc151=
+886240"></a><a
+name=3D"_Toc151892155"></a><a name=3D"_Toc153684427"></a><a name=3D"_Toc151=
+974258"></a><a
+name=3D"_Toc151873650"></a><a name=3D"_Toc151873508"></a><a name=3D"_Toc149=
+118641"></a><a
+name=3D"_Toc149118380"></a><a name=3D"_Toc149118215"></a><a name=3D"_Toc149=
+118079"></a><a
+name=3D"_Toc151973942"></a><a name=3D"_Toc151974416"></a><a name=3D"_Toc769=
+78452"></a><a
+name=3D"_Toc149120311"><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Overview</span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></a><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-fareast-font-family=
+:"Times New Roman"'><o:p></o:p></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></h1>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>This
+document provides a conceptual overview of the <i style=3D'mso-bidi-font-st=
+yle:
+normal'>Classification Subsystem</i>.<span style=3D'mso-spacerun:yes'>&nbsp;
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>The
+Classification Subsystem is composed of two separate areas that are describ=
+ed
+in greater detail below:</span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoListBullet2CxSpFirst><span style=3D'mso-bookmark:_Toc76978452=
+'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'><![if !supportLists]><span
+style=3D'font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-fa=
+mily:
+Symbol'><span style=3D'mso-list:Ignore'>&middot;<span style=3D'font:7.0pt "=
+Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span></span><![endif]>Text Classification</span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></p>
+
+<p class=3DMsoListBullet2CxSpLast><span style=3D'mso-bookmark:_Toc76978452'=
+><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'><![if !supportLists]><span
+style=3D'font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-fa=
+mily:
+Symbol'><span style=3D'mso-list:Ignore'>&middot;<span style=3D'font:7.0pt "=
+Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span></span><![endif]>Text Formatting</span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></p>
+
+<h1><span style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_=
+Toc151974416'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><a name=3D"_Toc149120312"><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Text Classification</sp=
+an></a></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-fareast-font-family=
+:"Times New Roman"'><o:p></o:p></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></h1>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>The
+Classification subsystem provides abstractions, extensions, and services to
+partition text into equivalence classes of different types in a light weight
+and efficient manner.<span style=3D'mso-spacerun:yes'>&nbsp; </span>Other
+components can consume these equivalence classes and use them to do meaning=
+ful
+work. </span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>The
+<i>Text Classification </i>area of the Classification Subsystem is concerned
+with the actual process of splitting the text into different equivalence
+classes, determining the different valid types, and aggregating the
+contributions from all clients that contribute classifications.</span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_=
+Toc151974416'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><a name=3D"_Toc149120313"><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Classification types</s=
+pan></a></span></span></span></span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-fareast-font-family=
+:"Times New Roman"'><o:p></o:p></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>A <i>classification</i>
+<i>type </i>is defined as an equivalence class, which is an abstract catego=
+ry
+of text.<span style=3D'mso-spacerun:yes'>&nbsp; </span>These types can mult=
+iply
+inherit from other classification types.<span style=3D'mso-spacerun:yes'>&n=
+bsp;
+</span>Examples of classifications in an IDE might be &#8220;keyword&#8221;,
+&#8220;comment&#8221;, and &#8220;identifier&#8221; all inheriting from
+&#8220;code&#8221;.<span style=3D'mso-spacerun:yes'>&nbsp; </span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>Examples
+of classifications in a word processor might be &#8220;noun&#8221;,
+&#8220;verb&#8221;, and &#8220;adjective&#8221; all inheriting from
+&#8220;natural </span></span></span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-ascii-font-family:C=
+alibri;
+mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;mso-hansi-th=
+eme-font:
+minor-latin'>language&#8221;.<span style=3D'mso-spacerun:yes'>&nbsp; </span=
+>The </span><strong><span
+style=3D'font-family:"Calibri","sans-serif"'>IClassificationType</span></st=
+rong></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-ascii-font-family:C=
+alibri;
+mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;mso-hansi-th=
+eme-font:
+minor-latin'> is the</span> type used to represent classification types.<sp=
+an
+style=3D'mso-spacerun:yes'>&nbsp; </span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>Clients
+need to define new classification types if the existing types existing in t=
+he
+system don&#8217;t meet their needs.</span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_=
+Toc151974416'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><a name=3D"_Toc149120314"><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Classifications</span><=
+/a></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-fareast-font-family=
+:"Times New Roman"'><o:p></o:p></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>A <i>classification</i>
+is defined as an instance of a particular classification type, typically ov=
+er a
+span of text.<span style=3D'mso-spacerun:yes'>&nbsp; </span><strong><span
+style=3D'font-family:"Calibri","sans-serif"'>ClassificationSpan</span></str=
+ong></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-ascii-font-family:C=
+alibri;
+mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;mso-hansi-th=
+eme-font:
+minor-latin'> is used to represent a classification.<span
+style=3D'mso-spacerun:yes'>&nbsp; </span><b style=3D'mso-bidi-font-weight:n=
+ormal'>ClassificationSpan</b>
+can be thought</span> of as a label over a particular span of text that tel=
+ls
+the system that this span of text is of a particular classification type.<s=
+pan
+style=3D'mso-spacerun:yes'>&nbsp; </span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>Examples
+of classifications in a C# file could be &#8220;for&#8221;,
+&#8220;while&#8221;, &#8220;return&#8221; (all keywords).<span
+style=3D'mso-spacerun:yes'>&nbsp; </span>Examples of classifications in a W=
+ord
+document could be &#8220;run&#8221;, &#8220;eat&#8221;, &#8220;sat&#8221; (=
+all
+verbs).<span style=3D'mso-spacerun:yes'>&nbsp; </span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>Clients
+need to </span></span></span></span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-ascii-font-family:C=
+alibri;
+mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;mso-hansi-th=
+eme-font:
+minor-latin'>instantiate </span><strong><span style=3D'font-family:"Calibri=
+","sans-serif"'>ClassificationSpans</span></strong></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-ascii-font-family:C=
+alibri;
+mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;mso-hansi-th=
+eme-font:
+minor-latin'>, which</span> are the physical manifestation of a classificat=
+ion
+type, if they define a classifier.</span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></p>
+
+<h2><span style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_=
+Toc151974416'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><a name=3D"_Toc149120315"><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Classifiers</span></a><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-fareast-font-family=
+:"Times New Roman"'><o:p></o:p></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>A <i>classifier</i>
+is defined as a mechanism that breaks text up into a set of
+classifications.<span style=3D'mso-spacerun:yes'>&nbsp; </span>Classifiers =
+must
+be defined per content type and instantiated per text buffer (see the Text
+Model subsystem overview).<span style=3D'mso-spacerun:yes'>&nbsp; </span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>For
+example a C# classifier could produce classifications that label all keywor=
+ds
+and comments in a C# file.<span style=3D'mso-spacerun:yes'>&nbsp; </span>An
+English language classifier could take a document and produce classificatio=
+ns
+that label all nouns, verbs and adjectives in a document.<span
+style=3D'mso-spacerun:yes'>&nbsp; </span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>Clients
+need to </span></span></span></span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-ascii-font-family:C=
+alibri;
+mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;mso-hansi-th=
+eme-font:
+minor-latin'>implement </span><strong><span style=3D'font-family:"Calibri",=
+"sans-serif"'>IClassifier</span></strong></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-ascii-font-family:C=
+alibri;
+mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;mso-hansi-th=
+eme-font:
+minor-latin'> to take part in tex</span>t classification.<span
+style=3D'mso-spacerun:yes'>&nbsp; </span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_=
+Toc151974416'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><a name=3D"_Toc149120316"><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Classifier aggregators<=
+/span></a></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-fareast-font-family=
+:"Times New Roman"'><o:p></o:p></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>A <i>classifier
+aggregator</i> is defined as a mechanism to combine all classifier contribu=
+tions
+for a single text buffer into a single set of classifications.<span
+style=3D'mso-spacerun:yes'>&nbsp; </span>Since more than one classifier may=
+ label
+a span of text, the aggregator is needed to combine the contributions.<span
+style=3D'mso-spacerun:yes'>&nbsp; </span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>For
+example, both a C# classifier and an English language classifier could crea=
+te
+classifications over a comment in a C# file.<span
+style=3D'mso-spacerun:yes'>&nbsp; </span>If the comment was &#8220;</span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'font-family:Consolas;
+color:green'>// This method produces a classifier.</span>&#8221; a C#
+classifier might label the entire span as a comment and the English language
+classifier might classify &#8220;produces&#8221; as a &#8220;verb&#8221; an=
+d &#8220;method&#8221;
+as a &#8220;noun&#8221; the aggregator would produce a set of non-overlappi=
+ng
+classifications whose type is based on all of the contributions.<span
+style=3D'mso-spacerun:yes'>&nbsp; </span>The classifications over the examp=
+le
+comment would look like:</span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></p>
+
+<div style=3D'mso-element:para-border-div;border:solid windowtext 1.0pt;
+mso-border-alt:solid windowtext .5pt;padding:1.0pt 4.0pt 1.0pt 4.0pt;
+background:#E5E5E5;mso-shading:windowtext;mso-pattern:gray-10 auto'>
+
+<p class=3DMsoNormal style=3D'background:#E5E5E5;mso-shading:windowtext;mso=
+-pattern:
+gray-10 auto;border:none;mso-border-alt:solid windowtext .5pt;padding:0in;
+mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt'><span style=3D'mso-bookmark:_Toc76=
+978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'font-family:Consolas;color:green'>//</span><sup>{comment}</sup></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'font-family:Consolas;
+color:green'> This</span><sup>{comment, pronoun}</sup></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'font-family:Consolas;
+color:green'> method</span><sup>{comment, noun}</sup></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'font-family:Consolas;
+color:green'> produces</span><sup>{comment, verb}</sup></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'font-family:Consolas;
+color:green'> a</span><sup>{comment, indefinite article}</sup></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'font-family:Consolas;
+color:green'> classifier</span><sup>{comment, noun}</sup></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'font-family:Consolas;
+color:green'>.</span><sup>{comment, punctuation}</sup></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'font-family:Consolas;
+color:green'><o:p></o:p></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</p>
+
+</div>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>A
+classifier aggregator is also a classifier since it breaks up text into a s=
+et
+of classifications.<span style=3D'mso-spacerun:yes'>&nbsp; </span>The class=
+ifier
+aggregator is also responsible for ensuring that there are no overlapping
+classifications and that the classifications are sorted.<span
+style=3D'mso-spacerun:yes'>&nbsp; </span>Individual classifiers are free to
+return any set of classifications in any order and overlapping in any way.<=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>Clients
+do not need to implement a classifier aggregator because an implementation =
+of<b
+style=3D'mso-bidi-font-weight:normal'> IClassifierAggregatorService</b> exi=
+sts in
+the Classification subsystem.</span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+p>
+
+<h1><span style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_=
+Toc151974416'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><a name=3D"_Toc149120317"><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Classification formatti=
+ng and
+text coloring</span></a></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-fareast-font-family=
+:"Times New Roman"'><o:p></o:p></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></h1>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>The
+<i style=3D'mso-bidi-font-style:normal'>Text Formatting</i> area is one exa=
+mple
+of a system built on top of text classification.<span
+style=3D'mso-spacerun:yes'>&nbsp; </span>Since it is so central to applicat=
+ion
+development, it is included in the Classification subsystem.<span
+style=3D'mso-spacerun:yes'>&nbsp; </span>The classification formatting area=
+ is
+what is used by the Text View subsystem to determine the display of text in=
+ an
+application.<span style=3D'mso-spacerun:yes'>&nbsp; </span>The Text Formatt=
+ing
+area is dependent on WPF, but no other piece of classification is.</span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_=
+Toc151974416'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><a name=3D"_Toc149120318"><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Classification formats<=
+/span></a></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-fareast-font-family=
+:"Times New Roman"'><o:p></o:p></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>A
+classification format is defined as a set of formatting properties over a
+specific classification type.<span style=3D'mso-spacerun:yes'>&nbsp; </span=
+>These
+formats inherit from format of the classification type&#8217;s parent.</spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_=
+Toc151974416'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><a name=3D"_Toc149120319"><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Classification format m=
+ap</span></a></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1519744=
+16'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-fareast-font-family=
+:"Times New Roman"'><o:p></o:p></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>A <i>classification
+format map</i> is defined as a map from a classification type to a set of t=
+ext
+formatting properties (see Text View subsystem overview).<span
+style=3D'mso-spacerun:yes'>&nbsp; </span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'>An
+implementation of the format map is provided which takes care of handling a=
+ll
+of the productions of classification formats and determining a static map.<=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc76978452'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc155080=
+032'><a
+name=3D"_ClassificationSpan"></a><a name=3D"_ClassificationTypeAttribute"><=
+/a><a
+name=3D"_IClassificationType"></a><a name=3D"_IDocument"></a><a
+name=3D"_IClassificationTypeRegistry"></a><a name=3D"_IClassifier"></a><a
+name=3D"_IClassificationFormatMap"></a><a name=3D"_IClassificationFormatMap=
+Selector"></a><a
+name=3D"_IClassificationFormatMapMerger"></a><span style=3D'font-family:"Ge=
+orgia","serif"'><o:p>&nbsp;</o:p></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></p>
+
+<span style=3D'mso-bookmark:_Toc155080032'></span><span style=3D'mso-bookma=
+rk:_Toc151442559'></span><span
+style=3D'mso-bookmark:_Toc153700829'></span><span style=3D'mso-bookmark:_To=
+c151886043'></span><span
+style=3D'mso-bookmark:_Toc151886240'></span><span style=3D'mso-bookmark:_To=
+c151892155'></span><span
+style=3D'mso-bookmark:_Toc153684427'></span><span style=3D'mso-bookmark:_To=
+c151974258'></span><span
+style=3D'mso-bookmark:_Toc151873650'></span><span style=3D'mso-bookmark:_To=
+c151873508'></span><span
+style=3D'mso-bookmark:_Toc149118641'></span><span style=3D'mso-bookmark:_To=
+c149118380'></span><span
+style=3D'mso-bookmark:_Toc149118215'></span><span style=3D'mso-bookmark:_To=
+c149118079'></span><span
+style=3D'mso-bookmark:_Toc151973942'></span><span style=3D'mso-bookmark:_To=
+c151974416'></span><span
+style=3D'mso-bookmark:_Toc76978452'></span>
+
+<p class=3DMsoNormal><o:p>&nbsp;</o:p></p>
+
+</div>
+
+</body>
+
+</html>
+
+------=_NextPart_01C89573.42B3B3B0
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Classification.Overview_files/themedata.thmx
+Content-Transfer-Encoding: base64
+Content-Type: application/vnd.ms-officetheme
+
+UEsDBBQABgAIAAAAIQCCirwT+gAAABwCAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbKyRy2rDMBBF
+94X+g9C22HK6KKXYzqJJd30s0g8Y5LEtao+ENAnJ33fsuFC6CC10IxBizpl7Va6P46AOGJPzVOlV
+XmiFZH3jqKv0++4pu9cqMVADgyes9AmTXtfXV+XuFDApmaZU6Z45PBiTbI8jpNwHJHlpfRyB5Ro7
+E8B+QIfmtijujPXESJzxxNB1+SoLRNegeoPILzCKx7Cg8Pv5DCSAmAtYq8czYVqi0hDC4CywRDAH
+an7oM9+2zmLj7X4UaT6DF9jNBDO/XGD1P+ov5wZb2A+stkfp4lx/xCH9LdtSay6Tc/7Uu5AuGC6X
+t7Rh5r+tPwEAAP//AwBQSwMEFAAGAAgAAAAhAKXWp+fAAAAANgEAAAsAAABfcmVscy8ucmVsc4SP
+z2rDMAyH74W9g9F9UdLDGCV2L6WQQy+jfQDhKH9oIhvbG+vbT8cGCrsIhKTv96k9/q6L+eGU5yAW
+mqoGw+JDP8to4XY9v3+CyYWkpyUIW3hwhqN727VfvFDRozzNMRulSLYwlRIPiNlPvFKuQmTRyRDS
+SkXbNGIkf6eRcV/XH5ieGeA2TNP1FlLXN2Cuj6jJ/7PDMMyeT8F/ryzlRQRuN5RMaeRioagv41O9
+kKhlqtQe0LW4+db9AQAA//8DAFBLAwQUAAYACAAAACEAa3mWFoMAAACKAAAAHAAAAHRoZW1lL3Ro
+ZW1lL3RoZW1lTWFuYWdlci54bWwMzE0KwyAQQOF9oXeQ2TdjuyhFYrLLrrv2AEOcGkHHoNKf29fl
+44M3zt8U1ZtLDVksnAcNimXNLoi38Hwspxuo2kgcxSxs4ccV5ul4GMm0jRPfSchzUX0j1ZCFrbXd
+INa1K9Uh7yzdXrkkaj2LR1fo0/cp4kXrKyYKAjj9AQAA//8DAFBLAwQUAAYACAAAACEAlrWt4pYG
+AABQGwAAFgAAAHRoZW1lL3RoZW1lL3RoZW1lMS54bWzsWU9v2zYUvw/YdyB0b2MndhoHdYrYsZst
+TRvEboceaYmW2FCiQNJJfRva44ABw7phhxXYbYdhW4EW2KX7NNk6bB3Qr7BHUpLFWF6SNtiKrT4k
+Evnj+/8eH6mr1+7HDB0SISlP2l79cs1DJPF5QJOw7d0e9i+teUgqnASY8YS0vSmR3rWN99+7itdV
+RGKCYH0i13Hbi5RK15eWpA/DWF7mKUlgbsxFjBW8inApEPgI6MZsablWW12KMU08lOAYyN4aj6lP
+0FCT9DZy4j0Gr4mSesBnYqBJE2eFwQYHdY2QU9llAh1i1vaAT8CPhuS+8hDDUsFE26uZn7e0cXUJ
+r2eLmFqwtrSub37ZumxBcLBseIpwVDCt9xutK1sFfQNgah7X6/W6vXpBzwCw74OmVpYyzUZ/rd7J
+aZZA9nGedrfWrDVcfIn+ypzMrU6n02xlsliiBmQfG3P4tdpqY3PZwRuQxTfn8I3OZre76uANyOJX
+5/D9K63Vhos3oIjR5GAOrR3a72fUC8iYs+1K+BrA12oZfIaCaCiiS7MY80QtirUY3+OiDwANZFjR
+BKlpSsbYhyju4ngkKNYM8DrBpRk75Mu5Ic0LSV/QVLW9D1MMGTGj9+r596+eP0XHD54dP/jp+OHD
+4wc/WkLOqm2chOVVL7/97M/HH6M/nn7z8tEX1XhZxv/6wye//Px5NRDSZybOiy+f/PbsyYuvPv39
+u0cV8E2BR2X4kMZEopvkCO3zGBQzVnElJyNxvhXDCNPyis0klDjBmksF/Z6KHPTNKWaZdxw5OsS1
+4B0B5aMKeH1yzxF4EImJohWcd6LYAe5yzjpcVFphR/MqmXk4ScJq5mJSxu1jfFjFu4sTx7+9SQp1
+Mw9LR/FuRBwx9xhOFA5JQhTSc/yAkArt7lLq2HWX+oJLPlboLkUdTCtNMqQjJ5pmi7ZpDH6ZVukM
+/nZss3sHdTir0nqLHLpIyArMKoQfEuaY8TqeKBxXkRzimJUNfgOrqErIwVT4ZVxPKvB0SBhHvYBI
+WbXmlgB9S07fwVCxKt2+y6axixSKHlTRvIE5LyO3+EE3wnFahR3QJCpjP5AHEKIY7XFVBd/lbobo
+d/ADTha6+w4ljrtPrwa3aeiINAsQPTMR2pdQqp0KHNPk78oxo1CPbQxcXDmGAvji68cVkfW2FuJN
+2JOqMmH7RPldhDtZdLtcBPTtr7lbeJLsEQjz+Y3nXcl9V3K9/3zJXZTPZy20s9oKZVf3DbYpNi1y
+vLBDHlPGBmrKyA1pmmQJ+0TQh0G9zpwOSXFiSiN4zOq6gwsFNmuQ4OojqqJBhFNosOueJhLKjHQo
+UcolHOzMcCVtjYcmXdljYVMfGGw9kFjt8sAOr+jh/FxQkDG7TWgOnzmjFU3grMxWrmREQe3XYVbX
+Qp2ZW92IZkqdw61QGXw4rxoMFtaEBgRB2wJWXoXzuWYNBxPMSKDtbvfe3C3GCxfpIhnhgGQ+0nrP
++6hunJTHirkJgNip8JE+5J1itRK3lib7BtzO4qQyu8YCdrn33sRLeQTPvKTz9kQ6sqScnCxBR22v
+1VxuesjHadsbw5kWHuMUvC51z4dZCBdDvhI27E9NZpPlM2+2csXcJKjDNYW1+5zCTh1IhVRbWEY2
+NMxUFgIs0Zys/MtNMOtFKWAj/TWkWFmDYPjXpAA7uq4l4zHxVdnZpRFtO/ualVI+UUQMouAIjdhE
+7GNwvw5V0CegEq4mTEXQL3CPpq1tptzinCVd+fbK4Ow4ZmmEs3KrUzTPZAs3eVzIYN5K4oFulbIb
+5c6vikn5C1KlHMb/M1X0fgI3BSuB9oAP17gCI52vbY8LFXGoQmlE/b6AxsHUDogWuIuFaQgquEw2
+/wU51P9tzlkaJq3hwKf2aYgEhf1IRYKQPShLJvpOIVbP9i5LkmWETESVxJWpFXtEDgkb6hq4qvd2
+D0UQ6qaaZGXA4E7Gn/ueZdAo1E1OOd+cGlLsvTYH/unOxyYzKOXWYdPQ5PYvRKzYVe16szzfe8uK
+6IlZm9XIswKYlbaCVpb2rynCObdaW7HmNF5u5sKBF+c1hsGiIUrhvgfpP7D/UeEz+2VCb6hDvg+1
+FcGHBk0Mwgai+pJtPJAukHZwBI2THbTBpElZ02atk7ZavllfcKdb8D1hbC3ZWfx9TmMXzZnLzsnF
+izR2ZmHH1nZsoanBsydTFIbG+UHGOMZ80ip/deKje+DoLbjfnzAlTTDBNyWBofUcmDyA5LcczdKN
+vwAAAP//AwBQSwMEFAAGAAgAAAAhAA3RkJ+2AAAAGwEAACcAAAB0aGVtZS90aGVtZS9fcmVscy90
+aGVtZU1hbmFnZXIueG1sLnJlbHOEj00KwjAUhPeCdwhvb9O6EJEm3YjQrdQDhOQ1DTY/JFHs7Q2u
+LAguh2G+mWm7l53JE2My3jFoqhoIOumVcZrBbbjsjkBSFk6J2TtksGCCjm837RVnkUsoTSYkUigu
+MZhyDidKk5zQilT5gK44o49W5CKjpkHIu9BI93V9oPGbAXzFJL1iEHvVABmWUJr/s/04GolnLx8W
+Xf5RQXPZhQUoosbM4CObqkwEylu6usTfAAAA//8DAFBLAQItABQABgAIAAAAIQCCirwT+gAAABwC
+AAATAAAAAAAAAAAAAAAAAAAAAABbQ29udGVudF9UeXBlc10ueG1sUEsBAi0AFAAGAAgAAAAhAKXW
+p+fAAAAANgEAAAsAAAAAAAAAAAAAAAAAKwEAAF9yZWxzLy5yZWxzUEsBAi0AFAAGAAgAAAAhAGt5
+lhaDAAAAigAAABwAAAAAAAAAAAAAAAAAFAIAAHRoZW1lL3RoZW1lL3RoZW1lTWFuYWdlci54bWxQ
+SwECLQAUAAYACAAAACEAlrWt4pYGAABQGwAAFgAAAAAAAAAAAAAAAADRAgAAdGhlbWUvdGhlbWUv
+dGhlbWUxLnhtbFBLAQItABQABgAIAAAAIQAN0ZCftgAAABsBAAAnAAAAAAAAAAAAAAAAAJsJAAB0
+aGVtZS90aGVtZS9fcmVscy90aGVtZU1hbmFnZXIueG1sLnJlbHNQSwUGAAAAAAUABQBdAQAAlgoA
+AAAA
+
+------=_NextPart_01C89573.42B3B3B0
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Classification.Overview_files/colorschememapping.xml
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/xml
+
+<?xml version=3D"1.0" encoding=3D"UTF-8" standalone=3D"yes"?>
+<a:clrMap xmlns:a=3D"http://schemas.openxmlformats.org/drawingml/2006/main"=
+ bg1=3D"lt1" tx1=3D"dk1" bg2=3D"lt2" tx2=3D"dk2" accent1=3D"accent1" accent=
+2=3D"accent2" accent3=3D"accent3" accent4=3D"accent4" accent5=3D"accent5" a=
+ccent6=3D"accent6" hlink=3D"hlink" folHlink=3D"folHlink"/>
+------=_NextPart_01C89573.42B3B3B0
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Classification.Overview_files/header.htm
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/html; charset="us-ascii"
+
+<html xmlns:v=3D"urn:schemas-microsoft-com:vml"
+xmlns:o=3D"urn:schemas-microsoft-com:office:office"
+xmlns:w=3D"urn:schemas-microsoft-com:office:word"
+xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml"
+xmlns=3D"http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=3DContent-Type content=3D"text/html; charset=3Dus-ascii">
+<meta name=3DProgId content=3DWord.Document>
+<meta name=3DGenerator content=3D"Microsoft Word 12">
+<meta name=3DOriginator content=3D"Microsoft Word 12">
+<link id=3DMain-File rel=3DMain-File
+href=3D"../Microsoft.VisualStudio.Text.Classification.Overview.htm">
+<![if IE]>
+<base
+href=3D"file:///C:\515CB117\Microsoft.VisualStudio.Text.Classification.Over=
+view_files\header.htm"
+id=3D"webarch_temp_base_tag">
+<![endif]>
+</head>
+
+<body lang=3DEN-US link=3Dblue vlink=3Dpurple>
+
+<div style=3D'mso-element:footnote-separator' id=3Dfs>
+
+<p class=3DMsoNormal><span style=3D'mso-special-character:footnote-separato=
+r'><![if !supportFootnotes]>
+
+<hr align=3Dleft size=3D1 width=3D"33%">
+
+<![endif]></span></p>
+
+</div>
+
+<div style=3D'mso-element:footnote-continuation-separator' id=3Dfcs>
+
+<p class=3DMsoNormal><span style=3D'mso-special-character:footnote-continua=
+tion-separator'><![if !supportFootnotes]>
+
+<hr align=3Dleft size=3D1>
+
+<![endif]></span></p>
+
+</div>
+
+<div style=3D'mso-element:endnote-separator' id=3Des>
+
+<p class=3DMsoNormal><span style=3D'mso-special-character:footnote-separato=
+r'><![if !supportFootnotes]>
+
+<hr align=3Dleft size=3D1 width=3D"33%">
+
+<![endif]></span></p>
+
+</div>
+
+<div style=3D'mso-element:endnote-continuation-separator' id=3Decs>
+
+<p class=3DMsoNormal><span style=3D'mso-special-character:footnote-continua=
+tion-separator'><![if !supportFootnotes]>
+
+<hr align=3Dleft size=3D1>
+
+<![endif]></span></p>
+
+</div>
+
+</body>
+
+</html>
+
+------=_NextPart_01C89573.42B3B3B0
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Classification.Overview_files/filelist.xml
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/xml; charset="utf-8"
+
+<xml xmlns:o=3D"urn:schemas-microsoft-com:office:office">
+ <o:MainFile HRef=3D"../Microsoft.VisualStudio.Text.Classification.Overview=
+.htm"/>
+ <o:File HRef=3D"themedata.thmx"/>
+ <o:File HRef=3D"colorschememapping.xml"/>
+ <o:File HRef=3D"header.htm"/>
+ <o:File HRef=3D"filelist.xml"/>
+</xml>
+------=_NextPart_01C89573.42B3B3B0--
diff --git a/src/Text/Def/TextLogic/Diagrams/Tagging.cd b/src/Text/Def/TextLogic/Diagrams/Tagging.cd
new file mode 100644
index 0000000..7be15b0
--- /dev/null
+++ b/src/Text/Def/TextLogic/Diagrams/Tagging.cd
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+ <Comment CommentText="Provision - extension points for creating taggers on source buffers.">
+ <Position X="3.542" Y="0.802" Height="0.75" Width="1.7" />
+ </Comment>
+ <Comment CommentText="Aggregation is a provided service that takes care of creating, projecting, and aggregating tags/taggers over a buffer or view. Currently, consumers of tagging must consume tags by getting aggregators for the buffer or view they are interested in (there is no explicit ITagConsumer or the like). The buffer version of this service is here, in TextLogic, and the view version is in TextUI (IVewTagAggregatorFactoryService).">
+ <Position X="10.782" Y="0.541" Height="1.625" Width="3.064" />
+ </Comment>
+ <Comment CommentText=" &lt;-- Tag Creation Aggregation --&gt;">
+ <Position X="7" Y="3.875" Height="0.802" Width="2.356" />
+ </Comment>
+ <Comment CommentText="On the consumer side, tags are retrieved by passing in a SnapshotSpan and returned as MappingTagSpans. The change event at this level is in terms of mapping spans.">
+ <Position X="8.75" Y="4.865" Height="1.729" Width="2.148" />
+ </Comment>
+ <Comment CommentText="On the producer side, tags are retrieved (by the aggregator) by passing in a NormalizedSnapshotSpanCollection, and returned as TagSpans. In this way, producers need have no knowledge of projection/buffer graphs. The change event at this level also is in terms of SnapshotSpans.">
+ <Position X="5.635" Y="4.875" Height="1.75" Width="2.096" />
+ </Comment>
+ <Class Name="Microsoft.VisualStudio.Text.Tagging.TagSpan&lt;T&gt;">
+ <Position X="1.75" Y="2.75" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAA=</HashCode>
+ <FileName>Tagging\TagSpan.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.Tagging.MappingTagSpan&lt;T&gt;" Collapsed="true">
+ <Position X="13.75" Y="3.75" Width="2" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAA=</HashCode>
+ <FileName>Tagging\MappingTagSpan.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.Tagging.TagsChangedEventArgs" Collapsed="true">
+ <Position X="13.75" Y="4.5" Width="2.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAA=</HashCode>
+ <FileName>Tagging\TagsChangedEventArgs.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Interface Name="Microsoft.VisualStudio.Text.Tagging.ITagAggregator&lt;T&gt;">
+ <Position X="11" Y="3.75" Width="2.5" />
+ <TypeIdentifier>
+ <HashCode>AAAAAIAAQAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAIA=</HashCode>
+ <FileName>Tagging\ITagAggregator.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Tagging.IBufferTagAggregatorFactoryService">
+ <Position X="10.75" Y="2.25" Width="3" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Tagging\IBufferTagAggregatorFactoryService.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Tagging.ITagger&lt;T&gt;">
+ <Position X="3.75" Y="3.75" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>AAAAAIAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Tagging\ITagger.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Tagging.ITaggerProvider">
+ <Position X="3.5" Y="2.25" Width="2" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Tagging\ITaggerProvider.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Tagging.ITag" Collapsed="true">
+ <Position X="7.5" Y="2.25" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Tagging\ITag.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Font Name="Segoe UI" Size="9" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/Diagrams/Undo.cd b/src/Text/Def/TextLogic/Diagrams/Undo.cd
new file mode 100644
index 0000000..2edfbad
--- /dev/null
+++ b/src/Text/Def/TextLogic/Diagrams/Undo.cd
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1" MembersFormat="NameAndType">
+ <Comment CommentText="Clients use the tb undo manager to get the UndoHistory so that they can create transactions. Serves the same purpose as the undo history registry -- do we need both?">
+ <Position X="2.344" Y="7.48" Height="1.719" Width="1.7" />
+ </Comment>
+ <Comment CommentText="RegisterHistory is called on each text buffer by EditorOperations; it returns an undo history">
+ <Position X="7.687" Y="7.153" Height="1.01" Width="1.7" />
+ </Comment>
+ <Comment CommentText="Platform callers to Undo &amp; Redo: none are in VS.&#xD;&#xA;1. DefaultKeyProcessor &#xD;&#xA;2. Masticater&#xD;&#xA;3. Various tests&#xD;&#xA;4. Undo margin&#xD;&#xA;">
+ <Position X="2.938" Y="3.125" Height="1.938" Width="1.7" />
+ </Comment>
+ <Comment CommentText="TBUndoManager registers undo history with buffer; listens for changes and creates undo transaction if none has been already created&#xD;&#xA;">
+ <Position X="0.583" Y="2.781" Height="1.5" Width="1.7" />
+ </Comment>
+ <Interface Name="Microsoft.VisualStudio.Text.Operations.IMergeTextUndoTransactionPolicy">
+ <Position X="8.75" Y="4.75" Width="2.75" />
+ <TypeIdentifier>
+ <HashCode>AAgAAAAAAAAAAAQAAQAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Undo\IMergeTextUndoTransactionPolicy.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Operations.ITextUndoHistoryRegistry">
+ <Position X="4.75" Y="6.5" Width="2.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAAAAIAAAAAgAAAgAAACAEAAAAAA=</HashCode>
+ <FileName>Undo\ITextUndoHistoryRegistry.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Operations.ITextUndoPrimitive">
+ <Position X="12.75" Y="0.5" Width="1.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAABAAABAAAAQAAQAAACAAAAQAAAAAAAAEAAAA=</HashCode>
+ <FileName>Undo\ITextUndoPrimitive.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Operations.ITextBufferUndoManager">
+ <Position X="0.5" Y="0.75" Width="3" />
+ <TypeIdentifier>
+ <HashCode>AEAAAAAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Undo\ITextBufferUndoManager.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Operations.ITextBufferUndoManagerProvider">
+ <Position X="0.5" Y="5.75" Width="3.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Undo\ITextBufferUndoManagerProvider.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Operations.ITextUndoHistory">
+ <Position X="4.5" Y="0.5" Width="3" />
+ <TypeIdentifier>
+ <HashCode>CAAAAAAAJAAABQAAAAAAAABBAAAAAgAgIAAABQEAoAA=</HashCode>
+ <FileName>Undo\ITextUndoHistory.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="LastUndoTransaction" />
+ <Property Name="CurrentTransaction" />
+ <Property Name="State" />
+ <Property Name="LastRedoTransaction" />
+ </ShowAsAssociation>
+ <ShowAsCollectionAssociation>
+ <Property Name="RedoStack" />
+ <Property Name="UndoStack" />
+ </ShowAsCollectionAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Operations.ITextUndoTransaction">
+ <Position X="9.25" Y="0.5" Width="1.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAARCAgBAIAAAAAQAAACAAAIgAAAAACBAEAAAA=</HashCode>
+ <FileName>Undo\ITextUndoTransaction.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="MergePolicy" />
+ <Property Name="State" />
+ <Property Name="History" />
+ <Property Name="Parent" />
+ </ShowAsAssociation>
+ <ShowAsCollectionAssociation>
+ <Property Name="UndoPrimitives" />
+ </ShowAsCollectionAssociation>
+ </Interface>
+ <Enum Name="Microsoft.VisualStudio.Text.Operations.TextUndoHistoryState">
+ <Position X="5.25" Y="4.75" Width="1.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAABAAAAAAAAAAAAQAAAAAAAAAAAAAAAAQAAAAAA=</HashCode>
+ <FileName>Undo\TextUndoHistoryState.cs</FileName>
+ </TypeIdentifier>
+ </Enum>
+ <Enum Name="Microsoft.VisualStudio.Text.Operations.UndoTransactionState">
+ <Position X="13" Y="4.5" Width="1.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAEAAAIAIAgAAQAAAAAAAAAAAAAAAAQQAAAAA=</HashCode>
+ <FileName>Undo\TextUndoTransactionState.cs</FileName>
+ </TypeIdentifier>
+ </Enum>
+ <Font Name="Segoe UI" Size="9" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/DifferenceBuffer/DifferenceBufferOptions.cs b/src/Text/Def/TextLogic/DifferenceBuffer/DifferenceBufferOptions.cs
new file mode 100644
index 0000000..c5dd9e1
--- /dev/null
+++ b/src/Text/Def/TextLogic/DifferenceBuffer/DifferenceBufferOptions.cs
@@ -0,0 +1,31 @@
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ public static class DifferenceBufferOptions
+ {
+ /// <summary>
+ /// What type of whitespace, if any, to ignore when performing line-level differencing.
+ /// </summary>
+ public static readonly EditorOptionKey<IgnoreWhiteSpaceBehavior> IgnoreWhiteSpaceBehaviorId = new EditorOptionKey<IgnoreWhiteSpaceBehavior>(IgnoreWhiteSpaceBehaviorName);
+ public const string IgnoreWhiteSpaceBehaviorName = "Diff/Buffer/IgnoreWhitespaceBehavior";
+
+ /// <summary>
+ /// Whether or not to ignore case when performing line-level differencing.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> IgnoreCaseId = new EditorOptionKey<bool>(IgnoreCaseName);
+ public const string IgnoreCaseName = "Diff/Buffer/IgnoreCase";
+ }
+
+ /// <summary>
+ /// A base class that can be used for options that are specific to an <see cref="IDifferenceBuffer"/>.
+ /// </summary>
+ public abstract class DifferenceBufferOption<T> : EditorOptionDefinition<T>
+ {
+ public override bool IsApplicableToScope(IPropertyOwner scope)
+ {
+ return scope is IDifferenceBuffer;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/DifferenceBuffer/DifferenceMappingMode.cs b/src/Text/Def/TextLogic/DifferenceBuffer/DifferenceMappingMode.cs
new file mode 100644
index 0000000..36e691c
--- /dev/null
+++ b/src/Text/Def/TextLogic/DifferenceBuffer/DifferenceMappingMode.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.VisualStudio.Text.Projection;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// The mapping modes that can be used when mapping points inside a difference between the left and right snapshots.
+ /// </summary>
+ public enum DifferenceMappingMode
+ {
+ /// <summary>
+ /// Map any point in a difference to the start of the corresponding difference in the other snapshot.
+ /// </summary>
+ Start,
+
+ /// <summary>
+ /// Map any point in a difference to the corresponding line/column of the corresponding difference in the other snapshot.
+ /// </summary>
+ /// <remarks>
+ /// If the difference is in the other snapshot doesn't have a corresponding line the point will be mapped to the end of the difference.
+ /// If the column if greater than the length of the corresponding line in the other snapshpt, then the point will be mapped to the end of the corresponding line.
+ /// </remarks>
+ LineColumn,
+
+ /// <summary>
+ /// Map any point in a difference to the end of the corresponding difference in the other snapshot.
+ /// </summary>
+ End
+ }
+}
diff --git a/src/Text/Def/TextLogic/DifferenceBuffer/DifferenceTrackingSpans.cs b/src/Text/Def/TextLogic/DifferenceBuffer/DifferenceTrackingSpans.cs
new file mode 100644
index 0000000..0eb0559
--- /dev/null
+++ b/src/Text/Def/TextLogic/DifferenceBuffer/DifferenceTrackingSpans.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// Tracking spans for an <see cref="ISnapshotDifference"/> for the various line and word differences.
+ /// </summary>
+ public interface IDifferenceTrackingSpanCollection
+ {
+ /// <summary>
+ /// Removed line spans, against the <see cref="IDifferenceBuffer.LeftBuffer"/>.
+ /// </summary>
+ IEnumerable<ITrackingSpan> RemovedLineSpans { get; }
+
+ /// <summary>
+ /// Removed word spans, against the <see cref="IDifferenceBuffer.LeftBuffer"/>.
+ /// </summary>
+ IEnumerable<ITrackingSpan> RemovedWordSpans { get; }
+
+
+ /// <summary>
+ /// Added line spans, against the <see cref="IDifferenceBuffer.RightBuffer"/>.
+ /// </summary>
+ IEnumerable<ITrackingSpan> AddedLineSpans { get; }
+
+ /// <summary>
+ /// Added line spans, against the <see cref="IDifferenceBuffer.RightBuffer"/>.
+ /// </summary>
+ IEnumerable<ITrackingSpan> AddedWordSpans { get; }
+ }
+}
diff --git a/src/Text/Def/TextLogic/DifferenceBuffer/IDifferenceBuffer.cs b/src/Text/Def/TextLogic/DifferenceBuffer/IDifferenceBuffer.cs
new file mode 100644
index 0000000..98bda0d
--- /dev/null
+++ b/src/Text/Def/TextLogic/DifferenceBuffer/IDifferenceBuffer.cs
@@ -0,0 +1,133 @@
+using System;
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Text.Projection;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// A difference buffer constantly computes the differences between two <see cref="ITextBuffer"/>s,
+ /// providing an <see cref="IProjectionBuffer"/>, <see cref="IDifferenceBuffer.InlineBuffer"/>, that
+ /// contains the differences between the two <see cref="ITextBuffer"/>s in an inline difference.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// The differences are computed on a background thread in response to various changes (text change,
+ /// options changing, etc.), though all of the events around differencing, like <see cref="SnapshotDifferenceChanged"/>,
+ /// will be raised on the thread that owns the <see cref="LeftBuffer"/> and <see cref="RightBuffer"/> (generally,
+ /// the UI thread).
+ /// </para>
+ /// <para>
+ /// Because the differences are computed asynchronously, the <see cref="CurrentSnapshotDifference"/> may be
+ /// behind the current versions of any of the buffers, and will be <c>null</c> before the first difference
+ /// is computed.
+ /// </para>
+ /// </remarks>
+ public interface IDifferenceBuffer : IDisposable, IPropertyOwner
+ {
+ /// <summary>
+ /// The source of the left buffer in the difference.
+ /// </summary>
+ ITextBuffer BaseLeftBuffer { get; }
+
+ /// <summary>
+ /// The left buffer of the difference.
+ /// </summary>
+ /// <remarks>This is a projection of the BaseLeftBuffer that has been made read-only. It's contents are identical to the contents of BaseLeftBuffer.</remarks>
+ ITextBuffer LeftBuffer { get; }
+
+ /// <summary>
+ /// The source of the right buffer in the difference.
+ /// </summary>
+ ITextBuffer BaseRightBuffer { get; }
+
+ /// <summary>
+ /// The right buffer in the difference.
+ /// </summary>
+ /// <remarks>
+ /// <para>This will either be equal to the BaseRightBuffer or it will be a projection of the BaseRightBuffer that has been made read-only. It's contents are identical to the contents of BaseRightBuffer.</para>
+ ///
+ /// </remarks>
+ ITextBuffer RightBuffer { get; }
+
+ /// <summary>
+ /// The top-level buffer, which contains the differences combined.
+ /// </summary>
+ IProjectionBuffer InlineBuffer { get; }
+
+ /// <summary>
+ /// The currently-used snapshot difference that matches up with the current snapshot
+ /// of <see cref="InlineBuffer"/>.
+ /// </summary>
+ /// <remarks>Will be <c>null</c> before the first snapshot difference is computed.</remarks>
+ ISnapshotDifference CurrentSnapshotDifference { get; }
+
+ /// <summary>
+ /// The snapshot of <see cref="InlineBuffer"/> that corresponds to the state at
+ /// which <see cref="CurrentSnapshotDifference"/> is current.
+ /// </summary>
+ /// <remarks>Will be <c>null</c> if <see cref="CurrentSnapshotDifference"/> is <c>null</c>.</remarks>
+ IProjectionSnapshot CurrentInlineBufferSnapshot { get; }
+
+ /// <summary>
+ /// Raised immediately before the <see cref="CurrentSnapshotDifference"/> and
+ /// <see cref="InlineBuffer"/> are updated.
+ /// </summary>
+ event EventHandler<SnapshotDifferenceChangeEventArgs> SnapshotDifferenceChanging;
+
+ /// <summary>
+ /// Raised when the <see cref="CurrentSnapshotDifference"/> and
+ /// <see cref="InlineBuffer"/> have changed.
+ /// </summary>
+ event EventHandler<SnapshotDifferenceChangeEventArgs> SnapshotDifferenceChanged;
+
+ #region Customization settings
+
+ /// <summary>
+ /// Used to modify general difference buffer options (<see cref="DifferenceBufferOptions"/>).
+ /// </summary>
+ IEditorOptions Options { get; }
+
+ /// <summary>
+ /// Used to get or set the options used in differencing the two buffers. These options are used
+ /// in calls to the <see cref="IHierarchicalStringDifferenceService"/> that performs the actual
+ /// comparison.
+ /// </summary>
+ StringDifferenceOptions DifferenceOptions { get; set; }
+
+ /// <summary>
+ /// Is editing disabled in this <see cref="IDifferenceBuffer"/>?
+ /// </summary>
+ /// <remarks><para>If true, then this.RightBuffer is a read-only projection of this.BaseRightBuffer.</para></remarks>
+ bool IsEditingDisabled { get; }
+
+ /// <summary>
+ /// Add a predicate to selectively ignore differences.
+ /// </summary>
+ /// <param name="predicate">A predicate to be called for every computed line difference.</param>
+ void AddIgnoreDifferencePredicate(IgnoreDifferencePredicate predicate);
+
+ /// <summary>
+ /// Remove a predicate previously added with <see cref="AddIgnoreDifferencePredicate"/>.
+ /// </summary>
+ /// <param name="predicate">The predicate to remove.</param>
+ /// <returns><c>true</c> if the predicate was found and removed, <c>false</c> otherwise.</returns>
+ bool RemoveIgnoreDifferencePredicate(IgnoreDifferencePredicate predicate);
+
+ /// <summary>
+ /// Add a custom <see cref="SnapshotLineTransform"/>, which can modify lines of text before they are
+ /// compared.
+ /// </summary>
+ /// <param name="transform">The transform to add.</param>
+ void AddSnapshotLineTransform(SnapshotLineTransform transform);
+
+ /// <summary>
+ /// Remove a custom <see cref="SnapshotLineTransform"/> previously added with <see cref="AddSnapshotLineTransform"/>.
+ /// </summary>
+ /// <param name="transform">The transform to remove.</param>
+ /// <returns><c>true</c> if the transform was found and removed, <c>false</c> otherwise.</returns>
+ bool RemoveSnapshotLineTransform(SnapshotLineTransform transform);
+
+ #endregion
+ }
+}
diff --git a/src/Text/Def/TextLogic/DifferenceBuffer/IDifferenceBufferFactoryService.cs b/src/Text/Def/TextLogic/DifferenceBuffer/IDifferenceBufferFactoryService.cs
new file mode 100644
index 0000000..7b519a4
--- /dev/null
+++ b/src/Text/Def/TextLogic/DifferenceBuffer/IDifferenceBufferFactoryService.cs
@@ -0,0 +1,46 @@
+using Microsoft.VisualStudio.Text.Projection;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// A factory for creating <see cref="IDifferenceBuffer"/> instances.
+ /// </summary>
+ /// <remarks>
+ /// This is a MEF service and can be imported.
+ /// </remarks>
+ public interface IDifferenceBufferFactoryService
+ {
+ /// <summary>
+ /// Create an <see cref="IDifferenceBuffer"/> for the given left and right buffers.
+ /// </summary>
+ /// <param name="leftBaseBuffer">The left (old, before) buffer.</param>
+ /// <param name="rightBaseBuffer">The right (new, after) buffer.</param>
+ /// <remarks>This is equivalent to calling <code>CreateDifferenceBuffer(left, right, new StringDifferenceOptions());</code>.</remarks>
+ IDifferenceBuffer CreateDifferenceBuffer(ITextBuffer leftBaseBuffer, ITextBuffer rightBaseBuffer);
+
+ /// <summary>
+ /// Create an <see cref="IDifferenceBuffer"/> for the given left and right buffers and with the given difference options.
+ /// </summary>
+ /// <param name="leftBaseBuffer">The left (old, before) buffer.</param>
+ /// <param name="rightBaseBuffer">The right (new, after) buffer.</param>
+ /// <param name="options">The options to use in computing differences between the buffers.</param>
+ /// <param name="disableEditing">If true, disable editing in the right and inlines views.</param>
+ /// <param name="wrapLeftBuffer">If true, create a read-only projection of <paramref name="leftBaseBuffer"/> (which will prevent
+ /// that buffer from being modified through the difference buffers).</param>
+ /// <param name="wrapRightBuffer">If true and editing is disabled, create a read-only projection of <paramref name="rightBaseBuffer"/> (which will prevent
+ /// that buffer from being modified through the difference buffers).</param>
+ /// <remarks>
+ /// <para>If <paramref name="disableEditing"/> is false, then <paramref name="wrapRightBuffer"/> is ignored (and the right buffer will not be wrapped).</para>
+ /// <para>If <paramref name="wrapLeftBuffer"/> is false, then the caller of this method is responsible for making sure <paramref name="leftBaseBuffer"/> is read-only.</para>
+ /// <para>If <paramref name="disableEditing"/> is true and <paramref name="wrapRightBuffer"/> is false, then the caller of this method is responsible for making sure <paramref name="rightBaseBuffer"/> is read-only.</para>
+ /// </remarks>
+ IDifferenceBuffer CreateDifferenceBuffer(ITextBuffer leftBaseBuffer, ITextBuffer rightBaseBuffer, StringDifferenceOptions options,
+ bool disableEditing = false, bool wrapLeftBuffer = true, bool wrapRightBuffer = true);
+
+ /// <summary>
+ /// If there is a <see cref="IDifferenceBuffer"/> for the given projection buffer, retrieve it.
+ /// </summary>
+ /// <returns>The difference buffer if one exists, <c>null</c> otherwise.</returns>
+ IDifferenceBuffer TryGetDifferenceBuffer(IProjectionBufferBase projectionBuffer);
+ }
+}
diff --git a/src/Text/Def/TextLogic/DifferenceBuffer/ISnapshotDifference.cs b/src/Text/Def/TextLogic/DifferenceBuffer/ISnapshotDifference.cs
new file mode 100644
index 0000000..4cdd1e8
--- /dev/null
+++ b/src/Text/Def/TextLogic/DifferenceBuffer/ISnapshotDifference.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.VisualStudio.Text.Projection;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// A set of differences between two <see cref="ITextSnapshot"/>s. These are created by
+ /// an <see cref="IDifferenceBuffer"/>, and are valid to a specific set of snapshots for the
+ /// <see cref="IDifferenceBuffer.LeftBuffer"/>/<see cref="IDifferenceBuffer.RightBuffer"/> and
+ /// the <see cref="StringDifferenceOptions"/> and collections of <see cref="SnapshotLineTransform"/>
+ /// and <see cref="IgnoreDifferencePredicate"/> in place at that time.
+ /// </summary>
+ public interface ISnapshotDifference
+ {
+ /// <summary>
+ /// The <see cref="IDifferenceBuffer"/> that generated this difference.
+ /// </summary>
+ /// <remarks>
+ /// To determine if this difference is current, you can compare it against
+ /// <see cref="IDifferenceBuffer.CurrentSnapshotDifference"/>.
+ /// </remarks>
+ IDifferenceBuffer DifferenceBuffer { get; }
+
+ /// <summary>
+ /// The snapshot of the left buffer used to compute this difference.
+ /// </summary>
+ ITextSnapshot LeftBufferSnapshot { get; }
+
+ /// <summary>
+ /// The snapshot of the right buffer used to compute this difference.
+ /// </summary>
+ ITextSnapshot RightBufferSnapshot { get; }
+
+ /// <summary>
+ /// The snapshot generated for the inline buffer for this difference.
+ /// </summary>
+ IProjectionSnapshot InlineBufferSnapshot { get; }
+
+ /// <summary>
+ /// The difference options that were used to generate this difference.
+ /// </summary>
+ StringDifferenceOptions DifferenceOptions { get; }
+
+ /// <summary>
+ /// The line transforms that were used to generate this difference.
+ /// </summary>
+ IEnumerable<SnapshotLineTransform> SnapshotLineTransforms { get; }
+
+ /// <summary>
+ /// The ignore difference predicates that were used to generate this difference.
+ /// </summary>
+ IEnumerable<IgnoreDifferencePredicate> IgnoreDifferencePredicates { get; }
+
+ /// <summary>
+ /// The differences for this snapshot.
+ /// </summary>
+ /// <remarks>
+ /// To find word-level differences, use <see cref="IHierarchicalDifferenceCollection.HasContainedDifferences"/>
+ /// and <see cref="IHierarchicalDifferenceCollection.GetContainedDifferences"/>.
+ /// </remarks>
+ IHierarchicalDifferenceCollection LineDifferences { get; }
+
+ /// <summary>
+ /// The word and line difference spans as <see cref="ITrackingSpan"/>s against the left and right buffer.
+ /// </summary>
+ IDifferenceTrackingSpanCollection DifferenceSpans { get; }
+
+ #region Convenience methods
+
+ /// <summary>
+ /// Map a point from either the left or right buffer to the inline snapshot.
+ /// </summary>
+ /// <param name="point">The point to map up.</param>
+ /// <returns>A point in the <see cref="InlineBufferSnapshot"/>.</returns>
+ /// <remarks>This is equivalent to calling MapToSnapshot(point, snapshot.InlineBufferSnapshot).</remarks>
+ SnapshotPoint MapToInlineSnapshot(SnapshotPoint point);
+
+ /// <summary>
+ /// Find the match or difference that contains the specified point.
+ /// </summary>
+ /// <param name="point">Point for which to find the corresponding difference. This can be on the left, right or inline buffers.</param>
+ /// <param name="match">Match containing the <paramref name="point"/> (will be null if <paramref name="point"/> lies in a difference).</param>
+ /// <param name="difference">Difference containing the <paramref name="point"/> (will be null if <paramref name="point"/> lies in a match).</param>
+ /// <returns>Index of the matching difference.</returns>
+ /// <remarks>
+ /// <para> If the <paramref name="point"/> is contained in a match, then it is the index of the following difference. If <paramref name="point"/> is contained in a match
+ /// after the last difference, then index will be equal to the count of differences.</para></remarks>
+ int FindMatchOrDifference(SnapshotPoint point, out Match match, out Difference difference);
+
+ /// <summary>
+ /// Translate the specified point to the corresponding snapshot associated with snapshot difference.
+ /// </summary>
+ /// <param name="point">SnapshotPoint to translate.</param>
+ /// <returns><paramref name="point"/> translated from its snapshot to this.LeftBufferSnapshot, this.RightBufferSnapshot, or this.InlineBufferSnapshot.</returns>
+ SnapshotPoint TranslateToSnapshot(SnapshotPoint point);
+
+ /// <summary>
+ /// Map the specified <see cref="SnapshotPoint"/> in the inline buffer to its corresponding location in the left or right snapshots.
+ /// </summary>
+ /// <param name="inlinePoint">Point to map.</param>
+ /// <returns>Corresponding location on either the left or right buffers.</returns>
+ /// <remarks>
+ /// <para>Locations inside matching text will always map to the right buffer.</para>
+ /// </remarks>
+ SnapshotPoint MapToSourceSnapshot(SnapshotPoint inlinePoint);
+
+ /// <summary>
+ /// Map the specified <see cref="SnapshotPoint"/> to the specified <see cref="ITextSnapshot"/>.
+ /// </summary>
+ /// <param name="point">Point to map.</param>
+ /// <param name="target">Target snapshot</param>
+ /// <param name="mode">The mapping used when mapping between the left and right snapshots (or vs. versa) when <paramref name="point"/> lies inside a difference.</param>
+ /// <remarks>
+ /// <para>Mapping to the left or right buffers may be lossy. Points inside a difference will be mapped according to <paramref name="mode"/>.</para>
+ /// <para>Mapping between the inline snapshot and the source snapshots or vs. versa will, with one exception, be invertable. The exception is that a point between the \r\n
+ /// of a line break may be mapped to the end of the corresponding line.</para>
+ /// </remarks>
+ SnapshotPoint MapToSnapshot(SnapshotPoint point, ITextSnapshot target, DifferenceMappingMode mode = DifferenceMappingMode.LineColumn);
+
+ /// <summary>
+ /// Get the extent of the difference in the specified snapshot.
+ /// </summary>
+ /// <param name="difference"></param>
+ /// <param name="target"></param>
+ /// <returns></returns>
+ SnapshotSpan MapToSnapshot(Difference difference, ITextSnapshot target);
+
+ #endregion
+ }
+}
diff --git a/src/Text/Def/TextLogic/DifferenceBuffer/IgnoreDifferencePredicate.cs b/src/Text/Def/TextLogic/DifferenceBuffer/IgnoreDifferencePredicate.cs
new file mode 100644
index 0000000..5232a96
--- /dev/null
+++ b/src/Text/Def/TextLogic/DifferenceBuffer/IgnoreDifferencePredicate.cs
@@ -0,0 +1,12 @@
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// A custom predicate that the <see cref="IDifferenceBuffer"/> uses to selectively ignore differences.
+ /// </summary>
+ /// <param name="lineDifference">The lines that have changed. The <see cref="Difference.Left"/> and <see cref="Difference.Right"/> spans
+ /// are line numbers in the <paramref name="leftSnapshot"/> and <paramref name="rightSnapshot"/>, respectively.</param>
+ /// <param name="leftSnapshot">The snapshot of the <see cref="IDifferenceBuffer.LeftBuffer"/> being compared.</param>
+ /// <param name="rightSnapshot">The snapshot of the <see cref="IDifferenceBuffer.RightBuffer"/> being compared.</param>
+ /// <returns><c>true</c> to ignore the given difference, <c>false</c> to include it in the list of differences.</returns>
+ public delegate bool IgnoreDifferencePredicate(Difference lineDifference, ITextSnapshot leftSnapshot, ITextSnapshot rightSnapshot);
+}
diff --git a/src/Text/Def/TextLogic/DifferenceBuffer/IgnoreWhiteSpaceBehavior.cs b/src/Text/Def/TextLogic/DifferenceBuffer/IgnoreWhiteSpaceBehavior.cs
new file mode 100644
index 0000000..a0cb00a
--- /dev/null
+++ b/src/Text/Def/TextLogic/DifferenceBuffer/IgnoreWhiteSpaceBehavior.cs
@@ -0,0 +1,21 @@
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ public enum IgnoreWhiteSpaceBehavior
+ {
+ /// <summary>
+ /// Don't ignore whitespace.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// Ignore whitespace at the start and end of lines when performing line-level differencing.
+ /// </summary>
+ /// <remarks>This is equivalent to <see cref="StringDifferenceOptions.IgnoreTrimWhiteSpace"/>.</remarks>
+ IgnoreTrimWhiteSpace,
+
+ /// <summary>
+ /// Ignore all whitespace when performing line-level differencing.
+ /// </summary>
+ IgnoreAllWhiteSpace
+ }
+}
diff --git a/src/Text/Def/TextLogic/DifferenceBuffer/LineType.cs b/src/Text/Def/TextLogic/DifferenceBuffer/LineType.cs
new file mode 100644
index 0000000..dbf329e
--- /dev/null
+++ b/src/Text/Def/TextLogic/DifferenceBuffer/LineType.cs
@@ -0,0 +1,23 @@
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// The line type, as used in methods on <see cref="IDifferenceBuffer"/>.
+ /// </summary>
+ public enum LineType
+ {
+ /// <summary>
+ /// A line that was added, meaning it only appears in the right buffer.
+ /// </summary>
+ Added,
+
+ /// <summary>
+ /// A line that was removed, meaning it only appears in the left buffer.
+ /// </summary>
+ Removed,
+
+ /// <summary>
+ /// A line that appears in both the left and right buffer.
+ /// </summary>
+ Matched
+ }
+}
diff --git a/src/Text/Def/TextLogic/DifferenceBuffer/SnapshotDifferenceChangeEventArgs.cs b/src/Text/Def/TextLogic/DifferenceBuffer/SnapshotDifferenceChangeEventArgs.cs
new file mode 100644
index 0000000..d1276f4
--- /dev/null
+++ b/src/Text/Def/TextLogic/DifferenceBuffer/SnapshotDifferenceChangeEventArgs.cs
@@ -0,0 +1,34 @@
+using System;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// Used in conjunction with <see cref="IDifferenceBuffer.SnapshotDifferenceChanging"/> and
+ /// <see cref="IDifferenceBuffer.SnapshotDifferenceChanged"/>.
+ /// </summary>
+ public class SnapshotDifferenceChangeEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Create a change event from the given before and after <see cref="ISnapshotDifference"/>s.
+ /// </summary>
+ /// <param name="before">The <see cref="ISnapshotDifference"/> before the change (may be <c>null</c>).</param>
+ /// <param name="after">The <see cref="ISnapshotDifference"/> after the change.</param>
+ public SnapshotDifferenceChangeEventArgs(ISnapshotDifference before, ISnapshotDifference after)
+ {
+ Before = before; After = after;
+ }
+
+ /// <summary>
+ /// The <see cref="ISnapshotDifference"/> before the change, which is <c>null</c> for the
+ /// first change event.
+ /// </summary>
+ public ISnapshotDifference Before { get; private set; }
+
+ /// <summary>
+ /// The <see cref="ISnapshotDifference"/> after the change.
+ /// If this is a <see cref="IDifferenceBuffer.SnapshotDifferenceChanging"/>
+ /// event, this property will be <c>null</c>, as it hasn't been computed yet.
+ /// </summary>
+ public ISnapshotDifference After { get; private set; }
+ }
+}
diff --git a/src/Text/Def/TextLogic/DifferenceBuffer/SnapshotLineTransform.cs b/src/Text/Def/TextLogic/DifferenceBuffer/SnapshotLineTransform.cs
new file mode 100644
index 0000000..57ceda2
--- /dev/null
+++ b/src/Text/Def/TextLogic/DifferenceBuffer/SnapshotLineTransform.cs
@@ -0,0 +1,12 @@
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// A custom transform for text snapshot lines, to allow clients of <see cref="IDifferenceBuffer"/> to modify lines before
+ /// performing any comparison.
+ /// </summary>
+ /// <param name="line">The original snapshot line that this transform is being asked to operate on.</param>
+ /// <param name="currentText">The current text of the line, which may differ from <see cref="ITextSnapshotLine.GetText"/> if an
+ /// earlier transform has already processed the line.</param>
+ /// <returns>The new line text to use for the line.</returns>
+ public delegate string SnapshotLineTransform(ITextSnapshotLine line, string currentText);
+}
diff --git a/src/Text/Def/TextLogic/EditorOptions/DefaultOptions.cs b/src/Text/Def/TextLogic/EditorOptions/DefaultOptions.cs
new file mode 100644
index 0000000..6fffe2e
--- /dev/null
+++ b/src/Text/Def/TextLogic/EditorOptions/DefaultOptions.cs
@@ -0,0 +1,371 @@
+using System;
+using System.ComponentModel.Composition;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Editor.OptionsExtensionMethods
+{
+ /// <summary>
+ /// Extension methods for common general options.
+ /// </summary>
+ public static class DefaultOptionExtensions
+ {
+ #region Extension methods
+ /// <summary>
+ /// Determines whether the option to convert tabs to spaces is enabled in the specified <see cref="IEditorOptions"/>.
+ /// </summary>
+ /// <param name="options">The <see cref="IEditorOptions"/>.</param>
+ /// <returns><c>true</c> if the option is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsConvertTabsToSpacesEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue(DefaultOptions.ConvertTabsToSpacesOptionId);
+ }
+
+ /// <summary>
+ ///Gets the size of the tab for the specified <see cref="IEditorOptions"/>.
+ /// </summary>
+ /// <param name="options">The <see cref="IEditorOptions"/>.</param>
+ /// <returns>The number of spaces of the tab size.</returns>
+ public static int GetTabSize(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue(DefaultOptions.TabSizeOptionId);
+ }
+
+ /// <summary>
+ ///Gets the size of an indent for the specified <see cref="IEditorOptions"/>.
+ /// </summary>
+ /// <param name="options">The <see cref="IEditorOptions"/>.</param>
+ /// <returns>The number of spaces of the indent size.</returns>
+ public static int GetIndentSize(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue(DefaultOptions.IndentSizeOptionId);
+ }
+
+ /// <summary>
+ /// Determines whether to duplicate the new line character if it is already present when inserting a new line.
+ /// </summary>
+ /// <param name="options">The <see cref="IEditorOptions"/>.</param>
+ /// <returns><c>true</c> if the new line character should be duplicated, otherwise <c>false</c>.</returns>
+ public static bool GetReplicateNewLineCharacter(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue(DefaultOptions.ReplicateNewLineCharacterOptionId);
+ }
+
+ /// <summary>
+ /// Gets the new line character for the specified editor options.
+ /// </summary>
+ /// <param name="options">The <see cref="IEditorOptions"/>.</param>
+ /// <returns>A string containing the new line character or characters.</returns>
+ public static string GetNewLineCharacter(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue(DefaultOptions.NewLineCharacterOptionId);
+ }
+
+ /// <summary>
+ /// Determines whether to trim trailing whitespace.
+ /// </summary>
+ /// <param name="options">The <see cref="IEditorOptions"/>.</param>
+ /// <returns><c>true</c> if trailing whitespace should be trimmed, otherwise <c>false</c>.</returns>
+ public static bool GetTrimTrailingWhieSpace(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue(DefaultOptions.TrimTrailingWhiteSpaceOptionId);
+ }
+
+ /// <summary>
+ /// Determines whether to insert final newline.
+ /// </summary>
+ /// <param name="options">The <see cref="IEditorOptions"/>.</param>
+ /// <returns><c>true</c> if a final new line should be inserted, otherwise <c>false</c>.</returns>
+ public static bool GetInsertFinalNewLine(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue(DefaultOptions.InsertFinalNewLineOptionId);
+ }
+
+ #endregion
+ }
+}
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Common general options.
+ /// </summary>
+ public static class DefaultOptions
+ {
+ #region Option identifiers
+ /// <summary>
+ /// The default option that determines whether to convert tabs to spaces.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> ConvertTabsToSpacesOptionId = new EditorOptionKey<bool>(ConvertTabsToSpacesOptionName);
+ public const string ConvertTabsToSpacesOptionName = "Tabs/ConvertTabsToSpaces";
+
+ /// <summary>
+ /// The default option that determines size of a tab.
+ /// </summary>
+ /// <remarks>This option is used to determine the numerical column offset of a tab
+ /// character ('\t') and, if <see cref="ConvertTabsToSpaces"/> is enabled, the number of spaces to which a tab
+ /// should be converted.</remarks>
+ public static readonly EditorOptionKey<int> TabSizeOptionId = new EditorOptionKey<int>(TabSizeOptionName);
+ public const string TabSizeOptionName = "Tabs/TabSize";
+
+ /// <summary>
+ /// The default option that determines size of an indent.
+ /// </summary>
+ /// <remarks>This option is used to determine the numerical column offset of an indent level.</remarks>
+ public static readonly EditorOptionKey<int> IndentSizeOptionId = new EditorOptionKey<int>(IndentSizeOptionName);
+ public const string IndentSizeOptionName = "Tabs/IndentSize";
+
+ /// <summary>
+ /// The default option that determines whether to duplicate the new line character already present
+ /// when inserting a new line.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> ReplicateNewLineCharacterOptionId = new EditorOptionKey<bool>(ReplicateNewLineCharacterOptionName);
+ public const string ReplicateNewLineCharacterOptionName = "ReplicateNewLineCharacter";
+
+ /// <summary>
+ /// The default option that determines the newline character or characters.
+ /// </summary>
+ /// <remarks>The newline character can be a string, as in the common case of "\r\n". This setting applies
+ /// when <see cref="ReplicateNewLineCharacter"/> is <c>false</c>, or when <see cref="ReplicateNewLineCharacter"/> is <c>true</c> and
+ /// the text buffer is empty.</remarks>
+ public static readonly EditorOptionKey<string> NewLineCharacterOptionId = new EditorOptionKey<string>(NewLineCharacterOptionName);
+ public const string NewLineCharacterOptionName = "NewLineCharacter";
+
+ /// <summary>
+ /// The default option that determines the threshold for special handling of long lines.
+ /// </summary>
+ /// <remarks>
+ /// Some operations will not operate on lines longer than this threshold.
+ /// </remarks>
+ public static readonly EditorOptionKey<int> LongBufferLineThresholdId = new EditorOptionKey<int>(LongBufferLineThresholdOptionName);
+ public const string LongBufferLineThresholdOptionName = "LongBufferLineThreshold";
+
+ /// <summary>
+ /// The default option that determines the chunking size for long lines.
+ /// </summary>
+ /// <remarks>
+ /// Lines longer than <see cref="LongBufferLineThreshold"/> may be considered in chunks of this size.
+ /// </remarks>
+ public static readonly EditorOptionKey<int> LongBufferLineChunkLengthId = new EditorOptionKey<int>(LongBufferLineChunkLengthOptionName);
+ public const string LongBufferLineChunkLengthOptionName = "LongBufferLineChunkLength";
+
+ /// <summary>
+ /// The default option that determines whether to trim trailing whitespace.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> TrimTrailingWhiteSpaceOptionId = new EditorOptionKey<bool>(TrimTrailingWhiteSpaceOptionName);
+ public const string TrimTrailingWhiteSpaceOptionName = "TrimTrailingWhiteSpace";
+
+ /// <summary>
+ /// The default option that determines whether to insert final new line charcter.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> InsertFinalNewLineOptionId = new EditorOptionKey<bool>(InsertFinalNewLineOptionName);
+ public const string InsertFinalNewLineOptionName = "InsertFinalNewLine";
+
+ #endregion
+ }
+
+ #region Option definitions
+ /// <summary>
+ /// The option definition that determines whether to convert tabs to spaces.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultOptions.ConvertTabsToSpacesOptionName)]
+ public sealed class ConvertTabsToSpaces : EditorOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value (<c>true</c>)>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the editor option key.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultOptions.ConvertTabsToSpacesOptionId; } }
+ }
+
+ /// <summary>
+ /// The option definition that determines the size (in number of spaces) of a tab.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultOptions.TabSizeOptionName)]
+ public sealed class TabSize : EditorOptionDefinition<int>
+ {
+ /// <summary>
+ /// Gets the default value (4).
+ /// </summary>
+ public override int Default { get { return 4; } }
+
+ /// <summary>
+ /// Gets the editor option key.
+ /// </summary>
+ public override EditorOptionKey<int> Key { get { return DefaultOptions.TabSizeOptionId; } }
+
+ /// <summary>
+ /// Determines whether a given tab size is valid.
+ /// </summary>
+ /// <param name="proposedValue">The size of the tab, in number of spaces.</param>
+ /// <returns><c>true</c> if <paramref name="proposedValue"/> is a valid size, otherwise <c>false</c>.</returns>
+ public override bool IsValid(ref int proposedValue)
+ {
+ return proposedValue > 0;
+ }
+ }
+
+ /// <summary>
+ /// The option definition that determines the size (in number of spaces) of an indent.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultOptions.IndentSizeOptionName)]
+ public sealed class IndentSize : EditorOptionDefinition<int>
+ {
+ /// <summary>
+ /// Gets the default value (4).
+ /// </summary>
+ public override int Default { get { return 4; } }
+
+ /// <summary>
+ /// Gets the editor option key.
+ /// </summary>
+ public override EditorOptionKey<int> Key { get { return DefaultOptions.IndentSizeOptionId; } }
+
+ /// <summary>
+ /// Determines whether a given indent size is valid.
+ /// </summary>
+ /// <param name="proposedValue">The size of the indent, in number of spaces.</param>
+ /// <returns><c>true</c> if <paramref name="proposedValue"/> is a valid size, otherwise <c>false</c>.</returns>
+ public override bool IsValid(ref int proposedValue)
+ {
+ return proposedValue > 0;
+ }
+ }
+
+ /// <summary>
+ /// The option definition that determines whether to duplicate a newline character when inserting a line.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultOptions.ReplicateNewLineCharacterOptionName)]
+ public sealed class ReplicateNewLineCharacter : EditorOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value (<c>true</c>).
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the editor option key.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultOptions.ReplicateNewLineCharacterOptionId; } }
+ }
+
+ /// <summary>
+ /// The option definition that specifies the newline character or characters.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultOptions.NewLineCharacterOptionName)]
+ public sealed class NewLineCharacter : EditorOptionDefinition<string>
+ {
+ /// <summary>
+ /// Gets the default value ("\r\n").
+ /// </summary>
+ public override string Default { get { return "\r\n"; } }
+
+ /// <summary>
+ /// Gets the editor option key.
+ /// </summary>
+ public override EditorOptionKey<string> Key { get { return DefaultOptions.NewLineCharacterOptionId; } }
+ }
+
+ /// <summary>
+ /// The option definition that determines the threshold for special handling of long lines.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultOptions.LongBufferLineThresholdOptionName)]
+ public sealed class LongBufferLineThreshold : EditorOptionDefinition<int>
+ {
+ /// <summary>
+ /// Gets the default value (32K).
+ /// </summary>
+ public override int Default { get { return 32 * 1024; } }
+
+ /// <summary>
+ /// Gets the editor option key.
+ /// </summary>
+ public override EditorOptionKey<int> Key { get { return DefaultOptions.LongBufferLineThresholdId; } }
+ }
+
+ /// <summary>
+ /// The option definition that determines the determines the chunking size for long lines.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultOptions.LongBufferLineChunkLengthOptionName)]
+ public sealed class LongBufferLineChunk : EditorOptionDefinition<int>
+ {
+ /// <summary>
+ /// Gets the default value (4K).
+ /// </summary>
+ public override int Default { get { return 4 * 1024; } }
+
+ /// <summary>
+ /// Gets the editor option key.
+ /// </summary>
+ public override EditorOptionKey<int> Key { get { return DefaultOptions.LongBufferLineChunkLengthId; } }
+ }
+
+ /// <summary>
+ /// The option definition that determines whether to trim trailing whitespace.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultOptions.TrimTrailingWhiteSpaceOptionName)]
+ public sealed class TrimTrailingWhiteSpace : EditorOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value (<c>false</c>).
+ /// </summary>
+ public override bool Default { get { return false; } }
+
+ /// <summary>
+ /// Gets the editor option key.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultOptions.TrimTrailingWhiteSpaceOptionId; } }
+ }
+
+ /// <summary>
+ /// The option definition that determines whether to insert a final newline.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultOptions.InsertFinalNewLineOptionName)]
+ public sealed class InsertFinalNewLine : EditorOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value (<c>false</c>).
+ /// </summary>
+ public override bool Default { get { return false; } }
+
+ /// <summary>
+ /// Gets the editor option key.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultOptions.InsertFinalNewLineOptionId; } }
+ }
+
+ #endregion
+}
diff --git a/src/Text/Def/TextLogic/EditorOptions/DeferCreationAttribute.cs b/src/Text/Def/TextLogic/EditorOptions/DeferCreationAttribute.cs
new file mode 100644
index 0000000..77bde55
--- /dev/null
+++ b/src/Text/Def/TextLogic/EditorOptions/DeferCreationAttribute.cs
@@ -0,0 +1,45 @@
+// ****************************************************************************
+// Copyright (C) Microsoft Corporation. All Rights Reserved.
+// ****************************************************************************
+using System;
+using System.ComponentModel.Composition;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Specifies optional deferred creation semantics.
+ /// </summary>
+ [MetadataAttribute]
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Field, AllowMultiple = false)]
+ public sealed class DeferCreationAttribute : SingletonBaseMetadataAttribute
+ {
+ private string optionName = string.Empty;
+
+ /// <summary>
+ /// Instantiates a new instance of a <see cref="DeferCreationAttribute"/>.
+ /// </summary>
+ public DeferCreationAttribute()
+ {
+ }
+
+ /// <summary>
+ /// The optional OptionName that controls creation.
+ /// </summary>
+ public string OptionName
+ {
+ get
+ {
+ return this.optionName;
+ }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+ this.optionName = value;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/EditorOptions/EditorOptionChangedEventArgs.cs b/src/Text/Def/TextLogic/EditorOptions/EditorOptionChangedEventArgs.cs
new file mode 100644
index 0000000..dcdbbda
--- /dev/null
+++ b/src/Text/Def/TextLogic/EditorOptions/EditorOptionChangedEventArgs.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Provides information for the <see cref="IEditorOptions.OptionChanged"/> event.
+ /// </summary>
+ public class EditorOptionChangedEventArgs : EventArgs
+ {
+ private string _optionId;
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="EditorOptionChangedEventArgs"/>.
+ /// </summary>
+ /// <param name="optionId">The ID of the option.</param>
+ public EditorOptionChangedEventArgs(string optionId)
+ {
+ _optionId = optionId;
+ }
+
+ /// <summary>
+ /// Gets the ID of the option that has changed.
+ /// </summary>
+ public string OptionId { get { return _optionId; } }
+ }
+}
diff --git a/src/Text/Def/TextLogic/EditorOptions/EditorOptionDefinition.cs b/src/Text/Def/TextLogic/EditorOptions/EditorOptionDefinition.cs
new file mode 100644
index 0000000..6c278bf
--- /dev/null
+++ b/src/Text/Def/TextLogic/EditorOptions/EditorOptionDefinition.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// The definition of an editor option.
+ /// </summary>
+ /// <remarks>
+ /// This is a MEF component part, and should be exported with:
+ /// [Export(typeof(EditorOptionDefinition))]
+ /// </remarks>
+ public abstract class EditorOptionDefinition
+ {
+ /// <summary>
+ /// Gets the default value of the option.
+ /// </summary>
+ /// <remarks> The type of the value must be the same as the <see cref="ValueType"/>.</remarks>
+ public abstract object DefaultValue { get; }
+
+ /// <summary>
+ /// Gets the actual type of the option. This is used to ensure
+ /// that setting the option by using the editor options registry
+ /// is type-safe.
+ /// </summary>
+ public abstract Type ValueType { get; }
+
+ /// <summary>
+ /// Gets the name of the option from the options registry.
+ /// </summary>
+ public abstract string Name { get; }
+
+ /// <summary>
+ /// Determines whether this option is applicable for the given scope (for example, a text buffer).
+ /// The default implementation returns <c>true</c>. An option, by default, is applicable to any scope.
+ /// </summary>
+ /// <remarks>This method will not be called for the global scope. Every option is
+ /// valid by definition in the global scope.</remarks>
+ public virtual bool IsApplicableToScope(IPropertyOwner scope)
+ {
+ return true;
+ }
+
+ /// <summary>
+ /// Determines whether the proposed value is valid.
+ /// </summary>
+ /// <param name="proposedValue">The proposed value for this option.</param>
+ /// <returns><c>true</c> if the value is valid, otherwise <c>false</c>.</returns>
+ /// <remarks>By the time the value is passed to this method, it has already
+ /// been checked to be of the correct ValueType.
+ /// The implementer of this method may modify the value.</remarks>
+ public virtual bool IsValid(ref object proposedValue)
+ {
+ return true;
+ }
+
+ #region Object overrides
+
+ /// <summary>
+ /// Determines whether two <see cref="EditorOptionDefinition"/> objects are the same.
+ /// </summary>
+ /// <param name="obj">The object to be compared.</param>
+ /// <returns><c>true</c> if the two objects are the same, otherwise <c>false</c>.</returns>
+ public override bool Equals(object obj)
+ {
+ EditorOptionDefinition other = obj as EditorOptionDefinition;
+ return other != null && other.Name == this.Name;
+ }
+
+ /// <summary>
+ /// Gets the hash code of this type.
+ /// </summary>
+ /// <returns>The hash code.</returns>
+ public override int GetHashCode()
+ {
+ return this.Name.GetHashCode();
+ }
+
+ #endregion
+ }
+
+ /// <summary>
+ /// Represents the definition of an editor option.
+ /// </summary>
+ public abstract class EditorOptionDefinition<T> : EditorOptionDefinition
+ {
+ /// <summary>
+ /// Gets the actual type of the option.
+ /// </summary>
+ public sealed override Type ValueType { get { return typeof(T); } }
+
+ /// <summary>
+ /// Gets the name of the option.
+ /// </summary>
+ public sealed override string Name { get { return Key.Name; } }
+
+ /// <summary>
+ /// Gets the default value of the option.
+ /// </summary>
+ public sealed override object DefaultValue { get { return Default; } }
+
+ /// <summary>Determines whether the proposed value is valid.
+ /// </summary>
+ /// <param name="proposedValue">The proposed value for this option.</param>
+ /// <returns><c>true</c> if the value is valid, otherwise <c>false</c>.</returns>
+ /// <remarks>By the time the value is passed to this method, it has already
+ /// been checked to be of the correct ValueType.
+ /// The implementer of this method may modify the value.</remarks>
+ public sealed override bool IsValid(ref object proposedValue)
+ {
+ if (proposedValue is T)
+ {
+ T value = (T)proposedValue;
+
+ var result = IsValid(ref value);
+ proposedValue = value;
+
+ return result;
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Gets the key of this option.
+ /// </summary>
+ public abstract EditorOptionKey<T> Key { get; }
+
+ /// <summary>
+ /// Gets the default value of this option.
+ /// </summary>
+ public virtual T Default { get { return default(T); } }
+
+ /// <summary>
+ /// Determines whether the proposed value is valid.
+ /// </summary>
+ /// <param name="proposedValue">The proposed value for this option.</param>
+ /// <returns><c>true</c> if the value is valid, otherwise <c>false</c>.</returns>
+ /// <remarks>The implementer of this method may modify the value.</remarks>
+ public virtual bool IsValid(ref T proposedValue) { return true; }
+ }
+
+}
diff --git a/src/Text/Def/TextLogic/EditorOptions/EditorOptionKey.cs b/src/Text/Def/TextLogic/EditorOptions/EditorOptionKey.cs
new file mode 100644
index 0000000..aad0095
--- /dev/null
+++ b/src/Text/Def/TextLogic/EditorOptions/EditorOptionKey.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Represents a type-safe key for editor options.
+ /// </summary>
+ /// <typeparam name="T">The type of the option value.</typeparam>
+ public struct EditorOptionKey<T>
+ {
+ #region Private data
+ private string _name;
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="EditorOptionKey&lt;T&gt;"/>.
+ /// </summary>
+ /// <param name="name">The name of the option key.</param>
+ public EditorOptionKey(string name) { _name = name; }
+
+ /// <summary>
+ /// Gets the name of this key.
+ /// </summary>
+ public string Name { get { return _name; } }
+
+ #region Object overrides
+
+ /// <summary>
+ /// Determines whether two <see cref="EditorOptionKey&lt;T&gt;"/> objects are the same.
+ /// </summary>
+ /// <param name="obj">The object to be compared.</param>
+ /// <returns><c>true</c> if the objects are the same, otherwise <c>false</c>.</returns>
+ public override bool Equals(object obj)
+ {
+ if (obj is EditorOptionKey<T>)
+ {
+ EditorOptionKey<T> other = (EditorOptionKey<T>)obj;
+ return other.Name == this.Name;
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Gets the hash code for this object.
+ /// </summary>
+ /// <returns>The hash code.</returns>
+ public override int GetHashCode()
+ {
+ return this.Name.GetHashCode();
+ }
+
+ /// <summary>
+ /// Converts this object to a string.
+ /// </summary>
+ /// <returns>The name of the option.</returns>
+ public override string ToString()
+ {
+ return this.Name;
+ }
+
+ /// <summary>
+ /// Determines whether two instances of this type are the same.
+ /// </summary>
+ public static bool operator ==(EditorOptionKey<T> left, EditorOptionKey<T> right)
+ {
+ return left.Name == right.Name;
+ }
+
+ /// <summary>
+ /// Determines whether two instances of this type are different.
+ /// </summary>
+ public static bool operator !=(EditorOptionKey<T> left, EditorOptionKey<T> right)
+ {
+ return !(left == right);
+ }
+
+ #endregion
+ }
+
+}
diff --git a/src/Text/Def/TextLogic/EditorOptions/IEditorOptions.cs b/src/Text/Def/TextLogic/EditorOptions/IEditorOptions.cs
new file mode 100644
index 0000000..4929965
--- /dev/null
+++ b/src/Text/Def/TextLogic/EditorOptions/IEditorOptions.cs
@@ -0,0 +1,117 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using System.Collections;
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Represents common editor options and an extensible mechanism for modifying values and adding new options.
+ /// </summary>
+ public interface IEditorOptions
+ {
+ /// <summary>
+ /// Gets the value of the option identified by the specified option ID.
+ /// </summary>
+ /// <typeparam name="T">The type of the value.</typeparam>
+ /// <param name="optionId">The ID of the option.</param>
+ /// <returns>The current value of the option.</returns>
+ T GetOptionValue<T>(string optionId);
+
+ /// <summary>
+ /// Gets the value of the option identified by the specified key.
+ /// </summary>
+ /// <typeparam name="T">The type of the value.</typeparam>
+ /// <param name="key">The key of the option.</param>
+ /// <returns>The current value of the option.</returns>
+ T GetOptionValue<T>(EditorOptionKey<T> key);
+
+ /// <summary>
+ /// Gets the value of the option specified by the option ID.
+ /// </summary>
+ /// <param name="optionId">The ID of the option.</param>
+ /// <returns>The current value of the option, as an object. The caller is responsible for casting the object to the correct type.</returns>
+ object GetOptionValue(string optionId);
+
+ /// <summary>
+ /// Sets the value of the specified option in the current scope. If the given option is not applicable
+ /// in the current scope, it attempts to set the option in the global scope.
+ /// </summary>
+ /// <param name="optionId">The ID of the option.</param>
+ /// <param name="value">The new value of the option.</param>
+ void SetOptionValue(string optionId, object value);
+
+ /// <summary>
+ /// Sets the value of the specified option in the current scope. If the given option is not applicable
+ /// in the current scope, it attempts to set the option in the global scope.
+ /// </summary>
+ /// <param name="key">The key of the option.</param>
+ /// <param name="value">The new value of the option.</param>
+ void SetOptionValue<T>(EditorOptionKey<T> key, T value);
+
+ /// <summary>
+ /// Determines whether the specified option is defined.
+ /// </summary>
+ /// <param name="optionId">The ID of the option.</param>
+ /// <param name="localScopeOnly"><c>true</c> to search only in this scope, <c>false</c>
+ /// to try parent scopes as well. This setting has no effect if the current scope is global.</param>
+ /// <returns><c>true</c> if the option is defined, otherwise <c>false</c>.</returns>
+ bool IsOptionDefined(string optionId, bool localScopeOnly);
+
+ /// <summary>
+ /// Determines whether the specified editor option is defined.
+ /// </summary>
+ /// <param name="key">The key of the option.</param>
+ /// <param name="localScopeOnly"><c>true</c> to search only in this scope, <c>false</c>
+ /// to try parent scopes as well. This setting has no effect if the current scope is global.</param>
+ /// <returns><c>true</c> if the option is defined, otherwise <c>false</c>.</returns>
+ bool IsOptionDefined<T>(EditorOptionKey<T> key, bool localScopeOnly);
+
+ /// <summary>
+ /// Clear the locally-defined value for the given option.
+ /// </summary>
+ /// <param name="optionId">The ID of the option.</param>
+ /// <returns><c>true</c> if the option was defined locally and cleared.</returns>
+ bool ClearOptionValue(string optionId);
+
+ /// <summary>
+ /// Clear the locally-defined value for the given option.
+ /// </summary>
+ /// <param name="key">The key of the option.</param>
+ /// <returns><c>true</c> if the option was defined locally and cleared.</returns>
+ bool ClearOptionValue<T>(EditorOptionKey<T> key);
+
+ /// <summary>
+ /// Gets the supported options.
+ /// </summary>
+ IEnumerable<EditorOptionDefinition> SupportedOptions { get; }
+
+ /// <summary>
+ /// Gets the global options.
+ /// </summary>
+ /// <remarks>This returns the global <see cref="IEditorOptions"/>, even if
+ /// the current scope is global.</remarks>
+ IEditorOptions GlobalOptions { get; }
+
+ /// <summary>
+ /// Gets or sets the immediate parent of this set of options. If this set of
+ /// options has no parent scope (because it is the global scope), this property is null
+ /// and cannot be set.
+ /// </summary>
+ /// <remarks>
+ /// When calling set, the new parent must be non-null and a different instance
+ /// of IEditorOptions that was created from the same
+ /// <see cref="IEditorOptionsFactoryService" /> as this instance. Also,
+ /// cycles in the Parent chain are not allowed.</remarks>
+ IEditorOptions Parent { get; set; }
+
+ /// <summary>
+ /// Occurs when any option changes. Options that change in the global scope
+ /// cause this event to be raised if they are also applicable to this
+ /// scope.
+ /// </summary>
+ event EventHandler<EditorOptionChangedEventArgs> OptionChanged;
+ }
+}
diff --git a/src/Text/Def/TextLogic/EditorOptions/IEditorOptionsFactoryService.cs b/src/Text/Def/TextLogic/EditorOptions/IEditorOptionsFactoryService.cs
new file mode 100644
index 0000000..81aaade
--- /dev/null
+++ b/src/Text/Def/TextLogic/EditorOptions/IEditorOptionsFactoryService.cs
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using System.ComponentModel.Composition;
+
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Represents a service that gets <see cref="IEditorOptions"/> for a specified scope or for the global scope.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IEditorOptionsFactoryService factory = null;
+ /// </remarks>
+ public interface IEditorOptionsFactoryService
+ {
+ /// <summary>
+ /// Gets the <see cref="IEditorOptions"/> for the <see cref="IPropertyOwner"/>. Buffers and views are
+ /// property owners. Creates new options for the scope if none have previously been created.
+ /// </summary>
+ /// <param name="scope">The <see cref="IPropertyOwner"/>.</param>
+ /// <returns>The <see cref="IEditorOptions"/> for the given <see cref="IPropertyOwner"/>.</returns>
+ /// <remarks>
+ /// This method returns a set of options for a given scope. Options defined in this scope will
+ /// not affect options in its ancestor scopes. If you try to get an option in this scope, the method checks
+ /// for any overridden values in the scope. If there are none, it gets the value from the options of
+ /// its parent scope. The set of applicable options may change depending on the
+ /// scope. An option defined in a text view scope will not apply to text buffers.
+ /// </remarks>
+ IEditorOptions GetOptions(IPropertyOwner scope);
+
+ /// <summary>
+ /// Creates a new instance of <see cref="IEditorOptions"/> that is not bound to any
+ /// particular scope.
+ /// </summary>
+ /// <returns>A new instance of <see cref="IEditorOptions"/>, parented on the
+ /// <see cref="GlobalOptions"/></returns>
+ IEditorOptions CreateOptions();
+
+ /// <summary>
+ /// Gets the global <see cref="IEditorOptions"/>.
+ /// </summary>
+ /// <remarks>
+ /// An option set in the global scope does not override the same option set in a specific scope, but it is visible in
+ /// a specific scope that has not overridden that option.
+ /// </remarks>
+ IEditorOptions GlobalOptions { get; }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Find/FindData.cs b/src/Text/Def/TextLogic/Find/FindData.cs
new file mode 100644
index 0000000..0e7ea65
--- /dev/null
+++ b/src/Text/Def/TextLogic/Find/FindData.cs
@@ -0,0 +1,184 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Represents the set of data used in a search by the <see cref="ITextSearchService"/>.
+ /// </summary>
+ public struct FindData
+ {
+ private string _searchString;
+ private ITextSnapshot _textSnapshotToSearch;
+ private FindOptions _findOptions;
+ private ITextStructureNavigator _textStructureNavigator;
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="FindData"/> with the specified search pattern, text snapshot,
+ /// find options, and text structure navigator.
+ /// </summary>
+ /// <param name="searchPattern">The search pattern.</param>
+ /// <param name="textSnapshot">The <see cref="ITextSnapshot"/> to search.</param>
+ /// <param name="findOptions">The <see cref="FindOptions"/> to use during the search.</param>
+ /// <param name="textStructureNavigator">The <see cref="ITextStructureNavigator"/> to use during the search.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="searchPattern"/> or <paramref name="textSnapshot"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="searchPattern"/> is an empty string.</exception>
+ public FindData(string searchPattern, ITextSnapshot textSnapshot, FindOptions findOptions, ITextStructureNavigator textStructureNavigator)
+ {
+ if (searchPattern == null)
+ {
+ throw new ArgumentNullException("searchPattern");
+ }
+ if (searchPattern.Length == 0)
+ {
+ throw new ArgumentOutOfRangeException("searchPattern");
+ }
+
+ if (textSnapshot == null)
+ {
+ throw new ArgumentNullException("textSnapshot");
+ }
+
+ _searchString = searchPattern;
+ _textSnapshotToSearch = textSnapshot;
+ _findOptions = findOptions;
+ _textStructureNavigator = textStructureNavigator;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="FindData"/> with the specified search pattern and text snapshot.
+ /// </summary>
+ /// <param name="searchPattern">The search pattern.</param>
+ /// <param name="textSnapshot">The <see cref="ITextSnapshot"/> to search.</param>
+ public FindData(string searchPattern, ITextSnapshot textSnapshot)
+ : this(searchPattern, textSnapshot, FindOptions.None, null)
+ {
+ }
+
+
+ internal FindData(ITextSnapshot textSnapshot) // For unit testing
+ {
+ _searchString = null;
+ _textSnapshotToSearch = textSnapshot;
+ _findOptions = FindOptions.None;
+ _textStructureNavigator = null;
+ }
+
+ /// <summary>
+ /// Gets or sets the string to use in the search.
+ /// </summary>
+ /// <exception cref="ArgumentNullException">The value is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">The value is an empty string.</exception>
+ public string SearchString
+ {
+ get { return _searchString; }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+ if (value.Length == 0)
+ {
+ throw new ArgumentOutOfRangeException("value");
+ }
+ _searchString = value;
+ }
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="FindData"/> objects are the same.
+ /// </summary>
+ /// <param name="obj">The object to compare.</param>
+ /// <returns><c>true</c> if the objects are the same, otherwise <c>false</c>.</returns>
+ public override bool Equals(object obj)
+ {
+ if (obj is FindData)
+ {
+ FindData other = (FindData)obj;
+
+ return (_searchString == other._searchString) &&
+ (_findOptions == other._findOptions) &&
+ object.ReferenceEquals(_textSnapshotToSearch, other._textSnapshotToSearch) &&
+ object.ReferenceEquals(_textStructureNavigator, other._textStructureNavigator);
+ }
+ return false;
+ }
+
+ /// <summary>
+ /// Gets the hash code for the object.
+ /// </summary>
+ /// <returns>The hash code.</returns>
+ public override int GetHashCode()
+ {
+ return _searchString.GetHashCode();
+ }
+
+ /// <summary>
+ /// Converts the <see cref="FindData"/> object to a string.
+ /// </summary>
+ /// <returns>The string representation of the <see cref="FindData"/> object.</returns>
+ public override string ToString()
+ {
+ return base.ToString();
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="FindData"/> objects are the same.
+ /// </summary>
+ /// <param name="data1">The first object.</param>
+ /// <param name="data2">The second object.</param>
+ /// <returns><c>true</c> if the objects are the same, otherwise <c>false</c>.</returns>
+ public static bool operator ==(FindData data1, FindData data2)
+ {
+ return data1.Equals(data2);
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="FindData"/> objects are different.
+ /// </summary>
+ /// <param name="data1">The first object.</param>
+ /// <param name="data2">The second object.</param>
+ /// <returns><c>true</c> if the two objects are different, otherwise <c>false</c>.</returns>
+ public static bool operator !=(FindData data1, FindData data2)
+ {
+ return data1.Equals(data2);
+ }
+
+ /// <summary>
+ /// Gets or sets the options that are used for the search.
+ /// </summary>
+ public FindOptions FindOptions
+ {
+ get { return _findOptions; }
+ set { _findOptions = value; }
+ }
+
+ /// <summary>
+ /// Gets or sets the <see cref="ITextSnapshot"/> on which to perform the search.
+ /// </summary>
+ /// <exception cref="ArgumentNullException">The value is null.</exception>
+ public ITextSnapshot TextSnapshotToSearch
+ {
+ get { return _textSnapshotToSearch; }
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("value");
+ }
+ _textSnapshotToSearch = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the <see cref="ITextStructureNavigator"/> to use in determining word boundaries.
+ /// </summary>
+ public ITextStructureNavigator TextStructureNavigator
+ {
+ get { return _textStructureNavigator; }
+ set { _textStructureNavigator = value; }
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Find/FindOptions.cs b/src/Text/Def/TextLogic/Find/FindOptions.cs
new file mode 100644
index 0000000..58de95a
--- /dev/null
+++ b/src/Text/Def/TextLogic/Find/FindOptions.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Represents the options that are used in a search.
+ /// </summary>
+ [Flags]
+ public enum FindOptions
+ {
+ /// <summary>
+ /// No options have been set.
+ /// </summary>
+ None = 0x000,
+
+ /// <summary>
+ /// The search is case-sensitive.
+ /// </summary>
+ MatchCase = 0x01,
+
+ /// <summary>
+ /// The search uses .NET regular expressions.
+ /// </summary>
+ UseRegularExpressions = 0x02,
+
+ /// <summary>
+ /// The search matches whole words only.
+ /// </summary>
+ WholeWord = 0x04,
+
+ /// <summary>
+ /// The search starts at the end of the string.
+ /// </summary>
+ SearchReverse = 0x08,
+
+ /// <summary>
+ /// The search should wrap around if it hits boundaries of the search range.
+ /// </summary>
+ Wrap = 0x10,
+
+ /// <summary>
+ /// The search contains data that could match over line endings.
+ /// </summary>
+ Multiline = 0x20,
+
+ /// <summary>
+ /// The string comparison used for the search is culture-insensitive (ordinal). For regular expression searches,
+ /// this options specifies the <see cref="RegexOptions.CultureInvariant"/>.
+ /// </summary>
+ OrdinalComparison = 0x40,
+
+ /// <summary>
+ /// Only valid in conjunction with <see cref="UseRegularExpressions"/>. When supplied, uses the <see cref="RegexOptions.Singleline"/> option to perform the searches.
+ /// </summary>
+ SingleLine = 0x80
+ }
+}
diff --git a/src/Text/Def/TextLogic/Find/ITextSearchNavigator.cs b/src/Text/Def/TextLogic/Find/ITextSearchNavigator.cs
new file mode 100644
index 0000000..9d2c7ce
--- /dev/null
+++ b/src/Text/Def/TextLogic/Find/ITextSearchNavigator.cs
@@ -0,0 +1,100 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Provides a service to navigate between search results on a <see cref="ITextBuffer"/> and to
+ /// perform replacements.
+ /// </summary>
+ public interface ITextSearchNavigator
+ {
+ /// <summary>
+ /// The term to search for.
+ /// </summary>
+ /// <remarks>
+ /// Modifying the <see cref="SearchTerm"/> does not perform a search. To do so, call the
+ /// <see cref="Find"/> method.
+ /// </remarks>
+ string SearchTerm { get; set; }
+
+ /// <summary>
+ /// The term to replace matches with.
+ /// </summary>
+ string ReplaceTerm { get; set; }
+
+ /// <summary>
+ /// Sets or gets options used for the search.
+ /// </summary>
+ /// <remarks>
+ /// Modifying the <see cref="SearchOptions"/> don't change the current search. To perform a search
+ /// using the new options, call the <see cref="Find"/> method.
+ /// </remarks>
+ FindOptions SearchOptions { get; set; }
+
+ /// <summary>
+ /// Indicates the position in <see cref="ITextBuffer.CurrentSnapshot"/> at which the search should be started.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// If <see cref="CurrentResult"/> is not null then <see cref="CurrentResult"/> will
+ /// be used as the starting point for the next search or replace operation.
+ /// </para>
+ /// <para>
+ /// If <see cref="CurrentResult"/> is null and this value is also null, then
+ /// the beginning of the document will be used as the search's starting point.
+ /// </para>
+ /// StartPoint can be set to a snapshot point belonging to any <see cref="ITextSnapshot"/> belonging
+ /// to this <see cref="ITextBuffer"/>. However, value returned by this property is always
+ /// translated to current snapshot.
+ /// </remarks>
+ SnapshotPoint? StartPoint { get; set; }
+
+ /// <summary>
+ /// Indicates the range that should be searched (if any).
+ /// </summary>
+ /// <remarks>
+ /// If the <see cref="SearchSpan"/> is null then the entire document will be searched. Otherwise only results that
+ /// are contained by the provided span will be returned.
+ /// </remarks>
+ ITrackingSpan SearchSpan { get; set; }
+
+ /// <summary>
+ /// Returns the <see cref="SnapshotSpan"/> corresponding to the result of the last
+ /// find operation. If no matches were found or if no search has been performed yet,
+ /// null is returned.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// If <see cref="CurrentResult"/> is not null, then the next find operation will search
+ /// from either endpoint of the current result depending on the search direction.
+ /// </para>
+ /// </remarks>
+ SnapshotSpan? CurrentResult { get; }
+
+ /// <summary>
+ /// Finds the next occurrence of the text matching the <see cref="SearchTerm"/>.
+ /// </summary>
+ /// <returns>
+ /// Returns <c>true</c> if a match is found, <c>false</c> otherwise.
+ /// </returns>
+ bool Find();
+
+ /// <summary>
+ /// Replaces the current result with <see cref="ReplaceTerm"/>.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, <c>false</c> otherwise.
+ /// </returns>
+ bool Replace();
+
+ /// <summary>
+ /// Clears the current result.
+ /// </summary>
+ /// <remarks>
+ /// Searches will be performed starting from the <see cref="StartPoint"/> when
+ /// no current result is available.
+ /// </remarks>
+ void ClearCurrentResult();
+ }
+}
diff --git a/src/Text/Def/TextLogic/Find/ITextSearchNavigatorFactoryService.cs b/src/Text/Def/TextLogic/Find/ITextSearchNavigatorFactoryService.cs
new file mode 100644
index 0000000..b301781
--- /dev/null
+++ b/src/Text/Def/TextLogic/Find/ITextSearchNavigatorFactoryService.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// A service that creates <see cref="ITextSearchNavigator"/> objects.
+ /// </summary>
+ /// <remarks>
+ /// This service is provided by the editor and should be consumed via the Managed Extensibility Framework.
+ /// </remarks>
+ /// <example>
+ /// [Import]
+ /// ITextSearchNavigatorFactoryService TextSearchNavigatorProvider { get; set; }
+ /// </example>
+ public interface ITextSearchNavigatorFactoryService
+ {
+ /// <summary>
+ /// Creates an <see cref="ITextSearchNavigator"/> that searches the provided <paramref name="buffer"/>.
+ /// </summary>
+ /// <param name="buffer">
+ /// The <see cref="ITextBuffer"/> to search.
+ /// </param>
+ /// <param name="searchTerm">
+ /// The term to search for.
+ /// </param>
+ /// <param name="searchOptions">
+ /// The options to use for performing of search.
+ /// </param>
+ /// <returns>
+ /// An <see cref="ITextSearchNavigator"/> that searches the provided <see cref="ITextBuffer"/>.
+ /// </returns>
+ ITextSearchNavigator CreateSearchNavigator(ITextBuffer buffer);
+ }
+}
diff --git a/src/Text/Def/TextLogic/Find/ITextSearchService.cs b/src/Text/Def/TextLogic/Find/ITextSearchService.cs
new file mode 100644
index 0000000..f4a8dd1
--- /dev/null
+++ b/src/Text/Def/TextLogic/Find/ITextSearchService.cs
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ using System;
+ using System.Collections.ObjectModel;
+ using System.ComponentModel.Composition;
+
+ /// <summary>
+ /// Searches a <see cref="ITextSnapshot"/> with different search options.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// ITextSearchService textSearch = null;
+ /// </remarks>
+ public interface ITextSearchService
+ {
+ /// <summary>
+ /// Searches for the next occurrence of the search string.
+ /// </summary>
+ /// <param name="startIndex">
+ /// The index from which to begin the search.
+ /// </param>
+ /// <param name="wraparound">
+ /// Determines whether the search wraps to the beginning of the buffer when it reaches the end of the buffer.
+ /// </param>
+ /// <param name="findData">
+ /// The data to use for this search.
+ /// </param>
+ /// <returns>
+ /// The <see cref="SnapshotSpan"/> containing the match if a match was found, or null if no matches were found.
+ /// </returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="startIndex"/> is less than zero or greater than the length of the data.</exception>
+ /// <exception cref="ArgumentException"> The UseRegularExpressions flag is set and the search string is an invalid regular expression.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="findData"/> is null.</exception>
+ SnapshotSpan? FindNext(int startIndex, bool wraparound, FindData findData);
+
+ /// <summary>
+ /// Searches for all the occurrences of the search string.
+ /// </summary>
+ /// <param name="findData">
+ /// The data to use for this search.
+ /// </param>
+ /// <returns>
+ /// A list of all the matches, or null if no matches were found.
+ /// </returns>
+ /// <exception cref="ArgumentException"> The UseRegularExpressions flag of the find options is set and the search string is an invalid regular expression.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="findData"/> is null.</exception>
+ Collection<SnapshotSpan> FindAll(FindData findData);
+ }
+}
diff --git a/src/Text/Def/TextLogic/Find/ITextSearchService2.cs b/src/Text/Def/TextLogic/Find/ITextSearchService2.cs
new file mode 100644
index 0000000..d8d0fd3
--- /dev/null
+++ b/src/Text/Def/TextLogic/Find/ITextSearchService2.cs
@@ -0,0 +1,214 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ using System;
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Provides methods for searching contents of a <see cref="ITextSnapshot"/>. Additionally, provides
+ /// helper methods for performing replace operations.
+ /// </summary>
+ public interface ITextSearchService2 : ITextSearchService
+ {
+ /// <summary>
+ /// Searches for the next occurrence of the search string.
+ /// </summary>
+ /// <param name="startingPosition">
+ /// The position from which to begin the search. The search will be performed on the <see cref="ITextSnapshot"/> to which
+ /// this parameter belongs.
+ /// </param>
+ /// <param name="searchPattern">
+ /// The pattern to search for.
+ /// </param>
+ /// <param name="options">
+ /// Specifies options used for the search operation.
+ /// </param>
+ /// <returns>
+ /// A <see cref="SnapshotSpan"/> containing the match if a match was found, or null if no matches were found.
+ /// </returns>
+ /// <remarks>
+ /// This method is safe to be executed from any thread.
+ /// </remarks>
+ /// <exception cref="ArgumentException">
+ /// The <see cref="FindOptions.UseRegularExpressions"/> flag is set and the search string is an invalid regular expression.
+ /// </exception>
+ SnapshotSpan? Find(SnapshotPoint startingPosition, string searchPattern, FindOptions options);
+
+ /// <summary>
+ /// Searches for the next occurrence of the search string.
+ /// </summary>
+ /// <param name="searchRange">
+ /// The range of text to search in.
+ /// </param>
+ /// <param name="startingPosition">
+ /// The position from which to begin the search. The search will be performed on the <see cref="ITextSnapshot"/> to which
+ /// this parameter belongs.
+ /// </param>
+ /// <param name="options">
+ /// Specifies options used for the search operation.
+ /// </param>
+ /// <param name="searchPattern">
+ /// The pattern to search for.
+ /// </param>
+ /// <returns>
+ /// A <see cref="SnapshotSpan"/> containing the match if a match was found, or null if no matches were found.
+ /// </returns>
+ /// <remarks>
+ /// This method can be executed from any thread.
+ /// </remarks>
+ /// <exception cref="ArgumentException">
+ /// The <see cref="FindOptions.UseRegularExpressions"/> flag is set and the search string is an invalid regular expression.
+ /// </exception>
+ SnapshotSpan? Find(SnapshotSpan searchRange, SnapshotPoint startingPosition, string searchPattern, FindOptions options);
+
+ /// <summary>
+ /// Searches for the next occurence of <paramref name="searchPattern"/> and sets <paramref name="expandedReplacePattern"/> to the result of
+ /// the text replacement.
+ /// </summary>
+ /// <param name="startingPosition">
+ /// The position from which search is started. The search will be performed on the <see cref="ITextSnapshot"/> to which this
+ /// parameter belongs.
+ /// </param>
+ /// <param name="searchPatterh">
+ /// The pattern to look for.
+ /// </param>
+ /// <param name="replacePattern">
+ /// The pattern to replace the found text with.
+ /// </param>
+ /// <param name="options">
+ /// Options used to perform the search.
+ /// </param>
+ /// <param name="expandedReplacePattern">
+ /// The result of the replacement. This output parameter will be useful when performing regular expression searches. Will be empty
+ /// if no matches are found.
+ /// </param>
+ /// <returns>
+ /// A <see cref="SnapshotSpan"/> pointing to the search result found. If no matches are found, null is returned.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// This function does not perform any edits. The consumers would need to create an <see cref="ITextEdit"/> to perform the actual text
+ /// replacement if desired. This method is safe to be executed from any thread.
+ /// </para>
+ /// <para>
+ /// Note that <paramref name="expandedReplacePattern"/> will always equal <paramref name="replacePattern"/> if the search is not using regular
+ /// expressions. In those scenarios you can utilize the more lightweight <see cref="Find(SnapshotSpan, SnapshotPoint, string, FindOptions)"/>.
+ /// </para>
+ /// </remarks>
+ SnapshotSpan? FindForReplace(SnapshotPoint startingPosition, string searchPattern, string replacePattern, FindOptions options, out string expandedReplacePattern);
+
+ /// <summary>
+ /// Searches for the next occurence of <paramref name="searchPattern"/> and sets <paramref name="expandedReplacePattern"/> to the result of
+ /// the text replacement.
+ /// </summary>
+ /// <param name="searchRange">
+ /// The range of text to search in.
+ /// </param>
+ /// <param name="searchPatterh">
+ /// The pattern to look for.
+ /// </param>
+ /// <param name="replacePattern">
+ /// The pattern to replace the found text with.
+ /// </param>
+ /// <param name="options">
+ /// Options used to perform the search.
+ /// </param>
+ /// <param name="expandedReplacePattern">
+ /// The result of the replacement. This output parameter will be useful when performing regular expression searches. Will be empty
+ /// if no matches are found.
+ /// </param>
+ /// <returns>
+ /// A <see cref="SnapshotSpan"/> pointing to the search result found. If no matches are found, null is returned.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// This function does not perform any edits. The consumers would need to create an <see cref="ITextEdit"/> to perform the actual text
+ /// replacement if desired. This method is safe to be executed from any thread.
+ /// </para>
+ /// <para>
+ /// Note that <paramref name="expandedReplacePattern"/> will always equal <paramref name="replacePattern"/> if search is not using regular
+ /// expressions. In those scenarios you can utilize the more lightweight <see cref="Find(SnapshotSpan, SnapshotPoint, string, FindOptions)"/>.
+ /// </para>
+ /// </remarks>
+ SnapshotSpan? FindForReplace(SnapshotSpan searchRange, string searchPattern, string replacePattern, FindOptions options, out string expandedReplacePattern);
+
+ /// <summary>
+ /// Finds all occurences of the <paramref name="searchPattern"/> in <paramref name="searchRange"/>.
+ /// </summary>
+ /// <param name="searchRange">
+ /// The range to search in.
+ /// </param>
+ /// <param name="searchPattern">
+ /// The pattern to search for.
+ /// </param>
+ /// <param name="options">
+ /// The options to use while performing the search operation.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IEnumerable{SnapshotSpan}"/> containing all occurences of the <paramref name="searchPattern"/>.
+ /// </returns>
+ /// <remarks>
+ /// This method is safe to execute on any thread.
+ /// </remarks>
+ IEnumerable<SnapshotSpan> FindAll(SnapshotSpan searchRange, string searchPattern, FindOptions options);
+
+ /// <summary>
+ /// Finds all occurences of the <paramref name="searchPattern"/> in <paramref name="searchRange"/> starting from
+ /// <paramref name="startingPosition"/>.
+ /// </summary>
+ /// <param name="searchRange">
+ /// The range to search in.
+ /// </param>
+ /// <param name="startingPosition">
+ /// The location from which the search should be started.
+ /// </param>
+ /// <param name="searchPattern">
+ /// The pattern to search for.
+ /// </param>
+ /// <param name="options">
+ /// The options to use while performing the search operation.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IEnumerable{SnapshotSpan}"/> containing all occurences of the <paramref name="searchPattern"/>.
+ /// </returns>
+ /// <remarks>
+ /// This method is safe to execute on any thread.
+ /// </remarks>
+ IEnumerable<SnapshotSpan> FindAll(SnapshotSpan searchRange, SnapshotPoint startingPosition, string searchPattern, FindOptions options);
+
+ /// <summary>
+ /// Searches for all occurences of the <paramref name="searchPattern"/> and calculates all
+ /// the corresponding replacement results for every match according to the <paramref name="replacePattern"/>.
+ /// </summary>
+ /// <param name="searchRange">
+ /// The range of text to search in.
+ /// </param>
+ /// <param name="searchPattern">
+ /// The pattern to search for.
+ /// </param>
+ /// <param name="replacePattern">
+ /// The replace pattern to use for the operation.
+ /// </param>
+ /// <param name="options">
+ /// The options to use while performing the search operation.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IEnumerable{T}"/> containing all matches found and their corresponding replacement values.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The returned <see cref="IEnumerable{T}"/> will contain a collection of tuples indicating all the matches. Each
+ /// <see cref="Tuple"/> will contain a <see cref="SnapshotSpan"/> referencing the location of the match and a <see cref="string"/>
+ /// containing the calculated replacement text for the match.
+ /// </para>
+ /// <para>
+ /// If you are not using regular expressions then the calculated replacement text will always
+ /// equal the <paramref name="replacePattern"/>. In that scenario, you can use the
+ /// <see cref="ITextSearchService2.FindAll(SnapshotSpan, string, FindOptions)"/> method to only obtain the search results.
+ /// </para>
+ /// </remarks>
+ IEnumerable<Tuple<SnapshotSpan, string>> FindAllForReplace(SnapshotSpan searchRange, string searchPattern, string replacePattern, FindOptions options);
+ }
+}
diff --git a/src/Text/Def/TextLogic/FxCopSuppressions.cs b/src/Text/Def/TextLogic/FxCopSuppressions.cs
new file mode 100644
index 0000000..6f55742
--- /dev/null
+++ b/src/Text/Def/TextLogic/FxCopSuppressions.cs
@@ -0,0 +1,59 @@
+#if CODE_ANALYSIS_BASELINE
+using System.Diagnostics.CodeAnalysis;
+
+[module: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope="namespace", Target="Microsoft.VisualStudio.Text.Document", MessageId="", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.VisualStudio.Text", MessageId = "", Justification = "BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames", Scope = "", Target = "microsoft.visualstudio.text.logic.dll", MessageId = "", Justification = "BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces", Scope = "type", Target = "Microsoft.VisualStudio.Text.Classification.IClassificationTypeDefinition")]
+[module: SuppressMessage("Microsoft.Design", "CA1018:MarkAttributesWithAttributeUsage", Scope = "type", Target = "Microsoft.VisualStudio.Text.Classification.ClassificationTypeAttribute", MessageId = "", Justification = "BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope="member", Target="Microsoft.VisualStudio.Text.Operations.FindData.#.ctor(Microsoft.VisualStudio.Text.ITextSnapshot)", MessageId="", Justification="Used by unit tests")]
+
+[module: SuppressMessage("Microsoft.Design","CA1004:GenericMethodsShouldProvideTypeParameter", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.IEditorOptions.#GetOptionValue`1(System.String)")]
+[module: SuppressMessage("Microsoft.Design","CA1020:AvoidNamespacesWithFewTypes", Scope="namespace", Target="Microsoft.VisualStudio.Text.Editor.OptionsExtensionMethods")]
+[module: SuppressMessage("Microsoft.Design","CA1045:DoNotPassTypesByReference", MessageId="0#", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.EditorOptionDefinition.#IsValid(System.Object&)")]
+[module: SuppressMessage("Microsoft.Design","CA1007:UseGenericsWhereAppropriate", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.EditorOptionDefinition.#IsValid(System.Object&)")]
+[module: SuppressMessage("Microsoft.Naming","CA1716:IdentifiersShouldNotMatchKeywords", MessageId="Default", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.EditorOptionDefinition`1.#Default")]
+[module: SuppressMessage("Microsoft.Design","CA1045:DoNotPassTypesByReference", MessageId="0#", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.EditorOptionDefinition`1.#IsValid(!0&)")]
+
+// Tagging
+
+[module: SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces", Scope = "type", Target = "Microsoft.VisualStudio.Text.Tagging.ITag", Justification = "Intentional")]
+
+[module: SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces", Scope = "type", Target = "Microsoft.VisualStudio.Text.Tagging.IElisionTag", Justification = "Intentional")]
+
+[module: SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Scope = "member", Target = "Microsoft.VisualStudio.Text.Tagging.ITagAggregator`1.#GetTags(Microsoft.VisualStudio.Text.SnapshotSpan)")]
+
+[module: SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Scope = "member", Target = "Microsoft.VisualStudio.Text.Tagging.ITagAggregator`1.#GetTags(Microsoft.VisualStudio.Text.IMappingSpan)")]
+[module: SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Scope = "member", Target = "Microsoft.VisualStudio.Text.Tagging.ITagAggregator`1.#GetTags(Microsoft.VisualStudio.Text.NormalizedSnapshotSpanCollection)")]
+
+[module: SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Scope = "member", Target = "Microsoft.VisualStudio.Text.Tagging.ITagger.#GetTags`1(Microsoft.VisualStudio.Text.SnapshotSpan)")]
+[module: SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Scope = "member", Target = "Microsoft.VisualStudio.Text.Tagging.ITaggerProvider.#CreateTagger`1(Microsoft.VisualStudio.Text.ITextBuffer)")]
+
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tagger", Scope = "type", Target = "Microsoft.VisualStudio.Text.Tagging.ITaggerProvider", Justification = "This isn't misspelled.")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tagger", Scope = "type", Target = "Microsoft.VisualStudio.Text.Tagging.ITagger`1", Justification = "This isn't misspelled")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tagger", Scope = "member", Target = "Microsoft.VisualStudio.Text.Tagging.ITaggerProvider.#CreateTagger`1(Microsoft.VisualStudio.Text.ITextBuffer)", Justification = "This is not misspelled.")]
+
+[module: SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Scope = "member", Target = "Microsoft.VisualStudio.Text.Tagging.TextMarkerTag.#Type")]
+
+[module: SuppressMessage("Microsoft.Design","CA1004:GenericMethodsShouldProvideTypeParameter", Scope="member", Target="Microsoft.VisualStudio.Text.Tagging.IBufferTagAggregatorFactoryService.#CreateTagAggregator`1(Microsoft.VisualStudio.Text.ITextBuffer)")]
+[module: SuppressMessage("Microsoft.Design","CA1004:GenericMethodsShouldProvideTypeParameter", Scope="member", Target="Microsoft.VisualStudio.Text.Tagging.IBufferTagAggregatorFactoryService.#CreateTagAggregator`1(Microsoft.VisualStudio.Text.ITextBuffer,Microsoft.VisualStudio.Text.Tagging.TagAggregatorOptions)")]
+[module: SuppressMessage("Microsoft.Design","CA1006:DoNotNestGenericTypesInMemberSignatures", Scope="member", Target="Microsoft.VisualStudio.Text.Tagging.ITagger`1.#GetTags(Microsoft.VisualStudio.Text.NormalizedSnapshotSpanCollection)")]
+[module: SuppressMessage("Microsoft.Design","CA1006:DoNotNestGenericTypesInMemberSignatures", Scope="member", Target="Microsoft.VisualStudio.Text.Tagging.SimpleTagger`1.#RemoveTagSpans(System.Predicate`1<Microsoft.VisualStudio.Text.Tagging.TrackingTagSpan`1<!0>>)", Justification="Need to nest the generic type")]
+
+[module: SuppressMessage("Microsoft.Design","CA1018:MarkAttributesWithAttributeUsage", Scope="type", Target="Microsoft.VisualStudio.Text.Tagging.TagTypeAttribute")]
+[module: SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Scope="type", Target="Microsoft.VisualStudio.Text.Tagging.TagTypeAttribute")]
+
+
+[module: SuppressMessage("Microsoft.Naming","CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId="1#", Scope="member", Target="Microsoft.VisualStudio.Text.Tagging.TrackingTagSpanComparer`1.#Compare(Microsoft.VisualStudio.Text.Tagging.TrackingTagSpan`1<!0>,Microsoft.VisualStudio.Text.Tagging.TrackingTagSpan`1<!0>)")]
+[module: SuppressMessage("Microsoft.Naming","CA1725:ParameterNamesShouldMatchBaseDeclaration", MessageId="0#", Scope="member", Target="Microsoft.VisualStudio.Text.Tagging.TrackingTagSpanComparer`1.#Compare(Microsoft.VisualStudio.Text.Tagging.TrackingTagSpan`1<!0>,Microsoft.VisualStudio.Text.Tagging.TrackingTagSpan`1<!0>)")]
+[module: SuppressMessage("Microsoft.Design","CA1006:DoNotNestGenericTypesInMemberSignatures", Scope="member", Target="Microsoft.VisualStudio.Text.Tagging.SimpleTagger`1.#GetTaggedSpans(Microsoft.VisualStudio.Text.SnapshotSpan)")]
+[module: SuppressMessage("Microsoft.Naming","CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="Tagger", Scope="type", Target="Microsoft.VisualStudio.Text.Tagging.SimpleTagger`1")]
+
+[module: SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Scope="member", Target="Microsoft.VisualStudio.Text.VirtualSnapshotSpan.#GetText()", MessageId="", Justification="Matches method on SnapshotSpan.")]
+
+[module: SuppressMessage("Microsoft.Naming","CA1716:IdentifiersShouldNotMatchKeywords", MessageId="Do", Scope="member", Target="Microsoft.VisualStudio.Text.Operations.ITextUndoPrimitive.#Do()")]
+
+//ToDo: To be looked at
+[module: SuppressMessage("Microsoft.Design","CA1020:AvoidNamespacesWithFewTypes", Scope="namespace", Target="Microsoft.VisualStudio.Text.Tagging", Justification="ToDo: To be looked at")]
+
+#endif
diff --git a/src/Text/Def/TextLogic/Navigation/ITextStructureNavigator.cs b/src/Text/Def/TextLogic/Navigation/ITextStructureNavigator.cs
new file mode 100644
index 0000000..7f37fe1
--- /dev/null
+++ b/src/Text/Def/TextLogic/Navigation/ITextStructureNavigator.cs
@@ -0,0 +1,99 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Provides methods to navigate text, such as getting word extents.
+ /// </summary>
+ public interface ITextStructureNavigator
+ {
+ /// <summary>
+ /// Gets the extent of the word at the given position.
+ /// </summary>
+ /// <remarks><see cref="TextExtent.IsSignificant"/> should be set to <c>false</c> for words
+ /// consisting only of whitespace, unless the whitespace is a significant part of the document. If the
+ /// returned extent consists only of insignificant whitespace, it should include all of the adjacent whitespace,
+ /// including newline characters, spaces, and tabs.</remarks>
+ /// <param name="currentPosition">
+ /// The text position anywhere in the word for which a <see cref="TextExtent"/> is needed.
+ /// </param>
+ /// <returns>
+ /// A <see cref="TextExtent" /> that represents the word. The <see cref="TextExtent.IsSignificant"/> field is set to <c>false</c> for whitespace or other
+ /// insignificant characters that should be ignored during navigation.
+ /// </returns>
+ TextExtent GetExtentOfWord(SnapshotPoint currentPosition);
+
+ /// <summary>
+ /// Gets the span of the enclosing syntactic element of the specified snapshot span.
+ /// </summary>
+ /// <param name="activeSpan">
+ /// The <see cref="SnapshotSpan"/> from which to get the enclosing syntactic element.
+ /// </param>
+ /// <returns>
+ /// A <see cref="SnapshotSpan"/> that represents the enclosing syntactic element. If the specified snapshot
+ /// span covers multiple syntactic elements, then the method returns the least common ancestor of the elements.
+ /// If the snapshot span covers the root element (in other words, the whole document),
+ /// then the method returns <see cref="SnapshotSpan"/> of the whole document.
+ /// </returns>
+ SnapshotSpan GetSpanOfEnclosing(SnapshotSpan activeSpan);
+
+ /// <summary>
+ /// Gets the span of the first child syntactic element of the specified snapshot span.
+ /// If the snapshot span has zero length, then the behavior is the same as that of
+ /// <see cref="GetSpanOfEnclosing"/>.
+ /// </summary>
+ /// <param name="activeSpan">
+ /// The <see cref="SnapshotSpan"/> from which to get the span of the first child syntactic element.
+ /// </param>
+ /// <returns>
+ /// A <see cref="SnapshotSpan" /> that represents the first child syntactic element. If the specified snapshot
+ /// span covers multiple syntactic elements, then this method returns the span of the least common ancestor of
+ /// the elements. If the specified snapshot span covers the child element, then the
+ /// behavior is the same as that of <see cref="GetSpanOfEnclosing"/>.
+ /// </returns>
+ SnapshotSpan GetSpanOfFirstChild(SnapshotSpan activeSpan);
+
+ /// <summary>
+ /// Gets the span of the next sibling syntactic element of the specified snapshot span. If the
+ /// snapshot span has zero length, then the behavior is the same as that of
+ /// <see cref="GetSpanOfEnclosing"/>.
+ /// </summary>
+ /// <param name="activeSpan">
+ /// The <see cref="SnapshotSpan"/> from which to get the span of the next sibling syntactic element.
+ /// </param>
+ /// <returns>
+ /// A <see cref="SnapshotSpan"/> that represents the next sibling syntactic element. If the given active
+ /// span covers multiple syntactic elements, then this method returns the span of the next sibling element.
+ /// If the specified snapshot span covers a syntactic element that does not have a sibling element, then the
+ /// behavior is the same as that of <see cref="GetSpanOfEnclosing"/>.
+ /// </returns>
+ SnapshotSpan GetSpanOfNextSibling(SnapshotSpan activeSpan);
+
+ /// <summary>
+ /// Gets the span of the previous sibling syntactic element of the specified snapshot span.
+ /// If the specified span has zero length, then the behavior is the same as that of
+ /// <see cref="GetSpanOfEnclosing"/>.
+ /// </summary>
+ /// <param name="activeSpan">
+ /// The <see cref="SnapshotSpan"/> from which to get the span of the previous sibling syntactic element.
+ /// </param>
+ /// <returns>
+ /// A <see cref="SnapshotSpan"/> that represents the previous sibling syntactic element. If the specified snapshot
+ /// span covers multiple syntactic elements, then this method returns the span of the previous element.
+ /// If the specified snapshot span covers a syntactic element that does not have a sibling element, then the
+ /// behavior is the same as that of <see cref="GetSpanOfEnclosing"/>.
+ /// </returns>
+ SnapshotSpan GetSpanOfPreviousSibling(SnapshotSpan activeSpan);
+
+ /// <summary>
+ /// Gets the content type that this navigator supports.
+ /// </summary>
+ IContentType ContentType
+ {
+ get;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/Navigation/ITextStructureNavigatorProvider.cs b/src/Text/Def/TextLogic/Navigation/ITextStructureNavigatorProvider.cs
new file mode 100644
index 0000000..f42cfeb
--- /dev/null
+++ b/src/Text/Def/TextLogic/Navigation/ITextStructureNavigatorProvider.cs
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Gets an <see cref="ITextStructureNavigator"/> for a given <see cref="ITextBuffer"/>.
+ /// Component exporters must supply at least one content type attribute"/> to specify the applicable content types.
+ /// </summary>
+ /// <remarks>
+ /// <para>This is a MEF component part, and should be exported with the following attribute:
+ /// [Export(NameSource=typeof(ITextStructureNavigatorProvider))]</para>
+ /// <para>Use the <see cref="ITextStructureNavigatorSelectorService"/> to import a provider for a particular content type.</para>
+ /// </remarks>
+ public interface ITextStructureNavigatorProvider
+ {
+ /// <summary>
+ /// Creates a new <see cref="ITextStructureNavigator"/> for a given <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> for which to get the <see cref="ITextStructureNavigator"/>.</param>
+ /// <returns>The <see cref="ITextStructureNavigator"/> for <paramref name="textBuffer"/>, or null.</returns>
+ /// <remarks>
+ /// Providers should expect the result of this call to be cached and made available through the
+ /// <see cref="ITextStructureNavigatorSelectorService"/>.
+ /// </remarks>
+ ITextStructureNavigator CreateTextStructureNavigator(ITextBuffer textBuffer);
+ }
+}
diff --git a/src/Text/Def/TextLogic/Navigation/ITextStructureNavigatorSelectorService.cs b/src/Text/Def/TextLogic/Navigation/ITextStructureNavigatorSelectorService.cs
new file mode 100644
index 0000000..4b6aa19
--- /dev/null
+++ b/src/Text/Def/TextLogic/Navigation/ITextStructureNavigatorSelectorService.cs
@@ -0,0 +1,69 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ using System;
+ using System.ComponentModel.Composition;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Selects and caches <see cref="ITextStructureNavigator"/> objects based on content type.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// ITextStructureNavigatorSelectorService navigator = null;
+ /// </remarks>
+ public interface ITextStructureNavigatorSelectorService
+ {
+ /// <summary>
+ /// Gets a <see cref="ITextStructureNavigator"/> for the specified <see cref="ITextBuffer"/>, either by
+ /// creating a new one or by using a cached value.
+ /// </summary>
+ /// <param name="textBuffer">
+ /// The <see cref="ITextBuffer"/> that the <see cref="ITextStructureNavigator"/> will navigate.
+ /// </param>
+ /// <returns>
+ /// A valid <see cref="ITextStructureNavigator"/>. This value will never be <c>null</c>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// If a navigator for the exact <see cref="IContentType"/> of the given <see cref="ITextBuffer"/> cannot be found, this method returns
+ /// one for the parent <see cref="IContentType"/>. If there is more than one parent <see cref="IContentType"/> for which
+ /// there is a matching <see cref="ITextStructureNavigator"/>, then this method returns the <see cref="ITextStructureNavigator"/>
+ /// of an arbitrary parent.
+ /// </para>
+ /// <para>
+ /// If a new navigator is created, it is cached together with <paramref name="textBuffer"/>, and its lifetime is the same as that of <paramref name="textBuffer"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="textBuffer"/> is <c>null</c>.</exception>
+ ITextStructureNavigator GetTextStructureNavigator(ITextBuffer textBuffer);
+
+ /// <summary>
+ /// Creates a new <see cref="ITextStructureNavigator"/> for the specified <see cref="ITextBuffer"/> by using the
+ /// specified <see cref="IContentType"/> to select the navigator.
+ /// </summary>
+ /// <param name="textBuffer">
+ /// The <see cref="ITextBuffer"/> that the <see cref="ITextStructureNavigator"/> will navigate.
+ /// </param>
+ /// <param name="contentType">The content type to use.</param>
+ /// <returns>
+ /// A valid <see cref="ITextStructureNavigator"/>. This value is never <c>null</c>).
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// If a navigator for the given content type cannot be found, this method
+ /// uses one for the parent <see cref="IContentType"/>. If there is more than one parent <see cref="IContentType"/> for which
+ /// there is a matching <see cref="ITextStructureNavigator"/>, then this method returns the <see cref="ITextStructureNavigator"/>
+ /// of an arbitrary parent.
+ /// </para>
+ /// <para>
+ /// The navigator that is created is not cached; subsequent calls to this method for the same buffer and
+ /// content type will return different <see cref="ITextStructureNavigator"/> objects.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="textBuffer"/> is <c>null</c>.</exception>
+ ITextStructureNavigator CreateTextStructureNavigator(ITextBuffer textBuffer, IContentType contentType);
+ }
+}
diff --git a/src/Text/Def/TextLogic/Navigation/TextExtent.cs b/src/Text/Def/TextLogic/Navigation/TextExtent.cs
new file mode 100644
index 0000000..802b27c
--- /dev/null
+++ b/src/Text/Def/TextLogic/Navigation/TextExtent.cs
@@ -0,0 +1,116 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ using System;
+
+ /// <summary>
+ /// Represents the extent of a word.
+ /// </summary>
+ public struct TextExtent
+ {
+ #region Private Members
+
+ SnapshotSpan _span;
+ bool _isSignificant;
+
+ #endregion // Private Members
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="TextExtent"/>.
+ /// </summary>
+ /// <param name="span">
+ /// The <see cref="SnapshotSpan"/> that includes the extent.
+ /// </param>
+ /// <param name="isSignificant">
+ /// <c>false</c> if the extent contains whitespace, unless whitespace should be treated like any other character.
+ /// </param>
+ public TextExtent(SnapshotSpan span, bool isSignificant)
+ {
+ _span = span;
+ _isSignificant = isSignificant;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="TextExtent"/> from the specified <see cref="TextExtent"/>.
+ /// </summary>
+ /// <param name="textExtent">The <see cref="TextExtent"/> from which to copy.
+ /// </param>
+ public TextExtent(TextExtent textExtent)
+ {
+ _span = textExtent.Span;
+ _isSignificant = textExtent.IsSignificant;
+ }
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the <see cref="SnapshotSpan"/>.
+ /// </summary>
+ public SnapshotSpan Span
+ {
+ get { return _span; }
+ }
+
+ /// <summary>
+ /// Determines whether the extent is significant. <c>false</c> for whitespace or other
+ /// insignificant characters that should be ignored during navigation.
+ /// </summary>
+ public bool IsSignificant
+ {
+ get { return _isSignificant; }
+ }
+
+ #endregion // Public Properties
+
+ #region Overrides and operators
+ /// <summary>
+ /// Determines whether two <see cref="TextExtent"/> objects are the same.
+ /// </summary>
+ /// <param name="obj">The <see cref="TextExtent"/> to compare.</param>
+ /// <returns><c>true</c> if the two objects are the same, otherwise <c>false</c>.</returns>
+ public override bool Equals(object obj)
+ {
+ if (obj != null && obj is TextExtent)
+ {
+ return this == (TextExtent)obj;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ /// <summary>
+ /// Gets the hash code of the object.
+ /// </summary>
+ /// <returns>The hash code.</returns>
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="TextExtent"/> objects are the same.
+ /// </summary>
+ /// <param name="extent1">The first object.</param>
+ /// <param name="extent2">The second object.</param>
+ /// <returns><c>true</c> if the objects are the same, otherwise false.</returns>
+ public static bool operator ==(TextExtent extent1, TextExtent extent2)
+ {
+ return extent1._span == extent2._span && extent1._isSignificant == extent2._isSignificant;
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="TextExtent"/> objects are different.
+ /// </summary>
+ /// <param name="extent1">The first object.</param>
+ /// <param name="extent2">The second object.</param>
+ /// <returns><c>true</c> if the two objects are different, otherwise <c>false</c>.</returns>
+ public static bool operator !=(TextExtent extent1, TextExtent extent2)
+ {
+ return !(extent1 == extent2);
+ }
+ #endregion
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tagging/BatchedTagsChangedEventArgs.cs b/src/Text/Def/TextLogic/Tagging/BatchedTagsChangedEventArgs.cs
new file mode 100644
index 0000000..9e9d300
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/BatchedTagsChangedEventArgs.cs
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+
+ /// <summary>
+ /// Provides a list of all mapping spans where tags have changed since the last BatchedTagsChanged event.
+ /// The BatchedTagsChanged event is raised on the same thread as the thread that created the tag aggregator.
+ /// </summary>
+ public class BatchedTagsChangedEventArgs : EventArgs
+ {
+ ReadOnlyCollection<IMappingSpan> _spans;
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="BatchedTagsChangedEventArgs"/> with the specified list of <see cref="IMappingSpan" />s.
+ /// </summary>
+ /// <param name="spans">The list of <see cref="IMappingSpan" />s where the tags have changed.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="spans"/> is null.</exception>
+ public BatchedTagsChangedEventArgs(IList<IMappingSpan> spans)
+ {
+ if (spans == null)
+ throw new ArgumentNullException("spans");
+
+ //Make a copy of spans so we don't need to worry about it changing.
+ _spans = new ReadOnlyCollection<IMappingSpan>(new List<IMappingSpan>(spans));
+ }
+
+ /// <summary>
+ /// The list of <see cref="IMappingSpan" />s where the tags have changed.
+ /// </summary>
+ public ReadOnlyCollection<IMappingSpan> Spans { get { return _spans; } }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tagging/IBufferTagAggregatorFactoryService.cs b/src/Text/Def/TextLogic/Tagging/IBufferTagAggregatorFactoryService.cs
new file mode 100644
index 0000000..befbf66
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/IBufferTagAggregatorFactoryService.cs
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using System.ComponentModel.Composition;
+ using Microsoft.VisualStudio.Text;
+
+ /// <summary>
+ /// A factory that creates an <see cref="ITagAggregator&lt;T&gt;"/> for an <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and implementations should use the following to import it:
+ /// [Import]
+ /// IBufferTagAggregatorFactoryService factory = null;
+ /// </remarks>
+ public interface IBufferTagAggregatorFactoryService
+ {
+ /// <summary>
+ /// Creates a tag aggregator for a <paramref name="textBuffer"/>.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> over which the aggregator should aggregate tags,
+ /// including all source buffers if the buffer is a projection buffer.</param>
+ /// <typeparam name="T">The type of tag to aggregate.</typeparam>
+ /// <returns>The tag aggregator for <paramref name="textBuffer"/>.</returns>
+ /// <remarks>The ITagAggregatorr&lt;T&gt;.DispatchedTagsChanged event will be raised on the thread used to create the tag aggregator.</remarks>
+ ITagAggregator<T> CreateTagAggregator<T>(ITextBuffer textBuffer) where T : ITag;
+
+ /// <summary>
+ /// Creates a tag aggregator for a <paramref name="textBuffer"/>, using the given options.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> over which the aggregator should aggregate tags,
+ /// including all source buffers if the buffer is a projection buffer.</param>
+ /// <param name="options">The options to use for the newly created aggregator.</param>
+ /// <typeparam name="T">The type of tag to aggregate.</typeparam>
+ /// <returns>The tag aggregator for <paramref name="textBuffer"/>.</returns>
+ ITagAggregator<T> CreateTagAggregator<T>(ITextBuffer textBuffer, TagAggregatorOptions options) where T : ITag;
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tagging/ITag.cs b/src/Text/Def/TextLogic/Tagging/ITag.cs
new file mode 100644
index 0000000..fc95d65
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/ITag.cs
@@ -0,0 +1,12 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// The base interface of all tags.
+ /// </summary>
+ public interface ITag
+ {
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/Tagging/ITagAggregator.cs b/src/Text/Def/TextLogic/Tagging/ITagAggregator.cs
new file mode 100644
index 0000000..6e2354d
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/ITagAggregator.cs
@@ -0,0 +1,90 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.VisualStudio.Utilities;
+ using Microsoft.VisualStudio.Text.Projection;
+
+ /// <summary>
+ /// Aggregates all the tag providers in a buffer graph for the specified type of tag.
+ /// </summary>
+ /// <typeparam name="T">The type of tag returned by the aggregator.</typeparam>
+ /// <remarks>
+ /// The default tag aggregator implementation also does the following:
+ /// for each <see cref="ITagger&lt;T&gt;"/> over which it aggregates tags, if the tagger is
+ /// <see cref="IDisposable"/>, call Dispose() on it when the aggregator is disposed
+ /// or when the taggers are dropped. For example, you should call Dispose() when
+ /// the content type of a text buffer changes or when a buffer is removed from the buffer graph.
+ /// </remarks>
+ public interface ITagAggregator<out T> : IDisposable where T : ITag
+ {
+ /// <summary>
+ /// Gets all the tags that intersect the specified <paramref name="span"/> of the same type as the aggregator.
+ /// </summary>
+ /// <param name="span">The span to search.</param>
+ /// <returns>All the tags that intersect the region.</returns>
+ /// <remarks>
+ /// <para>The default tag aggregator lazily enumerates the tags of its <see cref="ITagger&lt;T&gt;"/> objects.
+ /// Because of this, the ordering of the returned mapping spans cannot be predicted.
+ /// If you need an ordered set of spans, you should collect the returned tag spans, after being mapped
+ /// to the buffer of interest, into a sortable collection.</para>
+ /// </remarks>
+ IEnumerable<IMappingTagSpan<T>> GetTags(SnapshotSpan span);
+
+ /// <summary>
+ /// Gets all the tags that intersect the specified <paramref name="span"/> of the type of the aggregator.
+ /// </summary>
+ /// <param name="span">The span to search.</param>
+ /// <returns>All the tags that intersect the region.</returns>
+ /// <remarks>
+ /// <para>The default tag aggregator lazily enumerates the tags of its <see cref="ITagger&lt;T&gt;"/> objects.
+ /// Because of this, the ordering of the returned mapping spans cannot be predicted.
+ /// If you need an ordered set of spans, you should collect the returned tag spans, after being mapped
+ /// to the buffer of interest, into a sortable collection.</para>
+ /// </remarks>
+ IEnumerable<IMappingTagSpan<T>> GetTags(IMappingSpan span);
+
+ /// <summary>
+ /// Gets all the tags that intersect the specified <paramref name="snapshotSpans"/> of the type of the aggregator.
+ /// </summary>
+ /// <param name="snapshotSpans">The spans to search.</param>
+ /// <returns>All the tags that intersect the region.</returns>
+ /// <remarks>
+ /// <para>The default tag aggregator lazily enumerates the tags of its <see cref="ITagger&lt;T&gt;"/> objects.
+ /// Because of this, the ordering of the returned mapping spans cannot be predicted.
+ /// If you need an ordered set of spans, you should collect the returned tag spans, after being mapped
+ /// to the buffer of interest, into a sortable collection.</para>
+ /// </remarks>
+ IEnumerable<IMappingTagSpan<T>> GetTags(NormalizedSnapshotSpanCollection snapshotSpans);
+
+ /// <summary>
+ /// Occurs when tags are added to or removed from providers.
+ /// </summary>
+ event EventHandler<TagsChangedEventArgs> TagsChanged;
+
+ /// <summary>
+ /// Occurs on idle after one or more TagsChanged events.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This is a batched version of the TagsChanged event. One or more TagsChanged events
+ /// are accumulated and then raised as a single BatchedTagsChanged event on idle using the
+ /// <see cref="T:System.Windows.Threading.Dispatcher.CurrentDispatcher" /> that was active when the ITagAggregator was
+ /// created.
+ /// </para>
+ /// <para>
+ /// This event is less noisy than TagsChanged and is always raised on the thread
+ /// that was active when the ITagAggregator was created.
+ /// </para>
+ /// </remarks>
+ event EventHandler<BatchedTagsChangedEventArgs> BatchedTagsChanged;
+
+ /// <summary>
+ /// The buffer graph over which this aggregator operates.
+ /// </summary>
+ IBufferGraph BufferGraph { get; }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tagging/ITagger.cs b/src/Text/Def/TextLogic/Tagging/ITagger.cs
new file mode 100644
index 0000000..2ca8b4a
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/ITagger.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// A provider of tags over a buffer.
+ /// </summary>
+ /// <typeparam name="T">The type of tags to generate.</typeparam>
+ public interface ITagger<out T> where T : ITag
+ {
+ /// <summary>
+ /// Gets all the tags that intersect the <paramref name="spans"/>.
+ /// </summary>
+ /// <param name="spans">The spans to visit.</param>
+ /// <returns>A <see cref="ITagSpan&lt;T&gt;"/> for each tag.</returns>
+ /// <remarks>
+ /// <para>Taggers are not required to return their tags in any specific order.</para>
+ /// <para>The recommended way to implement this method is by using generators ("yield return"),
+ /// which allows lazy evaluation of the entire tagging stack.</para>
+ /// </remarks>
+ IEnumerable<ITagSpan<T>> GetTags(NormalizedSnapshotSpanCollection spans);
+
+ /// <summary>
+ /// Occurs when tags are added to or removed from the provider.
+ /// </summary>
+ event EventHandler<SnapshotSpanEventArgs> TagsChanged;
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tagging/ITaggerProvider.cs b/src/Text/Def/TextLogic/Tagging/ITaggerProvider.cs
new file mode 100644
index 0000000..d93e120
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/ITaggerProvider.cs
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// Creates an <see cref="ITagger&lt;T&gt;"/> for a given buffer.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and implementers must use the following attributes:
+ /// [Export(nameSource=typeof(ITaggerProvider))]
+ /// Exports must specify at least one content type attribute and at least one tag type attribute.</remarks>
+ public interface ITaggerProvider
+ {
+ /// <summary>
+ /// Creates a tag provider for the specified buffer.
+ /// </summary>
+ /// <param name="buffer">The <see cref="ITextBuffer"/>.</param>
+ /// <typeparam name="T">The type of the tag.</typeparam>
+ ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag;
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tagging/MappingTagSpan.cs b/src/Text/Def/TextLogic/Tagging/MappingTagSpan.cs
new file mode 100644
index 0000000..4844b22
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/MappingTagSpan.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// Associates an <see cref="ITag" /> with a specified <see cref="IMappingSpan" />.
+ /// </summary>
+ /// <typeparam name="T">The type, which must be a subtype of <see cref="ITag"/>.</typeparam>
+ /// <remarks>
+ /// Use <see cref="MappingTagSpan&lt;T&gt;" /> as the implementation of this
+ /// interface.
+ /// </remarks>
+ public interface IMappingTagSpan<out T> where T : ITag
+ {
+ /// <summary>
+ /// Gets the tag located in this span.
+ /// </summary>
+ T Tag { get; }
+
+ /// <summary>
+ /// Gets the mapping span for this tag.
+ /// </summary>
+ IMappingSpan Span { get; }
+ }
+
+ /// <summary>
+ /// The implementation of IMappingTagSpan&lt;T&gt;.
+ /// </summary>
+ public class MappingTagSpan<T> : IMappingTagSpan<T> where T : ITag
+ {
+ #region IMappingTagSpan<T> members
+
+ /// <summary>
+ /// Gets the tag located in this span.
+ /// </summary>
+ public T Tag { get; private set; }
+
+ /// <summary>
+ /// Gets the mapping span for this tag.
+ /// </summary>
+ public IMappingSpan Span { get; private set; }
+
+ #endregion
+
+ /// <summary>
+ /// Creates a mapping tag span.
+ /// </summary>
+ /// <param name="span">The mapping span with which to associate the tag.</param>
+ /// <param name="tag">The tag associated with the span.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/> or <paramref name="tag"/> is null.</exception>
+ public MappingTagSpan(IMappingSpan span, T tag)
+ {
+ if (span == null)
+ throw new ArgumentNullException("span");
+ if (tag == null)
+ throw new ArgumentNullException("tag");
+
+ Span = span;
+ Tag = tag;
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tagging/SimpleTagger.cs b/src/Text/Def/TextLogic/Tagging/SimpleTagger.cs
new file mode 100644
index 0000000..22ab418
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/SimpleTagger.cs
@@ -0,0 +1,288 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading;
+
+ using Microsoft.VisualStudio.Text;
+
+ /// <summary>
+ /// Provides simple, thread-safe storage of and interaction with tags of the given type.
+ /// </summary>
+ /// <typeparam name="T">The type, which must be a subtype of <see cref="ITag"/>.</typeparam>
+ public class SimpleTagger<T> : ITagger<T> where T : ITag
+ {
+ #region Private members
+
+ private List<TrackingTagSpan<T>> _trackingTagSpans = new List<TrackingTagSpan<T>>();
+
+ private ITextBuffer buffer;
+ private object mutex = new object();
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="SimpleTagger&lt;T&gt;"/> for the specified buffer.
+ /// </summary>
+ /// <param name="buffer">Subject buffer that will be tagged.</param>
+ public SimpleTagger(ITextBuffer buffer)
+ {
+ this.buffer = buffer;
+ }
+
+ private int _batchNesting;
+ private ITrackingSpan _batchSpan;
+
+ private void StartBatch()
+ {
+ Interlocked.Increment(ref _batchNesting);
+ }
+
+ private void EndBatch()
+ {
+ if (Interlocked.Decrement(ref _batchNesting) == 0)
+ {
+ ITrackingSpan batchedRange = Interlocked.Exchange(ref _batchSpan, null);
+
+ if (batchedRange != null)
+ {
+ EventHandler<SnapshotSpanEventArgs> handler = this.TagsChanged;
+ if (handler != null)
+ {
+ handler(this, new SnapshotSpanEventArgs(batchedRange.GetSpan(buffer.CurrentSnapshot)));
+ }
+ }
+ }
+ }
+
+ private void UpdateBatchSpan(ITrackingSpan snapshotSpan)
+ {
+ ITrackingSpan newBatchSpan = snapshotSpan;
+
+ // If there currently is a batch span, update it to include the biggest
+ // range of buffer affected so far.
+ if (_batchSpan != null)
+ {
+ ITextSnapshot snapshot = buffer.CurrentSnapshot;
+
+ SnapshotSpan currentBatchSpan = _batchSpan.GetSpan(snapshot);
+ SnapshotSpan currentUpdate = snapshotSpan.GetSpan(snapshot);
+
+ SnapshotPoint newStart = currentBatchSpan.Start < currentUpdate.Start ? currentBatchSpan.Start : currentUpdate.Start;
+ SnapshotPoint newEnd = currentBatchSpan.End > currentUpdate.End ? currentBatchSpan.End : currentUpdate.End;
+
+ // In the event of multiple updates, we use the tracking mode of the first update's span for predictability
+ newBatchSpan = snapshot.CreateTrackingSpan(new SnapshotSpan(newStart, newEnd), _batchSpan.TrackingMode);
+ }
+
+ _batchSpan = newBatchSpan;
+ }
+
+ #region SimpleTagger<T> Members
+
+ /// <summary>
+ /// Adds a tag over the given span.
+ /// </summary>
+ /// <param name="span">The <see cref="ITrackingSpan"/> that tracks the tag across text versions.</param>
+ /// <param name="tag">The tag to associate with the given span.</param>
+ /// <returns>The <see cref="TrackingTagSpan&lt;T&gt;"/> that was added, which can be used to remove the tag later on.</returns>
+ /// <remarks>This method is safe to use from any thread.</remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/> or <paramref name="tag"/> is null.</exception>
+ public TrackingTagSpan<T> CreateTagSpan(ITrackingSpan span, T tag)
+ {
+ if (span == null)
+ throw new ArgumentNullException("span");
+ if (tag == null)
+ throw new ArgumentNullException("tag");
+
+ var tagSpan = new TrackingTagSpan<T>(span, tag);
+
+ StartBatch();
+ try
+ {
+ lock (mutex)
+ {
+ _trackingTagSpans.Add(tagSpan);
+ UpdateBatchSpan(tagSpan.Span);
+ }
+ }
+ finally
+ {
+ EndBatch();
+ }
+
+ return tagSpan;
+ }
+
+ /// <summary>
+ /// Removes a tag span that was created by calling <see cref="CreateTagSpan"/>.
+ /// </summary>
+ /// <param name="tagSpan">The <see cref="TrackingTagSpan&lt;T&gt;"/> returned from a previous call to <see cref="CreateTagSpan"/>.</param>
+ /// <returns><c>true</c> if removed successfully, otherwise <c>false</c>.</returns>
+ /// <remarks>This method is safe to use from any thread.</remarks>
+ public bool RemoveTagSpan(TrackingTagSpan<T> tagSpan)
+ {
+ if (tagSpan == null)
+ throw new ArgumentNullException("tagSpan");
+
+ bool removed = false;
+
+ StartBatch();
+ try
+ {
+ lock (mutex)
+ {
+ // Find the tracking tag span to be removed
+ removed = (_trackingTagSpans.Remove(tagSpan));
+ if (removed)
+ {
+ UpdateBatchSpan(tagSpan.Span);
+ }
+ }
+ }
+ finally
+ {
+ EndBatch();
+ }
+
+ return removed;
+ }
+
+ /// <summary>
+ /// Removes all tag spans that match the conditions specified by the predicate.
+ /// </summary>
+ /// <param name="match">The <see cref="Predicate&lt;T&gt;"/> that defines the match.</param>
+ /// <returns>The number of tag spans removed.</returns>
+ /// <remarks>This method is safe to use from any thread.</remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="match"/> is null.</exception>
+ public int RemoveTagSpans(Predicate<TrackingTagSpan<T>> match)
+ {
+ if (match == null)
+ throw new ArgumentNullException("match");
+
+ int removedCount = 0;
+
+ StartBatch();
+ try
+ {
+ lock (mutex)
+ {
+ removedCount = _trackingTagSpans.RemoveAll(tagSpan =>
+ {
+ // If we have a match, then we'll need to update the batch span to include this span.
+ if (match(tagSpan))
+ {
+ UpdateBatchSpan(tagSpan.Span);
+ return true;
+ }
+ return false;
+ });
+ }
+ }
+ finally
+ {
+ EndBatch();
+ }
+
+ return removedCount;
+ }
+
+ /// <summary>
+ /// Gets the tagged spans that intersect the given <see cref="SnapshotSpan"/>.
+ /// </summary>
+ /// <param name="span">The <see cref="SnapshotSpan"/> to use.</param>
+ /// <returns>The set of <see cref="TrackingTagSpan&lt;T&gt;"/> objects that intersect the given span, in order.</returns>
+ public IEnumerable<TrackingTagSpan<T>> GetTaggedSpans(SnapshotSpan span)
+ {
+ IList<TrackingTagSpan<T>> tagSpanList = new List<TrackingTagSpan<T>>(_trackingTagSpans);
+
+ lock (mutex)
+ {
+ tagSpanList = new List<TrackingTagSpan<T>>(_trackingTagSpans);
+ }
+
+ return tagSpanList.Where(tagSpan => span.IntersectsWith(tagSpan.Span.GetSpan(span.Snapshot)));
+ }
+
+ /// <summary>
+ /// Gets an IDisposable object that represents an update batch.
+ /// </summary>
+ /// <returns>An IDisposable object that represents an update batch.</returns>
+ public IDisposable Update()
+ {
+ return new Batch(this);
+ }
+
+ #endregion
+
+ #region ITagger<T> Members
+
+ /// <summary>
+ /// Gets all the tags that intersect the spans in the specified snapshot
+ /// of the desired type.
+ /// </summary>
+ /// <param name="spans">The spans to visit.</param>
+ /// <returns>A <see cref="ITagSpan&lt;T&gt;"/> for each tag.</returns>
+ public IEnumerable<ITagSpan<T>> GetTags(NormalizedSnapshotSpanCollection spans)
+ {
+ if (spans.Count == 0)
+ yield break;
+
+ IList<TrackingTagSpan<T>> tagSpanList;
+
+ lock (mutex)
+ {
+ tagSpanList = new List<TrackingTagSpan<T>>(_trackingTagSpans);
+ }
+
+ foreach (var tagSpan in tagSpanList)
+ {
+ SnapshotSpan tagSnapshotSpan = tagSpan.Span.GetSpan(spans[0].Snapshot);
+
+ foreach (var querySpan in spans)
+ {
+ if (tagSnapshotSpan.IntersectsWith(querySpan))
+ {
+ yield return new TagSpan<T>(tagSnapshotSpan, tagSpan.Tag);
+ break;
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Occurs when one or more tags have been added or removed.
+ /// </summary>
+ public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
+
+ #endregion
+
+ private class Batch : IDisposable
+ {
+ SimpleTagger<T> _tagger;
+ internal Batch(SimpleTagger<T> tagger)
+ {
+ if (tagger == null)
+ {
+ throw new ArgumentNullException("tagger");
+ }
+ _tagger = tagger;
+ _tagger.StartBatch();
+ }
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ _tagger.EndBatch();
+ _tagger = null;
+ GC.SuppressFinalize(this);
+ }
+
+ #endregion
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tagging/TagAggregatorOptions.cs b/src/Text/Def/TextLogic/Tagging/TagAggregatorOptions.cs
new file mode 100644
index 0000000..0738482
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/TagAggregatorOptions.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using System;
+ using Microsoft.VisualStudio.Text.Projection;
+
+ /// <summary>
+ /// Tag Aggregator options.
+ /// </summary>
+ [Flags]
+ public enum TagAggregatorOptions
+ {
+ /// <summary>
+ /// Default behavior. The tag aggregator will map up and down through all projection buffers.
+ /// </summary>
+ None = 0,
+
+ /// <summary>
+ /// Only map through projection buffers that have the "projection" content type.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Normally, a tag aggregator will map up and down through all projection buffers (buffers
+ /// that implement <see cref="IProjectionBufferBase"/>). This flag will cause the projection buffer
+ /// to not map through buffers that are projection buffers but do not have a projection content type.
+ /// </para>
+ /// </remarks>
+ /// <comment>This is used by the classifier aggregator, as classification depends on content type.</comment>
+ MapByContentType = 0x1
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/Tagging/TagSpan.cs b/src/Text/Def/TextLogic/Tagging/TagSpan.cs
new file mode 100644
index 0000000..dd61ab9
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/TagSpan.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// Associates an <see cref="ITag" /> with a given <see cref="SnapshotSpan" />.
+ /// </summary>
+ /// <typeparam name="T">The type, which must be a subclass of <see cref="ITag"/>.</typeparam>
+ /// <remarks>
+ /// Use <see cref="TagSpan&lt;T&gt;" /> as the implementation of this
+ /// interface.
+ /// </remarks>
+ public interface ITagSpan<out T> where T : ITag
+ {
+ /// <summary>
+ /// Gets the tag located in this span.
+ /// </summary>
+ T Tag { get; }
+
+ /// <summary>
+ /// Gets the snapshot span for this tag.
+ /// </summary>
+ SnapshotSpan Span { get; }
+ }
+
+ /// <summary>
+ /// The implementation of ITagSpan&lt;T&gt;.
+ /// </summary>
+ public class TagSpan<T> : ITagSpan<T> where T : ITag
+ {
+ #region ITagSpan<T> members
+
+ /// <summary>
+ /// Gets the tag located in this span.
+ /// </summary>
+ public T Tag { get; private set; }
+
+ /// <summary>
+ /// Gets the snapshot span for this tag.
+ /// </summary>
+ public SnapshotSpan Span { get; private set; }
+
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="TagSpan&lt;T&gt;"/> with the specified snapshot span and tag.
+ /// </summary>
+ /// <param name="span">The <see cref="SnapshotSpan"/> with which to associate the tag.</param>
+ /// <param name="tag">The tag associated with the span.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="tag"/> is null.</exception>
+ public TagSpan(SnapshotSpan span, T tag)
+ {
+ if (tag == null)
+ throw new ArgumentNullException("tag");
+
+ Span = span;
+ Tag = tag;
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tagging/TagTypeAttribute.cs b/src/Text/Def/TextLogic/Tagging/TagTypeAttribute.cs
new file mode 100644
index 0000000..ecddbaf
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/TagTypeAttribute.cs
@@ -0,0 +1,45 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+ using Microsoft.VisualStudio.Utilities;
+ using Microsoft.VisualStudio.Text.Tagging;
+ using System.ComponentModel.Composition;
+
+ /// <summary>
+ /// Declares the types of tags an <see cref="ITagger&lt;T&gt;"/>
+ /// produces. This attribute is placed on the provider of the tagger.
+ /// </summary>
+ public sealed class TagTypeAttribute : MultipleBaseMetadataAttribute
+ {
+ private Type type;
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="TagTypeAttribute"/>.
+ /// </summary>
+ /// <param name="tagType">The tag type, which must derive from <see cref="ITag"/>.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="tagType"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="tagType"/> does not derive from <see cref="ITag"/>.</exception>
+ public TagTypeAttribute(Type tagType)
+ {
+ if (tagType == null)
+ throw new ArgumentNullException("tagType");
+ if (!typeof(ITag).IsAssignableFrom(tagType))
+ throw new ArgumentException("Given type must derive from ITag", "tagType");
+
+ this.type = tagType;
+ }
+
+ /// <summary>
+ /// Gets the type of the tag.
+ /// </summary>
+ public Type TagTypes
+ {
+ get { return type; }
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tagging/TagsChangedEventArgs.cs b/src/Text/Def/TextLogic/Tagging/TagsChangedEventArgs.cs
new file mode 100644
index 0000000..7f756ca
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/TagsChangedEventArgs.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using System;
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Provides information about the <see cref="ITagAggregator&lt;T&gt;" />.TagsChanged event.
+ /// </summary>
+ public class TagsChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the span over which tags have changed.
+ /// </summary>
+ public IMappingSpan Span { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="TagsChangedEventArgs"/> with the specified <see cref="IMappingSpan" />.
+ /// </summary>
+ /// <param name="span">The <see cref="IMappingSpan" />.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/> is null.</exception>
+ public TagsChangedEventArgs(IMappingSpan span)
+ {
+ if (span == null)
+ throw new ArgumentNullException("span");
+
+ Span = span;
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tagging/TrackingTagSpan.cs b/src/Text/Def/TextLogic/Tagging/TrackingTagSpan.cs
new file mode 100644
index 0000000..8ad4adc
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tagging/TrackingTagSpan.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// Associates an <see cref="ITag" /> with a given <see cref="ITrackingSpan" />.
+ /// This is used by SimpleTagger to provide buffer-level tracking and caching of tag spans.
+ /// </summary>
+ /// <typeparam name="T">The type, which must be a subclass of <see cref="ITag"/>.</typeparam>
+ public class TrackingTagSpan<T> where T : ITag
+ {
+ /// <summary>
+ /// The tag located in this span.
+ /// </summary>
+ public T Tag { get; private set; }
+
+ /// <summary>
+ /// The tracking span for this tag.
+ /// </summary>
+ public ITrackingSpan Span { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="TrackingTagSpan&lt;T&gt;"/>.
+ /// </summary>
+ /// <param name="span">The tracking span with which to associate the tag.</param>
+ /// <param name="tag">The tag associated with the span.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/> or <paramref name="tag"/> is null.</exception>
+ public TrackingTagSpan(ITrackingSpan span, T tag)
+ {
+ if (span == null)
+ throw new ArgumentNullException("span");
+ if (tag == null)
+ throw new ArgumentNullException("tag");
+
+ Span = span;
+ Tag = tag;
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tags/ClassificationTag.cs b/src/Text/Def/TextLogic/Tags/ClassificationTag.cs
new file mode 100644
index 0000000..07daef4
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tags/ClassificationTag.cs
@@ -0,0 +1,31 @@
+using System;
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using Microsoft.VisualStudio.Text.Classification;
+
+ /// <summary>
+ /// An implementation of <see cref="IClassificationTag" />.
+ /// </summary>
+ public class ClassificationTag : IClassificationTag
+ {
+ /// <summary>
+ /// Create a new tag associated with the given type of
+ /// classification.
+ /// </summary>
+ /// <param name="type">The type of classification</param>
+ /// <exception cref="ArgumentNullException">If the type is passed in as null</exception>
+ public ClassificationTag(IClassificationType type)
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+
+ ClassificationType = type;
+ }
+
+ /// <summary>
+ /// The classification type associated with this tag.
+ /// </summary>
+ public IClassificationType ClassificationType { get; private set; }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tags/IClassificationTag.cs b/src/Text/Def/TextLogic/Tags/IClassificationTag.cs
new file mode 100644
index 0000000..0ddb96c
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tags/IClassificationTag.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using Microsoft.VisualStudio.Text.Classification;
+
+ /// <summary>
+ /// A tag that represents a classification type.
+ /// </summary>
+ public interface IClassificationTag : ITag
+ {
+ /// <summary>
+ /// The classification type associated with this tag.
+ /// </summary>
+ IClassificationType ClassificationType { get; }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tags/IUrlTag.cs b/src/Text/Def/TextLogic/Tags/IUrlTag.cs
new file mode 100644
index 0000000..1b6ae9c
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tags/IUrlTag.cs
@@ -0,0 +1,14 @@
+using System;
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// A tag that represents a URL.
+ /// </summary>
+ public interface IUrlTag : ITag
+ {
+ /// <summary>
+ /// The URL.
+ /// </summary>
+ Uri Url { get; }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Tags/UrlTag.cs b/src/Text/Def/TextLogic/Tags/UrlTag.cs
new file mode 100644
index 0000000..7d7a7ec
--- /dev/null
+++ b/src/Text/Def/TextLogic/Tags/UrlTag.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// An implementation of <see cref="IUrlTag" />.
+ /// </summary>
+ public class UrlTag : IUrlTag
+ {
+ public Uri Url { get; private set; }
+
+ /// <summary>
+ /// Create a new tag with the given URL.
+ /// </summary>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="url" /> is <c>null</c></exception>
+ public UrlTag(Uri url)
+ {
+ if (url == null)
+ throw new ArgumentNullException("url");
+
+ Url = url;
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/TextLogic.csproj b/src/Text/Def/TextLogic/TextLogic.csproj
new file mode 100644
index 0000000..1679147
--- /dev/null
+++ b/src/Text/Def/TextLogic/TextLogic.csproj
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="BuildProps">
+ <BuildPropsFile>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), Build.props))\Build.props</BuildPropsFile>
+ </PropertyGroup>
+ <Import Project="$(BuildPropsFile)" Condition="'$(BuildProps_Imported)'!='True' AND Exists('$(BuildPropsFile)') AND '$(VisualStudioDir)'==''" />
+ <Import Project="..\Platform.Settings.targets" />
+ <Import Project="$(PlatformPath)\Tools\Targets\Platform.Settings.Selector.targets" />
+ <PropertyGroup>
+ <AssemblyName>Microsoft.VisualStudio.Text.Logic</AssemblyName>
+ <OutputPath>$(BinariesDirectory)\bin\$(BuildArchitecture)</OutputPath>
+ <OutputType>Library</OutputType>
+ <SignAssemblyAttribute>true</SignAssemblyAttribute>
+ <UseVsVersion>true</UseVsVersion>
+ <AssemblyAttributeClsCompliant>true</AssemblyAttributeClsCompliant>
+ <GenerateAssemblyRefs>true</GenerateAssemblyRefs>
+ <NoWarn>649;436;$(NoWarn)</NoWarn>
+ <GeneratedModuleId>Microsoft.VisualStudio.Text.Logic</GeneratedModuleId>
+ <GeneratedModuleVersion>$(VsAssemblyVersion)</GeneratedModuleVersion>
+ <BuildArchitecturesAllowed>$(BuildArchitecturesAllowed);amd64;arm</BuildArchitecturesAllowed>
+ </PropertyGroup>
+ <!-- IDE specific Information -->
+ <PropertyGroup>
+ <ProjectGuid>{26FAFDBB-9C63-4F92-A176-6E350178DB67}</ProjectGuid>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="AssemblyInfo.cs" />
+ <Compile Include="Classification\ClassificationChangedEventArgs.cs" />
+ <Compile Include="Classification\ClassificationSpan.cs" />
+ <Compile Include="Classification\ClassificationTypeAttribute.cs" />
+ <Compile Include="Classification\IClassificationType.cs" />
+ <Compile Include="Classification\ClassificationTypeDefinition.cs" />
+ <Compile Include="Classification\IClassificationTypeRegistryService.cs" />
+ <Compile Include="Classification\IClassifier.cs" />
+ <Compile Include="Classification\IClassifierAggregatorService.cs" />
+ <Compile Include="Classification\IClassifierProvider.cs" />
+ <Compile Include="DifferenceBuffer\DifferenceBufferOptions.cs" />
+ <Compile Include="DifferenceBuffer\DifferenceMappingMode.cs" />
+ <Compile Include="DifferenceBuffer\DifferenceTrackingSpans.cs" />
+ <Compile Include="DifferenceBuffer\IDifferenceBuffer.cs" />
+ <Compile Include="DifferenceBuffer\IDifferenceBufferFactoryService.cs" />
+ <Compile Include="DifferenceBuffer\IgnoreWhiteSpaceBehavior.cs" />
+ <Compile Include="DifferenceBuffer\ISnapshotDifference.cs" />
+ <Compile Include="DifferenceBuffer\IgnoreDifferencePredicate.cs" />
+ <Compile Include="DifferenceBuffer\LineType.cs" />
+ <Compile Include="DifferenceBuffer\SnapshotDifferenceChangeEventArgs.cs" />
+ <Compile Include="DifferenceBuffer\SnapshotLineTransform.cs" />
+ <Compile Include="EditorOptions\DeferCreationAttribute.cs" />
+ <Compile Include="EditorOptions\EditorOptionKey.cs" />
+ <Compile Include="EditorOptions\DefaultOptions.cs" />
+ <Compile Include="Find\ITextSearchNavigator.cs" />
+ <Compile Include="Find\ITextSearchNavigatorFactoryService.cs" />
+ <Compile Include="Find\ITextSearchService.cs" />
+ <Compile Include="Find\ITextSearchService2.cs" />
+ <Compile Include="Navigation\ITextStructureNavigatorProvider.cs" />
+ <Compile Include="Navigation\ITextStructureNavigatorSelectorService.cs" />
+ <Compile Include="EditorOptions\EditorOptionChangedEventArgs.cs" />
+ <Compile Include="EditorOptions\EditorOptionDefinition.cs" />
+ <Compile Include="EditorOptions\IEditorOptions.cs" />
+ <Compile Include="EditorOptions\IEditorOptionsFactoryService.cs" />
+ <Compile Include="Tagging\TagAggregatorOptions.cs" />
+ <Compile Include="Tagging\BatchedTagsChangedEventArgs.cs" />
+ <Compile Include="Tagging\TrackingTagSpan.cs" />
+ <Compile Include="Tagging\ITagAggregator.cs" />
+ <Compile Include="Tagging\IBufferTagAggregatorFactoryService.cs" />
+ <Compile Include="Tagging\ITagger.cs" />
+ <Compile Include="Tagging\MappingTagSpan.cs" />
+ <Compile Include="Tagging\SimpleTagger.cs" />
+ <Compile Include="Tagging\TagsChangedEventArgs.cs" />
+ <Compile Include="Tagging\ITaggerProvider.cs" />
+ <Compile Include="Tagging\TagSpan.cs" />
+ <Compile Include="Tagging\TagTypeAttribute.cs" />
+ <Compile Include="Tags\ClassificationTag.cs" />
+ <Compile Include="Tags\IClassificationTag.cs" />
+ <Compile Include="Tags\IUrlTag.cs" />
+ <Compile Include="Tags\UrlTag.cs" />
+ <Compile Include="TextModel\ChangeTag.cs" />
+ <Compile Include="TextModel\ChangeTypes.cs" />
+ <Compile Include="TextModel\ITextDataModel.cs" />
+ <Compile Include="TextModel\TextDataModelContentTypeChangedEventArgs.cs" />
+ <Compile Include="Find\FindData.cs" />
+ <Compile Include="Find\FindOptions.cs" />
+ <Compile Include="FxCopSuppressions.cs" />
+ <Compile Include="Navigation\ITextStructureNavigator.cs" />
+ <Compile Include="Navigation\TextExtent.cs" />
+ <Compile Include="Tagging\ITag.cs" />
+ <Compile Include="TextModel\VirtualSnapshotPoint.cs" />
+ <Compile Include="TextModel\VirtualSnapshotSpan.cs" />
+ <Compile Include="Undo\IMergeTextUndoTransactionPolicy.cs" />
+ <Compile Include="Undo\ITextBufferUndoManager.cs" />
+ <Compile Include="Undo\ITextBufferUndoManagerProvider.cs" />
+ <Compile Include="Undo\ITextUndoHistory.cs" />
+ <Compile Include="Undo\ITextUndoHistoryRegistry.cs" />
+ <Compile Include="Undo\ITextUndoPrimitive.cs" />
+ <Compile Include="Undo\ITextUndoTransaction.cs" />
+ <Compile Include="Undo\TextUndoHistoryState.cs" />
+ <Compile Include="Undo\TextUndoRedoEventArgs.cs" />
+ <Compile Include="Undo\TextUndoTransactionCompletedEventArgs.cs" />
+ <Compile Include="Undo\TextUndoTransactionState.cs" />
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.Composition" />
+ <Reference Include="System.Core" />
+ <CopyFile Include="Classification\Microsoft.VisualStudio.Text.Classification.Overview.mht">
+ <DestFolder>$(SuiteBinPath)\PlatformOverviews</DestFolder>
+ <Visible>false</Visible>
+ </CopyFile>
+ <ProjectReference Include="..\TextData\TextData.csproj">
+ <Project>{80A00E91-51E5-471C-80BA-0D863987ECC7}</Project>
+ <Name>TextData %28Text\Def\TextData\TextData%29</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\Core\Def\CoreUtility.csproj">
+ <Project>{BA3DD7EC-3F13-4400-A3A9-96AD425B3369}</Project>
+ <Name>CoreUtility</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <PublishPartLinked Include="$(OutputPath)\$(AssemblyName).dll">
+ <Visibility>Inter</Visibility>
+ <FileType>Reference</FileType>
+ <DoNotCopyPDB>true</DoNotCopyPDB>
+ </PublishPartLinked>
+ </ItemGroup>
+ <!--Import the targets-->
+ <Import Project="$(PlatformPath)\Tools\Targets\Platform.Imports.targets" />
+ <PropertyGroup>
+ <CopyToSuiteBin>true</CopyToSuiteBin>
+ </PropertyGroup>
+ <ItemGroup>
+ <None Include="Diagrams\Tagging.cd" />
+ <None Include="Diagrams\Undo.cd" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/TextModel/ChangeTag.cs b/src/Text/Def/TextLogic/TextModel/ChangeTag.cs
new file mode 100644
index 0000000..e0a9a7b
--- /dev/null
+++ b/src/Text/Def/TextLogic/TextModel/ChangeTag.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Document
+{
+ using Microsoft.VisualStudio.Text.Tagging;
+
+ /// <summary>
+ /// A tag associated with a span of modified text.
+ /// </summary>
+ /// <remarks>
+ /// <para>Use the CreateTagAggregator method of IViewTagAggregatorFactoryService to instantiate an aggregator of change tags.</para>
+ /// <para>Change taggers lose their change history when they are no longer consumed by any tag aggregators. They resume
+ /// tracking changes if a new aggregator is created.</para>
+ /// </remarks>
+ public class ChangeTag : ITag
+ {
+ /// <summary>
+ /// Gets the type of change for the tag.
+ /// </summary>
+ public ChangeTypes ChangeTypes { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="ChangeTag"/> with the specified change type.
+ /// </summary>
+ /// <param name="type">The type of change for the tag.</param>
+ public ChangeTag(ChangeTypes type)
+ {
+ this.ChangeTypes = type;
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/TextModel/ChangeTypes.cs b/src/Text/Def/TextLogic/TextModel/ChangeTypes.cs
new file mode 100644
index 0000000..d1c9b2c
--- /dev/null
+++ b/src/Text/Def/TextLogic/TextModel/ChangeTypes.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Document
+{
+ /// <summary>
+ /// Specifies the types of changes for modified text.
+ /// </summary>
+ [System.Flags]
+ public enum ChangeTypes
+ {
+ /// <summary>
+ /// No change types are set.
+ /// </summary>
+ None = 0x00,
+
+ /// <summary>
+ /// The change occurred after the document was opened.
+ /// </summary>
+ ChangedSinceOpened = 0x01,
+
+ /// <summary>
+ /// The change occurred after the document was saved.
+ /// </summary>
+ ChangedSinceSaved = 0x02
+ }
+}
diff --git a/src/Text/Def/TextLogic/TextModel/ITextDataModel.cs b/src/Text/Def/TextLogic/TextModel/ITextDataModel.cs
new file mode 100644
index 0000000..53707e9
--- /dev/null
+++ b/src/Text/Def/TextLogic/TextModel/ITextDataModel.cs
@@ -0,0 +1,48 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using Microsoft.VisualStudio.Text.Projection;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Prepares the <see cref="ITextBuffer"/> for presentation in the editor. Typically the <see cref="ITextDataModel"/>
+ /// comprises a single <see cref="ITextBuffer"/> that is exposed as both the <see cref="DocumentBuffer"/> and
+ /// the <see cref="DataBuffer"/>. However, in some cases, a graph of <see cref="IProjectionBuffer"/>s is useful to
+ /// present as it if were a single document. In that case, the <see cref="DataBuffer"/> will be an <see cref="IProjectionBuffer"/>
+ /// that uses the <see cref="DocumentBuffer"/> as a source buffer, directly or indirectly.
+ /// </summary>
+ /// <remarks>
+ /// The <see cref="ContentType"/> usually is the same as that of the <see cref="DocumentBuffer"/>
+ /// </remarks>
+ public interface ITextDataModel
+ {
+ /// <summary>
+ /// The <see cref="IContentType"/> of the text data model. Usually this is the same as the <see cref="IContentType"/>
+ /// of the <see cref="DocumentBuffer"/> but it need not be.
+ /// </summary>
+ IContentType ContentType { get; }
+
+ /// <summary>
+ /// Raised when the <see cref="ContentType"/> of this text data model changes.
+ /// </summary>
+ event EventHandler<TextDataModelContentTypeChangedEventArgs> ContentTypeChanged;
+
+ /// <summary>
+ /// Gets the <see cref="ITextBuffer"/> corresponding to a document in the file system.
+ /// </summary>
+ ITextBuffer DocumentBuffer { get; }
+
+ /// <summary>
+ /// Gets the <see cref="ITextBuffer"/> that should be presented in the editor.
+ /// </summary>
+ /// <remarks>
+ /// This text buffer may be the same as the <see cref="DocumentBuffer"/>, or it may be a projection buffer
+ /// whose ultimate source is the <see cref="DocumentBuffer"/>. The data buffer is the highest buffer that
+ /// is shared among different views.
+ /// </remarks>
+ ITextBuffer DataBuffer { get; }
+ }
+}
diff --git a/src/Text/Def/TextLogic/TextModel/TextDataModelContentTypeChangedEventArgs.cs b/src/Text/Def/TextLogic/TextModel/TextDataModelContentTypeChangedEventArgs.cs
new file mode 100644
index 0000000..6ce93af
--- /dev/null
+++ b/src/Text/Def/TextLogic/TextModel/TextDataModelContentTypeChangedEventArgs.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Provides information about a change to the <see cref="IContentType"/> of an <see cref="ITextDataModel"/>.
+ /// </summary>
+ public class TextDataModelContentTypeChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// The <see cref="IContentType"/> of the <see cref="ITextDataModel"/> before the change.
+ /// </summary>
+ public IContentType BeforeContentType { get; private set; }
+
+ /// <summary>
+ /// The <see cref="IContentType"/> of the <see cref="ITextDataModel"/> after the change.
+ /// </summary>
+ public IContentType AfterContentType { get; private set; }
+
+ /// <summary>
+ /// Constructs a <see cref="TextDataModelContentTypeChangedEventArgs"/>.
+ /// </summary>
+ /// <param name="beforeContentType">The <see cref="IContentType"/> before the change.</param>
+ /// <param name="afterContentType">The <see cref="IContentType"/> after the change.</param>
+ public TextDataModelContentTypeChangedEventArgs(IContentType beforeContentType, IContentType afterContentType)
+ {
+ BeforeContentType = beforeContentType;
+ AfterContentType = afterContentType;
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/TextModel/VirtualSnapshotPoint.cs b/src/Text/Def/TextLogic/TextModel/VirtualSnapshotPoint.cs
new file mode 100644
index 0000000..124c1aa
--- /dev/null
+++ b/src/Text/Def/TextLogic/TextModel/VirtualSnapshotPoint.cs
@@ -0,0 +1,322 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// Represents a <see cref="SnapshotPoint"/> that may have virtual spaces.
+ /// </summary>
+ public struct VirtualSnapshotPoint : IComparable<VirtualSnapshotPoint>
+ {
+ private readonly SnapshotPoint _position;
+ private readonly int _virtualSpaces;
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="VirtualSnapshotPoint"/> at <paramref name="position"/>, with zero virtual spaces.
+ /// </summary>
+ /// <param name="position">The position the point in the snapshot.</param>
+ public VirtualSnapshotPoint(SnapshotPoint position)
+ {
+ _position = position;
+ _virtualSpaces = 0;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="VirtualSnapshotPoint"/> at <paramref name="position"/> in a <paramref name="snapshot"/>, with zero virtual spaces.
+ /// </summary>
+ /// <param name="snapshot">The snapshot to use.</param>
+ /// <param name="position">The position of the snapshot point.</param>
+ public VirtualSnapshotPoint(ITextSnapshot snapshot, int position)
+ {
+ _position = new SnapshotPoint(snapshot, position);
+ _virtualSpaces = 0;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="VirtualSnapshotPoint"/> at <paramref name="position"/>, with the specified number of virtual spaces.
+ /// </summary>
+ /// <param name="position">The position of the virtual snapshot point.</param>
+ /// <param name="virtualSpaces">The number of virtual spaces after <paramref name="position"/>.</param>
+ /// <remarks><paramref name="virtualSpaces"/> must be zero unless
+ /// <paramref name="position"/> corresponds to a location at the end
+ /// of a <see cref="ITextSnapshotLine"/>.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="virtualSpaces"/> is negative.</exception>
+ /// <remarks>If <paramref name="position"/> specifies a location that is not at the end of a line, then <paramref name="virtualSpaces"/> is set to 0.</remarks>
+ public VirtualSnapshotPoint(SnapshotPoint position, int virtualSpaces)
+ {
+ if (virtualSpaces < 0)
+ throw new ArgumentOutOfRangeException("virtualSpaces");
+
+ //Treat trying to set virtual spaces in the middle of a line as a soft error. It is easy to do if some 3rd party does an unexpected edit on a text change
+ //and setting virtualSpaces to 0 is a reasonable fallback behavior.
+ if ((virtualSpaces != 0) && (position.GetContainingLine().End != position))
+ virtualSpaces = 0;
+
+ _position = position;
+ _virtualSpaces = virtualSpaces;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="VirtualSnapshotPoint"/>
+ /// at <paramref name="offset"/> of <paramref name="line"/>, placing the point in virtual space if necessary.
+ /// </summary>
+ /// <param name="line">The line on which to place the point.</param>
+ /// <param name="offset">The offset (zero-based) of the point.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="line"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> is negative.</exception>
+ /// <remarks>
+ /// <paramref name="offset"/> is a character offset from the start of the line. It does not correspond to a column position (for example, if the line consists of a single tab and the offset is 2, then
+ /// the resulting VirtualSnapshotPoint will be one "space" past the end of the line).</remarks>
+ public VirtualSnapshotPoint(ITextSnapshotLine line, int offset)
+ {
+ if (line == null)
+ throw new ArgumentNullException("line");
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException("offset");
+
+ if (offset <= line.Length)
+ {
+ _position = line.Start + offset;
+ _virtualSpaces = 0;
+ }
+ else
+ {
+ _position = line.End;
+ _virtualSpaces = (offset - line.Length);
+ }
+ }
+
+ /// <summary>
+ /// Gets the position of the snapshot point.
+ /// </summary>
+ public SnapshotPoint Position
+ {
+ get { return _position; }
+ }
+
+ /// <summary>
+ /// Gets the number of virtual spaces.
+ /// </summary>
+ public int VirtualSpaces
+ {
+ get { return _virtualSpaces; }
+ }
+
+ /// <summary>
+ /// Determines whether the snapshot point has virtual spaces.
+ /// </summary>
+ public bool IsInVirtualSpace
+ {
+ get { return _virtualSpaces > 0; }
+ }
+
+ /// <summary>
+ /// Gets the hash code for the object.
+ /// </summary>
+ /// <returns></returns>
+ public override int GetHashCode()
+ {
+ return _position.GetHashCode() ^ _virtualSpaces.GetHashCode();
+ }
+
+ /// <summary>
+ /// Translates this point to the <paramref name="snapshot"/>.
+ /// </summary>
+ /// <param name="snapshot">The target snapshot.</param>
+ /// <returns>The corresponding <see cref="VirtualSnapshotPoint"/> in <paramref name="snapshot"/>.</returns>
+ /// <exception cref="ArgumentException"><paramref name="snapshot"/> is for an earlier snapshot.</exception>
+ public VirtualSnapshotPoint TranslateTo(ITextSnapshot snapshot)
+ {
+ return TranslateTo(snapshot, PointTrackingMode.Positive);
+ }
+
+ /// <summary>
+ /// Translates this point to the <paramref name="snapshot"/> with the given tracking mode.
+ /// </summary>
+ /// <param name="snapshot">The target snapshot.</param>
+ /// <param name="trackingMode">The tracking mode to use.</param>
+ /// <returns>The corresponding <see cref="VirtualSnapshotPoint"/> in <paramref name="snapshot"/>.</returns>
+ /// <exception cref="ArgumentException"><paramref name="snapshot"/> is for an earlier snapshot.</exception>
+ /// <remarks>
+ /// <para>
+ /// The tracking mode is relative to the virtual point, not the snapshot point. If
+ /// the point is in virtual space, it will behave as if the underlying (non-virtual)
+ /// point is always tracking positive, as any text inserted at the point (at the
+ /// end of the line it is on) will still be inserted "before" the virtual point.
+ /// </para>
+ /// </remarks>
+ public VirtualSnapshotPoint TranslateTo(ITextSnapshot snapshot, PointTrackingMode trackingMode)
+ {
+ if (snapshot == null)
+ {
+ throw new ArgumentNullException("snapshot");
+ }
+
+ if (snapshot.Version.VersionNumber < _position.Snapshot.Version.VersionNumber)
+ {
+ throw new ArgumentException("VirtualSnapshotPoints can only be translated to later snapshots", "snapshot");
+ }
+ else if (snapshot == _position.Snapshot)
+ {
+ return this;
+ }
+ else
+ {
+ if (this.IsInVirtualSpace)
+ {
+ SnapshotPoint newPosition = _position.TranslateTo(snapshot, PointTrackingMode.Positive);
+
+ //The new virtual snapshot point is only placed in virtual space if the old one was,
+ //it is still at the physical end of a line, and the character after _position wasn't deleted.
+ int newVirtualSpaces = (_virtualSpaces != 0) &&
+ (newPosition.GetContainingLine().End == newPosition) &&
+ !CharacterDeleted(_position, snapshot)
+ ? _virtualSpaces : 0;
+
+ return new VirtualSnapshotPoint(newPosition, newVirtualSpaces);
+ }
+ else
+ {
+ return new VirtualSnapshotPoint(_position.TranslateTo(snapshot, trackingMode));
+ }
+ }
+ }
+
+ /// <summary>
+ /// Converts the object to a string.
+ /// </summary>
+ /// <returns>The string form of this object.</returns>
+ public override string ToString()
+ {
+ return string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0}+{1}", _position, _virtualSpaces);
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="VirtualSnapshotPoint"/> objects are the same.
+ /// </summary>
+ /// <param name="obj">The object to compare.</param>
+ /// <returns><c>true</c> if the objects are the same, otherwise <c>false</c>.</returns>
+ public override bool Equals(object obj)
+ {
+ if (obj is VirtualSnapshotPoint)
+ {
+ VirtualSnapshotPoint other = (VirtualSnapshotPoint)obj;
+ return other == this;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="VirtualSnapshotPoint"/> objects are the same.
+ /// </summary>
+ /// <param name="left">The first object.</param>
+ /// <param name="right">The second object.</param>
+ /// <returns><c>true</c> if the two objects are the same, otherwise <c>false</c>.</returns>
+ public static bool operator ==(VirtualSnapshotPoint left, VirtualSnapshotPoint right)
+ {
+ return left._position == right._position && left._virtualSpaces == right._virtualSpaces;
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="VirtualSnapshotPoint"/> objects are different.
+ /// </summary>
+ /// <param name="left">The first object.</param>
+ /// <param name="right">The second object.</param>
+ /// <returns><c>true</c> if the two objects are different, otherwise <c>false</c>.</returns>
+ public static bool operator !=(VirtualSnapshotPoint left, VirtualSnapshotPoint right)
+ {
+ return !(left == right);
+ }
+
+ /// <summary>
+ /// Determines whether the position of the left point is greater than the position of the right point.
+ /// </summary>
+ /// <returns><c>true</c> if left.Position is greater than right.Position, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentException">The snapshots of the two points do not match.</exception>
+ public static bool operator >(VirtualSnapshotPoint left, VirtualSnapshotPoint right)
+ {
+ return left.CompareTo(right) > 0;
+ }
+
+ /// <summary>
+ /// Determines whether the position of the left point is greater than or equal to the position of the right point.
+ /// </summary>
+ /// <returns><c>true</c> if left.Position is greater than or equal to right.Position, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentException">The snapshots of the two points do not match.</exception>
+ public static bool operator >=(VirtualSnapshotPoint left, VirtualSnapshotPoint right)
+ {
+ return left.CompareTo(right) >= 0;
+ }
+
+ /// <summary>
+ /// Determines whether the position of the left point is less than the position of the right point.
+ /// </summary>
+ /// <returns><c>true</c> if left.Position is less than right.Position, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentException">If the snapshots of the points do not match.</exception>
+ public static bool operator <(VirtualSnapshotPoint left, VirtualSnapshotPoint right)
+ {
+ return left.CompareTo(right) < 0;
+ }
+
+ /// <summary>
+ /// Determines whether the position of the left point is less than or equal to the position of the right point.
+ /// </summary>
+ /// <returns><c>true</c> if left.Position is less than or equal to right.Position, otherwise <c>false</c>.</returns>
+ /// <exception cref="ArgumentException">If the snapshots of the points do not match.</exception>
+ public static bool operator <=(VirtualSnapshotPoint left, VirtualSnapshotPoint right)
+ {
+ return left.CompareTo(right) <= 0;
+ }
+
+ #region IComparable<VirtualSnapshotPoint>
+ /// <summary>
+ /// Compares one <see cref="VirtualSnapshotPoint"/> to another.
+ /// </summary>
+ /// <param name="other">The second <see cref="VirtualSnapshotPoint"/>.</param>
+ /// <returns>Compares the position and number of virtual spaces of the two points.</returns>
+ public int CompareTo(VirtualSnapshotPoint other)
+ {
+ int cmp = _position.CompareTo(other._position);
+ return (cmp == 0) ? (_virtualSpaces - other._virtualSpaces) : cmp;
+ }
+ #endregion
+
+ //Check to see if, when translating position to snapshot, the character after position was deleted.
+ private static bool CharacterDeleted(SnapshotPoint position, ITextSnapshot snapshot)
+ {
+ int currentPosition = position.Position;
+
+ ITextVersion version = position.Snapshot.Version;
+ while (version.VersionNumber != snapshot.Version.VersionNumber)
+ {
+ foreach (ITextChange change in version.Changes)
+ {
+ if (change.NewPosition > currentPosition)
+ break;
+ else
+ {
+ if (change.NewPosition + change.OldLength > currentPosition)
+ {
+ //Line break (or the first character of it) was deleted.
+ return true;
+ }
+ else
+ {
+ //Change occurs entirely before currentPosition so adjust.
+ currentPosition += change.Delta;
+ }
+ }
+ }
+
+ version = version.Next;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/TextModel/VirtualSnapshotSpan.cs b/src/Text/Def/TextLogic/TextModel/VirtualSnapshotSpan.cs
new file mode 100644
index 0000000..20ab6d0
--- /dev/null
+++ b/src/Text/Def/TextLogic/TextModel/VirtualSnapshotSpan.cs
@@ -0,0 +1,393 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text
+{
+ using System;
+
+ /// <summary>
+ /// Represents two <see cref="VirtualSnapshotPoint" />s
+ /// </summary>
+ public struct VirtualSnapshotSpan
+ {
+ private readonly VirtualSnapshotPoint _start;
+ private readonly VirtualSnapshotPoint _end;
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="VirtualSnapshotSpan"/> at <paramref name="snapshotSpan"/>, with no virtual spaces.
+ /// </summary>
+ /// <param name="snapshotSpan">A snapshot span.</param>
+ public VirtualSnapshotSpan(SnapshotSpan snapshotSpan)
+ {
+ _start = new VirtualSnapshotPoint(snapshotSpan.Start);
+ _end = new VirtualSnapshotPoint(snapshotSpan.End);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="VirtualSnapshotSpan"/> from the given
+ /// <see cref="VirtualSnapshotPoint" />s.
+ /// </summary>
+ /// <param name="start">The start point.</param>
+ /// <param name="end">The end point, which must be from the same <see cref="ITextSnapshot"/>
+ /// as the start point.</param>
+ /// <exception cref="ArgumentException">The snapshot points belong to different
+ /// <see cref="ITextSnapshot"/> objects.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">The end point comes before the start
+ /// point.</exception>
+ public VirtualSnapshotSpan(VirtualSnapshotPoint start, VirtualSnapshotPoint end)
+ {
+ if (start.Position.Snapshot == null || end.Position.Snapshot == null)
+ {
+ throw new ArgumentException("The VirtualSnapshotPoint is not initialized.");
+ }
+ if (start.Position.Snapshot != end.Position.Snapshot)
+ {
+ throw new ArgumentException("The specified VirtualSnapshotPoints belong to different ITextSnapshots.");
+ }
+ if (end < start)
+ {
+ throw new ArgumentOutOfRangeException("end");
+ }
+
+ _start = start;
+ _end = end;
+ }
+
+ /// <summary>
+ /// Gets the starting virtual point.
+ /// </summary>
+ public VirtualSnapshotPoint Start
+ {
+ get { return _start; }
+ }
+
+ /// <summary>
+ /// Gets the ending virtual point.
+ /// </summary>
+ public VirtualSnapshotPoint End
+ {
+ get { return _end; }
+ }
+
+ /// <summary>
+ /// The <see cref="ITextSnapshot"/> to which this snapshot span refers.
+ /// </summary>
+ public ITextSnapshot Snapshot
+ {
+ get { return _start.Position.Snapshot; }
+ }
+
+ /// <summary>
+ /// The length of this span, taking into account virtual space.
+ /// </summary>
+ /// <remarks>
+ /// If neither endpoint is in virtual space or only the start point is
+ /// in virtual space, this will be equivalent to SnapshotSpan.Length.
+ /// Otherwise, it will include virtual space.
+ /// </remarks>
+ public int Length
+ {
+ get
+ {
+ // If _start and _end are at the same virtual start point, then
+ // the length of this span is the distance between them in virtual spaces.
+ if (_start.Position == _end.Position)
+ {
+ return _end.VirtualSpaces - _start.VirtualSpaces;
+ }
+ else
+ {
+ return this.SnapshotSpan.Length + _end.VirtualSpaces;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The text contained by this virtual snapshot span.
+ /// </summary>
+ /// <returns>A non-null string.</returns>
+ public string GetText()
+ {
+ return this.SnapshotSpan.GetText();
+ }
+
+ /// <summary>
+ /// Gets the non-virtual SnapshotSpan that this corresponds to.
+ /// </summary>
+ public SnapshotSpan SnapshotSpan
+ {
+ get { return new SnapshotSpan(_start.Position, _end.Position); }
+ }
+
+ /// <summary>
+ /// Determines whether the start or end points are in virtual space.
+ /// </summary>
+ public bool IsInVirtualSpace
+ {
+ get { return _start.IsInVirtualSpace || _end.IsInVirtualSpace; }
+ }
+
+ /// <summary>
+ /// Determines whether the start and end points are in the same place.
+ /// </summary>
+ /// <remarks>
+ /// Because the start and end can both be in virtual space, the non-virtual
+ /// span that this corresponds to can be non-empty at the same time that this
+ /// property returns <c>true</c>.
+ /// </remarks>
+ public bool IsEmpty
+ {
+ get { return _start == _end; }
+ }
+
+ /// <summary>
+ /// Determines whether or not the given virtual point is contained
+ /// within this virtual span.
+ /// </summary>
+ /// <param name="virtualPoint">
+ /// The virtual point to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the position is greater than or equal to Start and strictly less
+ /// than End, otherwise <c>false</c>.
+ /// </returns>
+ public bool Contains(VirtualSnapshotPoint virtualPoint)
+ {
+ return (virtualPoint >= _start && virtualPoint < _end);
+ }
+
+ /// <summary>
+ /// Determines whether <paramref name="virtualSpan"/> falls completely within
+ /// this virtual span.
+ /// </summary>
+ /// <param name="virtualSpan">
+ /// The virtual span to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the specified span falls completely within this span,
+ /// otherwise <c>false</c>.
+ /// </returns>
+ public bool Contains(VirtualSnapshotSpan virtualSpan)
+ {
+ return (virtualSpan._start >= _start && virtualSpan._end <= _end);
+ }
+
+ /// <summary>
+ /// Determines whether <paramref name="virtualSpan"/> overlaps this span. Two spans are considered to overlap
+ /// if they have positions in common and neither is empty. Empty spans do not overlap with any
+ /// other span.
+ /// </summary>
+ /// <param name="virtualSpan">
+ /// The virtual span to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the spans overlap, otherwise <c>false</c>.
+ /// </returns>
+ public bool OverlapsWith(VirtualSnapshotSpan virtualSpan)
+ {
+ VirtualSnapshotPoint overlapStart = (_start > virtualSpan._start) ? _start : virtualSpan._start;
+ VirtualSnapshotPoint overlapEnd = (_end < virtualSpan._end) ? _end : virtualSpan._end;
+
+ return overlapStart < overlapEnd;
+ }
+
+ /// <summary>
+ /// Returns the overlap with the given virtual span, or null if there is no overlap.
+ /// </summary>
+ /// <param name="virtualSpan">
+ /// The virtual span to check.
+ /// </param>
+ /// <returns>
+ /// The overlap of the spans, or null if the overlap is empty.
+ /// </returns>
+ public VirtualSnapshotSpan? Overlap(VirtualSnapshotSpan virtualSpan)
+ {
+ VirtualSnapshotPoint overlapStart = (_start > virtualSpan._start) ? _start : virtualSpan._start;
+ VirtualSnapshotPoint overlapEnd = (_end < virtualSpan._end) ? _end : virtualSpan._end;
+
+ if (overlapStart < overlapEnd)
+ {
+ return new VirtualSnapshotSpan(overlapStart, overlapEnd);
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Determines whether <paramref name="virtualSpan"/> intersects this span. Two spans are considered to
+ /// intersect if they have positions in common or the end of one span
+ /// coincides with the start of the other span.
+ /// </summary>
+ /// <param name="virtualSpan">
+ /// The virtual span to check.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the spans intersect, otherwise <c>false</c>.
+ /// </returns>
+ public bool IntersectsWith(VirtualSnapshotSpan virtualSpan)
+ {
+ return (virtualSpan._start <= _end && virtualSpan._end >= _start);
+ }
+
+ /// <summary>
+ /// Returns the intersection with the given virtual span, or null if there is no intersection.
+ /// </summary>
+ /// <param name="virtualSpan">
+ /// The virtual span to check.
+ /// </param>
+ /// <returns>
+ /// The intersection of the spans, or null if the intersection is empty.
+ /// </returns>
+ public VirtualSnapshotSpan? Intersection(VirtualSnapshotSpan virtualSpan)
+ {
+ VirtualSnapshotPoint intersectStart = (_start > virtualSpan._start) ? _start : virtualSpan._start;
+ VirtualSnapshotPoint intersectEnd = (_end < virtualSpan._end) ? _end : virtualSpan._end;
+
+ if (intersectStart <= intersectEnd)
+ {
+ return new VirtualSnapshotSpan(intersectStart, intersectEnd);
+ }
+
+ return null;
+ }
+
+
+ /// <summary>
+ /// Gets the hash code for the object.
+ /// </summary>
+ /// <returns></returns>
+ public override int GetHashCode()
+ {
+ return _start.GetHashCode() ^ _end.GetHashCode();
+ }
+
+ /// <summary>
+ /// Translates this span to the <paramref name="snapshot"/>.
+ /// </summary>
+ /// <param name="snapshot">The target snapshot.</param>
+ /// <returns>The corresponding <see cref="VirtualSnapshotSpan"/> in <paramref name="snapshot"/>.</returns>
+ /// <exception cref="ArgumentException"><paramref name="snapshot"/> is for an earlier snapshot.</exception>
+ public VirtualSnapshotSpan TranslateTo(ITextSnapshot snapshot)
+ {
+ return TranslateTo(snapshot, SpanTrackingMode.EdgePositive);
+ }
+
+ /// <summary>
+ /// Translates this span to the <paramref name="snapshot"/> with the given tracking mode.
+ /// </summary>
+ /// <param name="snapshot">The target snapshot.</param>
+ /// <param name="trackingMode">The span tracking mode.</param>
+ /// <returns>The corresponding <see cref="VirtualSnapshotSpan"/> in <paramref name="snapshot"/>.</returns>
+ /// <exception cref="ArgumentException"><paramref name="snapshot"/> is for an earlier snapshot.</exception>
+ /// <remarks>
+ /// <para>
+ /// See <see cref="VirtualSnapshotPoint.TranslateTo(ITextSnapshot, PointTrackingMode)" /> for a description of
+ /// how <see cref="VirtualSnapshotPoint" /> translation behaves.
+ /// </para>
+ /// </remarks>
+ public VirtualSnapshotSpan TranslateTo(ITextSnapshot snapshot, SpanTrackingMode trackingMode)
+ {
+ if (snapshot == null)
+ {
+ throw new ArgumentNullException("snapshot");
+ }
+
+ if (snapshot.Version.VersionNumber < _start.Position.Snapshot.Version.VersionNumber)
+ {
+ throw new ArgumentException("VirtualSnapshotSpans can only be translated to later snapshots", "snapshot");
+ }
+ else if (snapshot == _start.Position.Snapshot)
+ {
+ return this;
+ }
+ else
+ {
+ // Translate endpoints with the appropriate PointTrackingMode
+ var newStart = _start.TranslateTo(snapshot, GetStartPointMode(trackingMode));
+ var newEnd = _end.TranslateTo(snapshot, GetEndPointMode(trackingMode));
+
+ // If the end point has tracked to before the start point, just create
+ // an empty span at the start point.
+ if (newStart <= newEnd)
+ return new VirtualSnapshotSpan(newStart, newEnd);
+ else
+ return new VirtualSnapshotSpan(newStart, newStart);
+ }
+ }
+
+ /// <summary>
+ /// Get the equivalent PointTrackingMode for our start point for
+ /// the given SpanTrackingMode.
+ /// </summary>
+ static PointTrackingMode GetStartPointMode(SpanTrackingMode trackingMode)
+ {
+ if (trackingMode == SpanTrackingMode.EdgeInclusive ||
+ trackingMode == SpanTrackingMode.EdgeNegative)
+ return PointTrackingMode.Negative;
+ else
+ return PointTrackingMode.Positive;
+ }
+
+ /// <summary>
+ /// Get the equivalent PointTrackingMode for our end point for
+ /// the given SpanTrackingMode.
+ /// </summary>
+ static PointTrackingMode GetEndPointMode(SpanTrackingMode trackingMode)
+ {
+ if (trackingMode == SpanTrackingMode.EdgeInclusive ||
+ trackingMode == SpanTrackingMode.EdgePositive)
+ return PointTrackingMode.Positive;
+ else
+ return PointTrackingMode.Negative;
+ }
+
+ /// <summary>
+ /// Converts the object to a string.
+ /// </summary>
+ /// <returns>The string form of this object.</returns>
+ public override string ToString()
+ {
+ return string.Format(System.Globalization.CultureInfo.CurrentCulture, "({0},{1})", _start, _end);
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="VirtualSnapshotSpan"/> objects are the same.
+ /// </summary>
+ /// <param name="obj">The object to compare.</param>
+ /// <returns><c>true</c> if the objects are the same, otherwise <c>false</c>.</returns>
+ public override bool Equals(object obj)
+ {
+ if (obj is VirtualSnapshotSpan)
+ {
+ VirtualSnapshotSpan other = (VirtualSnapshotSpan)obj;
+ return other == this;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="VirtualSnapshotSpan"/> objects are the same.
+ /// </summary>
+ /// <param name="left">The first object.</param>
+ /// <param name="right">The second object.</param>
+ /// <returns><c>true</c> if the two objects are the same, otherwise <c>false</c>.</returns>
+ public static bool operator ==(VirtualSnapshotSpan left, VirtualSnapshotSpan right)
+ {
+ return left._start == right._start && left._end == right._end;
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="VirtualSnapshotSpan"/> objects are different.
+ /// </summary>
+ /// <param name="left">The first object.</param>
+ /// <param name="right">The second object.</param>
+ /// <returns><c>true</c> if the two objects are different, otherwise <c>false</c>.</returns>
+ public static bool operator !=(VirtualSnapshotSpan left, VirtualSnapshotSpan right)
+ {
+ return !(left == right);
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Undo/IMergeTextUndoTransactionPolicy.cs b/src/Text/Def/TextLogic/Undo/IMergeTextUndoTransactionPolicy.cs
new file mode 100644
index 0000000..9a214f3
--- /dev/null
+++ b/src/Text/Def/TextLogic/Undo/IMergeTextUndoTransactionPolicy.cs
@@ -0,0 +1,52 @@
+// ****************************************************************************
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// ****************************************************************************
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Provides the merge policy for undo transactions.
+ /// </summary>
+ /// <remarks>
+ /// These policies are
+ /// used when transactions are completed and pushed onto the undo stack. Only adjacent
+ /// <see cref="ITextUndoTransaction"/> objects can be merged.
+ /// </remarks>
+ public interface IMergeTextUndoTransactionPolicy
+ {
+ /// <summary>
+ /// Determines whether one <see cref="IMergeTextUndoTransactionPolicy"/> is compatible with another.
+ /// </summary>
+ /// <param name="other">The <see cref="IMergeTextUndoTransactionPolicy"/> to test.</param>
+ /// <returns><c>true</c> if the merge should proceed, otherwise <c>false</c>.</returns>
+ /// <remarks>
+ /// Merging happens only when merge policies in primitives are compatible. This function should be symmetric
+ /// and ideally constant time. For instance, (this.GetType() == other.GetType()).
+ /// </remarks>
+ bool TestCompatiblePolicy(IMergeTextUndoTransactionPolicy other);
+
+ /// <summary>
+ /// Determines whether two <see cref="ITextUndoTransaction"/> objects can be merged.
+ /// </summary>
+ /// <param name="newerTransaction">The newer transaction.</param>
+ /// <param name="olderTransaction">The older transaction.</param>
+ /// <returns><c>true</c> of the merge should proceed, otherwise <c>false</c>.</returns>
+ /// <summary>
+ /// If this method returns <c>true</c>, then the merge can proceed, given specific knowledge of the transactions in question. CanMerge
+ /// is called only when TestCompatiblePolicy succeeds.
+ /// </summary>
+ bool CanMerge(ITextUndoTransaction newerTransaction, ITextUndoTransaction olderTransaction);
+
+ /// <summary>
+ /// Merges a new <see cref="ITextUndoTransaction"/> with an existing one.
+ /// </summary>
+ /// <param name="existingTransaction">The existing transaction.</param>
+ /// <param name="newTransaction">The new transaction.</param>
+ /// <remarks>
+ /// Merges newTransaction into existingTransaction by adding, removing, or modifying the
+ /// primitives in existingTransaction.UndoPrimitives. A simple implementation could be to add
+ /// each primitive in newTransaction.UndoPrimitives to existingTransaction.UndoPrimitives.
+ /// </remarks>
+ void PerformTransactionMerge(ITextUndoTransaction existingTransaction, ITextUndoTransaction newTransaction);
+ }
+}
diff --git a/src/Text/Def/TextLogic/Undo/ITextBufferUndoManager.cs b/src/Text/Def/TextLogic/Undo/ITextBufferUndoManager.cs
new file mode 100644
index 0000000..c37fee8
--- /dev/null
+++ b/src/Text/Def/TextLogic/Undo/ITextBufferUndoManager.cs
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Registers the <see cref="ITextUndoHistory"/> for a <see cref="TextBuffer"/>,
+ /// listens for change events on a <see cref="TextBuffer"/>,
+ /// and adds <see cref="ITextUndoPrimitive"/> objects to the <see cref="ITextUndoHistory"/>.
+ /// </summary>
+ public interface ITextBufferUndoManager
+ {
+ /// <summary>
+ /// Gets the <see cref="ITextBuffer"/> for which this <see cref="ITextBufferUndoManager"/> manages undo operations.
+ /// </summary>
+ ITextBuffer TextBuffer { get; }
+
+ /// <summary>
+ /// Gets the <see cref="ITextUndoHistory"/> for the underlying <see cref="ITextBuffer"/>.
+ /// </summary>
+ ITextUndoHistory TextBufferUndoHistory { get; }
+
+ /// <summary>
+ /// Unregisters the <see cref="ITextUndoHistory"/> for the underlying <see cref="ITextBuffer"/> from the <see cref="ITextUndoHistoryRegistry"/>.
+ /// </summary>
+ void UnregisterUndoHistory();
+ }
+}
diff --git a/src/Text/Def/TextLogic/Undo/ITextBufferUndoManagerProvider.cs b/src/Text/Def/TextLogic/Undo/ITextBufferUndoManagerProvider.cs
new file mode 100644
index 0000000..b12f73b
--- /dev/null
+++ b/src/Text/Def/TextLogic/Undo/ITextBufferUndoManagerProvider.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ using System;
+
+ /// <summary>
+ /// Provides an <see cref="ITextBufferUndoManager"/> for a given <see cref="ITextBuffer"/>. This is a cached factory, and only
+ /// one <see cref="ITextBufferUndoManager"/> will ever be created for a given <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be exported with the following attribute:
+ /// [Export(NameSource=typeof(ITextBufferUndoManagerProvider))]
+ /// </remarks>
+ public interface ITextBufferUndoManagerProvider
+ {
+ /// <summary>
+ /// Gets the <see cref="ITextBufferUndoManager"/> for the specified <see cref="ITextBuffer"/>. If no undo manager
+ /// has been created for this text buffer, a new one is created.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> for which to get the <see cref="ITextBufferUndoManager"/>.</param>
+ /// <returns>The <see cref="ITextBufferUndoManager"/> for <paramref name="textBuffer"/>.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="textBuffer" /> is null.</exception>
+ ITextBufferUndoManager GetTextBufferUndoManager(ITextBuffer textBuffer);
+
+ /// <summary>
+ /// Removes the <see cref="ITextBufferUndoManager"/>, if any, from <paramref name="textBuffer" />.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> to check.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="textBuffer" /> is null.</exception>
+ void RemoveTextBufferUndoManager(ITextBuffer textBuffer);
+ }
+}
diff --git a/src/Text/Def/TextLogic/Undo/ITextUndoHistory.cs b/src/Text/Def/TextLogic/Undo/ITextUndoHistory.cs
new file mode 100644
index 0000000..b98d782
--- /dev/null
+++ b/src/Text/Def/TextLogic/Undo/ITextUndoHistory.cs
@@ -0,0 +1,150 @@
+// ****************************************************************************
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// ****************************************************************************
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Contains undo transactions.
+ /// </summary>
+ /// <remarks>
+ /// Typically only one undo transaction history at a time is availbble to the user.
+ /// </remarks>
+ public interface ITextUndoHistory : IPropertyOwner
+ {
+ /// <summary>
+ /// The undo stack for this history. It does not include any currently open or redo transactions.
+ /// </summary>
+ /// <remarks>
+ /// This stack includes the most recent transaction (the top item of the stack) to the oldest transaction (the bottom
+ /// item of the stack).
+ /// </remarks>
+ IEnumerable<ITextUndoTransaction> UndoStack { get; }
+
+ /// <summary>
+ /// The redo stack for this history. It does not include any currently open or undo transactions.
+ /// </summary>
+ /// <remarks>
+ /// This stack includes the most recent transaction (the top item of the stack) to the oldest transaction (the bottom
+ /// item of the stack).
+ /// </remarks>
+ IEnumerable<ITextUndoTransaction> RedoStack { get; }
+
+ /// <summary>
+ /// Gets the most recent (top) item of the <see cref="ITextUndoHistory.UndoStack"/>, or <c>null</c> if the stack is
+ /// empty.
+ /// </summary>
+ ITextUndoTransaction LastUndoTransaction { get; }
+
+ /// <summary>
+ /// Gets the most recent (top) item of the <see cref="ITextUndoHistory.RedoStack"/>, or <c>null</c> if the stack is
+ /// empty.
+ /// </summary>
+ ITextUndoTransaction LastRedoTransaction { get; }
+
+ /// <summary>
+ /// Determines whether a single undo is possible.
+ /// </summary>
+ /// <remarks>
+ /// This property corresponds to CanUndo for the most recent visible undo <see cref="ITextUndoTransaction"/>.
+ /// If there are hidden transactions on top of the visible transaction,
+ /// this property returns true only if they are
+ /// undoable as well.
+ /// </remarks>
+ bool CanUndo { get; }
+
+ /// <summary>
+ /// Determines whether a single redo is possible.
+ /// </summary>
+ /// <remarks>
+ /// This property corresponds to CanRedo for the most recent visible redo <see cref="ITextUndoTransaction"/>.
+ /// If there are hidden transactions on top of the visible transaction, this property returns <c>true</c> only if they are
+ /// redoable as well.
+ /// </remarks>
+ bool CanRedo { get; }
+
+ /// <summary>
+ /// Gets the description of the most recent visible undo <see cref="ITextUndoTransaction"/>.
+ /// </summary>
+ string UndoDescription { get; }
+
+ /// <summary>
+ /// Gets the description of the most recent visible redo <see cref="ITextUndoTransaction"/>.
+ /// </summary>
+ string RedoDescription { get; }
+
+ /// <summary>
+ /// Gets the current UndoTransaction in progress.
+ /// </summary>
+ ITextUndoTransaction CurrentTransaction { get; }
+
+ /// <summary>
+ /// Gets the current state of the UndoHistory.
+ /// </summary>
+ TextUndoHistoryState State { get; }
+
+ /// <summary>
+ /// Creates a new transaction, nests it in the previously current transaction, and marks it current.
+ /// </summary>
+ /// <param name="description">The description of the transaction.</param>
+ /// <returns>The new transaction.</returns>
+ ITextUndoTransaction CreateTransaction(string description);
+
+ /// <summary>
+ /// Performs the specified number of undo operations and places the transactions on the redo stack.
+ /// </summary>
+ /// <param name="count">
+ /// The number of undo operations to perform.
+ /// </param>
+ /// <remarks>
+ /// At the end of the operation, the specified number of visible
+ /// transactions are undone. Therefore, the actual number of transactions undone might be more than this number if there are
+ /// hidden transactions above or below the visible ones.
+ /// After the last visible transaction is undone, the hidden transactions left on top the stack are undone as well, until a
+ /// visible or linked transaction is encountered, or the stack is completely emptied.
+ /// </remarks>
+ void Undo(int count);
+
+ /// <summary>
+ /// Performs the specified number of redo operation and places the transactions on the undo stack.
+ /// </summary>
+ /// <param name="count">The number of redo operations to perform. At the end of the operation, the specified number of visible
+ /// transactions are redone. Therefore, the actual number of transactions redone might be more than this number, if there are
+ /// hidden transactions above or below the visible ones.
+ /// </param>
+ /// <remarks>
+ /// After the last visible transaction is redone, the hidden transactions left on top the stack are redone as well, until a
+ /// visible or linked transaction is encountered, or the stack is completely emptied.
+ /// </remarks>
+ void Redo(int count);
+
+ /// <summary>
+ /// Notifies consumers when an undo
+ /// or a redo has happened on this history.
+ /// </summary>
+ /// <remarks>
+ /// The sender object is the <see cref="ITextUndoHistory"/> that originated
+ /// it, and the event arguments are empty. The UndoHistory raises this event whenever an Undo() or
+ /// Redo() is initiated properly, regardless of whether one of the particular transactions or
+ /// primitives fails to perform that undo.
+ /// </remarks>
+ event EventHandler<TextUndoRedoEventArgs> UndoRedoHappened;
+
+ /// <summary>
+ /// Notifies consumers when an
+ /// <see cref="ITextUndoTransaction"/> is completed and added to the <see cref="ITextUndoHistory.UndoStack"/>.
+ /// </summary>
+ /// <remarks>
+ /// The sender object is the <see cref="ITextUndoHistory"/> that originated it, and the event argumentss are an
+ /// instance of <see cref="TextUndoTransactionCompletedEventArgs"/> class. This event is fired for the
+ /// topmost <see cref="ITextUndoTransaction"/> objects only. Completion of nested transactions does not generate
+ /// this event.
+ /// </remarks>
+ event EventHandler<TextUndoTransactionCompletedEventArgs> UndoTransactionCompleted;
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/Undo/ITextUndoHistoryRegistry.cs b/src/Text/Def/TextLogic/Undo/ITextUndoHistoryRegistry.cs
new file mode 100644
index 0000000..0816786
--- /dev/null
+++ b/src/Text/Def/TextLogic/Undo/ITextUndoHistoryRegistry.cs
@@ -0,0 +1,51 @@
+// ****************************************************************************
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// ****************************************************************************
+
+using System.Collections.Generic;
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Maps context objects to <see cref="ITextUndoHistory"/> objects and is meant to be exposed by a component part.
+ /// </summary>
+ public interface ITextUndoHistoryRegistry
+ {
+ /// <summary>
+ /// Gets, and if necessary creates, a history associated with the context.
+ /// </summary>
+ /// <param name="context">An arbitrary context object.</param>
+ /// <returns>A (possibly new) <see cref="ITextUndoHistory"/> associated with the context object.</returns>
+ /// <remarks>Only a weak reference is held to the context.</remarks>
+ ITextUndoHistory RegisterHistory(object context);
+
+ /// <summary>
+ /// Gets a history associated with the context, but does not create a new one.
+ /// </summary>
+ /// <param name="context">An arbitrary context object.</param>
+ /// <returns>An <see cref="ITextUndoHistory"/> associated with the context object.</returns>
+ ITextUndoHistory GetHistory(object context);
+
+ /// <summary>
+ /// Gets a history associated with the context, but does not create a new one.
+ /// </summary>
+ /// <param name="context">An arbitrary context object.</param>
+ /// <param name="history">An <see cref="ITextUndoHistory"/> associated with the context object.</param>
+ /// <returns><c>true</c> if a relevant <see cref="ITextUndoHistory"/> exists in this registry, otherwise <c>false</c>.</returns>
+ bool TryGetHistory(object context, out ITextUndoHistory history);
+
+ /// <summary>
+ /// Attaches an existing <see cref="ITextUndoHistory"/> to a new context. The context must not already be mapped in this registry.
+ /// </summary>
+ /// <param name="context">An arbitrary context object.</param>
+ /// <param name="history">An <see cref="ITextUndoHistory"/> object to associate with the context.</param>
+ /// <remarks>Only a weak reference is held to the context.</remarks>
+ void AttachHistory(object context, ITextUndoHistory history);
+
+ /// <summary>
+ /// Removes all mappings to a given <see cref="ITextUndoHistory"/> in this registry, if any exist.
+ /// </summary>
+ /// <param name="history">The <see cref="ITextUndoHistory"/> to remove from the registry.</param>
+ void RemoveHistory(ITextUndoHistory history);
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/Undo/ITextUndoPrimitive.cs b/src/Text/Def/TextLogic/Undo/ITextUndoPrimitive.cs
new file mode 100644
index 0000000..a155fc6
--- /dev/null
+++ b/src/Text/Def/TextLogic/Undo/ITextUndoPrimitive.cs
@@ -0,0 +1,55 @@
+// ****************************************************************************
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// ****************************************************************************
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Represents an atomic operation that knows how to Do/Undo/Redo itself.
+ /// </summary>
+ public interface ITextUndoPrimitive
+ {
+ /// <summary>
+ /// Gets or sets the <see cref="ITextUndoTransaction"/> that contains the primitive.
+ /// </summary>
+ ITextUndoTransaction Parent { get; set; }
+
+ /// <summary>
+ /// Determines whether it is currently possible to call Do() successfully.
+ /// </summary>
+ bool CanRedo { get; }
+
+ /// <summary>
+ /// Determines whether it is currently possible to call Undo() successfully.
+ /// </summary>
+ bool CanUndo { get; }
+
+ /// <summary>
+ /// Performs or redoes the operation.
+ /// </summary>
+ void Do();
+
+ /// <summary>
+ /// Performs rollback or undo on the operation.
+ /// </summary>
+ void Undo();
+
+ /// <summary>
+ /// Determines whether this undo primitive can merge with the specified undo primitive.
+ /// </summary>
+ /// <param name="older">The older primitive.</param>
+ /// <returns><c>true</c> if the given primitive can merge with this one, <c>false</c> otherwise.</returns>
+ bool CanMerge(ITextUndoPrimitive older);
+
+ /// <summary>
+ /// Performs the actual merge.
+ /// </summary>
+ /// <param name="older">The older primitive to merge.</param>
+ /// <returns>The replacement primitive.</returns>
+ /// <remarks>
+ /// The resulting <see cref="ITextUndoPrimitive"/> will be added to the transaction, and the
+ /// two input primitives will be removed.
+ /// </remarks>
+ ITextUndoPrimitive Merge(ITextUndoPrimitive older);
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextLogic/Undo/ITextUndoTransaction.cs b/src/Text/Def/TextLogic/Undo/ITextUndoTransaction.cs
new file mode 100644
index 0000000..8ddb94d
--- /dev/null
+++ b/src/Text/Def/TextLogic/Undo/ITextUndoTransaction.cs
@@ -0,0 +1,90 @@
+// ****************************************************************************
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// ****************************************************************************
+
+using System;
+using System.Collections.ObjectModel;
+using System.Collections.Generic;
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Represents a container for <see cref="ITextUndoPrimitive"/> objects. UndoTransactions are tracked in an UndoHistory.
+ /// </summary>
+ public interface ITextUndoTransaction : IDisposable
+ {
+ /// <summary>
+ /// Gets or sets the description
+ /// </summary>
+ string Description { get; set; }
+
+ /// <summary>
+ /// Gets the <see cref="UndoTransactionState"/> for the <see cref="ITextUndoTransaction"/>.
+ /// </summary>
+ UndoTransactionState State { get; }
+
+ /// <summary>
+ ///Gets the <see cref="ITextUndoHistory"/> that contains this transaction.
+ /// </summary>
+ ITextUndoHistory History { get; }
+
+ /// <summary>
+ /// Gets the collection of <see cref="ITextUndoPrimitive"/> objects in this container.
+ /// </summary>
+ /// <remarks>
+ /// <para>You should try to get these primitives only after the transaction has been completed.</para>
+ /// <para>You cannot modify the list except during merging
+ /// (i.e. from your <see cref="IMergeTextUndoTransactionPolicy.PerformTransactionMerge"/> implementation).</para>
+ /// </remarks>
+ IList<ITextUndoPrimitive> UndoPrimitives { get; }
+
+ /// <summary>
+ /// Marks the transaction as finished and eligible for undo.
+ /// </summary>
+ void Complete();
+
+ /// <summary>
+ /// Marks an open transaction as canceled, and undoes and clears any primitives that have been added.
+ /// </summary>
+ void Cancel();
+
+ /// <summary>
+ /// Adds a new primitive to the end of the list when the transaction is open.
+ /// </summary>
+ /// <param name="undo"></param>
+ void AddUndo(ITextUndoPrimitive undo);
+
+ /// <summary>
+ /// Gets the <see cref="ITextUndoTransaction"/> that contains this transaction.
+ /// </summary>
+ /// <remarks>
+ /// This property can be null if this is a root transaction. It is transient, since completed transactions are not nested.
+ /// </remarks>
+ ITextUndoTransaction Parent { get; }
+
+ /// <summary>
+ /// Determines whether it is currently possible to call Do() successfully.
+ /// </summary>
+ bool CanRedo { get; }
+
+ /// <summary>
+ /// Determines whether it is currently possible to call Undo() successfully.
+ /// </summary>
+ bool CanUndo { get; }
+
+ /// <summary>
+ /// Performs a do or redo.
+ /// </summary>
+ void Do();
+
+ /// <summary>
+ /// Performs a rollback or undo.
+ /// </summary>
+ void Undo();
+
+ /// <summary>
+ /// Gets the <see cref="IMergeTextUndoTransactionPolicy"/> associated with this transaction.
+ /// </summary>
+ IMergeTextUndoTransactionPolicy MergePolicy { get; set; }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Undo/TextUndoHistoryState.cs b/src/Text/Def/TextLogic/Undo/TextUndoHistoryState.cs
new file mode 100644
index 0000000..25e8a45
--- /dev/null
+++ b/src/Text/Def/TextLogic/Undo/TextUndoHistoryState.cs
@@ -0,0 +1,34 @@
+// ****************************************************************************
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// ****************************************************************************
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Provides information about the <see cref="ITextUndoHistory"/>.
+ /// </summary>
+ public enum TextUndoHistoryState
+ {
+ /// <summary>
+ /// The <see cref="ITextUndoHistory"/> is not in the process of performing an undo or redo.
+ /// </summary>
+ /// <remarks>
+ /// If you care whether the <see cref="ITextUndoHistory"/> is altering its contents, be sure to check CurrentTransaction also.
+ /// </remarks>
+ Idle,
+
+ /// <summary>
+ /// The <see cref="ITextUndoHistory"/> is in the process of executing its Undo method.
+ /// </summary>
+ Undoing,
+
+ /// <summary>
+ /// The <see cref="ITextUndoHistory"/> is in the process of executing its Redo method.
+ /// </summary>
+ Redoing,
+ }
+}
diff --git a/src/Text/Def/TextLogic/Undo/TextUndoRedoEventArgs.cs b/src/Text/Def/TextLogic/Undo/TextUndoRedoEventArgs.cs
new file mode 100644
index 0000000..6f4422c
--- /dev/null
+++ b/src/Text/Def/TextLogic/Undo/TextUndoRedoEventArgs.cs
@@ -0,0 +1,48 @@
+// ****************************************************************************
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// ****************************************************************************
+
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Provides information for the UndoRedoHappened event raised by <see cref="ITextUndoHistory"/>, about the effect of the undo or redo operation.
+ /// </summary>
+ public class TextUndoRedoEventArgs : EventArgs
+ {
+ private TextUndoHistoryState state;
+ private ITextUndoTransaction transaction;
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="TextUndoRedoEventArgs"/>.
+ /// </summary>
+ /// <param name="state">The <see cref="TextUndoHistoryState"/>.</param>
+ /// <param name="transaction">The <see cref="ITextUndoTransaction"/>.</param>
+ public TextUndoRedoEventArgs(TextUndoHistoryState state, ITextUndoTransaction transaction)
+ {
+ this.state = state;
+ this.transaction = transaction;
+ }
+
+ /// <summary>
+ /// Gets the transaction that was processed in this undo or redo.
+ /// </summary>
+ public ITextUndoTransaction Transaction
+ {
+ get { return this.transaction; }
+ }
+
+ /// <summary>
+ /// Gets the state of the transaction.
+ /// </summary>
+ /// <remarks>
+ /// The state is either UndoTransactionState.Undoing or UndoTransactionState.Redoing.
+ /// </remarks>
+ public TextUndoHistoryState State
+ {
+ get { return this.state; }
+ }
+ }
+}
diff --git a/src/Text/Def/TextLogic/Undo/TextUndoTransactionCompletedEventArgs.cs b/src/Text/Def/TextLogic/Undo/TextUndoTransactionCompletedEventArgs.cs
new file mode 100644
index 0000000..edd37b6
--- /dev/null
+++ b/src/Text/Def/TextLogic/Undo/TextUndoTransactionCompletedEventArgs.cs
@@ -0,0 +1,72 @@
+// ****************************************************************************
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// ****************************************************************************
+
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Provides information for the <see cref="ITextUndoHistory.UndoTransactionCompleted"/> event raised by the <see cref="ITextUndoHistory"/>.
+ /// </summary>
+ /// <remarks>
+ /// These event arguments contain the <see cref="ITextUndoTransaction"/> that has been added
+ /// and the result of the completion. This event is fired only for
+ /// the topmost <see cref="ITextUndoTransaction"/> that is placed on the <see cref="ITextUndoHistory.UndoStack"/>. Completion of nested
+ /// transactions does not raise this event.
+ /// </remarks>
+ public class TextUndoTransactionCompletedEventArgs : EventArgs
+ {
+ private ITextUndoTransaction transaction;
+ private TextUndoTransactionCompletionResult result;
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="TextUndoTransactionCompletedEventArgs"/>.
+ /// </summary>
+ /// <param name="transaction">The <see cref="ITextUndoTransaction"/>.</param>
+ /// <param name="result">The <see cref="TextUndoTransactionCompletionResult"/>.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="transaction"/> is null.</exception>
+ public TextUndoTransactionCompletedEventArgs(ITextUndoTransaction transaction, TextUndoTransactionCompletionResult result)
+ {
+ this.transaction = transaction;
+ this.result = result;
+ }
+
+ /// <summary>
+ /// Gets the transaction that was added to the <see cref="ITextUndoHistory"/>.
+ /// </summary>
+ public ITextUndoTransaction Transaction
+ {
+ get { return this.transaction; }
+ }
+
+ /// <summary>
+ /// Gets the result of the completed transaction.
+ /// </summary>
+ /// <remarks>
+ /// See <see cref="TextUndoTransactionCompletionResult"/> for the possible outcomes.
+ /// </remarks>
+ public TextUndoTransactionCompletionResult Result
+ {
+ get { return this.result; }
+ }
+ }
+
+ /// <summary>
+ /// Describes the possible results of a transaction completion for an <see cref="ITextUndoHistory"/>.
+ /// </summary>
+ public enum TextUndoTransactionCompletionResult
+ {
+ /// <summary>
+ /// The most recent transaction is added to the <see cref="ITextUndoHistory.UndoStack"/> of the <see cref="ITextUndoHistory"/>.
+ /// </summary>
+ TransactionAdded,
+
+ /// <summary>
+ /// The most recent transaction is merged with the transaction on the top of the <see cref="ITextUndoHistory.UndoStack"/> of
+ /// the associated <see cref="ITextUndoHistory"/>.
+ /// </summary>
+ TransactionMerged,
+ }
+}
diff --git a/src/Text/Def/TextLogic/Undo/TextUndoTransactionState.cs b/src/Text/Def/TextLogic/Undo/TextUndoTransactionState.cs
new file mode 100644
index 0000000..7182d7c
--- /dev/null
+++ b/src/Text/Def/TextLogic/Undo/TextUndoTransactionState.cs
@@ -0,0 +1,55 @@
+// ****************************************************************************
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// ****************************************************************************
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Holds the state of the transaction.
+ /// </summary>
+ /// <remarks>
+ /// There are five rough groups of transactions.
+ /// Open transactions are being defined. Canceled transactions have been aborted and are empty. Completed and undone
+ /// transactions have been defined and are ready for undo and redo, respectively. Undoing and redoing are
+ /// transient states as the transaction passes between completed and undone. Invalid is a state for transactions that
+ /// have expired.
+ /// </remarks>
+ public enum UndoTransactionState
+ {
+ /// <summary>
+ /// Represents the initial state of the transaction, after it has been created and before it is canceled or completed.
+ /// </summary>
+ Open,
+
+ /// <summary>
+ /// Indicates that the transaction is no longer being defined, and is eligible for undo.
+ /// </summary>
+ Completed,
+
+ /// <summary>
+ /// Indicates that the transaction is no longer being defined, but has been aborted and cleared.
+ /// </summary>
+ Canceled,
+
+ /// <summary>
+ /// Indicates a transient state set by Do(), between the undone state and the completed state.
+ /// </summary>
+ Redoing,
+
+ /// <summary>
+ /// Indicates a transient state set by Undo(), between the completed state and the Undone state.
+ /// </summary>
+ Undoing,
+
+ /// <summary>
+ /// Indicates that Undo() was called after completion.
+ /// </summary>
+ Undone,
+
+ /// <summary>
+ /// Indicates that the transaction has been removed the undo history stack, for example because it was on the redo stack when
+ /// a new operation cleared the redo stack. Once a transaction is invalid it should not be used for anything.
+ /// </summary>
+ Invalid
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Adornments/BlockContext.cs b/src/Text/Def/TextUI/Adornments/BlockContext.cs
new file mode 100644
index 0000000..b74d188
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/BlockContext.cs
@@ -0,0 +1,62 @@
+using Microsoft.VisualStudio.Text.Adornments;
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Text.Tagging;
+using System;
+
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ /// <summary>
+ /// An implementation of <see cref="IBlockContext"/>.
+ /// </summary>
+ public class BlockContext : IBlockContext
+ {
+ private readonly IBlockTag _blockTag;
+ private readonly ITextView _view;
+ private readonly object _content;
+ /// <summary>
+ /// Initializes a new instance of <see cref="IBlockContext"/> with the specified block tag.
+ /// </summary>
+ /// <param name="blockTag">The block tag associated with the structural block.</param>
+ /// <param name="view">The text view associated with the structural block.</param>
+ /// <param name="content">The content, including hiearchical parent statements, to be displayed in the tooltip.</param>
+ public BlockContext(IBlockTag blockTag, ITextView view, object content)
+ {
+ if (blockTag == null)
+ throw new ArgumentNullException("blockTag");
+
+ if (view == null)
+ throw new ArgumentNullException("view");
+
+ if (content == null)
+ throw new ArgumentNullException("content");
+
+ _blockTag = blockTag;
+ _view = view;
+ _content = content;
+ }
+
+ /// <summary>
+ /// Gets the block tag associated with this context.
+ /// </summary>
+ public IBlockTag BlockTag
+ {
+ get { return _blockTag; }
+ }
+
+ /// <summary>
+ /// Gets the text view associated with this context.
+ /// </summary>
+ public ITextView TextView
+ {
+ get { return _view; }
+ }
+
+ /// <summary>
+ /// Gets the content that will be displayed in the tool tip, including hierarchical parent content.
+ /// </summary>
+ public object Content
+ {
+ get { return _content; }
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/ErrorTypeDefinition.cs b/src/Text/Def/TextUI/Adornments/ErrorTypeDefinition.cs
new file mode 100644
index 0000000..f6b90f1
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ErrorTypeDefinition.cs
@@ -0,0 +1,20 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+ using System.ComponentModel.Composition;
+
+ /// <summary>
+ /// Defines error types.
+ /// </summary>
+ /// <remarks> This is a MEF component part, and should be exported as:
+ /// [Export(typeof(ErrorTypeDefinition))]
+ /// </remarks>
+ public sealed class ErrorTypeDefinition
+ {
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/IBlockContext.cs b/src/Text/Def/TextUI/Adornments/IBlockContext.cs
new file mode 100644
index 0000000..229eaf1
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/IBlockContext.cs
@@ -0,0 +1,26 @@
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Text.Tagging;
+
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ /// <summary>
+ /// Defines the block context used to display structural block information.
+ /// </summary>
+ public interface IBlockContext
+ {
+ /// <summary>
+ /// Gets the content that will be displayed in the tool tip, including hierarchical parent content.
+ /// </summary>
+ object Content { get; }
+
+ /// <summary>
+ /// Gets the block tag associated with this context.
+ /// </summary>
+ IBlockTag BlockTag { get; }
+
+ /// <summary>
+ /// Gets the text view associated with this context.
+ /// </summary>
+ ITextView TextView { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/IBlockContextProvider.cs b/src/Text/Def/TextUI/Adornments/IBlockContextProvider.cs
new file mode 100644
index 0000000..674881a
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/IBlockContextProvider.cs
@@ -0,0 +1,23 @@
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ /// <summary>
+ /// Creates a <see cref="IBlockContextSource"/> for a given buffer.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be exported as follows:
+ /// [Export(typeof(IBlockContextProvider))]
+ /// Component exporters must add the Name and Order attribute to define the order of the provider in the provider chain.
+ /// </remarks>
+ public interface IBlockContextProvider
+ {
+ /// <summary>
+ /// Creates a block context source for the given text buffer.
+ /// </summary>
+ /// <param name="textBuffer">The text buffer for which to create a provider.</param>
+ /// <param name="token">The cancelation token for this asynchronous method call.</param>
+ /// <returns>A valid <see cref="IBlockContextSource" /> instance, or null if none could be created.</returns>
+ Task<IBlockContextSource> TryCreateBlockContextSourceAsync(ITextBuffer textBuffer, CancellationToken token);
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/IBlockContextSource.cs b/src/Text/Def/TextUI/Adornments/IBlockContextSource.cs
new file mode 100644
index 0000000..bcb2bb5
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/IBlockContextSource.cs
@@ -0,0 +1,23 @@
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Text.Tagging;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ /// <summary>
+ /// Provides content for structural block tool tips for a given <see cref="IBlockTag"/>.
+ /// </summary>
+ public interface IBlockContextSource : IDisposable
+ {
+ /// <summary>
+ /// Gets the contexts for the given block tag.
+ /// </summary>
+ /// <param name="blockTag">The block tag for which the context is requested.</param>
+ /// <param name="view">The text view associated with the current context.</param>
+ /// <param name="token">The cancellation token for this asynchronous method call.</param>
+ /// <returns>The <see cref="IBlockContext" /> to be displayed in the tool tip.</returns>
+ Task<IBlockContext> GetBlockContextAsync(IBlockTag blockTag, ITextView view, CancellationToken token);
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/IErrorProviderFactory.cs b/src/Text/Def/TextUI/Adornments/IErrorProviderFactory.cs
new file mode 100644
index 0000000..488b8d4
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/IErrorProviderFactory.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using Microsoft.VisualStudio.Text;
+ using Microsoft.VisualStudio.Text.Editor;
+ using System.ComponentModel.Composition;
+ using Microsoft.VisualStudio.Text.Tagging;
+
+ /// <summary>
+ /// Gets a error tagger (a <see cref="SimpleTagger&lt;T&gt;"/> of type <see cref="ErrorTag"/>) for the given buffer,
+ /// or creates a new one if there is no error tagger already cached in the owned properties of the buffer.
+ /// </summary>
+ /// <remarks>This is a MEF somponent part, and should be exported with the following attribute:
+ /// [Export(typeof(IErrorProviderFactory))]
+ /// </remarks>
+ public interface IErrorProviderFactory
+ {
+ /// <summary>
+ /// Gets the cached error tagger for a given <see cref="ITextBuffer"/>.
+ /// If one does not exist, creates and caches a new <see cref="SimpleTagger&lt;ErrorTag&gt;"/>
+ /// with the <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> with which to get the error tagger.</param>
+ /// <returns>The cached error tagger for the <paramref name="textBuffer"/>.</returns>
+ SimpleTagger<ErrorTag> GetErrorTagger(ITextBuffer textBuffer);
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/ITextMarkerProviderFactory.cs b/src/Text/Def/TextUI/Adornments/ITextMarkerProviderFactory.cs
new file mode 100644
index 0000000..5aa4fef
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/ITextMarkerProviderFactory.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using Microsoft.VisualStudio.Text;
+ using Microsoft.VisualStudio.Text.Editor;
+ using System.ComponentModel.Composition;
+ using Microsoft.VisualStudio.Text.Tagging;
+
+ /// <summary>
+ /// Gets a text marker tagger (a <see cref="SimpleTagger&lt;T&gt;"/> of type <see cref="TextMarkerTag"/> for a given buffer, or creates a new one if
+ /// no text marker tagger is already cached in the owned properties of the buffer.
+ /// </summary>
+ /// <remarks>This is a MEF Component, and should be exported with the following attribute:
+ /// [Export(typeof(ITextMarkerProviderFactory))]
+ /// </remarks>
+ public interface ITextMarkerProviderFactory
+ {
+ /// <summary>
+ /// Gets the cached text marker tagger for a given <see cref="ITextBuffer"/>.
+ /// If one does not exist, creates and caches a new <see cref="SimpleTagger&lt;TextMarkerTag&gt;"/>
+ /// with the <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="textBuffer">The <see cref="ITextBuffer"/> with which to get the text marker tagger.</param>
+ /// <returns>The cached <see cref="SimpleTagger&lt;T&gt;"/> for <paramref name="textBuffer"/>.</returns>
+ SimpleTagger<TextMarkerTag> GetTextMarkerTagger(ITextBuffer textBuffer);
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/IToolTipProvider.cs b/src/Text/Def/TextUI/Adornments/IToolTipProvider.cs
new file mode 100644
index 0000000..584e9ad
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/IToolTipProvider.cs
@@ -0,0 +1,45 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using System.Collections.Generic;
+ using Microsoft.VisualStudio.Text;
+
+ /// <summary>
+ /// Creates and displays tooltips, using an arbitrary object as content.
+ /// </summary>
+ public interface IToolTipProvider
+ {
+ /// <summary>
+ /// Creates and displays a tooltip.
+ /// </summary>
+ /// <param name="span">
+ /// The range of text for which the tooltip is relevant.
+ /// </param>
+ /// <param name="toolTipContent">
+ /// The content to be displayed in the tooltip. This must be a string or UIElement for the WPF tooltip adornment surface.
+ /// </param>
+ /// <remarks>This is equivalent to ShowToolTip(..., PopupStyles.None).</remarks>
+ void ShowToolTip(ITrackingSpan span, object toolTipContent);
+
+ /// <summary>
+ /// Creates and displays a tooltip.
+ /// </summary>
+ /// <param name="span">
+ /// The range of text for which the tooltip is relevant.
+ /// </param>
+ /// <param name="toolTipContent">
+ /// The content to be displayed in the tooltip. This must be a string or UIElement for the WPF tooltip adornment surface.
+ /// </param>
+ /// <param name="style">
+ /// <see cref="PopupStyles"/> for the tooltip.
+ /// </param>
+ void ShowToolTip(ITrackingSpan span, object toolTipContent, PopupStyles style);
+
+ /// <summary>
+ /// Removes the tooltip currently being displayed, if any.
+ /// </summary>
+ void ClearToolTip();
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Adornments/IToolTipProviderFactory.cs b/src/Text/Def/TextUI/Adornments/IToolTipProviderFactory.cs
new file mode 100644
index 0000000..6d91cb2
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/IToolTipProviderFactory.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ using Microsoft.VisualStudio.Text;
+ using Microsoft.VisualStudio.Text.Editor;
+ using System.ComponentModel.Composition;
+
+ /// <summary>
+ /// Gets an existing tooltip adornment provider from the cached list, or creates one if there is not one
+ /// in the cache.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be exported with the following attribute:
+ /// [Export(typeof(IToolTipProviderFactory))]
+ /// </remarks>
+ public interface IToolTipProviderFactory
+ {
+ /// <summary>
+ /// Gets the cached <see cref="IToolTipProvider"/> for a given <see cref="ITextView"/>.
+ /// If one does not exist, creates and caches a new <see cref="IToolTipProvider"/> with the <see cref="ITextView"/>.
+ /// </summary>
+ /// <param name="textView">The <see cref="ITextView"/> with which to get the <see cref="IToolTipProvider"/>.</param>
+ /// <returns>The cached <see cref="IToolTipProvider"/> for <paramref name="textView"/>.</returns>
+ IToolTipProvider GetToolTipProvider(ITextView textView);
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/PopupStyles.cs b/src/Text/Def/TextUI/Adornments/PopupStyles.cs
new file mode 100644
index 0000000..e7db825
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/PopupStyles.cs
@@ -0,0 +1,49 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ /// <summary>
+ /// Represents the styles associated with pop-up windows.
+ /// </summary>
+ [System.Flags]
+ public enum PopupStyles
+ {
+ /// <summary>
+ /// Sets the default behavior: the pop-up window has no border, is not resizable, is not dismissed when the mouse moves,
+ /// </summary>
+ None = 0x00,
+
+ /// <summary>
+ /// Dismiss the pop-up window if the mouse leaves the associated text span.
+ /// This setting is mutually exclusive with <see cref="DismissOnMouseLeaveTextOrContent"/>.
+ /// </summary>
+ DismissOnMouseLeaveText = 0x04,
+
+ /// <summary>
+ /// Dismiss the pop-up window if the mouse leaves the associated text span or the pop-up content.
+ /// This setting is mutually exclusive with <see cref="DismissOnMouseLeaveText"/>.
+ /// </summary>
+ DismissOnMouseLeaveTextOrContent = 0x08,
+ /// <summary>
+ /// Try to position the pop-up window to the left or right of the visual span.
+ /// </summary>
+ PositionLeftOrRight = 0x10,
+
+ /// <summary>
+ /// Try to position the pop-up window to the left or above the visual span.
+ /// </summary>
+ PreferLeftOrTopPosition = 0x20,
+
+ /// <summary>
+ /// Align the right or bottom edges of the pop-up window with those of the visual span.
+ /// </summary>
+ RightOrBottomJustify = 0x40,
+
+ /// <summary>
+ /// Use the positioning preference specified, but if the opposite positioning can get the popup
+ /// closer to the visual span, use the opposition positioning.
+ /// </summary>
+ PositionClosest= 0x80
+ };
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Adornments/PredefinedErrorTypeNames.cs b/src/Text/Def/TextUI/Adornments/PredefinedErrorTypeNames.cs
new file mode 100644
index 0000000..82d6918
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/PredefinedErrorTypeNames.cs
@@ -0,0 +1,36 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ /// <summary>
+ /// Enumerates the predefined error types.
+ /// </summary>
+ public static class PredefinedErrorTypeNames
+ {
+ /// <summary>
+ /// Represents syntax errors.
+ /// </summary>
+ public const string SyntaxError = "syntax error";
+
+ /// <summary>
+ /// Represents compiler errors.
+ /// </summary>
+ public const string CompilerError = "compiler error";
+
+ /// <summary>
+ /// Represents other errors.
+ /// </summary>
+ public const string OtherError = "other error";
+
+ /// <summary>
+ /// Represents compiler warnings.
+ /// </summary>
+ public const string Warning = "compiler warning";
+
+ /// <summary>
+ /// Represents a suggestion.
+ /// </summary>
+ public const string Suggestion = "suggestion";
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/PredefinedStructureTypes.cs b/src/Text/Def/TextUI/Adornments/PredefinedStructureTypes.cs
new file mode 100644
index 0000000..b1146ae
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/PredefinedStructureTypes.cs
@@ -0,0 +1,40 @@
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ /// <summary>
+ /// Enumerates the predefined structural block types.
+ /// </summary>
+ public static class PredefinedStructureTypes
+ {
+ /// <summary>
+ /// Represents structural blocks, with vertical line adornments displayed.
+ /// </summary>
+ public const string Structural = "Structural";
+
+ /// <summary>
+ /// Represents non-structural blocks, with no vertical line adornments
+ /// displayed, only expand and collapse.
+ /// </summary>
+ public const string Nonstructural = "Nonstructural";
+
+ public const string PropertyBlock = "PropertyBlock";
+ public const string AccessorBlock = "AccessorBlock";
+ public const string AnonymousMethodBlock = "AnonymousMethodBlock"; // i.e. lambda bodies
+ public const string Constructor = "Constructor";
+ public const string Destructor = "Destructor";
+ public const string Operator = "Operator";
+ public const string Method = "Method";
+ public const string Namespace = "Namespace";
+ public const string Class = "Class";
+ public const string Interface = "Interface";
+ public const string Struct = "Struct";
+ public const string TryCatchFinally = "TryCatchFinally";
+ public const string Conditional = "Conditional"; // i.e. If statements, ‘switch’ statements.i.e conditionals+branches
+ public const string Case = "Case";
+ public const string Loop = "Loop"; // i.e. While/For/Foreach/Do/Until (i.e.loops)
+ public const string Standalone = "Standalone"; // i.e. stand-alone {} used for scoping.
+
+ public const string Lock = "Context"; // i.e. using/lock/checked/unchecked. Need a better name for this.
+
+ public const string Unknown = "Unknown";
+ }
+}
diff --git a/src/Text/Def/TextUI/Adornments/StructureAdornmentStyle.cs b/src/Text/Def/TextUI/Adornments/StructureAdornmentStyle.cs
new file mode 100644
index 0000000..f71fe11
--- /dev/null
+++ b/src/Text/Def/TextUI/Adornments/StructureAdornmentStyle.cs
@@ -0,0 +1,26 @@
+using System.Windows.Media;
+
+namespace Microsoft.VisualStudio.Text.Adornments
+{
+ /// <summary>
+ /// Defines a set of properties that will be used to style the default structural block tool tip.
+ /// </summary>
+ /// <remarks>
+ /// This is a MEF component part, and should be exported with the following attributes:
+ /// [Export(typeof(StructureAdornmentStyle))]
+ /// [Name]
+ /// [Order]
+ /// </remarks>
+ public class StructureAdornmentStyle
+ {
+ /// <summary>
+ /// Gets a <see cref="Brush"/> that will be used to paint the borders in the structure block tool tip.
+ /// </summary>
+ public virtual Brush BorderBrush { get; protected set; }
+
+ /// <summary>
+ /// Gets a <see cref="Brush"/> that will be used to paint the background of the structure block tool tip.
+ /// </summary>
+ public virtual Brush BackgroundBrush { get; protected set; }
+ }
+}
diff --git a/src/Text/Def/TextUI/AssemblyInfo.cs b/src/Text/Def/TextUI/AssemblyInfo.cs
new file mode 100644
index 0000000..c60ed90
--- /dev/null
+++ b/src/Text/Def/TextUI/AssemblyInfo.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+using System.Reflection;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+using System.Security.Permissions;
+
+
+//
+// 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: ComponentGuarantees(ComponentGuaranteesOptions.Stable)]
+
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+#pragma warning disable 618
+[assembly: SecurityPermission (SecurityAction.RequestMinimum, Flags = SecurityPermissionFlag.Execution)]
+#pragma warning restore 618
+[assembly: ReliabilityContract(Consistency.MayCorruptProcess, Cer.MayFail)]
diff --git a/src/Text/Def/TextUI/BraceCompletion/BracePairAttribute.cs b/src/Text/Def/TextUI/BraceCompletion/BracePairAttribute.cs
new file mode 100644
index 0000000..71c4c60
--- /dev/null
+++ b/src/Text/Def/TextUI/BraceCompletion/BracePairAttribute.cs
@@ -0,0 +1,56 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.BraceCompletion
+{
+ using System;
+ using System.ComponentModel.Composition;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Specifies the opening and closing braces.
+ /// <remarks>
+ /// This attribute may be exported on an <see cref="IBraceCompletionSessionProvider"/>, <see cref="IBraceCompletionContextProvider"/>,
+ /// or <see cref="IBraceCompletionDefaultProvider"/>.
+ /// </remarks></summary>
+ [MetadataAttribute]
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
+ public sealed class BracePairAttribute : MultipleBaseMetadataAttribute
+ {
+ private readonly char openingBraces;
+ private readonly char closingBraces;
+
+ /// <summary>
+ /// Instantiates a new instance of a <see cref="BracePairAttribute"/>.
+ /// </summary>
+ /// <param name="openingBrace">The opening brace character for this brace completion session.</param>
+ /// <param name="closingBrace">The closing brace character for this brace completion session.</param>
+ public BracePairAttribute(char openingBrace, char closingBrace)
+ {
+ openingBraces = openingBrace;
+ closingBraces = closingBrace;
+ }
+
+ /// <summary>
+ /// The opening brace character.
+ /// </summary>
+ public char OpeningBraces
+ {
+ get
+ {
+ return openingBraces;
+ }
+ }
+
+ /// <summary>
+ /// The closing brace character.
+ /// </summary>
+ public char ClosingBraces
+ {
+ get
+ {
+ return closingBraces;
+ }
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionContext.cs b/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionContext.cs
new file mode 100644
index 0000000..29a53b3
--- /dev/null
+++ b/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionContext.cs
@@ -0,0 +1,48 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.BraceCompletion
+{
+ using Microsoft.VisualStudio.Text;
+ using Microsoft.VisualStudio.Text.Editor;
+
+ /// <summary>
+ /// Represents a simple context used to extend the default brace completion behaviors to include
+ /// language-specific behaviors such as parsing and formatting.
+ /// </summary>
+ public interface IBraceCompletionContext
+ {
+ /// <summary>
+ /// Called before the session is added to the stack.
+ /// </summary>
+ /// <remarks>If additional formatting is required for the opening or closing brace it should be done here.</remarks>
+ /// <param name="session">Default brace completion session</param>
+ void Start(IBraceCompletionSession session);
+
+ /// <summary>
+ /// Called after the session has been removed from the stack.
+ /// </summary>
+ /// <param name="session">Default brace completion session</param>
+ void Finish(IBraceCompletionSession session);
+
+ /// <summary>
+ /// Called by the editor when return is pressed while both braces are on the same line
+ /// and no typing has occurred in the session.
+ /// </summary>
+ /// <remarks>Called after the newline has been inserted into the buffer.</remarks>
+ /// <remarks>Formatting for scenarios where the closing brace needs to be moved down an additional
+ /// line past the caret should be done here.</remarks>
+ /// <param name="session">Default brace completion session</param>
+ void OnReturn(IBraceCompletionSession session);
+
+ /// <summary>
+ /// Called by the editor when the closing brace character has been typed.
+ /// </summary>
+ /// <remarks>The closing brace character will not be inserted into the buffer until after this returns.</remarks>
+ /// <remarks>Does not occur if there is any non-whitespace between the caret and the closing brace.</remarks>
+ /// <remarks>Language-specific decisions may be made here to take into account scenarios such as an escaped closing char.</remarks>
+ /// <param name="session">Default brace completion session</param>
+ /// <returns>Returns true if the context is a valid overtype scenario.</returns>
+ bool AllowOverType(IBraceCompletionSession session);
+ }
+}
diff --git a/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionContextProvider.cs b/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionContextProvider.cs
new file mode 100644
index 0000000..40636b4
--- /dev/null
+++ b/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionContextProvider.cs
@@ -0,0 +1,41 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.BraceCompletion
+{
+ using Microsoft.VisualStudio.Text;
+ using Microsoft.VisualStudio.Text.Editor;
+
+ /// <summary>
+ /// Represents an extension point used to create an <see cref="IBraceCompletionContext"/>
+ /// to provide language-specific handling on top of default <see cref="IBraceCompletionSession"/>s.
+ /// </summary>
+ /// <remarks><see cref="IBraceCompletionContextProvider"/> extends the default brace completion
+ /// behaviors provided by <see cref="IBraceCompletionDefaultProvider"/>. It allows for additional
+ /// formatting after the closing brace has been inserted as well as custom handling
+ /// of overtype scenarios and newline insertions.</remarks>
+ /// <remarks>For a fully customizeable <see cref="IBraceCompletionSession"/> use <see cref="IBraceCompletionSessionProvider"/>.</remarks>
+ /// <remarks>
+ /// <para>This is a MEF component part, and should be exported with the following attribute:
+ /// [Export(typeof(IBraceCompletionContextProvider))]
+ /// </para>
+ /// <para>
+ /// Exports must include at least one [BracePair] attribute and at least one [ContentType] attribute.
+ /// </para>
+ /// </remarks>
+ public interface IBraceCompletionContextProvider
+ {
+ /// <summary>
+ /// Creates an <see cref="IBraceCompletionContext"/> to handle language-specific
+ /// actions such as parsing and formatting.
+ /// </summary>
+ /// <remarks>Opening points within strings and comments are usually invalid points to start an <see cref="IBraceCompletionSession"/> and will return false.</remarks>
+ /// <param name="textView">View containing the <paramref name="openingPoint"/>.</param>
+ /// <param name="openingPoint">Insertion point of the <paramref name="openingBrace"/>.</param>
+ /// <param name="openingBrace">Opening brace that has been typed by the user.</param>
+ /// <param name="closingBrace">Closing brace character</param>
+ /// <param name="context">Brace completion context if created.</param>
+ /// <returns>Returns true if the <paramref name="openingPoint"/> was a valid point in the buffer to start a <see cref="IBraceCompletionSession"/>.</returns>
+ bool TryCreateContext(ITextView textView, SnapshotPoint openingPoint, char openingBrace, char closingBrace, out IBraceCompletionContext context);
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionDefaultProvider.cs b/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionDefaultProvider.cs
new file mode 100644
index 0000000..16cd782
--- /dev/null
+++ b/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionDefaultProvider.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.BraceCompletion
+{
+ /// <summary>
+ /// Represents an extension point for the default non language-specific
+ /// brace completion behaviors. It should be used to export metadata
+ /// containing the opening and closing braces to provide
+ /// for the given ContentType.
+ /// </summary>
+ /// <remarks>
+ /// <para>This is a MEF component part, and should be exported with the following attribute:
+ /// [Export(typeof(IBraceCompletionDefaultProvider))]
+ /// </para>
+ /// <para>
+ /// Exports must include at least one [BracePair] attribute and at least one [ContentType] attribute.
+ /// </para>
+ /// </remarks>
+ public interface IBraceCompletionDefaultProvider
+ {
+
+ }
+}
diff --git a/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionSession.cs b/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionSession.cs
new file mode 100644
index 0000000..0ed1212
--- /dev/null
+++ b/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionSession.cs
@@ -0,0 +1,117 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.BraceCompletion
+{
+ using Microsoft.VisualStudio.Text;
+ using Microsoft.VisualStudio.Text.Editor;
+
+ /// <summary>
+ /// Represents a brace completion session for the purpose of tracking a pair of braces
+ /// and handling actions occurring between the OpeningPoint and ClosingPoint.
+ /// </summary>
+ public interface IBraceCompletionSession
+ {
+ /// <summary>
+ /// Gets the starting point of the session.
+ /// </summary>
+ /// <remarks>The OpeningPoint and ClosingPoint are used to determine if the caret is within the session.
+ /// If either one is null after Start has been called the session will be removed from the stack.</remarks>
+ ITrackingPoint OpeningPoint { get; }
+
+ /// <summary>
+ /// Gets the ending point of the session.
+ /// </summary>
+ /// <remarks>The OpeningPoint and ClosingPoint are used to determine if the caret is within the session.
+ /// If either one is null after Start has been called the session will be removed from the stack.</remarks>
+ ITrackingPoint ClosingPoint { get; }
+
+ /// <summary>
+ /// Gets the text view in which the brace completion session is occurring.
+ /// </summary>
+ ITextView TextView { get; }
+
+ /// <summary>
+ /// Gets the subject buffer in which the brace completion session is occurring.
+ /// </summary>
+ ITextBuffer SubjectBuffer { get; }
+
+ /// <summary>
+ /// Gets the opening brace character.
+ /// </summary>
+ char OpeningBrace { get; }
+
+ /// <summary>
+ /// Gets the closing brace character.
+ /// </summary>
+ char ClosingBrace { get; }
+
+ /// <summary>
+ /// Called before the session is added to the stack.
+ /// </summary>
+ /// <remarks>This method is called after the opening brace has been inserted into the buffer.</remarks>
+ void Start();
+
+ /// <summary>
+ /// Called after the session has been removed from the stack.
+ /// </summary>
+ void Finish();
+
+ /// <summary>
+ /// Called by the editor when the closing brace character has been typed and before it is
+ /// inserted into the buffer.
+ /// </summary>
+ /// <param name="handledCommand">Set to true to prevent the closing brace character from being
+ /// inserted into the buffer.</param>
+ void PreOverType(out bool handledCommand);
+
+ /// <summary>
+ /// Called by the editor after the closing brace character has been typed.
+ /// </summary>
+ void PostOverType();
+
+ /// <summary>
+ /// Called by the editor when tab has been pressed and before it is inserted into the buffer.
+ /// </summary>
+ /// <param name="handledCommand">Set to true to prevent the tab from being inserted into the buffer.</param>
+ void PreTab(out bool handledCommand);
+
+ /// <summary>
+ /// Called by the editor after the tab has been inserted.
+ /// </summary>
+ void PostTab();
+
+ /// <summary>
+ /// Called by the editor before the character has been removed.
+ /// </summary>
+ /// <param name="handledCommand">Set to true to prevent the backspace action from completing.</param>
+ void PreBackspace(out bool handledCommand);
+
+ /// <summary>
+ /// Called by the editor after the character has been removed.
+ /// </summary>
+ void PostBackspace();
+
+ /// <summary>
+ /// Called by the editor when delete is pressed within the session.
+ /// </summary>
+ /// <param name="handledCommand">Set to true to prevent the deletion.</param>
+ void PreDelete(out bool handledCommand);
+
+ /// <summary>
+ /// Called by the editor after the delete action.
+ /// </summary>
+ void PostDelete();
+
+ /// <summary>
+ /// Called by the editor when return is pressed within the session.
+ /// </summary>
+ /// <param name="handledCommand">Set to true to prevent the newline insertion.</param>
+ void PreReturn(out bool handledCommand);
+
+ /// <summary>
+ /// Called by the editor after the newline has been inserted.
+ /// </summary>
+ void PostReturn();
+ }
+}
diff --git a/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionSessionProvider.cs b/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionSessionProvider.cs
new file mode 100644
index 0000000..c73219b
--- /dev/null
+++ b/src/Text/Def/TextUI/BraceCompletion/IBraceCompletionSessionProvider.cs
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.BraceCompletion
+{
+ using Microsoft.VisualStudio.Text;
+ using Microsoft.VisualStudio.Text.Editor;
+
+ /// <summary>
+ /// Represents an extension point used to create an <see cref="IBraceCompletionSession"/>
+ /// for brace completion. A session tracks a set of braces and handles actions
+ /// performed by the user within the braces to allow for over typing of the
+ /// closing brace and additional formatting.
+ /// </summary>
+ /// <remarks>
+ /// <para>This is a MEF component part, and should be exported with the following attribute:
+ /// [Export(typeof(IBraceCompletionSessionProvider))]
+ /// </para>
+ /// <para>
+ /// Exports must include at least one [BracePair] attribute and at least one [ContentType] attribute.
+ /// </para>
+ /// </remarks>
+ public interface IBraceCompletionSessionProvider
+ {
+ /// <summary>
+ /// If appropriate, creates an <see cref="IBraceCompletionSession"/> based on the language context at the <paramref name="openingPoint"/>.
+ /// </summary>
+ /// <remarks>Opening points within strings and comments are usually invalid points to start an <see cref="IBraceCompletionSession"/> and will return false.</remarks>
+ /// <param name="textView">View containing the <paramref name="openingPoint"/>.</param>
+ /// <param name="openingPoint">Insertion point of the <paramref name="openingBrace"/> within the subject buffer.
+ /// The content type of the subject buffer will match one of the [ContentType] attributes for this extension.</param>
+ /// <param name="openingBrace">Opening brace that has been typed by the user.</param>
+ /// <param name="closingBrace">Closing brace character</param>
+ /// <param name="session">Brace completion session if created.</param>
+ /// <returns>Returns true if the <paramref name="openingPoint"/> was a valid point in the buffer to start a <see cref="IBraceCompletionSession"/>.</returns>
+ bool TryCreateSession(ITextView textView, SnapshotPoint openingPoint, char openingBrace, char closingBrace, out IBraceCompletionSession session);
+ }
+}
diff --git a/src/Text/Def/TextUI/Classification/IViewClassifierAggregatorService.cs b/src/Text/Def/TextUI/Classification/IViewClassifierAggregatorService.cs
new file mode 100644
index 0000000..2b2b099
--- /dev/null
+++ b/src/Text/Def/TextUI/Classification/IViewClassifierAggregatorService.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Classification
+{
+ using Microsoft.VisualStudio.Text.Editor;
+
+ /// <summary>
+ /// A service that returns an <see cref="IClassifier"/> that aggregates and normalizes all <see cref="IClassifier"/>
+ /// contributions for all <see cref="ITextBuffer"/>s in the buffer graph of a particular <see cref="ITextView"/>.
+ /// </summary>
+ /// <remarks>
+ /// <para>The normalized classifications produced by this aggregator are sorted and do not overlap. If a span of text
+ /// had multiple classifications based on the original classifier contributions, then in the normalized
+ /// classification it has a transient classification (<see cref="IClassificationTypeRegistryService"/>) that corresponds to
+ /// all of the original classifications.</para>
+ /// <para>Classifier aggregators are cached for each <see cref="ITextBuffer"/> and <see cref="ITextView"/> combination.</para>
+ /// </remarks>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IViewClassifierAggregatorService aggregator = null;
+ /// </remarks>
+ public interface IViewClassifierAggregatorService
+ {
+ /// <summary>
+ /// Gets the cached <see cref="IClassifier"/> for the given <see cref="ITextView"/>.
+ /// If one does not exist, an <see cref="IClassifier"/> will be created and cached for each <see cref="ITextBuffer"/> in the
+ /// view's buffer graph.
+ /// </summary>
+ /// <param name="textView">The <see cref="ITextView"/> to use in retrieving or creating the <see cref="IClassifier"/>.</param>
+ /// <returns>The cached <see cref="IClassifier"/>.</returns>
+ /// <exception cref="System.ArgumentNullException"><paramref name="textView"/> is null.</exception>
+ IClassifier GetClassifier(ITextView textView);
+ }
+}
diff --git a/src/Text/Def/TextUI/Diagrams/BasePrimitives.cd b/src/Text/Def/TextUI/Diagrams/BasePrimitives.cd
new file mode 100644
index 0000000..c45269d
--- /dev/null
+++ b/src/Text/Def/TextUI/Diagrams/BasePrimitives.cd
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+ <Comment CommentText="Editor primitive types exposed in the definition assembly">
+ <Position X="7.261" Y="0.5" Height="0.781" Width="1.7" />
+ </Comment>
+ <Class Name="Microsoft.VisualStudio.Text.Editor.TextBuffer">
+ <Position X="3.5" Y="0.5" Width="3.25" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAQAQAAQAAAAAAAAAAAAAAAACAAAAQAAAAAg=</HashCode>
+ <FileName>Primitives\TextBuffer.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.Editor.Caret">
+ <Position X="0.5" Y="4.5" Width="2.75" />
+ <TypeIdentifier>
+ <HashCode>AAAJAACgAIAAAAAAAACACAACJgAIAAAAAACAAAggAAQ=</HashCode>
+ <FileName>Primitives\Caret.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.Editor.Selection">
+ <Position X="0.5" Y="12.25" Width="3.25" />
+ <TypeIdentifier>
+ <HashCode>AABAAAAAACAAAAAAAAIAAEAAAAAAAAAQAAAAQABAAAA=</HashCode>
+ <FileName>Primitives\Selection.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.Editor.TextView">
+ <Position X="0.5" Y="0.5" Width="2.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAQAAAAgARAARAIAAAAAAAEAAAAAgkAAAEAAEAQAA=</HashCode>
+ <FileName>Primitives\TextView.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.Editor.TextRange">
+ <Position X="6.5" Y="12.25" Width="2.25" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAMABAMqAAQAAAAACEYAAAEAAIAQAALABg=</HashCode>
+ <FileName>Primitives\TextRange.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.1" />
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.Editor.TextPoint">
+ <Position X="6.5" Y="3.25" Width="2.5" />
+ <TypeIdentifier>
+ <HashCode>AAAJABCAAIAQggIEJABYCAAKKiAIAgAQAAGAAQkgABU=</HashCode>
+ <FileName>Primitives\TextPoint.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.Editor.DisplayTextPoint">
+ <Position X="4.25" Y="3.25" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAEAQEAAAAAAAAAAgAAAAAAAFAAAAAABA=</HashCode>
+ <FileName>Primitives\DisplayTextPoint.cs</FileName>
+ </TypeIdentifier>
+ </Class>
+ <Class Name="Microsoft.VisualStudio.Text.Editor.DisplayTextRange">
+ <Position X="4.25" Y="12.25" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>AEgQAAAAAAAAABAFAAAAAAAAAAgQAAAEAAAAAAAAABA=</HashCode>
+ <FileName>Primitives\DisplayTextRange.cs</FileName>
+ </TypeIdentifier>
+ <Lollipop Position="0.2" />
+ </Class>
+ <Enum Name="Microsoft.VisualStudio.Text.Editor.HowToShow">
+ <Position X="7.25" Y="1.5" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAAAAAAAACBCAAAAAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Primitives\HowToShow.cs</FileName>
+ </TypeIdentifier>
+ </Enum>
+ <Font Name="Segoe UI" Size="9" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Diagrams/Editor.cd b/src/Text/Def/TextUI/Diagrams/Editor.cd
new file mode 100644
index 0000000..6a1c4dd
--- /dev/null
+++ b/src/Text/Def/TextUI/Diagrams/Editor.cd
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ClassDiagram MajorVersion="1" MinorVersion="1">
+ <Interface Name="Microsoft.VisualStudio.Text.Editor.ITextView">
+ <Position X="4.25" Y="1.75" Width="2.5" />
+ <TypeIdentifier>
+ <HashCode>AAAAGAIABAEEAEAiKNwAAAAACgIQAkkAFAAACAjAQIA=</HashCode>
+ <FileName>Editor\ITextView.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="ViewScroller" />
+ <Property Name="Caret" />
+ <Property Name="Selection" />
+ <Property Name="TextBuffer" />
+ <Property Name="TextSnapshot" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Editor.ITextCaret">
+ <Position X="9.75" Y="1.75" Width="2.5" />
+ <TypeIdentifier>
+ <HashCode>ABAAAAAABBAAAAAgAACQAEAIAAALAAAACACAAAAAEAg=</HashCode>
+ <FileName>Editor\ITextCaret.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Editor.ITextSelection">
+ <Position X="7.75" Y="1.75" Width="1.5" />
+ <TypeIdentifier>
+ <HashCode>AAJAACAAAKAAIAgABAAAAAAAAAgAAEAAAAAAQABAAAA=</HashCode>
+ <FileName>Editor\ITextSelection.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="TextView" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextSnapshot" Collapsed="true">
+ <Position X="1.5" Y="1.75" Width="1.5" />
+ <TypeIdentifier />
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.ITextBuffer" Collapsed="true">
+ <Position X="1.5" Y="2.75" Width="1.5" />
+ <TypeIdentifier />
+ <ShowAsAssociation>
+ <Property Name="CurrentSnapshot" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Editor.IViewScroller">
+ <Position X="0.75" Y="4" Width="2.5" />
+ <TypeIdentifier>
+ <HashCode>AAQAAAAAAAAEAAAAAAAAAAAAAAAACAAhAAAAAAAAAAA=</HashCode>
+ <FileName>Editor\IViewScroller.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Editor.IScrollMap">
+ <Position X="1" Y="9.75" Width="2.25" />
+ <TypeIdentifier>
+ <HashCode>gAAAAAAAAAAAAAAAAAAAAAAAAAAAEAEAAAAAAACAAAA=</HashCode>
+ <FileName>Editor\IScrollMap.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Editor.IVerticalFractionMap">
+ <Position X="1" Y="7" Width="2.25" />
+ <AssociationLine Name="TextView" Type="Microsoft.VisualStudio.Text.Editor.ITextView" FixedFromPoint="true" FixedToPoint="true">
+ <Path>
+ <Point X="3.25" Y="7.406" />
+ <Point X="3.625" Y="7.406" />
+ <Point X="3.625" Y="6.625" />
+ <Point X="4.25" Y="6.625" />
+ </Path>
+ </AssociationLine>
+ <TypeIdentifier>
+ <HashCode>ABACAAAAAAAAAIAAAAAAAAAAAAgAAAAAAAAAAAAAAAA=</HashCode>
+ <FileName>Editor\IVerticalFractionMap.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="TextView" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Editor.ITextViewMargin">
+ <Position X="7.5" Y="7.5" Width="1.75" />
+ <TypeIdentifier>
+ <HashCode>AAAAAAAAAAAAAIAAAAAIAAAAAAAAAAACAAAAAAAAAAA=</HashCode>
+ <FileName>Editor\ITextViewMargin.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Editor.IVerticalScrollBar">
+ <Position X="4.75" Y="9.75" Width="2.25" />
+ <TypeIdentifier>
+ <HashCode>AAAAACQAABAgAAAAAACBAAAAAAAAAAAAAAAAAAAAACA=</HashCode>
+ <FileName>Editor\IVerticalScrollBar.cs</FileName>
+ </TypeIdentifier>
+ <ShowAsAssociation>
+ <Property Name="Map" />
+ </ShowAsAssociation>
+ </Interface>
+ <Interface Name="Microsoft.VisualStudio.Text.Formatting.ITextViewLine">
+ <Position X="12.75" Y="2.5" Width="3.25" />
+ <TypeIdentifier>
+ <HashCode>UEMIIACARChiAAQAYMgQEFBAAQGIQIIqGACAAoAUEAA=</HashCode>
+ <FileName>Formatting\ITextViewLine.cs</FileName>
+ </TypeIdentifier>
+ </Interface>
+ <Font Name="Segoe UI" Size="9" />
+</ClassDiagram> \ No newline at end of file
diff --git a/src/Text/Def/TextUI/DifferenceViewer/DifferenceHighlightMode.cs b/src/Text/Def/TextUI/DifferenceViewer/DifferenceHighlightMode.cs
new file mode 100644
index 0000000..be6a0eb
--- /dev/null
+++ b/src/Text/Def/TextUI/DifferenceViewer/DifferenceHighlightMode.cs
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+ namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// The highlight mode for this <see cref="IDifferenceViewer"/>.
+ /// </summary>
+ public enum DifferenceHighlightMode
+ {
+ /// <summary>
+ /// In this mode, line differences should be displayed only to the last character on each line.
+ /// </summary>
+ CodeContour,
+
+ /// <summary>
+ /// In this mode, line differences should be displayed so that they take up the entire width of the viewport.
+ /// </summary>
+ WholeLine
+ }
+}
diff --git a/src/Text/Def/TextUI/DifferenceViewer/DifferenceHighlightMode2.cs b/src/Text/Def/TextUI/DifferenceViewer/DifferenceHighlightMode2.cs
new file mode 100644
index 0000000..f4c5fea
--- /dev/null
+++ b/src/Text/Def/TextUI/DifferenceViewer/DifferenceHighlightMode2.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+ namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// The highlight mode for this <see cref="IDifferenceViewer"/>.
+ /// </summary>
+ public enum DifferenceHighlightMode2
+ {
+ /// <summary>
+ /// In this mode, line differences should be displayed only to the last character on each line.
+ /// </summary>
+ CodeContour = DifferenceHighlightMode.CodeContour,
+
+ /// <summary>
+ /// In this mode, line differences should be displayed so that they take up the entire width of the viewport.
+ /// </summary>
+ WholeLine = DifferenceHighlightMode.WholeLine,
+
+ /// <summary>
+ /// In this mode, line and word differences are shown as outlined rectangles.
+ /// </summary>
+ BlockOutline
+ }
+}
diff --git a/src/Text/Def/TextUI/DifferenceViewer/DifferenceViewMode.cs b/src/Text/Def/TextUI/DifferenceViewer/DifferenceViewMode.cs
new file mode 100644
index 0000000..8563678
--- /dev/null
+++ b/src/Text/Def/TextUI/DifferenceViewer/DifferenceViewMode.cs
@@ -0,0 +1,28 @@
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// The view mode for an <see cref="IDifferenceViewer"/>.
+ /// </summary>
+ public enum DifferenceViewMode
+ {
+ /// <summary>
+ /// View differences inline, mixing the removed and added regions in one view pane.
+ /// </summary>
+ Inline = 0,
+
+ /// <summary>
+ /// Show only the left file.
+ /// </summary>
+ LeftViewOnly = 1,
+
+ /// <summary>
+ /// Show only the right file.
+ /// </summary>
+ RightViewOnly = 2,
+
+ /// <summary>
+ /// View differences side-by-side, where the left pane is the left file and the right pane is the right file.
+ /// </summary>
+ SideBySide = 3
+ }
+}
diff --git a/src/Text/Def/TextUI/DifferenceViewer/DifferenceViewType.cs b/src/Text/Def/TextUI/DifferenceViewer/DifferenceViewType.cs
new file mode 100644
index 0000000..e0144d9
--- /dev/null
+++ b/src/Text/Def/TextUI/DifferenceViewer/DifferenceViewType.cs
@@ -0,0 +1,23 @@
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// The view type for a view created by an <see cref="IDifferenceViewer"/>.
+ /// </summary>
+ public enum DifferenceViewType
+ {
+ /// <summary>
+ /// View displaying the contents of the inline buffer (which is combines text from the left and right buffers).
+ /// </summary>
+ InlineView = 0,
+
+ /// <summary>
+ /// View containing the contents of the left buffer.
+ /// </summary>
+ LeftView = 1,
+
+ /// <summary>
+ /// View containing the contents of the right buffer.
+ /// </summary>
+ RightView = 2
+ }
+}
diff --git a/src/Text/Def/TextUI/DifferenceViewer/DifferenceViewerOptions.cs b/src/Text/Def/TextUI/DifferenceViewer/DifferenceViewerOptions.cs
new file mode 100644
index 0000000..d373359
--- /dev/null
+++ b/src/Text/Def/TextUI/DifferenceViewer/DifferenceViewerOptions.cs
@@ -0,0 +1,46 @@
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ public static class DifferenceViewerOptions
+ {
+ /// <summary>
+ /// The <see cref="DifferenceViewMode"/> the difference viewer should use (side-by-side, inline, one side at a time).
+ /// </summary>
+ public static readonly EditorOptionKey<DifferenceViewMode> ViewModeId = new EditorOptionKey<DifferenceViewMode>(DifferenceViewerOptions.ViewModeName);
+ public const string ViewModeName = "Diff/View/ViewMode";
+
+ /// <summary>
+ /// The <see cref="DifferenceHighlightMode"/> for the line changed markers.
+ /// </summary>
+ public static readonly EditorOptionKey<DifferenceHighlightMode> HighlightModeId = new EditorOptionKey<DifferenceHighlightMode>(DifferenceViewerOptions.HighlightModeName);
+ public const string HighlightModeName = "Diff/View/HighlightMode";
+
+ /// <summary>
+ /// If <c>true</c>, the difference viewer will scroll each contained view to the first visible difference after
+ /// the files are compared. If <c>false</c>, the scrolled area is left alone.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> ScrollToFirstDiffId = new EditorOptionKey<bool>(ScrollToFirstDiffName);
+ public const string ScrollToFirstDiffName = "Diff/View/ScrollToFirstDiff";
+
+ /// <summary>
+ /// If <c>true</c>, the left and right views of the side by side view are aligned with each other.
+ /// </summary>
+ /// <remarks>This option is ignored in the other view modes.</remarks>
+ public static readonly EditorOptionKey<bool> SynchronizeSideBySideViewsId = new EditorOptionKey<bool>(DifferenceViewerOptions.SynchronizeSideBySideViewsName);
+ public const string SynchronizeSideBySideViewsName = "Diff/View/SynchronizeSideBySideViews";
+ }
+
+ /// <summary>
+ /// A base class that can be used for options that are specific to an <see cref="IDifferenceViewer"/>.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public abstract class DifferenceViewerOption<T> : EditorOptionDefinition<T>
+ {
+ public override bool IsApplicableToScope(IPropertyOwner scope)
+ {
+ return scope is IDifferenceViewer;
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/DifferenceViewer/DifferenceViewerRoles.cs b/src/Text/Def/TextUI/DifferenceViewer/DifferenceViewerRoles.cs
new file mode 100644
index 0000000..65edcb9
--- /dev/null
+++ b/src/Text/Def/TextUI/DifferenceViewer/DifferenceViewerRoles.cs
@@ -0,0 +1,28 @@
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// The text view roles associated with an <see cref="IDifferenceViewer"/>.
+ /// </summary>
+ public static class DifferenceViewerRoles
+ {
+ /// <summary>
+ /// The text view role for any view owned by an <see cref="IDifferenceViewer"/>.
+ /// </summary>
+ public const string DiffTextViewRole = "DIFF";
+
+ /// <summary>
+ /// The text view role for the <see cref="IDifferenceViewer.LeftView"/>.
+ /// </summary>
+ public const string LeftViewTextViewRole = "LEFTDIFF";
+
+ /// <summary>
+ /// The text view role for the <see cref="IDifferenceViewer.RightView"/>.
+ /// </summary>
+ public const string RightViewTextViewRole = "RIGHTDIFF";
+
+ /// <summary>
+ /// The text view role for the <see cref="IDifferenceViewer.InlineView"/>.
+ /// </summary>
+ public const string InlineViewTextViewRole = "INLINEDIFF";
+ }
+}
diff --git a/src/Text/Def/TextUI/DifferenceViewer/IDifferenceViewer.cs b/src/Text/Def/TextUI/DifferenceViewer/IDifferenceViewer.cs
new file mode 100644
index 0000000..a876219
--- /dev/null
+++ b/src/Text/Def/TextUI/DifferenceViewer/IDifferenceViewer.cs
@@ -0,0 +1,129 @@
+using System;
+using Microsoft.VisualStudio.Text.Editor;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Differencing
+{
+ /// <summary>
+ /// A difference viewer is a container for viewing an <see cref="IDifferenceBuffer"/> in an inline or side-by-side
+ /// mode. It keeps the scroll state of the different views in sync, and provides helpers for scrolling to differences
+ /// and matches in all views.
+ /// </summary>
+ public interface IDifferenceViewer : IPropertyOwner
+ {
+ /// <summary>
+ /// The <see cref="IDifferenceBuffer"/> that this viewer is displaying.
+ /// </summary>
+ IDifferenceBuffer DifferenceBuffer { get; }
+
+ /// <summary>
+ /// The view for displaying <see cref="DifferenceViewMode.Inline"/> differences.
+ /// </summary>
+ /// <remarks>Will never be <c>null</c>, but will only be visible when <see cref="ViewMode"/>
+ /// is set to <see cref="DifferenceViewMode.Inline"/>.</remarks>
+ ITextView InlineView { get; }
+
+ /// <summary>
+ /// The view for displaying the left buffer for <see cref="DifferenceViewMode.SideBySide"/> differences.
+ /// </summary>
+ /// <remarks>Will never be <c>null</c>, but will only be visible when <see cref="ViewMode"/>
+ /// is set to <see cref="DifferenceViewMode.SideBySide"/>.</remarks>
+ ITextView LeftView { get; }
+
+ /// <summary>
+ /// The view for displaying the right buffer for <see cref="DifferenceViewMode.SideBySide"/> differences.
+ /// </summary>
+ /// <remarks>Will never be <c>null</c>, but will only be visible when <see cref="ViewMode"/>
+ /// is set to <see cref="DifferenceViewMode.SideBySide"/>.</remarks>
+ ITextView RightView { get; }
+
+ /// <summary>
+ /// The view mode (inline or side-by-side).
+ /// </summary>
+ DifferenceViewMode ViewMode { get; set; }
+
+ /// <summary>
+ /// Raised when the <see cref="ViewMode"/> changes.
+ /// </summary>
+ event EventHandler<EventArgs> ViewModeChanged;
+
+ /// <summary>
+ /// Identifies the active view that last had focus.
+ /// </summary>
+ DifferenceViewType ActiveViewType { get; }
+
+ /// <summary>
+ /// Used to get or set general difference viewer options (<see cref="DifferenceViewerOptions"/>).
+ /// </summary>
+ IEditorOptions Options { get; }
+
+ /// <summary>
+ /// Are the left and right views are synchronized in the side by side view.
+ /// </summary>
+ /// <remarks>
+ /// <para>In the side by side view, the left and right views are, normally, synchronized so that so that matching text always shown in each view.
+ /// If this synchronization is turned off, then each view will scroll independently.</para>
+ /// </remarks>
+ bool AreViewsSynchronized { get; }
+
+ /// <summary>
+ /// Close the viewer and all contained hosts.
+ /// </summary>
+ void Close();
+
+ /// <summary>
+ /// Determine if this viewer is closed.
+ /// </summary>
+ bool IsClosed { get; }
+
+ /// <summary>
+ /// Raised when the view is closed.
+ /// </summary>
+ event EventHandler<EventArgs> Closed;
+
+ #region Methods for scrolling
+
+ /// <summary>
+ /// Given the cursor position in the last focused text view, scroll and move the caret to the next difference.
+ /// </summary>
+ /// <param name="wrap">Wrap to the first difference if there is no next difference.</param>
+ /// <returns><c>true</c> on success (if there was a next difference), <c>false</c> otherwise.</returns>
+ bool ScrollToNextChange(bool wrap = false);
+
+ /// <summary>
+ /// Scroll and move the caret to the next difference after the specified location.
+ /// </summary>
+ /// <param name="point">Location to start scrolling from.</param>
+ /// <param name="wrap">Wrap to the first difference if there is no next difference.</param>
+ /// <returns><c>true</c> on success (if there was a next difference), <c>false</c> otherwise.</returns>
+ bool ScrollToNextChange(SnapshotPoint point, bool wrap = false);
+
+ /// <summary>
+ /// Given the cursor position in the last focused text view, scroll and move the caret to the previous difference.
+ /// </summary>
+ /// <param name="wrap">Wrap to the last difference if there is no previous difference.</param>
+ /// <returns><c>true</c> on success (if there was a previous difference), <c>false</c> otherwise.</returns>
+ bool ScrollToPreviousChange(bool wrap = false);
+
+ /// <summary>
+ /// Scroll and move the caret to the previous difference before the specified location.
+ /// </summary>
+ /// <param name="point">Location to start scrolling from.</param>
+ /// <param name="wrap">Wrap to the last difference if there is no previous difference.</param>
+ /// <returns><c>true</c> on success (if there was a next difference), <c>false</c> otherwise.</returns>
+ bool ScrollToPreviousChange(SnapshotPoint point, bool wrap = false);
+
+ /// <summary>
+ /// Scroll and move the caret to the start of the given difference.
+ /// </summary>
+ /// <param name="difference">The difference to scroll to.</param>
+ void ScrollToChange(Difference difference);
+
+ /// <summary>
+ /// Scroll and move the caret to the start of the given match.
+ /// </summary>
+ void ScrollToMatch(Match match);
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Editor/CaretPosition.cs b/src/Text/Def/TextUI/Editor/CaretPosition.cs
new file mode 100644
index 0000000..502b079
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/CaretPosition.cs
@@ -0,0 +1,160 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+
+ /// <summary>
+ /// Represents the position of a caret in an <see cref="ITextView"/>.
+ /// </summary>
+ public struct CaretPosition
+ {
+ #region Private Members
+ VirtualSnapshotPoint _bufferPosition;
+ PositionAffinity _affinity;
+ IMappingPoint _mappingPoint;
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="CaretPosition"/>.
+ /// </summary>
+ /// <param name="bufferPosition">The index of the caret. This corresponds to a gap between two characters in the underlying <see cref="ITextBuffer"/>.</param>
+ /// <param name="mappingPoint">A mapping point for the caret that can be used to find its position in any buffer.</param>
+ /// <param name="caretAffinity">The <see cref="PositionAffinity"/> of the caret. The caret can have an affinity with
+ /// the preceding edge of the gap or the following edge of the gap.</param>
+ public CaretPosition(VirtualSnapshotPoint bufferPosition, IMappingPoint mappingPoint, PositionAffinity caretAffinity)
+ {
+ if (mappingPoint == null)
+ {
+ throw new ArgumentNullException("mappingPoint");
+ }
+
+ _bufferPosition = bufferPosition;
+ _mappingPoint = mappingPoint;
+ _affinity = caretAffinity;
+ }
+ #region CaretPosition Members
+
+ /// <summary>
+ /// Gets the position of the caret, corresponding to a gap between two characters in the <see cref="ITextBuffer"/> of the view.
+ /// </summary>
+ /// <remarks>
+ /// This property gets the buffer position at the end of a line if the caret is positioned in virtual space.
+ /// </remarks>
+ public SnapshotPoint BufferPosition
+ {
+ get
+ {
+ return _bufferPosition.Position;
+ }
+ }
+
+ /// <summary>
+ /// Gets the <see cref="IMappingPoint"/>. This marks the position of the caret in the buffer.
+ /// </summary>
+ public IMappingPoint Point
+ {
+ get
+ {
+ return _mappingPoint;
+ }
+ }
+
+ /// <summary>
+ /// Gets the affinity of the caret.
+ /// <see cref="PositionAffinity.Predecessor"/> indicates that the caret is bound to the preceding edge of the gap.
+ /// <see cref="PositionAffinity.Successor"/> indicates that the caret is bound to the following edge of the gap.
+ /// </summary>
+ public PositionAffinity Affinity
+ {
+ get
+ {
+ return _affinity;
+ }
+ }
+
+ /// <summary>
+ /// Gets the virtual buffer position as a <see cref="VirtualSnapshotPoint"/>.
+ /// </summary>
+ public VirtualSnapshotPoint VirtualBufferPosition
+ {
+ get { return _bufferPosition; }
+ }
+
+ /// <summary>
+ /// Gets the number of spaces past the physical end of the line of the caret position.
+ /// </summary>
+ public int VirtualSpaces
+ {
+ get
+ {
+ return _bufferPosition.VirtualSpaces;
+ }
+ }
+ #endregion
+
+ #region Overrides
+
+ /// <summary>
+ /// Provides a string representation of the caret position.
+ /// </summary>
+ /// <returns>The string representation of the caret position.</returns>
+ public override string ToString()
+ {
+ if (_affinity == PositionAffinity.Predecessor)
+ return string.Format(System.Globalization.CultureInfo.InvariantCulture, "|{0}", _bufferPosition);
+ else
+ return string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}|", _bufferPosition);
+ }
+
+ /// <summary>
+ /// Gets the hash code for the <see cref="CaretPosition"/>.
+ /// </summary>
+ /// <returns>The hash code.</returns>
+ public override int GetHashCode()
+ {
+ return _bufferPosition.GetHashCode() ^ _affinity.GetHashCode();
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="CaretPosition"/> objects are the same
+ /// </summary>
+ /// <returns><c>true</c> if the two objects are the same, otherwise <c>false</c>.</returns>
+ public override bool Equals(object obj)
+ {
+ if (obj is CaretPosition)
+ {
+ CaretPosition caretPosition = (CaretPosition)obj;
+ return caretPosition == this;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ #endregion // Overrides
+
+ /// <summary>
+ /// Determines whether two <see cref="CaretPosition"/> objects are the same.
+ /// </summary>
+ /// <returns><c>true</c> if the two objects are the same, otherwise <c>false.</c></returns>
+ public static bool operator ==(CaretPosition caretPosition1, CaretPosition caretPosition2)
+ {
+ return (caretPosition1._bufferPosition == caretPosition2._bufferPosition) &&
+ (caretPosition1.Affinity == caretPosition2.Affinity);
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="CaretPosition"/> objects are different.
+ /// </summary>
+ /// <returns><c>true</c> if the two objects are different, otherwise <c>false.</c></returns>
+ public static bool operator !=(CaretPosition caretPosition1, CaretPosition caretPosition2)
+ {
+ return !(caretPosition1 == caretPosition2);
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/CaretPositionChangedEventArgs.cs b/src/Text/Def/TextUI/Editor/CaretPositionChangedEventArgs.cs
new file mode 100644
index 0000000..c3318ee
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/CaretPositionChangedEventArgs.cs
@@ -0,0 +1,76 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+
+ using Microsoft.VisualStudio.Text;
+
+ /// <summary>
+ /// Provides information for the <see cref="ITextCaret.PositionChanged"/> event.
+ /// </summary>
+ public class CaretPositionChangedEventArgs : EventArgs
+ {
+ #region Private Members
+ ITextView _textView;
+ CaretPosition _oldPosition, _newPosition;
+ #endregion // Private Members
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="CaretPositionChangedEventArgs"/>.
+ /// </summary>
+ /// <param name="textView">
+ /// The <see cref="ITextView"/> that contains the caret.
+ /// </param>
+ /// <param name="oldPosition">
+ /// The old <see cref="CaretPosition"/>.
+ /// </param>
+ /// <param name="newPosition">
+ /// The new <see cref="CaretPosition"/>.
+ /// </param>
+ public CaretPositionChangedEventArgs(ITextView textView, CaretPosition oldPosition, CaretPosition newPosition)
+ {
+ _textView = textView;
+ _oldPosition = oldPosition;
+ _newPosition = newPosition;
+ }
+
+ #region Exposed Properties
+
+ /// <summary>
+ /// Gets the <see cref="ITextView"/> that contains the caret.
+ /// </summary>
+ public ITextView TextView
+ {
+ get
+ {
+ return _textView;
+ }
+ }
+
+ /// <summary>
+ /// Gets the old <see cref="CaretPosition"/>.
+ /// </summary>
+ public CaretPosition OldPosition
+ {
+ get
+ {
+ return _oldPosition;
+ }
+ }
+
+ /// <summary>
+ /// Gets the new <see cref="CaretPosition"/>.
+ /// </summary>
+ public CaretPosition NewPosition
+ {
+ get
+ {
+ return _newPosition;
+ }
+ }
+
+ #endregion // Exposed Properties
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Editor/IScrollMap.cs b/src/Text/Def/TextUI/Editor/IScrollMap.cs
new file mode 100644
index 0000000..9bf11e9
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/IScrollMap.cs
@@ -0,0 +1,65 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using Microsoft.VisualStudio.Text;
+
+ /// <summary>
+ /// <para>Defines the mapping between character positions and scrollmap coordinates. This is not
+ /// the same as the coordinate system in which the scrollbar is rendered.</para>
+ /// </summary>
+ /// <remarks>
+ /// <para>Valid text positions range are [0...TextView.TextSnapshot.Length].</para>
+ /// <para>Corresponding scrollmap coordinates are [0.0 ... CoordinateOfBufferEnd].</para>
+ /// <para>Not every buffer position will have a distinct scrollmap coordinate. For example, every character on the same line of text will,
+ /// generally, have the same scrollmap coordinate.</para>
+ /// <para>Different scrollmap coordinates may map to the same buffer position. For example, scrollmap coordinates in the range [0.0, 1.0) will, generally,
+ /// map to the first character of the buffer.</para>
+ /// </remarks>
+ public interface IScrollMap : IVerticalFractionMap
+ {
+ /// <summary>
+ /// Gets the scrollmap coordinates of a buffer position.
+ /// </summary>
+ /// <param name="bufferPosition">The buffer position.</param>
+ /// <returns>The scrollmap coordinate, which will be between 0.0 and CoordinateOfBufferEnd inclusive.</returns>
+ double GetCoordinateAtBufferPosition(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Does the coordinate system used by this scroll map act as if all elisions are expanded?
+ /// </summary>
+ bool AreElisionsExpanded { get; }
+
+ /// <summary>
+ /// Gets the buffer position that corresponds to a scrollmap coordinate.
+ /// </summary>
+ /// <param name="coordinate">The scrollmap coordinate.</param>
+ /// <returns>The corresponding buffer position.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="coordinate"/> is NaN.</exception>
+ /// <remarks>Different buffer positions can have the same scroll map coordinates. This method is guaranteed only to be consistent: it will
+ /// return the same position for the same coordinate. The exact character returned will depend on the implementation of the scroll map.
+ /// It will generally be the first character on the line.</remarks>
+ SnapshotPoint GetBufferPositionAtCoordinate(double coordinate);
+
+ /// <summary>
+ /// The scrollmap coordinate of the start of the buffer.
+ /// </summary>
+ double Start { get; }
+
+ /// <summary>
+ /// The scrollmap coordinate of the end of the buffer.
+ /// </summary>
+ double End { get; }
+
+ /// <summary>
+ /// Gets the size of the text visible in the view (in scrollmap coordinates).
+ /// </summary>
+ /// <remarks>
+ /// This is equivalent to the scrollbar thumb size. The total height of the scroll map, in scrollmap coordinates,
+ /// is CoordinateOfBufferEnd + ThumbSize.
+ /// </remarks>
+ double ThumbSize { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/IScrollMapFactoryService.cs b/src/Text/Def/TextUI/Editor/IScrollMapFactoryService.cs
new file mode 100644
index 0000000..7cf6929
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/IScrollMapFactoryService.cs
@@ -0,0 +1,34 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using Microsoft.VisualStudio.Text;
+ using System.ComponentModel.Composition;
+ /// <summary>
+ /// Creates or reuses an <see cref="IScrollMap"/> for an <see cref="ITextView"/>.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IScrollMapFactoryService factory = null;
+ /// </remarks>
+ public interface IScrollMapFactoryService
+ {
+ /// <summary>
+ /// Creates or reuses an existing scroll map for the specified <see cref="ITextView"/>.
+ /// </summary>
+ /// <param name="textView"><see cref="ITextView"/> for which to get an <see cref="IScrollMap"/>.</param>
+ /// <returns>An <see cref="IScrollMap"/> for <paramref name="textView"/>.</returns>
+ /// <remarks>The coordinate system returned by this scroll map will act as if elisions are not expanded.</remarks>
+ IScrollMap Create(ITextView textView);
+
+ /// <summary>
+ /// Creates or reuses an existing scroll map for the specified <see cref="ITextView"/>.
+ /// </summary>
+ /// <param name="textView"><see cref="ITextView"/> for which to get an <see cref="IScrollMap"/>.</param>
+ /// <param name="areElisionsExpanded">Does the coordinate system used by this scroll map act as if all elisions are expanded?</param>
+ /// <returns>An <see cref="IScrollMap"/> for <paramref name="textView"/>.</returns>
+ IScrollMap Create(ITextView textView, bool areElisionsExpanded);
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/ISmartIndent.cs b/src/Text/Def/TextUI/Editor/ISmartIndent.cs
new file mode 100644
index 0000000..55f5d0b
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ISmartIndent.cs
@@ -0,0 +1,20 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+
+ /// <summary>
+ /// Provides for computing the desired indentation for a line.
+ /// </summary>
+ public interface ISmartIndent : IDisposable
+ {
+ /// <summary>
+ /// Gets the desired indentation of an <see cref="ITextSnapshotLine"/>.
+ /// </summary>
+ /// <param name="line">The line for which to compute the indentation.</param>
+ /// <returns>The number of spaces to place at the start of the line, or null if there is no desired indentation.</returns>
+ int? GetDesiredIndentation(ITextSnapshotLine line);
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Editor/ISmartIndentProvider.cs b/src/Text/Def/TextUI/Editor/ISmartIndentProvider.cs
new file mode 100644
index 0000000..8550562
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ISmartIndentProvider.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+
+ /// <summary>
+ /// Gets an <see cref="ISmartIndent"/> object for a given <see cref="ITextView"/>.
+ /// Component exporters must supply at least one content type attribute to specify the applicable content types.
+ /// </summary>
+ /// <remarks>
+ /// This is a MEF component part, and should be exported with the following attributes:
+ /// [Export(NameSource=typeof(ISmartIndentProvider))]
+ /// [ContentType("some content type")]
+ /// </remarks>
+ public interface ISmartIndentProvider
+ {
+ /// <summary>
+ /// Creates an <see cref="ISmartIndent"/> object for the given <see cref="ITextView"/>.
+ /// </summary>
+ /// <param name="textView">
+ /// The <see cref="ITextView"/> on which the <see cref="ISmartIndent"/> will navigate.
+ /// </param>
+ /// <returns>
+ /// A valid <see cref="ISmartIndent"/>. This value will never be <c>null</c>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="textView"/> is <c>null</c>.</exception>
+ ISmartIndent CreateSmartIndent(ITextView textView);
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/ISmartIndentationService.cs b/src/Text/Def/TextUI/Editor/ISmartIndentationService.cs
new file mode 100644
index 0000000..4f8558f
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ISmartIndentationService.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Provides a Visual Studio service that determines automatic indentation when the enter key is pressed or
+ /// when navigating to an empty line.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// ISmartIndentationService selector = null;
+ /// </remarks>
+ public interface ISmartIndentationService
+ {
+ /// <summary>
+ /// Gets the desired indentation of an <see cref="ITextSnapshotLine"/> as displayed in <see cref="ITextView"/>.
+ /// </summary>
+ /// <param name="textView">The text view in which the line is displayed.</param>
+ /// <param name="line">The line for which to compute the indentation.</param>
+ /// <returns>The number of spaces to place at the start of the line, or null if there is no desired indentation.</returns>
+ /// <remarks>
+ /// This service consumes <see cref="ISmartIndentProvider"/>s to determine how to perform the indentation.
+ /// </remarks>
+ int? GetDesiredIndentation(ITextView textView, ITextSnapshotLine line);
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/ITextCaret.cs b/src/Text/Def/TextUI/Editor/ITextCaret.cs
new file mode 100644
index 0000000..ca6b3bc
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ITextCaret.cs
@@ -0,0 +1,287 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using Microsoft.VisualStudio.Text;
+ using Microsoft.VisualStudio.Text.Formatting;
+
+ /// <summary>
+ /// <para>Represents the caret associated with an <see cref="ITextView"/>.</para>
+ /// </summary>
+ /// <remarks>
+ /// <para>Most properties and parameters that are doubles correspond to coordinates or distances in the text
+ /// rendering coordinate system. In this coordinate system, x = 0.0 corresponds to the left edge of the drawing
+ /// surface onto which text is rendered (x = view.ViewportLeft corresponds to the left edge of the viewport), and y = view.ViewportTop corresponds to the top edge of the viewport. The x-coordinate increases
+ /// from left to right, and the y-coordinate increases from top to bottom. </para>
+ /// <para>The horizontal and vertical axes of the view behave differently. When the text in the view is
+ /// formatted, only the visible lines are formatted. As a result,
+ /// a viewport cannot be scrolled horizontally and vertically in the same way.</para>
+ /// <para>A viewport is scrolled horizontally by changing the left coordinate of the
+ /// viewport so that it moves with respect to the drawing surface.</para>
+ /// <para>A view can be scrolled vertically only by performing a new layout.</para>
+ /// <para>Doing a layout in the view may cause the ViewportTop property of the view to change. For example, scrolling down one line will not translate any of the visible lines.
+ /// Instead it will simply change the view's ViewportTop property (causing the lines to move on the screen even though their y-coordinates have not changed).</para>
+ /// <para>Distances in the text rendering coordinate system correspond to logical pixels. If the text rendering
+ /// surface is displayed without any scaling transform, then 1 unit in the text rendering coordinate system
+ /// corresponds to one pixel on the display.</para>
+ /// </remarks>
+ public interface ITextCaret
+ {
+ /// <summary>
+ /// Makes the caret visible by scrolling the view up or down and left or right until the caret is visible.
+ /// </summary>
+ void EnsureVisible();
+
+ /// <summary>
+ /// Moves the caret to the best <see cref="CaretPosition"/> for the specified x-coordinate and text line.
+ /// </summary>
+ /// <param name="textLine">
+ /// The text line that will contain the caret.
+ /// </param>
+ /// <param name="xCoordinate">
+ /// The x-coordinate of the caret in the text rendering coordinate system.
+ /// </param>
+ /// <returns>
+ /// A <see cref="CaretPosition"/> that contains the valid values of the caret after the move has occurred.
+ /// </returns>
+ /// <remarks>This is equivalent to calling MoveTo(textLine, xCoordinate, true).</remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="xCoordinate"/> is NaN.</exception>
+ CaretPosition MoveTo(ITextViewLine textLine, double xCoordinate);
+
+ /// <summary>
+ /// Moves the caret to the best <see cref="CaretPosition"/> for the given x-coordinate and text line.
+ /// </summary>
+ /// <param name="textLine">
+ /// The text line that will contain the caret.
+ /// </param>
+ /// <param name="xCoordinate">
+ /// The x-coordinate of the caret in the text rendering coordinate system.
+ /// </param>
+ /// <param name="captureHorizontalPosition"><c>true</c> if the caret should capture its horizontal position for subsequent moves up or down.
+ /// <c>false</c> if the caret should retain its previously-captured horizontal position.</param>
+ /// <returns>
+ /// A <see cref="CaretPosition"/> that contains the valid values of the caret after the move has occurred.
+ /// </returns>
+ /// <remarks>This method takes care of UTF-16 surrogate pairs and combining character sequences.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="xCoordinate"/> is NaN.</exception>
+ CaretPosition MoveTo(ITextViewLine textLine, double xCoordinate, bool captureHorizontalPosition);
+
+ /// <summary>
+ /// Moves the caret to the specified <paramref name="textLine"/> while preserving its current x-coordinate.
+ /// </summary>
+ /// <param name="textLine">The text line that will contain the caret.</param>
+ /// <returns>
+ /// A <see cref="CaretPosition"/> that contains the valid values of the caret after the move has occurred.
+ /// </returns>
+ CaretPosition MoveTo(ITextViewLine textLine);
+
+ /// <summary>
+ /// Moves the caret to the given index in the underlying <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="bufferPosition">The <see cref="SnapshotPoint"/> in the underlying text buffer to which
+ /// to move the caret.</param>
+ /// <returns>A <see cref="CaretPosition"/> that contains the valid values of the caret after the move has occurred.</returns>
+ /// <remarks>This is equivalent to calling MoveTo(bufferPosition, PositionAffinity.Successor, true).</remarks>
+ CaretPosition MoveTo(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Moves the caret to the given index in the underlying <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="bufferPosition">The <see cref="SnapshotPoint"/> in the underlying text buffer to which
+ /// to move the caret.</param>
+ /// <param name="caretAffinity">The affinity of the caret. This will be ignored unless
+ /// <paramref name="bufferPosition"/> specifies a location that is at the seam between two word-wrapped lines.</param>
+ /// <returns>A <see cref="CaretPosition"/> that contains the valid values of the caret position after the move has occurred.</returns>
+ /// <remarks>This is equivalent to calling MoveTo(bufferPosition, caretAffinity, true).</remarks>
+ CaretPosition MoveTo(SnapshotPoint bufferPosition, PositionAffinity caretAffinity);
+
+ /// <summary>
+ /// Moves the caret to the given index in the underlying <see cref="ITextBuffer"/>.
+ /// </summary>
+ /// <param name="bufferPosition">The <see cref="SnapshotPoint"/> in the underlying text buffer to which
+ /// to move the caret.</param>
+ /// <param name="caretAffinity">The affinity of the caret. This will be ignored unless
+ /// <paramref name="bufferPosition"/> specifies a location that is at the seam between two word-wrapped lines.</param>
+ /// <param name="captureHorizontalPosition"><c>true</c> if the caret should capture its horizontal position for subsequent moves up or down,
+ /// <c>false</c> if the caret should retain its previously-captured horizontal position.</param>
+ /// <returns>A <see cref="CaretPosition"/> that contains the valid values of the caret position after the move has occurred.</returns>
+ /// <remarks>This method handles UTF-16 surrogate pairs and combining character sequences.
+ /// For example, if the text buffer consists of a high surrogate character at index 0 and a low surrogate character at index 1,
+ /// and <paramref name="bufferPosition"/> is 1 and
+ /// <paramref name="caretAffinity"/> is <see cref="PositionAffinity.Successor"/>,
+ /// the actual valid caret index is 0 (since the high surrogate and low surrogate characters form one text element).
+ /// If <paramref name="caretAffinity"/> is<see cref="PositionAffinity.Predecessor"/>, the actual valid caret index is 2.</remarks>
+ CaretPosition MoveTo(SnapshotPoint bufferPosition, PositionAffinity caretAffinity, bool captureHorizontalPosition);
+
+ /// <summary>
+ /// Moves the caret to the specified <paramref name="bufferPosition"/>.
+ /// </summary>
+ /// <param name="bufferPosition">The <see cref="VirtualSnapshotPoint"/> in the underlying text buffer to which
+ /// to move the caret.</param>
+ /// <returns>A <see cref="CaretPosition"/> that contains the valid values of the caret position after the move has occurred.</returns>
+ /// <remarks>This is equivalent to calling MoveTo(bufferPosition, PositionAffinity.Successor, true).</remarks>
+ CaretPosition MoveTo(VirtualSnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Moves the caret to the specified <paramref name="bufferPosition"/>.
+ /// </summary>
+ /// <param name="bufferPosition">The <see cref="VirtualSnapshotPoint"/> in the underlying text buffer to which
+ /// to move the caret.</param>
+ /// <param name="caretAffinity">The affinity of the caret. This will be ignored unless <paramref name="bufferPosition"/>
+ /// specifies a location that is at the seam between two word-wrapped lines.</param>
+ /// <returns>A <see cref="CaretPosition"/> that contains the valid values of the caret position after the move has occurred.</returns>
+ /// <remarks>This is equivalent to calling MoveTo(bufferPosition, caretAffinity, true).</remarks>
+ CaretPosition MoveTo(VirtualSnapshotPoint bufferPosition, PositionAffinity caretAffinity);
+
+
+ /// <summary>
+ /// Moves the caret to the specified <paramref name="bufferPosition"/>.
+ /// </summary>
+ /// <param name="bufferPosition">The <see cref="VirtualSnapshotPoint"/> in the underlying text buffer to which
+ /// to move the caret.</param>
+ /// <param name="caretAffinity">The affinity of the caret. This will be ignored unless <paramref name="bufferPosition"/>
+ /// specifies a location that is at the seam between two word-wrapped lines.</param>
+ /// <param name="captureHorizontalPosition">If <c>true</c>, the caret will capture its horizontal position for subsequent moves up or down.
+ /// If <c>false</c>, the caret retains its previously-captured horizontal position.</param>
+ /// <returns>A <see cref="CaretPosition"/> that contains the valid values of the caret position after the move has occurred.</returns>
+ /// <remarks>This method handles UTF-16 surrogate pairs and combining character sequences.
+ /// For example, if the text buffer consists of a high surrogate character at index 0 and a low surrogate character at index 1,
+ /// and <paramref name="bufferPosition"/> is 1 and <paramref name="caretAffinity"/> is <see cref="PositionAffinity.Successor"/>,
+ /// the actual valid caret index is 0 (since the high surrogate and low surrogate characters form one text element).
+ /// If <paramref name="caretAffinity"/> is <see cref="PositionAffinity.Predecessor"/>, the actual valid caret index is 2.</remarks>
+ CaretPosition MoveTo(VirtualSnapshotPoint bufferPosition, PositionAffinity caretAffinity, bool captureHorizontalPosition);
+
+ /// <summary>
+ /// Moves the caret to the preferred x and y-coordinates.
+ /// </summary>
+ /// <returns>A <see cref="CaretPosition"/> that contains the valid values of the caret position after the move has occurred.</returns>
+ /// <remarks>You cannot change the preferred coordinates by calling this method.</remarks>
+ CaretPosition MoveToPreferredCoordinates();
+
+ /// <summary>
+ /// Moves the caret to the next valid <see cref="CaretPosition"/>.
+ /// </summary>
+ /// <returns>A <see cref="CaretPosition"/> containing the valid values of the caret after the move has occurred.</returns>
+ /// <remarks>This method handles UTF-16 surrogate pairs and combining character sequences.</remarks>
+ CaretPosition MoveToNextCaretPosition();
+
+ /// <summary>
+ /// Moves the caret to the previous valid <see cref="CaretPosition"/>.
+ /// </summary>
+ /// <returns>A <see cref="CaretPosition"/> containing the valid values of the caret after the move has occurred.</returns>
+ /// <remarks>This method handles UTF-16 surrogate pairs and combining character sequences.</remarks>
+ CaretPosition MoveToPreviousCaretPosition();
+
+ /// <summary>
+ /// Gets the <see cref="ITextViewLine"/> that contains the caret, provided that that text line is visible
+ /// in the view.
+ /// </summary>
+ ITextViewLine ContainingTextViewLine { get; }
+
+ /// <summary>
+ /// Gets the position of the left edge of the caret in the text rendering coordinate system.
+ /// </summary>
+ double Left
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the width of the caret in the text rendering coordinate system.
+ /// </summary>
+ double Width
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the position of the right edge of the caret in the text rendering coordinate system.
+ /// </summary>
+ double Right
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the position of the top edge of the caret in the text rendering coordinate system.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">The caret does not lie in the text formatted by the view.</exception>
+ double Top
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the height of the caret in the text rendering coordinate system.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">The caret does not lie in the text formatted by the view.</exception>
+ double Height
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the position of the bottom edge of the caret in the text rendering coordinate system.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">The caret does not lie in the text formatted by the view.</exception>
+ double Bottom
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the current position of the caret.
+ /// </summary>
+ CaretPosition Position
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Determines whether the caret is in overwrite mode.
+ /// </summary>
+ /// <remarks>
+ /// <para>When the caret is in overwrite mode, typed characters replace the character under the caret,
+ /// and a block is drawn instead of a vertical line.</para>
+ /// <para>This is distinct from the IEditorOptions overwrite mode,
+ /// since the caret can switch modes based on its position in the view.
+ /// The caret is not in OverwriteMode when it is positioned at the end of the line in a view, or when there is a
+ /// non-empty selection, even if IEditorOptions.OverwriteMode is true.</para>
+ /// </remarks>
+ bool OverwriteMode
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Determines whether the caret lies in virtual space. A virtual space is one that is after the physical end of a line.
+ /// </summary>
+ /// <remarks>
+ /// <para>This is distinct from the <see cref="IEditorOptions"/> UseVirtualSpace,
+ /// since virtual space can be enabled even if the caret does not lie in virtual space.</para>
+ /// </remarks>
+ bool InVirtualSpace
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets or sets the visibility of the caret.
+ /// </summary>
+ bool IsHidden
+ {
+ get; set;
+ }
+
+ /// <summary>
+ /// Occurs when the position of the caret has been explicitly changed.
+ /// </summary>
+ /// <remarks>
+ /// The event is not raised if the caret position was changed as a consequence of tracking normal text edits.
+ /// The normal behavior of the caret is to move after the typed character.
+ /// </remarks>
+ event EventHandler<CaretPositionChangedEventArgs> PositionChanged;
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/ITextSelection.cs b/src/Text/Def/TextUI/Editor/ITextSelection.cs
new file mode 100644
index 0000000..f496334
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ITextSelection.cs
@@ -0,0 +1,158 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using System.Collections.ObjectModel;
+ using Microsoft.VisualStudio.Text;
+ using Microsoft.VisualStudio.Text.Formatting;
+
+ /// <summary>
+ /// Represents the selected text in an <see cref="ITextView"/>
+ /// </summary>
+ public interface ITextSelection
+ {
+ /// <summary>
+ /// Gets the text view to which this selection belongs.
+ /// </summary>
+ ITextView TextView { get; }
+
+ /// <summary>
+ /// Selects the text in the specified <paramref name="selectionSpan"/>.
+ /// </summary>
+ /// <param name="selectionSpan">The <see cref="SnapshotSpan"/> of text to select in the
+ /// underlying text buffer.</param>
+ /// <param name="isReversed"><c>true</c> if the selection was made in a reverse direction, otherwise <c>false</c>.</param>
+ void Select(SnapshotSpan selectionSpan, bool isReversed);
+
+ /// <summary>
+ /// Select from the anchor point to the active point.
+ /// </summary>
+ /// <param name="anchorPoint">The anchor point</param>
+ /// <param name="activePoint">The active point</param>
+ void Select(VirtualSnapshotPoint anchorPoint, VirtualSnapshotPoint activePoint);
+
+ /// <summary>
+ /// The currently-selected spans.
+ /// </summary>
+ /// <remarks>
+ /// <para>This span collection will never be empty. However, the spans in
+ /// this collection may be 0-length.</para>
+ /// <para>This value can be very expensive to compute the first time after the selection has changed.</para>
+ /// <para>Use GetSelectionOnTextViewLine() unless you need the entire selection.</para>
+ /// </remarks>
+ NormalizedSnapshotSpanCollection SelectedSpans { get; }
+
+ /// <summary>
+ /// The currently-selected spans, as <see cref="VirtualSnapshotSpan" /> objects.
+ /// </summary>
+ /// <remarks>
+ /// <para>This span collection will never be empty. However, the spans in
+ /// this collection may be 0-length.</para>
+ /// <para>This value can be very expensive to compute the first time after the selection has changed.</para>
+ /// <para>Use GetSelectionOnTextViewLine() unless you need the entire selection.</para>
+ /// </remarks>
+ ReadOnlyCollection<VirtualSnapshotSpan> VirtualSelectedSpans { get; }
+
+ /// <summary>
+ /// Get the selection on a particular <see cref="ITextViewLine"/>.
+ /// </summary>
+ /// <param name="line">Line for which to get the selection.</param>
+ /// <returns>The selection on <paramref name="line"/>.</returns>
+ VirtualSnapshotSpan? GetSelectionOnTextViewLine(ITextViewLine line);
+
+ /// <summary>
+ /// Get the current selection as if it were a stream selection, regardless
+ /// of the current selection mode.
+ /// </summary>
+ VirtualSnapshotSpan StreamSelectionSpan { get; }
+
+ /// <summary>
+ /// Gets or sets the selection mode.
+ /// </summary>
+ TextSelectionMode Mode { get; set; }
+
+ /// <summary>
+ /// Is <c>true</c> if the <see cref="ActivePoint"/> comes before the <see cref="AnchorPoint"/>.
+ /// </summary>
+ bool IsReversed { get; }
+
+ /// <summary>
+ /// Clears the selection.
+ /// </summary>
+ /// <remarks>
+ /// After calling this method, <see cref="IsEmpty"/> will be <c>true</c>.
+ /// </remarks>
+ void Clear();
+
+ /// <summary>
+ /// Determines whether the selection is empty.
+ /// </summary>
+ /// <remarks>The selection is empty if the active and anchor points are
+ /// the same point.</remarks>
+ bool IsEmpty { get; }
+
+ /// <summary>
+ /// Whether or not the selection is active.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// If <see cref="ActivationTracksFocus"/> is <c>true</c>, this property is automatically
+ /// updated when the <see cref="ITextView"/> gains and loses aggregate focus. You can still
+ /// override it while <see cref="ActivationTracksFocus"/> is <c>false</c>, but the value will change
+ /// whenever focus changes.
+ /// </para>
+ /// </remarks>
+ bool IsActive { get; set; }
+
+ /// <summary>
+ /// Determines whether <see cref="IsActive"/> should track when the <see cref="ITextView"/> gains and
+ /// loses aggregate focus. The default is <c>true</c>.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// While the value of this property is <c>true</c>, the value of <see cref="IsActive"/> will track
+ /// <see cref="ITextView.HasAggregateFocus"/>. When the value of this property changes to <c>true</c>,
+ /// the value of <see cref="IsActive"/> will be immediately updated.
+ /// </para>
+ /// </remarks>
+ bool ActivationTracksFocus { get; set; }
+
+ /// <summary>
+ /// Occurs when Select or Clear start to be called. The sender of the event will be this <see cref="ITextSelection"/>.
+ /// </summary>
+ /// <remarks>
+ /// This event is not raised if the selection shrinks or grows as a result of its associated span expanding or shrinking.
+ /// </remarks>
+ event EventHandler SelectionChanged;
+
+ /// <summary>
+ /// Gets the active point of the selection.
+ /// </summary>
+ /// <remarks><para>This point normally corresponds to the end of the selection that contains to the caret position.</para>
+ /// <para>If the selection is reversed, then this point will come before the AnchorPoint.</para></remarks>
+ VirtualSnapshotPoint ActivePoint { get; }
+
+ /// <summary>
+ /// Gets the anchor point of the selection.
+ /// </summary>
+ /// <remarks><para>This normally corresponds to the end of the selection that does not contain to the caret position.</para>
+ /// <para>If the selection is reversed, then this point will come after the ActivePoint.</para></remarks>
+
+ VirtualSnapshotPoint AnchorPoint { get; }
+
+ /// <summary>
+ /// Gets the start point of the selection.
+ /// </summary>
+ /// <remarks>This is either the active point or the anchor point, whichever comes first.</remarks>
+ VirtualSnapshotPoint Start { get; }
+
+ /// <summary>
+ /// Gets the end point of the selection.
+ /// </summary>
+ /// <remarks>This is either the active point or the anchor point, whichever comes last.</remarks>
+ VirtualSnapshotPoint End { get; }
+
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/ITextView.cs b/src/Text/Def/TextUI/Editor/ITextView.cs
new file mode 100644
index 0000000..f37e20c
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ITextView.cs
@@ -0,0 +1,467 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.VisualStudio.Text;
+ using Microsoft.VisualStudio.Text.Formatting;
+ using Microsoft.VisualStudio.Text.Projection;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Represents a view of text in an <see cref="ITextBuffer"/>. It is the base class for a platform-specific interface
+ /// that has methods to allow the formatted text to be rendered.
+ /// </summary>
+ /// <remarks>
+ /// <para>A text view is a platform-independent representation of a contiguous block of formatted and adorned text,
+ /// accessible through the <see cref="TextViewLines"/> property.
+ /// It also instantiates an instance of an IEditorOperations component part so that
+ /// it can execute various commands.</para>
+ /// <para>The text is formatted based on the classifiers attached to the underlying <see cref="ITextBuffer"/>.</para>
+ /// <para>Most properties and parameters that are doubles correspond to coordinates or distances in the text
+ /// rendering coordinate system. In this coordinate system, x = 0.0 corresponds to the left edge of the drawing
+ /// surface onto which text is rendered (x = view.ViewportLeft corresponds to the left edge of the viewport), and y = view.ViewportTop corresponds to the top edge of the viewport. The x-coordinate increases
+ /// from left to right, and the y-coordinate increases from top to bottom. </para>
+ /// <para>The horizontal and vertical axes of the view behave differently. When the text in the view is
+ /// formatted, only the visible lines are formatted. As a result,
+ /// a viewport cannot be scrolled horizontally and vertically in the same way.</para>
+ /// <para>A viewport is scrolled horizontally by changing the left coordinate of the
+ /// viewport so that it moves with respect to the drawing surface.</para>
+ /// <para>A view can be scrolled vertically only by performing a new layout.</para>
+ /// <para>Doing a layout in the view may cause the ViewportTop property of the view to change. For example, scrolling down one line will not translate any of the visible lines.
+ /// Instead it will simply change the view's ViewportTop property (causing the lines to move on the screen even though their y-coordinates have not changed).</para>
+ /// <para>Distances in the text rendering coordinate system correspond to logical pixels. If the text rendering
+ /// surface is displayed without any scaling transform, then 1 unit in the text rendering coordinate system
+ /// corresponds to one pixel on the display.</para>
+ /// </remarks>
+ public interface ITextView : IPropertyOwner
+ {
+ #region Methods
+ /// <summary>
+ /// Formats and displays the contents of the text buffer so that the <see cref="ITextViewLine"/> containing <paramref name="bufferPosition"/>
+ /// is displayed at the desired position.
+ /// </summary>
+ /// <param name="bufferPosition">
+ /// The position of the character that is to be contained in the <see cref="ITextViewLine"/> displayed at the specified vertical position.
+ /// </param>
+ /// <param name="verticalDistance">
+ /// The distance (in pixels) between the <see cref="ITextViewLine"/> and the edge of the view. If <paramref name="relativeTo"/> is equal to
+ /// <c>ViewRelativePosition.Top</c>, then the distance is from the top of the view to the top of the <see cref="ITextViewLine"/>. Otherwise,
+ /// it is the distance from the bottom of the <see cref="ITextViewLine"/> to the bottom on the view.
+ /// Negative values are allowed, which might cause the line to be displayed outside the viewport.
+ /// This method can become quite expensive if <paramref name="verticalDistance"/> is large. You
+ /// should avoid making <paramref name="verticalDistance"/> greater than the height of the view.
+ /// </param>
+ /// <param name="relativeTo">
+ /// Specifies whether the line offset is relative to the top or bottom of the view.
+ /// </param>
+ /// <returns>
+ /// The vertical distance (from the top or bottom of the view)
+ /// at which the <see cref="ITextViewLine"/> containing the specified position is to be displayed.
+ /// </returns>
+ /// <remarks>
+ /// <para>If word wrap is disabled in the view, then the <see cref="ITextViewLine"/>
+ /// corresponds to the entire <see cref="ITextSnapshotLine"/> that contains <paramref name="bufferPosition"/>.
+ /// If word wrap is enabled in the view, then the <see cref="ITextViewLine"/>
+ /// corresponds to the portion of the <see cref="ITextSnapshotLine"/> that both
+ /// contains <paramref name="bufferPosition"/> and fits into the view. <paramref name="bufferPosition"/> may not be the first
+ /// character in the <see cref="ITextViewLine"/>.</para>
+ /// <para>The returned value will generally be equal to <paramref name="verticalDistance"/>, except in cases where the view
+ /// was repositioned to prevent a gap from appearing at the top or bottom of the view.</para>
+ /// <para>Calling this method will cause the view to dispose of its current <see cref="TextViewLines"/>.</para>
+ /// </remarks>
+ /// <exception cref="ArgumentException"><paramref name="bufferPosition"/> is from the wrong
+ /// <see cref="ITextSnapshot"/> or <see cref="ITextBuffer"/>.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="relativeTo"/> is not a valid <see cref="ViewRelativePosition"/>.</exception>
+ void DisplayTextLineContainingBufferPosition(SnapshotPoint bufferPosition, double verticalDistance, ViewRelativePosition relativeTo);
+
+ /// <summary>
+ /// Formats and displays the contents of the text buffer so that the <see cref="ITextViewLine"/> containing <paramref name="bufferPosition"/>
+ /// is displayed at the desired position.
+ /// </summary>
+ /// <param name="bufferPosition">
+ /// The position of the character that is to be contained in the <see cref="ITextViewLine"/> displayed at the specified vertical position.
+ /// </param>
+ /// <param name="verticalDistance">
+ /// The distance (in pixels) between the <see cref="ITextViewLine"/> and the edge of the view. If <paramref name="relativeTo"/> is equal to
+ /// <c>ViewRelativePosition.Top</c>, then the distance is from the top of the view to the top of the <see cref="ITextViewLine"/>. Otherwise,
+ /// it is the distance from the bottom of the <see cref="ITextViewLine"/> to the bottom on the view.
+ /// Negative values are allowed, which might cause the line to be displayed outside the viewport.
+ /// This method can become quite expensive if <paramref name="verticalDistance"/> is large. You
+ /// should avoid making <paramref name="verticalDistance"/> greater than the height of the view.
+ /// </param>
+ /// <param name="relativeTo">
+ /// Specifies whether the line offset is relative to the top or bottom of the view.
+ /// </param>
+ /// <param name="viewportWidthOverride">
+ /// If specified, the text is formatted as if the viewport had the specified width.
+ /// </param>
+ /// <param name="viewportHeightOverride">
+ /// If specified, the text is formatted as if the viewport had the specified height.
+ /// </param>
+ /// <returns>
+ /// The vertical distance (from the top or bottom of the view)
+ /// at which the <see cref="ITextViewLine"/> containing the specified position is to be displayed.
+ /// </returns>
+ /// <remarks>
+ /// <para>If word wrap is disabled in the view, then the <see cref="ITextViewLine"/>
+ /// corresponds to the entire <see cref="ITextSnapshotLine"/> that contains <paramref name="bufferPosition"/>.
+ /// If word wrap is enabled in the view, then the <see cref="ITextViewLine"/>
+ /// corresponds to the portion of the <see cref="ITextSnapshotLine"/> that both
+ /// contains <paramref name="bufferPosition"/> and fits into the view. <paramref name="bufferPosition"/> may not be the first
+ /// character in the <see cref="ITextViewLine"/>.</para>
+ /// <para>The returned value will generally be equal to <paramref name="verticalDistance"/>, except in cases where the view
+ /// was repositioned to prevent a gap from appearing at the top or bottom of the view.</para>
+ /// <para>Calling this method will cause the view to dispose of its current <see cref="TextViewLines"/>.</para>
+ /// <para>The viewport width override will have no effect unless word wrap is enabled in the view.</para>
+ /// <para>The viewport height and width overrides only change how text is formatted for this call. Subsequent calls will use the
+ /// width and height of the viewport (unless explicitly overriden a second time).</para>
+ /// </remarks>
+ /// <exception cref="ArgumentException"><paramref name="bufferPosition"/> is from the wrong
+ /// <see cref="ITextSnapshot"/> or <see cref="ITextBuffer"/>.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="relativeTo"/> is not a valid <see cref="ViewRelativePosition"/>.</exception>
+ void DisplayTextLineContainingBufferPosition(SnapshotPoint bufferPosition, double verticalDistance, ViewRelativePosition relativeTo,
+ double? viewportWidthOverride, double? viewportHeightOverride);
+
+ /// <summary>
+ /// Gets the <see cref="SnapshotSpan"/> of text that constitutes a text element (a single visual representation)
+ /// at the given <see cref="SnapshotPoint"/>.
+ /// </summary>
+ /// <param name="point">The <see cref="SnapshotPoint"/> in the text snapshot at which to get the text element.</param>
+ /// <returns>A <see cref="SnapshotSpan"/> containing the bounds of the text element.</returns>
+ /// <exception cref="ArgumentException"><paramref name="point"/> is from the wrong
+ /// <see cref="ITextBuffer"/>.</exception>
+ /// <remarks>A text element may be a UTF-16 surrogate pair, consisting of a high
+ /// surrogate character and a low surrogate character. If a point in the text buffer
+ /// lies between a high surrogate character and a low surrogate character, the text element span will
+ /// start at the high surrogate character and end at the low surrogate character.</remarks>
+ SnapshotSpan GetTextElementSpan(SnapshotPoint point);
+
+ /// <summary>
+ /// Closes the text view and its view.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">The text view host is already closed.</exception>
+ void Close();
+
+ /// <summary>
+ /// Requests a refresh of the space reservation stack.
+ /// </summary>
+ /// <remarks>
+ /// Refreshing the space reservation stack involves asking each of the space reservation managers/agents to reposition
+ /// themselves. This method will be called mostly by space reservation agents that wish to reposition their content. The
+ /// space reservation stack is refreshed asynchronously. Calling QueueSpaceReservationStackRefresh will perform a refresh
+ /// of the space reservation stack, but the effects will not be visible immediately on return of the call.
+ /// </remarks>
+ void QueueSpaceReservationStackRefresh();
+
+ #endregion // Methods
+
+ #region Properties
+
+ /// <summary>
+ /// Determines whether the view is in the process of being laid out.
+ /// </summary>
+ /// <remarks>Attempting to get the text view lines of the view while it is being laid out will throw an exception.</remarks>
+ bool InLayout
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets a helper that provides various methods to scroll or manipulate the view.
+ /// </summary>
+ IViewScroller ViewScroller
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets a read-only list of the <see cref="ITextViewLine"/> objects rendered in this view.
+ /// </summary>
+ /// <remarks>
+ /// This list will be dense. That is, all characters between the first character of the first <see cref="ITextViewLine"/> through
+ /// the last character of the last <see cref="ITextViewLine"/> will be represented in one of the <see cref="ITextViewLine"/> objects,
+ /// except when the layout of the <see cref="ITextViewLine"/> objects is in progress.
+ /// <para>
+ /// <see cref="ITextViewLine"/> objects are disjoint. That is, a given character is part of only one <see cref="ITextViewLine"/>.
+ /// </para>
+ /// <para>
+ /// The <see cref="ITextViewLine"/> objects are sorted by the index of their first character.
+ /// </para>
+ /// <para>Some of the <see cref="ITextViewLine"/> objects may not be visible,
+ /// and all <see cref="ITextViewLine"/> objects will be disposed of when the view
+ /// recomputes its layout.</para>
+ /// <para>This property will be null during the view's initialization.</para>
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">View is in the process of being laid out.</exception>
+ ITextViewLineCollection TextViewLines
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="ITextViewLine"/> that contains the specified text buffer position.
+ /// </summary>
+ /// <param name="bufferPosition">
+ /// The text buffer position used to search for a text line.
+ /// </param>
+ /// <returns>
+ /// The <see cref="ITextViewLine"/> that contains the specified buffer position.
+ /// </returns>
+ /// <remarks>
+ /// <para>This method returns an <see cref="ITextViewLine"/> if it exists in the view.</para>
+ /// <para>If the line does not exist in the cache of formatted lines, it will be formatted and added to the cache.</para>
+ /// <para>The returned <see cref="ITextViewLine"/> could be invalidated by either a layout by the view or by subsequent calls to this method.</para>
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferPosition"/> is not a valid buffer position.</exception>
+ /// <exception cref="InvalidOperationException"> if the view has not completed initialization.</exception>
+ ITextViewLine GetTextViewLineContainingBufferPosition(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Gets the caret element.
+ /// </summary>
+ ITextCaret Caret
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the selection element.
+ /// </summary>
+ ITextSelection Selection
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the span of text covered by the provisional text highlight.
+ /// </summary>
+ /// <remarks>
+ /// If there is no provisional text, this method returns null.
+ /// </remarks>
+ ITrackingSpan ProvisionalTextHighlight
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// The roles which this view plays. Roles partially determine the extensions that are instantiated for the view.
+ /// </summary>
+ ITextViewRoleSet Roles
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="ITextBuffer"/> whose text is rendered in this view.
+ /// </summary>
+ ITextBuffer TextBuffer
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="IBufferGraph"/> that contains the set of source buffers that contribute to this view.
+ /// </summary>
+ IBufferGraph BufferGraph
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="ITextSnapshot"/> of the text that is currently rendered in the view.
+ /// </summary>
+ /// <remarks>
+ /// This snapshot will be identical to the CurrentSnapshot of <see cref="TextBuffer"/>, except when handling a
+ /// Changed event on that buffer.
+ /// </remarks>
+ ITextSnapshot TextSnapshot
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="ITextSnapshot"/> of the visual buffer that is being rendered.
+ /// </summary>
+ /// <remarks>
+ /// This snapshot should not be used in any method that requires a position in the text buffer, since
+ /// those positions refer to <see cref="TextSnapshot"/>.
+ /// </remarks>
+ ITextSnapshot VisualSnapshot
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="ITextViewModel"/> of this text view.
+ /// </summary>
+ ITextViewModel TextViewModel
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="ITextDataModel"/> of this text view.
+ /// </summary>
+ ITextDataModel TextDataModel
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the right coordinate of the longest line, whether or not that line is currently visible, in logical pixels.
+ /// </summary>
+ /// <remarks>This value is cached and may not represent the width of the widest line
+ /// in the underlying buffer. For example, if the widest line has never been formatted,
+ /// then it is not in the cache.</remarks>
+ double MaxTextRightCoordinate
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets or sets the position of the left edge of the viewport in the text rendering coordinate system.
+ /// </summary>
+ /// <remarks>
+ /// When set, the horizontal offset is clipped to [0.0, Max(0.0, formatted text width - viewport width)] on non word-wrapped views,
+ /// and [0,0] for views in which word-wrap is enabled.
+ /// </remarks>
+ double ViewportLeft
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets the position of the top edge of the viewport in the text rendering coordinate system.
+ /// </summary>
+ /// <remarks>
+ /// Scrolling the text is done by changing the set of formatted lines and/or the vertical offset of those lines.
+ /// </remarks>
+ double ViewportTop
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the position of the right edge of the viewport in the text rendering coordinate system.
+ /// </summary>
+ double ViewportRight
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the position of the bottom edge of the viewport in the text rendering coordinate system.
+ /// </summary>
+ double ViewportBottom
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the width of the visible content window in logical pixels.
+ /// </summary>
+ double ViewportWidth
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the height of the visible content window in logical pixels.
+ /// </summary>
+ double ViewportHeight
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the nominal height of a line of text in the view.
+ /// </summary>
+ double LineHeight
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Determines whether this text view has been closed.
+ /// </summary>
+ bool IsClosed { get; }
+
+ /// <summary>
+ /// Gets the options for this text view.
+ /// </summary>
+ IEditorOptions Options { get; }
+
+ /// <summary>
+ /// Determines whether the mouse is over the view or any of its adornments.
+ /// </summary>
+ bool IsMouseOverViewOrAdornments { get; }
+
+ /// <summary>
+ /// Determines whether the view or any of its adornments has focus.
+ /// </summary>
+ bool HasAggregateFocus { get; }
+
+ #endregion // Properties
+
+ #region Events
+
+ /// <summary>
+ /// Occurs whenever the text displayed in the view changes.
+ /// </summary>
+ /// <remarks><para>This event is raised whenever the rendered text displayed in the <see cref="ITextView"/> changes.</para>
+ /// <para>It is raised whenever the view does a layout (which happens when DisplayTextLineContainingBufferPosition is called or in response to text or classification changes).</para>
+ /// <para>It ia also raised whenever the view scrolls horizontally or when its size changes.</para></remarks>
+ event EventHandler<TextViewLayoutChangedEventArgs> LayoutChanged;
+
+ /// <summary>
+ /// Occurs when the position of the viewport's left edge is changed. (e.g. when the view is horizontally scrolled)
+ /// </summary>
+ /// <remarks>Deprecated. Use LayoutChanged instead.</remarks>
+ event EventHandler ViewportLeftChanged;
+
+ /// <summary>
+ /// Occurs when the viewport's height is changed.
+ /// </summary>
+ /// <remarks>Deprecated. Use LayoutChanged instead.</remarks>
+ event EventHandler ViewportHeightChanged;
+
+ /// <summary>
+ /// Occurs when the viewport's width is changed.
+ /// </summary>
+ /// <remarks>Deprecated. Use LayoutChanged instead.</remarks>
+ event EventHandler ViewportWidthChanged;
+
+ /// <summary>
+ /// Occurs when the mouse has hovered over the same character.
+ /// </summary>
+ /// <remarks>
+ /// This event is raised only once, unless either the mouse moves or the text in the view changes.
+ /// <para>The delay between the time when the mouse stops moving and the time when the event is raised
+ /// can be changed by adding a <see cref="MouseHoverAttribute"/> to the event handler.
+ /// If no <see cref="MouseHoverAttribute"/> is specified on the event handler, the delay will be 150ms.</para>
+ /// </remarks>
+ event EventHandler<MouseHoverEventArgs> MouseHover;
+
+ /// <summary>
+ /// Occurs immediately after the text view is closed.
+ /// </summary>
+ event EventHandler Closed;
+
+ /// <summary>
+ /// Occurs when the keyboard focus switches away from the view and any of its adornments.
+ /// </summary>
+ /// <remarks>This event will not be raised when keyboard focus transitions from the view to one of its popups.</remarks>
+ event EventHandler LostAggregateFocus;
+
+ /// <summary>Occurs when the keyboard focus switches to the view or one of its adornments.
+ /// </summary>
+ event EventHandler GotAggregateFocus;
+
+ #endregion // Events
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/ITextViewLineCollection.cs b/src/Text/Def/TextUI/Editor/ITextViewLineCollection.cs
new file mode 100644
index 0000000..c6998a3
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ITextViewLineCollection.cs
@@ -0,0 +1,174 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.VisualStudio.Text;
+ using Microsoft.VisualStudio.Text.Formatting;
+ using System.Collections.ObjectModel;
+
+ /// <summary>
+ /// <para>Represents a helper class for accessing the view's collection of <see cref="ITextViewLine"/> objects. The
+ /// TextViewLines property on the <see cref="ITextView"/> is used to get an instance of this interface.</para>
+ /// </summary>
+ /// <remarks>
+ /// <para>The <see cref="ITextView"/> disposes its <see cref="ITextViewLineCollection"/>
+ /// and all the <see cref="ITextViewLine"/> objects it contains every time it generates a new layout.</para>
+ /// <para>Most properties and parameters that are doubles correspond to coordinates or distances in the text
+ /// rendering coordinate system. In this coordinate system, x = 0.0 corresponds to the left edge of the drawing
+ /// surface onto which text is rendered (x = view.ViewportLeft corresponds to the left edge of the viewport), and y = view.ViewportTop corresponds to the top edge of the viewport. The x-coordinate increases
+ /// from left to right, and the y-coordinate increases from top to bottom. </para>
+ /// <para>The horizontal and vertical axes of the view behave differently. When the text in the view is
+ /// formatted, only the visible lines are formatted. As a result,
+ /// a viewport cannot be scrolled horizontally and vertically in the same way.</para>
+ /// <para>A viewport is scrolled horizontally by changing the left coordinate of the
+ /// viewport so that it moves with respect to the drawing surface.</para>
+ /// <para>A view can be scrolled vertically only by performing a new layout.</para>
+ /// <para>Doing a layout in the view may cause the ViewportTop property of the view to change. For example, scrolling down one line will not translate any of the visible lines.
+ /// Instead it will simply change the view's ViewportTop property (causing the lines to move on the screen even though their y-coordinates have not changed).</para>
+ /// <para>Distances in the text rendering coordinate system correspond to logical pixels. If the text rendering
+ /// surface is displayed without any scaling transform, then 1 unit in the text rendering coordinate system
+ /// corresponds to one pixel on the display.</para>
+ /// </remarks>
+ public interface ITextViewLineCollection : IList<ITextViewLine>
+ {
+ /// <summary>
+ /// Determines whether the specified buffer position is contained by any of the <see cref="ITextViewLine"/> objects in the collection.
+ /// </summary>
+ /// <param name="bufferPosition">The buffer position.</param>
+ /// <returns><c>true</c> if <paramref name="bufferPosition"/> is contained by ones of the <see cref="ITextViewLine"/> objects, otherwise <c>false</c>.</returns>
+ /// <remarks>
+ /// This method handles the special processing required for the last line of the buffer.
+ /// </remarks>
+ bool ContainsBufferPosition(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Detrmines whether the specified buffer span intersects any of the <see cref="ITextViewLine"/> objects in the collection.
+ /// </summary>
+ /// <param name="bufferSpan">The buffer span.</param>
+ /// <returns><c>true</c> if <paramref name="bufferSpan"/> is contained by ones of the <see cref="ITextViewLine"/> objects, otherwise <c>false</c>.</returns>
+ /// <remarks>
+ /// This method handles the special processing required for the last line of the buffer.
+ /// </remarks>
+ bool IntersectsBufferSpan(SnapshotSpan bufferSpan);
+
+ /// <summary>
+ /// Gets the <see cref="ITextViewLine"/> that contains the specified text buffer position.
+ /// </summary>
+ /// <param name="bufferPosition">
+ /// The text buffer position used to search for a text line.
+ /// </param>
+ /// <returns>
+ /// An <see cref="ITextViewLine"/> that contains the position, or null if none exists.
+ /// </returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferPosition"/> is not a valid buffer position.</exception>
+ ITextViewLine GetTextViewLineContainingBufferPosition(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Gets the <see cref="ITextViewLine"/> that contains the specified y-coordinate.
+ /// </summary>
+ /// <param name="y">
+ /// The y-coordinate in the text rendering coordinate.
+ /// </param>
+ /// <returns>
+ /// A text line that contains the y-coordinate, or null if none exists.
+ /// </returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="y"/> is NaN.</exception>
+ ITextViewLine GetTextViewLineContainingYCoordinate(double y);
+
+ /// <summary>
+ /// Gets all of the <see cref="ITextViewLine"/> objects that intersect <paramref name="bufferSpan"/>.
+ /// </summary>
+ /// <param name="bufferSpan">The span.</param>
+ /// <returns>A sorted collection of <see cref="ITextViewLine"/> objects that intersect the buffer span.</returns>
+ /// <remarks>
+ /// <para>This will return an empty list if there is no intersection between the
+ /// <see cref="ITextViewLine"/> objects in this collection and <paramref name="bufferSpan"/>.</para>
+ /// <para>This method handles the special processing required for the last line of the buffer.</para>
+ /// </remarks>
+ Collection<ITextViewLine> GetTextViewLinesIntersectingSpan(SnapshotSpan bufferSpan);
+
+ /// <summary>
+ /// Gets the span whose text element span contains the given buffer position.
+ /// </summary>
+ /// <param name="bufferPosition">The buffer position.</param>
+ /// <returns>The <see cref="SnapshotSpan"/> that corresponds to the given text element index.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferPosition"/> does not correspond to a position on this line.</exception>
+ SnapshotSpan GetTextElementSpan(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Gets the text bounds of the specified text buffer position.
+ /// </summary>
+ /// <param name="bufferPosition">
+ /// The text buffer-based index of the character.
+ /// </param>
+ /// <returns>
+ /// A rectangular <see cref="TextBounds"/> structure.
+ /// </returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferPosition"/> does not correspond to a position on this line.</exception>
+ TextBounds GetCharacterBounds(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Gets a collection of <see cref="TextBounds"/> structures for the text that corresponds to the given span.
+ /// </summary>
+ /// <param name="bufferSpan">
+ /// The buffer span representing the text for which to compute the text bounds.
+ /// </param>
+ /// <returns>
+ /// A read-only collection of <see cref="TextBounds"/> structures that contain the text specified in <paramref name="bufferSpan"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// If the line contains bidirectional text, the <see cref="TextBounds"/> objects that are returned may be disjoint.
+ /// </para>
+ /// <para>
+ /// The height and top of the bounds will be the maximum of the height and the minimum of the top of all text
+ /// in the line.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSpan"/> is not a legal span in the underlying text buffer.</exception>
+ Collection<TextBounds> GetNormalizedTextBounds(SnapshotSpan bufferSpan);
+
+ /// <summary>
+ /// Gets the index in the text lines of the given text view line.
+ /// </summary>
+ /// <param name="textLine">The <see cref="ITextViewLine"/> for which to find the index.</param>
+ /// <returns>The index of the <see cref="ITextViewLine"/> in the view's TextLines list.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="textLine"/> is null.</exception>
+ /// <exception cref="ObjectDisposedException"><paramref name="textLine"/> has been disposed.</exception>
+ int GetIndexOfTextLine(ITextViewLine textLine);
+
+ /// <summary>
+ /// Gets the first line that is not completely hidden.
+ /// </summary>
+ ITextViewLine FirstVisibleLine
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the last line that is not completely hidden.
+ /// </summary>
+ ITextViewLine LastVisibleLine
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the span of text contained in this <see cref="ITextViewLine"/> collection.
+ /// </summary>
+ SnapshotSpan FormattedSpan
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Determines whether this <see cref="ITextViewLineCollection"/> object is still valid.
+ /// </summary>
+ /// <remarks>The <see cref="ITextView"/> will always invalidate the <see cref="ITextViewLineCollection"/>
+ /// when performing a layout.</remarks>
+ bool IsValid { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/ITextViewMargin.cs b/src/Text/Def/TextUI/Editor/ITextViewMargin.cs
new file mode 100644
index 0000000..342a605
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ITextViewMargin.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Text;
+
+ /// <summary>
+ /// Represents margins that are attached to an edge of an <see cref="ITextView"/>.
+ /// </summary>
+ public interface ITextViewMargin : IDisposable
+ {
+ /// <summary>
+ /// Gets the size of the margin.
+ /// </summary>
+ /// <remarks>For a horizontal margin this is the height of the margin,
+ /// since the width will be determined by the <see cref="ITextView"/>.
+ /// For a vertical margin this is the width of the margin, since the height will be determined by the <see cref="ITextView"/>.</remarks>
+ /// <exception cref="ObjectDisposedException">The margin is disposed.</exception>
+ double MarginSize { get; }
+
+ /// <summary>
+ /// Determines whether the margin is enabled.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">The margin is disposed.</exception>
+ bool Enabled { get; }
+
+ /// <summary>
+ /// Gets the <see cref="ITextViewMargin"/> with the given <paramref name="marginName"/>.
+ /// </summary>
+ /// <param name="marginName">The name of the <see cref="ITextViewMargin"/>.</param>
+ /// <returns>The <see cref="ITextViewMargin"/> named <paramref name="marginName"/>, or null if no match is found.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="marginName"/> is null.</exception>
+ /// <remarks>A margin returns itself if it is passed its own name. If the name does not match and it is a container margin, it
+ /// forwards the call to its children. Margin name comparisons are case-insensitive.</remarks>
+ ITextViewMargin GetTextViewMargin(string marginName);
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/ITextViewModel.cs b/src/Text/Def/TextUI/Editor/ITextViewModel.cs
new file mode 100644
index 0000000..c709c23
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ITextViewModel.cs
@@ -0,0 +1,84 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Represents a set of zero or more <see cref="ITextBuffer"/> objects that are unique to the presentation of text
+ /// in a particular <see cref="ITextView"/>.
+ /// </summary>
+ public interface ITextViewModel : IPropertyOwner, IDisposable
+ {
+ /// <summary>
+ /// The <see cref="ITextDataModel"/> that supplies the <see cref="DataBuffer"/> and the governing <see cref="IContentType"/> for the view.
+ /// </summary>
+ ITextDataModel DataModel { get; }
+
+ /// <summary>
+ /// Represents the <see cref="ITextBuffer"/> for the data level. The data level text buffer is the highest buffer in the graph that
+ /// is shared across multiple views and is therefore the base of the view model.
+ /// </summary>
+ ITextBuffer DataBuffer { get; }
+
+ /// <summary>
+ /// The <see cref="ITextBuffer"/> in which editing positions are tracked and to which edits are applied.
+ /// All the text that appears in the view must reside in this buffer.
+ /// </summary>
+ /// <remarks>
+ /// This text buffer may be the same as the <see cref="DataBuffer"/>, or it may be a projection buffer
+ /// or elision buffer whose ultimate source is the data buffer.
+ /// </remarks>
+ ITextBuffer EditBuffer { get; }
+
+ /// <summary>
+ /// The <see cref="ITextBuffer"/> whose contents should be presented in the editor.
+ /// </summary>
+ /// <remarks>
+ /// This text buffer may be the same as the <see cref="EditBuffer"/> or it may be a projection buffer
+ /// or elision buffer whose ultimate source is the edit buffer.
+ /// </remarks>
+ ITextBuffer VisualBuffer { get; }
+
+ /// <summary>
+ /// Determines whether a point in the edit buffer is represented in the visual buffer.
+ /// </summary>
+ /// <param name="editBufferPoint">A point in the <see cref="EditBuffer"/>.</param>
+ /// <param name="affinity">
+ /// If the mapping is ambiguous, this parameter affects the mapping as follows:
+ /// if <paramref name="affinity"/> is <see cref="PositionAffinity.Predecessor"/>, the mapping targets
+ /// the position immediately after the preceding character in the projection buffer; if <paramref name="affinity"/> is
+ /// <see cref="PositionAffinity.Successor"/>, the mapping targets the position immediately before the following character
+ /// in the projection buffer. This parameter has no effect if the mapping is unambiguous.</param>
+ /// <returns><c>true</c> if the point is represented in the visual buffer, otherwise <c>false</c>.</returns>
+ /// <remarks>
+ /// A point that is represented in the visual buffer may not be visible on screen, but if the view
+ /// is scrolled to that position, then the point would become visible.
+ /// </remarks>
+ bool IsPointInVisualBuffer(SnapshotPoint editBufferPoint, PositionAffinity affinity);
+
+ /// <summary>
+ /// Gets a point in the <see cref="VisualBuffer"/> that corresponds to the specified point in the edit
+ /// buffer. If the point is hidden or has an alternative representation, gets
+ /// the nearest point to it.
+ /// </summary>
+ /// <remarks>The definition of "nearest" depends on the implementation of the text view model.</remarks>
+ /// <param name="editBufferPoint">A point in the <see cref="EditBuffer"/>.</param>
+ /// <returns>A point in the <see cref="VisualBuffer"/> that corresponds to the given point.</returns>
+ SnapshotPoint GetNearestPointInVisualBuffer(SnapshotPoint editBufferPoint);
+
+ /// <summary>
+ /// Gets a point in the <see cref="VisualBuffer"/> that corresponds to the specified point in the edit
+ /// buffer. If the point is hidden or has an alternative representation, gets
+ /// the nearest point to it.
+ /// </summary>
+ /// <remarks>The definition of "nearest" depends on the implementation of the text view model.</remarks>
+ /// <param name="editBufferPoint">A point in the <see cref="EditBuffer"/>.</param>
+ /// <param name="targetVisualSnapshot">The snapshot of <see cref="VisualBuffer"/> to map to.</param>
+ /// <param name="trackingMode">The <see cref="PointTrackingMode"/> to use when translating to targetVisualSnapshot.</param>
+ /// <returns>A point in the <see cref="VisualBuffer"/> that corresponds to the given point in targetVisualSnapshot.</returns>
+ SnapshotPoint GetNearestPointInVisualSnapshot(SnapshotPoint editBufferPoint, ITextSnapshot targetVisualSnapshot, PointTrackingMode trackingMode);
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/ITextViewModelProvider.cs b/src/Text/Def/TextUI/Editor/ITextViewModelProvider.cs
new file mode 100644
index 0000000..c779e58
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ITextViewModelProvider.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Provides <see cref="ITextViewModel"/> objects.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be exported with the following attribute:
+ /// [Export(NameSource=typeof(ITextViewModelProvider))]
+ /// Component exporters must specify at least one ContentTypeAttribute characterizing the data
+ /// models to which they apply and at least one TextViewRoleAttribute characterizing the views to which they apply.
+ /// </remarks>
+ public interface ITextViewModelProvider
+ {
+ /// <summary>
+ /// Creates an <see cref="ITextViewModel"/> for the given <see cref="ITextDataModel"/>.
+ /// </summary>
+ /// <param name="dataModel">The <see cref="ITextDataModel"/> for which to create the <see cref="ITextViewModel"/>.</param>
+ /// <param name="roles">The <see cref="ITextViewRoleSet"/> for the view that is about to be created.</param>
+ /// <returns>The <see cref="ITextViewModel"/> created for <paramref name="dataModel"/>,
+ /// or <c>null</c> if the text view model cannot be created.</returns>
+ ITextViewModel CreateTextViewModel(ITextDataModel dataModel, ITextViewRoleSet roles);
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/ITextViewRoleSet.cs b/src/Text/Def/TextUI/Editor/ITextViewRoleSet.cs
new file mode 100644
index 0000000..71259a0
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ITextViewRoleSet.cs
@@ -0,0 +1,49 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Set of text view roles.
+ /// </summary>
+ public interface ITextViewRoleSet : IEnumerable<string>
+ {
+ /// <summary>
+ /// Compute whether the given text view role is a member of the set.
+ /// </summary>
+ /// <exception cref="ArgumentNullException"><paramref name="textViewRole"/> is null.</exception>
+ bool Contains(string textViewRole);
+
+ /// <summary>
+ /// Compute whether the set contains all of the given text view roles.
+ /// </summary>
+ /// <exception cref="ArgumentNullException"> if <paramref name="textViewRoles"/> is null.</exception>
+ /// <param name="textViewRoles">The list of roles to check for inclusion.</param>
+ /// <remarks>
+ /// Returns <b>true</b> if <paramref name="textViewRoles"/> contains no roles. Null values
+ /// in <paramref name="textViewRoles"/> are ignored.
+ /// </remarks>
+ bool ContainsAll(IEnumerable<string> textViewRoles);
+
+ /// <summary>
+ /// Compute whether the set contains at least one of the given text view roles.
+ /// </summary>
+ /// <param name="textViewRoles">The list of roles to check for inclusion.</param>
+ /// <exception cref="ArgumentNullException"> if <paramref name="textViewRoles"/> is null.</exception>
+ /// <remarks>
+ /// Returns <b>false</b> if <paramref name="textViewRoles"/> contains no roles. Null values
+ /// in <paramref name="textViewRoles"/> are ignored.
+ /// </remarks>
+ bool ContainsAny(IEnumerable<string> textViewRoles);
+
+ /// <summary>
+ /// Compute the union of the set and another text view role set.
+ /// </summary>
+ /// <param name="roleSet"></param>
+ /// <exception cref="ArgumentNullException"> if <paramref name="roleSet"/> is null.</exception>
+ ITextViewRoleSet UnionWith(ITextViewRoleSet roleSet);
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/IVerticalFractionMap.cs b/src/Text/Def/TextUI/Editor/IVerticalFractionMap.cs
new file mode 100644
index 0000000..2472637
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/IVerticalFractionMap.cs
@@ -0,0 +1,53 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using Microsoft.VisualStudio.Text;
+
+ /// <summary>
+ /// <para>Maps between character positions and fractions of the total vertical extent of an <see cref="ITextView"/>.</para>
+ /// </summary>
+ /// <remarks>
+ /// <para>Valid text positions range are [0...TextView.TextSnapshot.Length].
+ /// Valid scrollbar coordinates are [0.0 ... 1.0].
+ /// 0.0 corresponds to the top of the first line in the text view; 1.0 corresponds to the bottom of the last line in the view.
+ /// Not every text position will have a unique value. For example, every character on
+ /// the same text buffer line will have the same value, assuming that word wrap is not enabled.</para>
+ /// <para>This interface is the base type of the <see cref="IScrollMap"/> interface,
+ /// which is created using the <see cref="IScrollMapFactoryService"/>.</para>
+ /// </remarks>
+ public interface IVerticalFractionMap
+ {
+ /// <summary>
+ /// Gets the text view to which this fraction map applies.
+ /// </summary>
+ ITextView TextView { get; }
+
+ /// <summary>
+ /// Gets the fraction of the vertical extent of the view that corresponds to the specified buffer position.
+ /// </summary>
+ /// <param name="bufferPosition">The buffer position.</param>
+ /// <returns>The corresponding fraction of the vertical extent of the view.</returns>
+ double GetFractionAtBufferPosition(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Gets the buffer position that corresponds to a fraction of the vertical extent of the view,
+ /// if it exists.
+ /// </summary>
+ /// <param name="fraction">The fraction of the vertical extent of the view.</param>
+ /// <returns>The corresponding character position.</returns>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="fraction"/> is NaN, less than 0.0 or greater than 1.0.</exception>
+ /// <remarks>Different buffer positions can have the same fractions. This method is guaranteed only to be consistent: it will
+ /// return the same position for the same fraction. The exact character returned depends on the implementation of the fraction map.
+ /// It will, generally, be the first character on the line, but this is not guaranteed.</remarks>
+ SnapshotPoint GetBufferPositionAtFraction(double fraction);
+
+ /// <summary>
+ /// Occurs when the mapping between character position and its vertical fraction has changed.
+ /// For example, the view may have re-rendered some lines, changing their font size.
+ /// </summary>
+ event EventHandler MappingChanged;
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/IVerticalScrollBar.cs b/src/Text/Def/TextUI/Editor/IVerticalScrollBar.cs
new file mode 100644
index 0000000..0933f6f
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/IVerticalScrollBar.cs
@@ -0,0 +1,77 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using Microsoft.VisualStudio.Text;
+
+ /// <summary>
+ /// Represents a vertical scroll bar.
+ /// </summary>
+ public interface IVerticalScrollBar
+ {
+ /// <summary>
+ /// Gets the mapping between the text position and the scrollbar coordinate for the scrollbar.
+ /// </summary>
+ IScrollMap Map { get; }
+
+ /// <summary>
+ /// Gets the y-coordinate in the scrollbar track that corresponds to a buffer position.
+ /// </summary>
+ /// <param name="bufferPosition">Desired position.</param>
+ /// <returns>Corresponding y-coordinate.</returns>
+ double GetYCoordinateOfBufferPosition(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Gets the y-coordinate in the scrollbar track that corresponds to a position in scroll map coordinates.
+ /// </summary>
+ /// <param name="scrollMapPosition">Desired position.</param>
+ /// <returns>Corresponding y-coordinate.</returns>
+ double GetYCoordinateOfScrollMapPosition(double scrollMapPosition);
+
+ /// <summary>
+ /// Gets the buffer position that corresponds to a y-coordinate in the scrollbar track.
+ /// </summary>
+ /// <param name="y">Desired y-coordinate.</param>
+ /// <returns>A position in the buffer, even if <paramref name="y"/> is below or above the mapped range of coordinates.</returns>
+ SnapshotPoint GetBufferPositionOfYCoordinate(double y);
+
+ /// <summary>
+ /// Gets the height of the scrollbar thumb in pixels.
+ /// </summary>
+ /// <remarks>
+ /// The last buffer position maps to the bottom of the scrollbar track minus the thumb height.
+ /// </remarks>
+ double ThumbHeight { get; }
+
+ /// <summary>
+ /// Gets the y-coordinate of the top of the scrollbar track as it is rendered in the display (excluding the scroll buttons
+ /// at the top and bottom).
+ /// </summary>
+ /// <remarks>
+ /// <para>If mapping from scrollbar coordinates to positions in the scrollbar's track, the correct mapping is:</para>
+ /// <para>pixel position = (scrollbar coordinate * TrackSpanHeight / (Map.Maximum + Map.ViewportSize)) + TrackSpanTop</para>
+ /// <para>scrollbar coordinate = (pixel position - TrackSpanTop) * (Map.Maximum + Map.ViewportSize) / TrackSpanHeight</para>
+ /// </remarks>
+ double TrackSpanTop { get; }
+
+ /// <summary>
+ /// Gets the y-coordinate of the bottom of the scrollbar track as it is rendered in the display (excluding the scroll buttons
+ /// at the top and bottom).
+ /// </summary>
+ double TrackSpanBottom { get; }
+
+ /// <summary>
+ /// Gets the height of the scrollbar track as it is rendered in the display (excluding the scroll buttons
+ /// at the top and bottom).
+ /// </summary>
+ double TrackSpanHeight { get; }
+
+ /// <summary>
+ /// Occurs when the span of the scrollbar track dimensions is changed. For example, they could change as a result of resizing
+ /// the view.
+ /// </summary>
+ event EventHandler TrackSpanChanged;
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/IViewScroller.cs b/src/Text/Def/TextUI/Editor/IViewScroller.cs
new file mode 100644
index 0000000..6fda405
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/IViewScroller.cs
@@ -0,0 +1,176 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using System.Collections.Generic;
+
+ using Microsoft.VisualStudio.Text;
+
+ /// <summary>
+ /// Represents a helper class for the <see cref="ITextView"/>, and provides basic functionality for scrolling. The
+ /// <see cref="ITextView.ViewScroller"/> property of <see cref="ITextView"/> is used to get an instance of the this
+ /// interface.
+ /// </summary>
+ /// <remarks>
+ /// <para>Most properties and parameters that are doubles correspond to coordinates or distances in the text
+ /// rendering coordinate system. In this coordinate system, x = 0.0 corresponds to the left edge of the drawing
+ /// surface onto which text is rendered (x = view.ViewportLeft corresponds to the left edge of the viewport), and y = view.ViewportTop corresponds to the top edge of the viewport. The x-coordinate increases
+ /// from left to right, and the y-coordinate increases from top to bottom. </para>
+ /// <para>The horizontal and vertical axes of the view behave differently. When the text in the view is
+ /// formatted, only the visible lines are formatted. As a result,
+ /// a viewport cannot be scrolled horizontally and vertically in the same way.</para>
+ /// <para>A viewport is scrolled horizontally by changing the left coordinate of the
+ /// viewport so that it moves with respect to the drawing surface.</para>
+ /// <para>A view can be scrolled vertically only by performing a new layout.</para>
+ /// <para>Doing a layout in the view may cause the ViewportTop property of the view to change. For example, scrolling down one line will not translate any of the visible lines.
+ /// Instead it will simply change the view's ViewportTop property (causing the lines to move on the screen even though their y-coordinates have not changed).</para>
+ /// <para>Distances in the text rendering coordinate system correspond to logical pixels. If the text rendering
+ /// surface is displayed without any scaling transform, then 1 unit in the text rendering coordinate system
+ /// corresponds to one pixel on the display.</para>
+ /// </remarks>
+ public interface IViewScroller
+ {
+ /// <summary>
+ /// Scrolls the viewport vertically by <paramref name="distanceToScroll"/>.
+ /// </summary>
+ /// <param name="distanceToScroll">
+ /// The distance to scroll in the text rendering coordinate system. Positive values scroll the viewport
+ /// up, and negative values scroll the viewport down.
+ /// </param>
+ /// <remarks>
+ /// <para>This can be very slow for large numbers of pixels. You should avoid
+ /// using this method to scroll more than the height of the viewport in either direction.</para>
+ /// <para>The viewport always contains at least one visible line along its top edge, and the distance
+ /// scrolled will be clipped to ensure that this always remains true.</para>
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="distanceToScroll"/> is NaN.</exception>
+ void ScrollViewportVerticallyByPixels(double distanceToScroll);
+
+ /// <summary>
+ /// Scrolls the viewport vertically one line up or down.
+ /// </summary>
+ /// <param name="direction">
+ /// The direction in which to scroll.
+ /// </param>
+ /// <remarks>
+ /// <para>The viewport always contains at least one visible line along its top edge, and the distance
+ /// scrolled is clipped to ensure that this always remains true.</para>
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="direction"/> is not a <see cref="ScrollDirection"/>.</exception>
+ void ScrollViewportVerticallyByLine(ScrollDirection direction);
+
+ /// <summary>
+ /// Scrolls the viewport vertically by multiple lines up or down.
+ /// </summary>
+ /// <param name="direction">
+ /// The direction in which to scroll.
+ /// </param>
+ /// <param name="count">
+ /// The number of lines to scroll up or down.
+ /// </param>
+ /// <remarks>
+ /// <para>The viewport always contains at least one visible line along its top edge, and the distance
+ /// scrolled is clipped to ensure that this always remains true.</para>
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="direction"/> is not a <see cref="ScrollDirection"/>.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is negative.</exception>
+ void ScrollViewportVerticallyByLines(ScrollDirection direction, int count);
+
+ /// <summary>
+ /// Scrolls the viewport vertically one page up or down.
+ /// </summary>
+ /// <param name="direction">
+ /// The direction in which to scroll.
+ /// </param>
+ /// <returns><c>true</c> if the view contains one or more fully visible lines prior to scrolling, otherwise <c>false</c>.</returns>
+ /// <remarks>
+ /// <para>When paging down, this method scrolls the view so that the line below the last fully-visible line
+ /// is even with the top of the view. When paging up, this method scrolls the view so that the line
+ /// above the first fully visible line is even with or slightly above the bottom of the view.
+ /// It may be shifted up to prevent a partially-visible line at the top of the view.
+ /// If there are no fully-visible lines in the view because the view is too short,
+ /// the view is scrolled by exactly the viewport height.</para>
+ /// <para>The view cannot be scrolled so that there is a gap between the top of the view and the first line of text.</para>
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="direction"/> is not a <see cref="ScrollDirection"/>.</exception>
+ bool ScrollViewportVerticallyByPage(ScrollDirection direction);
+
+ /// <summary>
+ /// Scrolls the viewport horizontally by <paramref name="distanceToScroll"/>.
+ /// </summary>
+ /// <param name="distanceToScroll">
+ /// The distance to scroll the viewport in the text rendering coordinate system. Positive values
+ /// scroll the viewport to the right, and negative values scroll the viewport to the left.
+ /// </param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="distanceToScroll"/> is NaN.</exception>
+ /// <remarks>
+ /// A view cannot be scrolled horizontally if word wrap is enabled.
+ /// If word wrap is disabled, the horizontal offset of the view must be between [0.0, max(0.0, formatted content width - viewport width)].
+ /// </remarks>
+ void ScrollViewportHorizontallyByPixels(double distanceToScroll);
+
+ /// <summary>
+ /// Ensures that all the text in <paramref name="span"/> is entirely visible in the view.
+ /// </summary>
+ /// <param name="span">The span to make visible.</param>
+ /// <remarks>
+ /// This is equivalent to scroller.EnsureSpanVisible(span, EnsureSpanVisibleOptions.None);
+ /// </remarks>
+ void EnsureSpanVisible(SnapshotSpan span);
+
+ /// <summary>
+ /// Ensures that all the text in <paramref name="span"/> is entirely visible in the view.
+ /// </summary>
+ /// <param name="span">The span to make visible.</param>
+ /// <param name="options">The <see cref="EnsureSpanVisibleOptions"/>.</param>
+ /// <remarks>
+ /// The view will not be scrolled if the text in <paramref name="span"/> is completely visible. If the text in <paramref name="span"/> is partially visible,
+ /// then the view will be scrolled as little as possible to make the text completely visible.
+ /// If none of the text in <paramref name="span"/> was visible, then it will be centered in the view.
+ /// </remarks>
+ void EnsureSpanVisible(SnapshotSpan span, EnsureSpanVisibleOptions options);
+
+ /// <summary>
+ /// Ensures that all the text in <paramref name="span"/> is entirely visible in the view.
+ /// </summary>
+ /// <param name="span">The span to make visible.</param>
+ /// <param name="options">The <see cref="EnsureSpanVisibleOptions"/>.</param>
+ /// <remarks>
+ /// The view will not be scrolled if the text in <paramref name="span"/> is completely visible. If the text in <paramref name="span"/> is partially visible,
+ /// then the view will be scrolled as little as possible to make the text completely visible.
+ /// If none of the text in <paramref name="span"/> was visible, then it will be centered in the view.
+ /// </remarks>
+ void EnsureSpanVisible(VirtualSnapshotSpan span, EnsureSpanVisibleOptions options);
+ }
+
+ /// <summary>
+ /// Options to control the behavior of <see cref="IViewScroller"/> EnsureSpanVisible.
+ /// </summary>
+ [System.Flags]
+ public enum EnsureSpanVisibleOptions
+ {
+
+ /// <summary>
+ /// Ensure that the start of the span is visible if it is impossible to display the entire span.
+ /// </summary>
+ ShowStart = 0x01,
+
+ /// <summary>
+ /// Do the minimum amount of scrolling to display the span in the view.
+ /// </summary>
+ MinimumScroll = 0x02,
+
+ /// <summary>
+ /// Always center the span in the view.
+ /// </summary>
+ AlwaysCenter = 0x04,
+
+ /// <summary>
+ /// Ensure that the end of the span is visible if it is impossible to display the entire span. If none of the text
+ /// in the span is currently visible, center the span in the view.
+ /// </summary>
+ None = 0x00
+ };
+}
diff --git a/src/Text/Def/TextUI/Editor/MarginContainerAttribute.cs b/src/Text/Def/TextUI/Editor/MarginContainerAttribute.cs
new file mode 100644
index 0000000..5f7aa7a
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/MarginContainerAttribute.cs
@@ -0,0 +1,46 @@
+// ****************************************************************************
+// Copyright (C) Microsoft Corporation. All Rights Reserved.
+// ****************************************************************************
+using System;
+using System.ComponentModel.Composition;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Specifies the type of margin container.
+ /// </summary>
+ [MetadataAttribute]
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Field, AllowMultiple = false)]
+ public sealed class MarginContainerAttribute : SingletonBaseMetadataAttribute
+ {
+ private readonly string marginContainer;
+
+ /// <summary>
+ /// Instantiates a new instance of a <see cref="MarginContainerAttribute"/>.
+ /// </summary>
+ /// <param name="marginContainer">The name of the container for this margin.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="marginContainer"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="marginContainer"/> is an empty string.</exception>
+ public MarginContainerAttribute(string marginContainer)
+ {
+ if (marginContainer == null)
+ throw new ArgumentNullException("marginContainer");
+ if (marginContainer.Length == 0)
+ throw new ArgumentException("marginContainer is an empty string.");
+
+ this.marginContainer = marginContainer;
+ }
+
+ /// <summary>
+ /// The name of the margin container.
+ /// </summary>
+ public string MarginContainer
+ {
+ get
+ {
+ return this.marginContainer;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Editor/MouseHoverAttribute.cs b/src/Text/Def/TextUI/Editor/MouseHoverAttribute.cs
new file mode 100644
index 0000000..408d4af
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/MouseHoverAttribute.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// An attribute to be placed on an event handler for <see cref="ITextView.MouseHover"/>,
+ /// specifying the delay between the time when the mouse stops moving
+ /// and the generation of the hover event.
+ /// </summary>
+ /// <remarks>The default, if no MouseHoverAttribute is specified, is 150ms.</remarks>
+ [global::System.AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
+ public sealed class MouseHoverAttribute : Attribute
+ {
+ #region Private Members
+ private readonly int _delay;
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="MouseHoverAttribute"/>.
+ /// </summary>
+ /// <param name="delay">The time in milliseconds between the time when the mouse stops moving and the generation of the hover event.</param>
+ public MouseHoverAttribute(int delay)
+ {
+ _delay = delay;
+ }
+
+ /// <summary>
+ /// Gets the time in milliseconds between the time when the mouse stops moving and the generation of the hover event.
+ /// </summary>
+ public int Delay
+ {
+ get
+ {
+ return _delay;
+ }
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/MouseHoverEventArgs.cs b/src/Text/Def/TextUI/Editor/MouseHoverEventArgs.cs
new file mode 100644
index 0000000..16202bc
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/MouseHoverEventArgs.cs
@@ -0,0 +1,78 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+#pragma warning disable 1634, 1691
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using Microsoft.VisualStudio.Text;
+
+ /// <summary>
+ /// Provides information for a MouseHover event of <see cref="ITextView"/>.
+ /// </summary>
+ public class MouseHoverEventArgs : EventArgs
+ {
+ #region Private Members
+
+ ITextView _view;
+ int _position;
+ IMappingPoint _textPosition;
+
+ #endregion // Private Members
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="MouseHoverEventArgs"/>.
+ /// </summary>
+ /// <param name="view">The view in which the hover event is being generated.</param>
+ /// <param name="position">The position of the character under the mouse in the snapshot span of the view.</param>
+ /// <param name="textPosition">The position mapped to the buffer graph of the character under the mouse.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="view"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is negative or greater than the length of the view's buffer.</exception>
+ public MouseHoverEventArgs(ITextView view, int position, IMappingPoint textPosition)
+ {
+ if (view == null)
+ throw new ArgumentNullException("view");
+#pragma warning suppress 56506 // ToDo: Add a comment on why it is not necessary to check view.TextSnapshot
+ if ((position < 0) || (position > view.TextSnapshot.Length)) // Allow positions at the end of the file
+ throw new ArgumentOutOfRangeException("position");
+ if (textPosition == null)
+ throw new ArgumentNullException("textPosition");
+ // we could be very paranoid and check:
+ //if (textPosition.AnchorBuffer != view.TextBuffer)
+ // throw new ArgumentException();
+
+ _view = view;
+ _position = position;
+ _textPosition = textPosition;
+ }
+
+ #region Exposed Properties
+
+ /// <summary>
+ /// The view for which the hover event is being generated.
+ /// </summary>
+ public ITextView View
+ {
+ get { return _view; }
+ }
+
+ /// <summary>
+ /// The position in the SnapshotSpan of the character under the mouse at the time of the hover.
+ /// </summary>
+ public int Position
+ {
+ get { return _position; }
+ }
+
+ /// <summary>
+ /// The position mapped to the buffer graph of the character under the mouse at the time of the hover.
+ /// </summary>
+ public IMappingPoint TextPosition
+ {
+ get { return _textPosition; }
+ }
+
+ #endregion // Exposed Properties
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/PredefinedMarginNames.cs b/src/Text/Def/TextUI/Editor/PredefinedMarginNames.cs
new file mode 100644
index 0000000..18e9229
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/PredefinedMarginNames.cs
@@ -0,0 +1,137 @@
+// Copyright (C) Microsoft Corporation. All Rights Reserved.
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Specifies the names of the pre-defined margins supplied by Visual Studio.
+ /// </summary>
+ public static class PredefinedMarginNames
+ {
+ /// <summary>
+ /// The margin to the left of the text view.
+ /// </summary>
+ public const string Left = "Left";
+
+ /// <summary>
+ /// The margin to the right of the text view.
+ /// </summary>
+ public const string Right = "Right";
+
+ /// <summary>
+ /// The margin above the text view.
+ /// </summary>
+ public const string Top = "Top";
+
+ /// <summary>
+ /// The margin below the text view.
+ /// </summary>
+ public const string Bottom = "Bottom";
+
+ /// <summary>
+ /// The margin to the left of the text view that implements mouse handlers for line selection.
+ /// This behavior is inherited by margins contained in the left selection margin.
+ /// </summary>
+ public const string LeftSelection = "LeftSelection";
+
+ /// <summary>
+ /// The margin to the left of the text view that allows collapsing and expansion of outlining regions.
+ /// </summary>
+ public const string Outlining = "Outlining";
+
+ /// <summary>
+ /// The margin to the left of the text view that shows line numbers.
+ /// </summary>
+ public const string LineNumber = "LineNumber";
+
+ /// <summary>
+ /// The standard horizontal scrollbar.
+ /// </summary>
+ public const string HorizontalScrollBar = "HorizontalScrollBar";
+
+ /// <summary>
+ /// The container margin that contains the <see cref="HorizontalScrollBar"/> by default.
+ /// </summary>
+ /// <remarks>
+ /// Other margins can be placed to the left or right of the <see cref="HorizontalScrollBar"/> depending on their order attribute.
+ /// </remarks>
+ public const string HorizontalScrollBarContainer = "HorizontalScrollBarContainer";
+
+ /// <summary>
+ /// The standard vertical scrollbar.
+ /// </summary>
+ public const string VerticalScrollBar = "VerticalScrollBar";
+
+ /// <summary>
+ /// The container margin that contains the <see cref="VerticalScrollBar"/> by default.
+ /// </summary>
+ /// <remarks>
+ /// Other margins can be placed above or below the <see cref="VerticalScrollBar"/> depending on their order attribute.
+ /// </remarks>
+ public const string VerticalScrollBarContainer = "VerticalScrollBarContainer";
+
+ /// <summary>
+ /// A vertical margin container in the <see cref="Right"/> margin that contains the <see cref="VerticalScrollBarContainer"/>.
+ /// </summary>
+ /// <remarks>
+ /// Margins that wish to appear on top or bottom of the vertical scrollbar and all its siblings should be added
+ /// to this container margin.
+ /// </remarks>
+ public const string RightControl = "RightControl";
+
+ /// <summary>
+ /// A horizontal margin container in the <see cref="Bottom"/> margin that contains the <see cref="HorizontalScrollBarContainer"/>.
+ /// </summary>
+ /// <remarks>
+ /// Margins that wish to appear to the left or right of the horizontal scrollbar and all its siblings should be added to
+ /// this container margin.
+ /// </remarks>
+ public const string BottomControl = "BottomControl";
+
+ /// <summary>
+ /// The margin that appears between the line number and outlining margins and shows which text
+ /// has changed in the current session.
+ /// </summary>
+ public const string Spacer = "Spacer";
+
+ /// <summary>
+ /// The margin to the left of the text view that shows breakpoint and other glyphs.
+ /// </summary>
+ public const string Glyph = "Glyph";
+
+ /// <summary>
+ /// The margin to the left of the text view that shows suggestion glyphs such as the Light Bulb.
+ /// </summary>
+ public const string Suggestion = "Suggestion";
+
+ /// <summary>
+ /// The margin to the left of the horizontal scroll bar that hosts a zoom control for zooming the view.
+ /// </summary>
+ public const string ZoomControl = "ZoomControl";
+
+ /// <summary>
+ /// The margin to the right of the "Bottom" margin and below the "Right" margin.
+ /// </summary>
+ public const string BottomRightCorner = "BottomRightCorner";
+
+ /// <summary>
+ /// Name of the margin that shows changes in the entire file.
+ /// </summary>
+ public const string OverviewChangeTracking = "OverviewChangeTrackingMargin";
+
+ /// <summary>
+ /// Name of the margin that shows marks in the entire file.
+ /// </summary>
+ public const string OverviewMark = "OverviewMarkMargin";
+
+ /// <summary>
+ /// Name of the margin that shows errors in the entire file.
+ /// </summary>
+ public const string OverviewError = "OverviewErrorMargin";
+
+ /// <summary>
+ /// Name of the margin that shows a zoomed-out image of the entire file.
+ /// </summary>
+ public const string OverviewSourceImage = "OverviewSourceImageMargin";
+
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/PredefinedTextViewRoles.cs b/src/Text/Def/TextUI/Editor/PredefinedTextViewRoles.cs
new file mode 100644
index 0000000..ceb2609
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/PredefinedTextViewRoles.cs
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Specifies the names of the pre-defined text view roles supplied by Visual Studio.
+ /// </summary>
+ public static class PredefinedTextViewRoles
+ {
+ // The following are the default text view roles.
+
+ /// <summary>
+ /// The predefined Document role. Applies to text views of entities, typically stored in files, that have
+ /// a definite first line and last line. This excludes entities such as output logs or textual displays of
+ /// data that are presented in a form.
+ /// </summary>
+ public const string Document = "DOCUMENT";
+
+ /// <summary>
+ /// The predefined Structured role. Applies to text views of entities that have internal structure that should
+ /// be exposed by editor facilities such as Outlining.
+ /// </summary>
+ public const string Structured = "STRUCTURED";
+
+ /// <summary>
+ /// The predefined Interactive role. Applies to text views with which the user can interact using the mouse and/or
+ /// keyboard. Views that are not interactive cannot display a caret or a selection and cannot have keyboard input.
+ /// </summary>
+ public const string Interactive = "INTERACTIVE";
+
+ /// <summary>
+ /// The predefined Editable role. Applies to text views that can be changed using the keyboard.
+ /// </summary>
+ public const string Editable = "EDITABLE";
+
+ /// <summary>
+ /// The predefined Analyzable role. Applies to text views of entities that can be analyzed for errors or
+ /// other information (such as "quick info").
+ /// </summary>
+ public const string Analyzable = "ANALYZABLE";
+
+ /// <summary>
+ /// The predefined Zoomable role. Applies to text views of entities that allow the user to perform zooming operations.
+ /// </summary>
+ public const string Zoomable = "ZOOMABLE";
+
+
+ // These are the non-default text view roles.
+
+ /// <summary>
+ /// The predefined Primary Document role. Applies to text views of documents that are open for mainline editing,
+ /// excluding auxiliary views of documents.
+ /// </summary>
+ public const string PrimaryDocument = "PRIMARYDOCUMENT";
+
+ /// <summary>
+ /// The predefined Debuggable role. Applies to text views of entities in which the debugger can display information
+ /// at runtime.
+ /// </summary>
+ public const string Debuggable = "DEBUGGABLE";
+
+ /// <summary>
+ /// The predefined role used for the preview window created by the enhanced scroll bar.
+ /// </summary>
+ public const string PreviewTextView = "ENHANCED_SCROLLBAR_PREVIEW";
+
+ /// <summary>
+ /// The predefined role used for text views embedded within a containing text view.
+ /// </summary>
+ public const string EmbeddedPeekTextView = "EMBEDDED_PEEK_TEXT_VIEW";
+
+ /// <summary>
+ /// The predefined role used for code definition windows.
+ /// </summary>
+ public const string CodeDefinitionView = "CODEDEFINITION";
+
+ /// <summary>
+ /// The predefined role used for printable views.
+ /// </summary>
+ public const string Printable = "PRINTABLE";
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Editor/ReplacesAttribute.cs b/src/Text/Def/TextUI/Editor/ReplacesAttribute.cs
new file mode 100644
index 0000000..233c00d
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ReplacesAttribute.cs
@@ -0,0 +1,50 @@
+// ****************************************************************************
+// Copyright (C) Microsoft Corporation. All Rights Reserved.
+// ****************************************************************************
+using System;
+using System.ComponentModel.Composition;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Specifies the name(s) of an asset that will be replaced by this asset.
+ /// </summary>
+ /// <remarks>
+ /// <para>You can specify multiple Replaces attributes if you want to replace multiple assets.</para>
+ /// <para>An asset must have a different Name attribute than its Replaces attribute (otherwise it would "replace" itself, preventing it from being created).</para>
+ /// <para>An asset is not created if its Name attribute matches the Replaces attribute of any other asset that would -- excluding this check -- be created. For
+ /// margin providers, the means that a provider must match the view's ContentType and TextViewRole before it can replace another provider.</para>
+ /// </remarks>
+ public sealed class ReplacesAttribute : MultipleBaseMetadataAttribute
+ {
+ private readonly string replaces;
+
+ /// <summary>
+ /// The name of the asset replaced by this asset.
+ /// </summary>
+ /// <param name="replaces">The name of the replaced asset.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="replaces"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="replaces"/> is an empty string.</exception>
+ public ReplacesAttribute(string replaces)
+ {
+ if (replaces == null)
+ throw new ArgumentNullException("replaces");
+ if (replaces.Length == 0)
+ throw new ArgumentException("replaces is an empty string.");
+
+ this.replaces = replaces;
+ }
+
+ /// <summary>
+ /// The name of the replaced margin.
+ /// </summary>
+ public string Replaces
+ {
+ get
+ {
+ return this.replaces;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Editor/ScrollDirection.cs b/src/Text/Def/TextUI/Editor/ScrollDirection.cs
new file mode 100644
index 0000000..348be95
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ScrollDirection.cs
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// The direction in which to scroll the <see cref="ITextView"/>.
+ /// </summary>
+ public enum ScrollDirection
+ {
+ /// <summary>
+ /// Scroll up.
+ /// </summary>
+ Up,
+
+ /// <summary>
+ /// Scroll down.
+ /// </summary>
+ Down
+ };
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Editor/TextSelectionMode.cs b/src/Text/Def/TextUI/Editor/TextSelectionMode.cs
new file mode 100644
index 0000000..4d759a9
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/TextSelectionMode.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Specifies the text selection mode.
+ /// </summary>
+ public enum TextSelectionMode
+ {
+ /// <summary>
+ /// A simple selection (only one span)
+ /// </summary>
+ Stream,
+ /// <summary>
+ /// A box selection (from a start line and column to an end line and column).
+ /// </summary>
+ Box
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/TextViewCreatedEventArgs.cs b/src/Text/Def/TextUI/Editor/TextViewCreatedEventArgs.cs
new file mode 100644
index 0000000..5cd5596
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/TextViewCreatedEventArgs.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+
+ /// <summary>
+ /// Provides information for newly created <see cref="ITextView"/>.
+ /// </summary>
+ public class TextViewCreatedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// The newly created <see cref="ITextView"/>.
+ /// </summary>
+ public ITextView TextView { get; private set; }
+
+ /// <summary>
+ /// Constructs a <see cref="TextViewCreatedEventArgs"/>.
+ /// </summary>
+ /// <param name="textView">The <see cref="ITextView"/> that was created.</param>
+ public TextViewCreatedEventArgs(ITextView textView)
+ {
+ if (textView == null)
+ {
+ throw new ArgumentNullException("textView");
+ }
+ TextView = textView;
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/TextViewLayoutChangedEventArgs.cs b/src/Text/Def/TextUI/Editor/TextViewLayoutChangedEventArgs.cs
new file mode 100644
index 0000000..aff82f3
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/TextViewLayoutChangedEventArgs.cs
@@ -0,0 +1,150 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using Microsoft.VisualStudio.Text;
+ using System.Collections.ObjectModel;
+ using System.Collections.Generic;
+ using Microsoft.VisualStudio.Text.Formatting;
+
+ /// <summary>
+ /// Provides information for a Layout Changed event of <see cref="ITextView"/>.
+ /// </summary>
+ public class TextViewLayoutChangedEventArgs : EventArgs
+ {
+ #region Private Members
+
+ readonly ViewState _oldViewState;
+ readonly ViewState _newViewState;
+
+ readonly ReadOnlyCollection<ITextViewLine> _newOrReformattedLines;
+ readonly ReadOnlyCollection<ITextViewLine> _translatedLines;
+
+ NormalizedSnapshotSpanCollection _newOrReformattedSpans;
+ NormalizedSnapshotSpanCollection _translatedSpans;
+
+ private static NormalizedSnapshotSpanCollection GetSpans(IList<ITextViewLine> lines)
+ {
+ if (lines.Count > 0)
+ {
+ List<Span> spans = new List<Span>();
+
+ foreach (ITextViewLine line in lines)
+ {
+ spans.Add(line.ExtentIncludingLineBreak.Span);
+ }
+
+ return new NormalizedSnapshotSpanCollection(lines[0].Snapshot, spans);
+ }
+ else
+ {
+ return NormalizedSnapshotSpanCollection.Empty;
+ }
+ }
+ #endregion // Private Members
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="TextViewLayoutChangedEventArgs"/>.
+ /// </summary>
+ /// <param name="oldState">
+ /// State of the view prior to the layout.
+ /// </param>
+ /// <param name="newState">
+ /// State of the view after the layout.
+ /// </param>
+ /// <param name="newOrReformattedLines">A list of the new or reformatted <see cref="ITextViewLine"/>.</param>
+ /// <param name="translatedLines">A list of the translated <see cref="ITextViewLine"/>.</param>
+ /// <exception name="ArgumentNullException"><paramref name="oldState"/>, <paramref name="newState"/>, <paramref name="translatedLines"/> or <paramref name="newOrReformattedLines"/> is null.</exception>
+ public TextViewLayoutChangedEventArgs(ViewState oldState, ViewState newState,
+ IList<ITextViewLine> newOrReformattedLines,
+ IList<ITextViewLine> translatedLines)
+ {
+ if (oldState == null)
+ throw new ArgumentNullException("oldState");
+ if (newState == null)
+ throw new ArgumentNullException("newState");
+ if (translatedLines == null)
+ throw new ArgumentNullException("translatedLines");
+ if (newOrReformattedLines == null)
+ throw new ArgumentNullException("newOrReformattedLines");
+
+ _oldViewState = oldState;
+ _newViewState = newState;
+
+ _newOrReformattedLines = new ReadOnlyCollection<ITextViewLine>(newOrReformattedLines);
+ _translatedLines = new ReadOnlyCollection<ITextViewLine>(translatedLines);
+ }
+
+ #region Exposed Properties
+ /// <summary>
+ /// State of the view prior to the layout.
+ /// </summary>
+ public ViewState OldViewState { get { return _oldViewState; } }
+
+ /// <summary>
+ /// State of the view after the layout.
+ /// </summary>
+ public ViewState NewViewState { get { return _newViewState; } }
+
+ /// <summary>
+ /// Has the view translated horizontally since the last layout?
+ /// </summary>
+ public bool HorizontalTranslation { get { return _oldViewState.ViewportLeft != _newViewState.ViewportLeft; } }
+
+ /// <summary>
+ /// Has the view translated vertically since the last layout?
+ /// </summary>
+ public bool VerticalTranslation { get { return _oldViewState.ViewportTop != _newViewState.ViewportTop; } }
+
+ /// <summary>
+ /// Gets the old snapshot of the view.
+ /// </summary>
+ /// <remarks>Deprecated. Use OldViewState.EditSnapshot instead.</remarks>
+ public ITextSnapshot OldSnapshot { get { return _oldViewState.EditSnapshot; } }
+
+ /// <summary>
+ /// Gets the new snapshot produced by the changed layout.
+ /// </summary>
+ /// <remarks>Deprecated. Use NewViewState.EditSnapshot instead.</remarks>
+ public ITextSnapshot NewSnapshot { get { return _newViewState.EditSnapshot; } }
+
+ /// <summary>
+ /// Gets a read-only collection of new or reformatted lines.
+ /// </summary>
+ public ReadOnlyCollection<ITextViewLine> NewOrReformattedLines { get { return _newOrReformattedLines; } }
+
+ /// <summary>
+ /// Gets a read-only collection of translated lines.
+ /// </summary>
+ public ReadOnlyCollection<ITextViewLine> TranslatedLines { get { return _translatedLines; } }
+
+ /// <summary>
+ /// Gets a collection the spans that are either new or have been reformatted.
+ /// </summary>
+ public NormalizedSnapshotSpanCollection NewOrReformattedSpans
+ {
+ get
+ {
+ if (_newOrReformattedSpans == null)
+ _newOrReformattedSpans = GetSpans(_newOrReformattedLines);
+ return _newOrReformattedSpans;
+ }
+ }
+
+ /// <summary>
+ /// Gets a collection spans that have been translated.
+ /// </summary>
+ public NormalizedSnapshotSpanCollection TranslatedSpans
+ {
+ get
+ {
+ if (_translatedSpans == null)
+ _translatedSpans = GetSpans(_translatedLines);
+ return _translatedSpans;
+ }
+ }
+ #endregion // Exposed Properties
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/TextViewRoleAttribute.cs b/src/Text/Def/TextUI/Editor/TextViewRoleAttribute.cs
new file mode 100644
index 0000000..726a542
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/TextViewRoleAttribute.cs
@@ -0,0 +1,35 @@
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using Microsoft.VisualStudio.Utilities;
+
+ /// <summary>
+ /// Use this attribute to specify the kinds of TextViews to which an extension applies.
+ /// </summary>
+ public sealed class TextViewRoleAttribute : MultipleBaseMetadataAttribute
+ {
+ string roles;
+
+ /// <summary>
+ /// Construct a new instance of the attribute.
+ /// </summary>
+ /// <param name="role">The case-insensitive name of the role.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="role"/> is null or empty.</exception>
+ public TextViewRoleAttribute(string role)
+ {
+ if (string.IsNullOrEmpty(role))
+ {
+ throw new ArgumentNullException("role");
+ }
+ this.roles = role;
+ }
+
+ /// <summary>
+ /// The role name.
+ /// </summary>
+ public string TextViewRoles
+ {
+ get { return this.roles; }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Editor/ViewRelativePosition.cs b/src/Text/Def/TextUI/Editor/ViewRelativePosition.cs
new file mode 100644
index 0000000..9f42203
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ViewRelativePosition.cs
@@ -0,0 +1,20 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Defines the meaning of the verticalOffset parameter in the <see cref="ITextView"/>.DisplayTextLineContaining(...).
+ /// </summary>
+ public enum ViewRelativePosition
+ {
+ /// <summary>
+ /// The offset with respect to the top of the view.
+ /// </summary>
+ Top,
+ /// <summary>
+ /// The offset with respect to the bottom of the view.
+ /// </summary>
+ Bottom
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Editor/ViewState.cs b/src/Text/Def/TextUI/Editor/ViewState.cs
new file mode 100644
index 0000000..62bca13
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ViewState.cs
@@ -0,0 +1,86 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ using System;
+ using Microsoft.VisualStudio.Text;
+ using System.Collections.ObjectModel;
+ using System.Collections.Generic;
+ using Microsoft.VisualStudio.Text.Formatting;
+
+ /// <summary>
+ /// View state at a particular point in time.
+ /// </summary>
+ public class ViewState
+ {
+ /// <summary>
+ /// Gets the X-coordinate of the viewport's left edge.
+ /// </summary>
+ public double ViewportLeft { get; private set; }
+
+ /// <summary>
+ /// Gets the Y-coordinate of the viewport's top edge.
+ /// </summary>
+ public double ViewportTop { get; private set; }
+
+ /// <summary>
+ /// Gets the Width of the viewport.
+ /// </summary>
+ public double ViewportWidth { get; private set; }
+
+ /// <summary>
+ /// Gets the Height of the viewport.
+ /// </summary>
+ public double ViewportHeight { get; private set; }
+
+ /// <summary>
+ /// Gets the X-coordinate of the viewport's right edge.
+ /// </summary>
+ public double ViewportRight { get { return this.ViewportLeft + this.ViewportWidth; } }
+
+ /// <summary>
+ /// Gets the Y-coordinate of the viewport's bottom edge.
+ /// </summary>
+ public double ViewportBottom { get { return this.ViewportTop + this.ViewportHeight; } }
+
+ /// <summary>
+ /// Gets the View's visual snapshot.
+ /// </summary>
+ public ITextSnapshot VisualSnapshot { get; private set; }
+
+ /// <summary>
+ /// Gets the view's edit snapshot.
+ /// </summary>
+ public ITextSnapshot EditSnapshot { get; private set; }
+
+ /// <summary>
+ /// Constructs a <see cref="ViewState"/>.
+ /// </summary>
+ /// <param name="view">The <see cref="ITextView"/> for this view state.</param>
+ /// <param name="effectiveViewportWidth">The width of the view port for <paramref name="view"/>.</param>
+ /// <param name="effectiveViewportHeight">The height of the view port for <paramref name="view"/>.</param>
+ public ViewState(ITextView view, double effectiveViewportWidth, double effectiveViewportHeight)
+ {
+ if (view == null)
+ throw new ArgumentNullException("view");
+
+ this.ViewportLeft = view.ViewportLeft;
+ this.ViewportTop = view.ViewportTop;
+ this.ViewportWidth = effectiveViewportWidth;
+ this.ViewportHeight = effectiveViewportHeight;
+
+ this.VisualSnapshot = view.VisualSnapshot;
+ this.EditSnapshot = view.TextSnapshot;
+ }
+
+ /// <summary>
+ /// Constructs a <see cref="ViewState"/>.
+ /// </summary>
+ /// <param name="view">The <see cref="ITextView"/> for this view state.</param>
+ public ViewState(ITextView view)
+ : this(view, (view != null) ? view.ViewportWidth : 0.0, (view != null) ? view.ViewportHeight : 0.0)
+ {
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/Editor/WordWrapStyles.cs b/src/Text/Def/TextUI/Editor/WordWrapStyles.cs
new file mode 100644
index 0000000..d52fb02
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/WordWrapStyles.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Sets a bitwise combination of enumeration values to specify the word wrap style of an <see cref="ITextView"/>.
+ /// </summary>
+ /// <remarks>The VisibleGlyphs and AutoIndent bits will have no effect
+ /// unless the WordWrap bit is also set.
+ /// </remarks>
+ [System.Flags]
+ public enum WordWrapStyles
+ {
+ /// <summary>
+ /// Word wrap is disabled.
+ /// </summary>
+ None = 0x00,
+ /// <summary>
+ /// Word wrap is enabled.
+ /// </summary>
+ WordWrap = 0x01,
+ /// <summary>
+ /// If word wrap is enabled, use visible glyphs.
+ /// </summary>
+ VisibleGlyphs = 0x02,
+ /// <summary>
+ /// If word wrap is enabled, use auto-indent.
+ /// </summary>
+ AutoIndent = 0x04
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Editor/ZoomConstants.cs b/src/Text/Def/TextUI/Editor/ZoomConstants.cs
new file mode 100644
index 0000000..0b7d8cd
--- /dev/null
+++ b/src/Text/Def/TextUI/Editor/ZoomConstants.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Defines the constants used for zoom operations
+ /// </summary>
+ public static class ZoomConstants
+ {
+ /// <summary>
+ /// The maximum zoom allowed on the text view
+ /// </summary>
+ public const double MaxZoom = 400.0;
+
+ /// <summary>
+ /// The minimum zoom allowed on the text view
+ /// </summary>
+ public const double MinZoom = 20.0;
+
+ /// <summary>
+ /// The default zoom level on the text view
+ /// </summary>
+ public const double DefaultZoom = 100.0;
+
+ /// <summary>
+ /// The scaling factor used for zooming in and out of the view. The view zooms by a factor of 10%
+ /// </summary>
+ public const double ScalingFactor = 1.1;
+ }
+}
diff --git a/src/Text/Def/TextUI/EditorOptions/ViewOptionDefinition.cs b/src/Text/Def/TextUI/EditorOptions/ViewOptionDefinition.cs
new file mode 100644
index 0000000..522e517
--- /dev/null
+++ b/src/Text/Def/TextUI/EditorOptions/ViewOptionDefinition.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Defines a <see cref="ITextView"/>-specific editor option.
+ /// </summary>
+ /// <remarks>
+ /// This is a MEF component part, and should be exported with:
+ /// [Export(typeof(EditorOptionDefinition))]
+ /// </remarks>
+ public abstract class ViewOptionDefinition<T> : EditorOptionDefinition<T>
+ {
+ /// <summary>
+ /// Determines whether the option is applicable to the specified scope.
+ /// </summary>
+ public override bool IsApplicableToScope(IPropertyOwner scope)
+ {
+ return scope is ITextView;
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/EditorOptions/ViewOptions.cs b/src/Text/Def/TextUI/EditorOptions/ViewOptions.cs
new file mode 100644
index 0000000..a493ce7
--- /dev/null
+++ b/src/Text/Def/TextUI/EditorOptions/ViewOptions.cs
@@ -0,0 +1,898 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel.Composition;
+using Microsoft.VisualStudio.Utilities;
+
+namespace Microsoft.VisualStudio.Text.Editor.OptionsExtensionMethods
+{
+ /// <summary>
+ /// Provides methods for <see cref="ITextView"/>-related options.
+ /// </summary>
+ public static class TextViewOptionExtensions
+ {
+ #region Extension methods
+
+ /// <summary>
+ /// Determines whether virtual space is enabled for the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if virtual space is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsVirtualSpaceEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewOptions.UseVirtualSpaceId);
+ }
+
+ /// <summary>
+ /// Determines whether overwrite mode is enabled with the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if overwrite mode is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsOverwriteModeEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewOptions.OverwriteModeId);
+ }
+
+ /// <summary>
+ /// Determines whether auto-scroll is enabled with the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if auto-scroll is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsAutoScrollEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewOptions.AutoScrollId);
+ }
+
+ /// <summary>
+ /// Gets the set of word wrap styles with the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns>The <see cref="WordWrapStyles"/> of the set of editor options.</returns>
+ public static WordWrapStyles WordWrapStyle(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<WordWrapStyles>(DefaultTextViewOptions.WordWrapStyleId);
+ }
+
+ /// <summary>
+ /// Determines whether visible whitespace is enabled with the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if visible whitespace is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsVisibleWhitespaceEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewOptions.UseVisibleWhitespaceId);
+ }
+
+ /// <summary>
+ /// Determines whether the view prohibits all user input.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns>if <c>true</c> then all user input to the view is prohibited.</returns>
+ /// <remarks>The view's underlying buffer can still be modified even if this option is set.</remarks>
+ public static bool DoesViewProhibitUserInput(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewOptions.ViewProhibitUserInputId);
+ }
+
+ /// <summary>
+ /// Determines whether the option for outlining undo enabled in the specified <see cref="IEditorOptions"/>.
+ /// </summary>
+ /// <param name="options">The <see cref="IEditorOptions"/>.</param>
+ /// <returns><c>true</c> if the option is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsOutliningUndoEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue(DefaultTextViewOptions.OutliningUndoOptionId);
+ }
+
+ /// <summary>
+ /// Determines whether the option for drag/drop editing is enabled in the specified <see cref="IEditorOptions"/>.
+ /// </summary>
+ /// <param name="options">The <see cref="IEditorOptions"/> used to look up the option value.</param>
+ /// <returns><c>true</c> if the drag/drop editing option is enabled, <c>false</c> otherwise.</returns>
+ public static bool IsDragDropEditingEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue(DefaultTextViewOptions.DragDropEditingId);
+ }
+
+ /// <summary>
+ /// Determines whether the view's ViewportLeft property is clipped to the text width.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if ViewportLeft is clipped, otherwise <c>false</c>.</returns>
+ public static bool IsViewportLeftClipped(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewOptions.IsViewportLeftClippedId);
+ }
+ #endregion
+ }
+
+ /// <summary>
+ /// Provides methods for <see cref="ITextView"/> host related options.
+ /// </summary>
+ public static class TextViewHostOptionExtensions
+ {
+ #region Extension methods
+
+ /// <summary>
+ /// Determines whether the vertical scrollbar is enabled with the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if the vertical scrollbar is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsVerticalScrollBarEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewHostOptions.VerticalScrollBarId);
+ }
+
+ /// <summary>
+ /// Determines whether the horizontal scrollbar is enabled with the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if the horizontal scrollbar is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsHorizontalScrollBarEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewHostOptions.HorizontalScrollBarId);
+ }
+
+ /// <summary>
+ /// Determines whether the glyph margin is enabled with the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if the glyph margin is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsGlyphMarginEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewHostOptions.GlyphMarginId);
+ }
+
+ /// <summary>
+ /// Determines whether the selection margin is enabled with the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if the selection margin is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsSelectionMarginEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewHostOptions.SelectionMarginId);
+ }
+
+ /// <summary>
+ /// Determines whether the line number margin is enabled with the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if the line number margin is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsLineNumberMarginEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewHostOptions.LineNumberMarginId);
+ }
+
+ /// <summary>
+ /// Determines whether change tracking is enabled with the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if change tracking is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsChangeTrackingEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewHostOptions.ChangeTrackingId);
+ }
+
+ /// <summary>
+ /// Determines whether the Outlining margin is enabled with the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if the Outlining margin is enabled, otherwise <c>false</c>.</returns>
+ /// <remarks>Disabling the margin does NOT turn off Outlining (it just hides the margin</remarks>
+ public static bool IsOutliningMarginEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewHostOptions.OutliningMarginId);
+ }
+
+ /// <summary>
+ /// Determines whether the zoom control is enabled with the specified set of editor options.
+ /// </summary>
+ /// <param name="options">The set of editor options.</param>
+ /// <returns><c>true</c> if the zoom control is enabled, otherwise <c>false</c>.</returns>
+ public static bool IsZoomControlEnabled(this IEditorOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException("options");
+
+ return options.GetOptionValue<bool>(DefaultTextViewHostOptions.ZoomControlId);
+ }
+ #endregion
+ }
+}
+
+namespace Microsoft.VisualStudio.Text.Editor
+{
+ /// <summary>
+ /// Defines common <see cref="ITextView"/> options.
+ /// </summary>
+ public static class DefaultTextViewOptions
+ {
+ #region Option identifiers
+
+ /// <summary>
+ /// Determines whether cut and copy causes a blank line to be cut or copied when the selection is empty.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> CutOrCopyBlankLineIfNoSelectionId = new EditorOptionKey<bool>(CutOrCopyBlankLineIfNoSelectionName);
+ public const string CutOrCopyBlankLineIfNoSelectionName = "TextView/CutOrCopyBlankLineIfNoSelection";
+
+ /// <summary>
+ /// Determines whether to prohibit user input. The text in the view's
+ /// buffer can still be modified, and other views on the same buffer may allow user input.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> ViewProhibitUserInputId = new EditorOptionKey<bool>(ViewProhibitUserInputName);
+ public const string ViewProhibitUserInputName = "TextView/ProhibitUserInput";
+
+ /// <summary>
+ /// Gets the word wrap style for the underlying view.
+ /// </summary>
+ /// <remarks>Turning word wrap on will always hide the host's horizontal scroll bar. Turning word wrap off
+ /// will always expose the host's horizontal scroll bar.</remarks>
+ public static readonly EditorOptionKey<WordWrapStyles> WordWrapStyleId = new EditorOptionKey<WordWrapStyles>(WordWrapStyleName);
+ public const string WordWrapStyleName = "TextView/WordWrapStyle";
+
+ /// <summary>
+ /// Determines whether to enable virtual space in the view.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> UseVirtualSpaceId = new EditorOptionKey<bool>(UseVirtualSpaceName);
+ public const string UseVirtualSpaceName = "TextView/UseVirtualSpace";
+
+ /// <summary>
+ /// Determines whether the view's ViewportLeft property is clipped to the text width.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> IsViewportLeftClippedId = new EditorOptionKey<bool>(IsViewportLeftClippedName);
+ public const string IsViewportLeftClippedName = "TextView/IsViewportLeftClipped";
+
+ /// <summary>
+ /// Determines whether overwrite mode is enabled.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> OverwriteModeId = new EditorOptionKey<bool>(OverwriteModeName);
+ public const string OverwriteModeName = "TextView/OverwriteMode";
+
+ /// <summary>
+ /// Determines whether the view should auto-scroll on text changes.
+ /// </summary>
+ /// <remarks>
+ /// If this option is enabled, whenever a text change occurs and the caret is on the last line,
+ /// the view will be scrolled to make the caret visible.
+ /// </remarks>
+ public static readonly EditorOptionKey<bool> AutoScrollId = new EditorOptionKey<bool>(AutoScrollName);
+ public const string AutoScrollName = "TextView/AutoScroll";
+
+ /// <summary>
+ /// Determines whether to show spaces and tabs as visible glyphs.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> UseVisibleWhitespaceId = new EditorOptionKey<bool>(UseVisibleWhitespaceName);
+ public const string UseVisibleWhitespaceName = "TextView/UseVisibleWhitespace";
+
+ /// <summary>
+ /// Enables or disables the code block structure visualizer text adornment feature.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> ShowBlockStructureId = new EditorOptionKey<bool>(ShowBlockStructureName);
+ public const string ShowBlockStructureName = "TextView/ShowBlockStructure";
+
+ /// <summary>
+ /// Whether or not to replace the coding characters and special symbols (such as (,),{,},etc.) with their textual representation
+ /// for automated objects to produce friendly text for screen readers.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> ProduceScreenReaderFriendlyTextId = new EditorOptionKey<bool>(ProduceScreenReaderFriendlyTextName);
+ public const string ProduceScreenReaderFriendlyTextName = "TextView/ProduceScreenReaderFriendlyText";
+
+ /// <summary>
+ /// The default option that determines whether outlining is undoable.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> OutliningUndoOptionId = new EditorOptionKey<bool>(OutliningUndoOptionName);
+ public const string OutliningUndoOptionName = "TextView/OutliningUndo";
+
+ /// <summary>
+ /// Determines whether URLs should be displayed as hyperlinks.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> DisplayUrlsAsHyperlinksId = new EditorOptionKey<bool>(DisplayUrlsAsHyperlinksName);
+ public const string DisplayUrlsAsHyperlinksName = "TextView/DisplayUrlsAsHyperlinks";
+
+ /// <summary>
+ /// The default option that determines whether drag/drop editing is enabled.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> DragDropEditingId = new EditorOptionKey<bool>(DragDropEditingName);
+ public const string DragDropEditingName = "TextView/DragDrop";
+
+ /// <summary>
+ /// Determines if automatic brace completion is enabled.
+ /// </summary>
+ public const string BraceCompletionEnabledOptionName = "BraceCompletion/Enabled";
+ public readonly static EditorOptionKey<bool> BraceCompletionEnabledOptionId = new EditorOptionKey<bool>(BraceCompletionEnabledOptionName);
+ #endregion
+ }
+
+ /// <summary>
+ /// Names of common <see cref="ITextView"/> host-related options.
+ /// </summary>
+ public static class DefaultTextViewHostOptions
+ {
+ #region Option identifiers
+
+ /// <summary>
+ /// Determines whether to have a vertical scroll bar.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> VerticalScrollBarId = new EditorOptionKey<bool>(VerticalScrollBarName);
+ public const string VerticalScrollBarName = "TextViewHost/VerticalScrollBar";
+
+ /// <summary>
+ /// Determines whether to have a horizontal scroll bar.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> HorizontalScrollBarId = new EditorOptionKey<bool>(HorizontalScrollBarName);
+ public const string HorizontalScrollBarName = "TextViewHost/HorizontalScrollBar";
+
+ /// <summary>
+ /// Determines whether to have a glyph margin.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> GlyphMarginId = new EditorOptionKey<bool>(GlyphMarginName);
+ public const string GlyphMarginName = "TextViewHost/GlyphMargin";
+
+ /// <summary>
+ /// Determines whether to have a suggestion margin.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> SuggestionMarginId = new EditorOptionKey<bool>(SuggestionMarginName);
+ public const string SuggestionMarginName = "TextViewHost/SuggestionMargin";
+
+ /// <summary>
+ /// Determines whether to have a selection margin.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> SelectionMarginId = new EditorOptionKey<bool>(SelectionMarginName);
+ public const string SelectionMarginName = "TextViewHost/SelectionMargin";
+
+ /// <summary>
+ /// Determines whether to have a line number margin.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> LineNumberMarginId = new EditorOptionKey<bool>(LineNumberMarginName);
+ public const string LineNumberMarginName = "TextViewHost/LineNumberMargin";
+
+ /// <summary>
+ /// Determines whether to have the change tracking margin.
+ /// </summary>
+ /// <remarks>The change tracking margins will "reset" (lose the change history) when this option is turned off.
+ /// If it is turned back on, it will track changes from the time the margin is turned on.</remarks>
+ public static readonly EditorOptionKey<bool> ChangeTrackingId = new EditorOptionKey<bool>(ChangeTrackingName);
+ public const string ChangeTrackingName = "TextViewHost/ChangeTracking";
+
+ /// <summary>
+ /// Determines whether to have an outlining margin.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> OutliningMarginId = new EditorOptionKey<bool>(OutliningMarginName);
+ public const string OutliningMarginName = "TextViewHost/OutliningMargin";
+
+ /// <summary>
+ /// Determines whether to have a zoom control.
+ /// </summary>
+ public static readonly EditorOptionKey<bool> ZoomControlId = new EditorOptionKey<bool>(ZoomControlName);
+ public const string ZoomControlName = "TextViewHost/ZoomControl";
+
+ /// <summary>
+ /// Determines whether any annotations are shown over the vertical scroll bar.
+ /// </summary>
+ public const string ShowScrollBarAnnotationsOptionName = "OverviewMargin/ShowScrollBarAnnotationsOption";
+ public readonly static EditorOptionKey<bool> ShowScrollBarAnnotationsOptionId = new EditorOptionKey<bool>(ShowScrollBarAnnotationsOptionName);
+
+ /// <summary>
+ /// Determines whether the vertical scroll bar is shown as a standard WPF scroll bar or the new enhanced scroll bar.
+ /// </summary>
+ public const string ShowEnhancedScrollBarOptionName = "OverviewMargin/ShowEnhancedScrollBar";
+ public readonly static EditorOptionKey<bool> ShowEnhancedScrollBarOptionId = new EditorOptionKey<bool>(ShowEnhancedScrollBarOptionName);
+
+ /// <summary>
+ /// Determines whether changes are shown over the vertical scroll bar.
+ /// </summary>
+ public const string ShowChangeTrackingMarginOptionName = "OverviewMargin/ShowChangeTracking";
+ public readonly static EditorOptionKey<bool> ShowChangeTrackingMarginOptionId = new EditorOptionKey<bool>(ShowChangeTrackingMarginOptionName);
+
+ /// <summary>
+ /// Determines the width of the change tracking margin.
+ /// </summary>
+ public const string ChangeTrackingMarginWidthOptionName = "OverviewMargin/ChangeTrackingWidth";
+ public readonly static EditorOptionKey<double> ChangeTrackingMarginWidthOptionId = new EditorOptionKey<double>(ChangeTrackingMarginWidthOptionName);
+
+ /// <summary>
+ /// Determines whether a preview tip is shown when the mouse moves over the vertical scroll bar.
+ /// </summary>
+ public const string ShowPreviewOptionName = "OverviewMargin/ShowPreview";
+ public readonly static EditorOptionKey<bool> ShowPreviewOptionId = new EditorOptionKey<bool>(ShowPreviewOptionName);
+
+ /// <summary>
+ /// Determines the size (in lines of text) of the default tip.
+ /// </summary>
+ public const string PreviewSizeOptionName = "OverviewMargin/PreviewSize";
+ public readonly static EditorOptionKey<int> PreviewSizeOptionId = new EditorOptionKey<int>(PreviewSizeOptionName);
+
+ /// <summary>
+ /// Determines whether the vertical margin shows the location of the caret.
+ /// </summary>
+ public const string ShowCaretPositionOptionName = "OverviewMargin/ShowCaretPosition";
+ public readonly static EditorOptionKey<bool> ShowCaretPositionOptionId = new EditorOptionKey<bool>(ShowCaretPositionOptionName);
+
+ /// <summary>
+ /// Determines whether the source image margin is displayed.
+ /// </summary>
+ /// <remarks>
+ /// This margin is only shown if this option and the ShowEnhancedScrollBarOption, and the SourceImageMarginWidth is >= 25.0.
+ /// </remarks>
+ public const string SourceImageMarginEnabledOptionName = "OverviewMargin/ShowSourceImageMargin";
+ public readonly static EditorOptionKey<bool> SourceImageMarginEnabledOptionId = new EditorOptionKey<bool>(SourceImageMarginEnabledOptionName);
+
+ /// <summary>
+ /// Determines the width of the source image margin.
+ /// </summary>
+ public const string SourceImageMarginWidthOptionName = "OverviewMargin/SourceImageMarginWidth";
+ public readonly static EditorOptionKey<double> SourceImageMarginWidthOptionId = new EditorOptionKey<double>(SourceImageMarginWidthOptionName);
+
+ /// <summary>
+ /// Determines whether marks (bookmarks, breakpoints, etc.) are shown over the vertical scroll bar.
+ /// </summary>
+ public const string ShowMarksOptionName = "OverviewMargin/ShowMarks";
+ public readonly static EditorOptionKey<bool> ShowMarksOptionId = new EditorOptionKey<bool>(ShowMarksOptionName);
+
+ /// <summary>
+ /// Determines whether errors are shown over the vertical scroll bar.
+ /// </summary>
+ public const string ShowErrorsOptionName = "OverviewMargin/ShowErrors";
+ public readonly static EditorOptionKey<bool> ShowErrorsOptionId = new EditorOptionKey<bool>(ShowErrorsOptionName);
+
+ /// <summary>
+ /// Determines the width of the marks margin.
+ /// </summary>
+ public const string MarkMarginWidthOptionName = "OverviewMargin/MarkMarginWidth";
+ public readonly static EditorOptionKey<double> MarkMarginWidthOptionId = new EditorOptionKey<double>(MarkMarginWidthOptionName);
+
+ /// <summary>
+ /// Determines the width of the error margin.
+ /// </summary>
+ public const string ErrorMarginWidthOptionName = "OverviewMargin/ErrorMarginWidth";
+ public readonly static EditorOptionKey<double> ErrorMarginWidthOptionId = new EditorOptionKey<double>(ErrorMarginWidthOptionName);
+ #endregion
+ }
+
+ /// <summary>
+ /// Defines the view option for drag/drop editing.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.DragDropEditingName)]
+ public sealed class DragDropEditing : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>true</c>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the default key for the drag/drop editing option.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewOptions.DragDropEditingId; } }
+ }
+
+ /// <summary>
+ /// Defines the view option for overwrite mode.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.OverwriteModeName)]
+ public sealed class OverwriteMode : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>false</c>.
+ /// </summary>
+ public override bool Default { get { return false; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewOptions.OverwriteModeId; } }
+ }
+
+ /// <summary>
+ /// Defines the Use Virtual Space option.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.UseVirtualSpaceName)]
+ public sealed class UseVirtualSpace : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>false</c>.
+ /// </summary>
+ public override bool Default { get { return false; } }
+
+ /// <summary>
+ /// Gets the default text view value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewOptions.UseVirtualSpaceId; } }
+ }
+
+ /// <summary>
+ /// Defines the Use Virtual Space option.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.IsViewportLeftClippedName)]
+ public sealed class IsViewportLeftClipped : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>true</c>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the default text view value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewOptions.IsViewportLeftClippedId; } }
+ }
+
+ /// <summary>
+ /// Defines the Prohibit User Input option.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.ViewProhibitUserInputName)]
+ public sealed class ViewProhibitUserInput : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>false</c>.
+ /// </summary>
+ public override bool Default { get { return false; } }
+
+ /// <summary>
+ /// GGets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewOptions.ViewProhibitUserInputId; } }
+ }
+
+ /// <summary>
+ /// Defines the option to cut or copy a blank line if the selection is empty.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.CutOrCopyBlankLineIfNoSelectionName)]
+ public sealed class CutOrCopyBlankLineIfNoSelection : ViewOptionDefinition<bool>
+ {
+
+ /// <summary>
+ /// Gets the default value, which is <c>true</c>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewOptions.CutOrCopyBlankLineIfNoSelectionId; } }
+ }
+
+ /// <summary>
+ /// Defines the word wrap style option.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.WordWrapStyleName)]
+ public sealed class WordWrapStyle : ViewOptionDefinition<WordWrapStyles>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>WordWrapStyles.None</c>.
+ /// </summary>
+ public override WordWrapStyles Default { get { return WordWrapStyles.None; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<WordWrapStyles> Key { get { return DefaultTextViewOptions.WordWrapStyleId; } }
+ }
+
+ /// <summary>
+ /// Defines the Use Visible Whitespace option.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.UseVisibleWhitespaceName)]
+ public sealed class UseVisibleWhitespace : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>false</c>.
+ /// </summary>
+ public override bool Default { get { return false; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewOptions.UseVisibleWhitespaceId; } }
+ }
+
+ /// <summary>
+ /// Defines the Show Block Structure option.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.ShowBlockStructureName)]
+ public sealed class ShowBlockStructure : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>true</c>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewOptions.ShowBlockStructureId; } }
+ }
+
+ /// <summary>
+ /// Defines the option to enable providing annotated text in automation controls so that screen readers can properly
+ /// read contents of code.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.ProduceScreenReaderFriendlyTextName)]
+ public sealed class ProduceScreenReaderFriendlyText : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>false</c>.
+ /// </summary>
+ public override bool Default { get { return false; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewOptions.ProduceScreenReaderFriendlyTextId; } }
+ }
+
+ /// <summary>
+ /// Defines the option to enable the vertical scroll bar.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewHostOptions.VerticalScrollBarName)]
+ public sealed class VerticalScrollBarEnabled : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>true</c>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewHostOptions.VerticalScrollBarId; } }
+ }
+
+ /// <summary>
+ /// Defines the option to enable the horizontal scroll bar.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewHostOptions.HorizontalScrollBarName)]
+ public sealed class HorizontalScrollBarEnabled : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>true</c>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewHostOptions.HorizontalScrollBarId; } }
+ }
+
+ /// <summary>
+ /// Defines the option to enable the glyph margin.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewHostOptions.GlyphMarginName)]
+ public sealed class GlyphMarginEnabled : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>true</c>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewHostOptions.GlyphMarginId; } }
+ }
+
+ /// <summary>
+ /// Defines the option to enable the suggestion margin.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewHostOptions.SuggestionMarginName)]
+ public sealed class SuggestionMarginEnabled : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>true</c>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewHostOptions.SuggestionMarginId; } }
+ }
+
+ /// <summary>
+ /// Defines the option to enable the selection margin.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewHostOptions.SelectionMarginName)]
+ public sealed class SelectionMarginEnabled : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>true</c>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewHostOptions.SelectionMarginId; } }
+ }
+
+ /// <summary>
+ /// Defines the option to enable the line number margin.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewHostOptions.LineNumberMarginName)]
+ public sealed class LineNumberMarginEnabled : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>false</c>.
+ /// </summary>
+ public override bool Default { get { return false; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewHostOptions.LineNumberMarginId; } }
+ }
+
+ /// <summary>
+ /// Defines the option to enable auto-scroll.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.AutoScrollName)]
+ public sealed class AutoScrollEnabled : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>false</c>.
+ /// </summary>
+ public override bool Default { get { return false; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewOptions.AutoScrollId; } }
+ }
+
+ /// <summary>
+ /// Defines the option to enable the change-tracking margin.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewHostOptions.ChangeTrackingName)]
+ public sealed class ChangeTrackingMarginEnabled : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>false</c>.
+ /// </summary>
+ public override bool Default { get { return false; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewHostOptions.ChangeTrackingId; } }
+ }
+
+ /// <summary>
+ /// Defines the option to enable the Outlining margin.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewHostOptions.OutliningMarginName)]
+ public sealed class OutliningMarginEnabled : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>true</c>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewHostOptions.OutliningMarginId; } }
+ }
+
+ /// <summary>
+ /// The option definition that determines whether outlining is undoable.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.OutliningUndoOptionName)]
+ public sealed class OutliningUndoEnabled : EditorOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value (<c>true</c>)>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the editor option key.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewOptions.OutliningUndoOptionId; } }
+ }
+
+
+ /// <summary>
+ /// Defines the option to enable the Zoom Control.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewHostOptions.ZoomControlName)]
+ public sealed class ZoomControlEnabled : ViewOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value, which is <c>true</c>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the default text view host value.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewHostOptions.ZoomControlId; } }
+ }
+
+ /// <summary>
+ /// The option definition that determines if URLs should be displayed as hyperlinks.
+ /// </summary>
+ [Export(typeof(EditorOptionDefinition))]
+ [Name(DefaultTextViewOptions.DisplayUrlsAsHyperlinksName)]
+ public sealed class DisplayUrlsAsHyperlinks : EditorOptionDefinition<bool>
+ {
+ /// <summary>
+ /// Gets the default value (<c>true</c>)>.
+ /// </summary>
+ public override bool Default { get { return true; } }
+
+ /// <summary>
+ /// Gets the editor option key.
+ /// </summary>
+ public override EditorOptionKey<bool> Key { get { return DefaultTextViewOptions.DisplayUrlsAsHyperlinksId; } }
+ }
+}
diff --git a/src/Text/Def/TextUI/Find/IIncrementalSearch.cs b/src/Text/Def/TextUI/Find/IIncrementalSearch.cs
new file mode 100644
index 0000000..b89f1d4
--- /dev/null
+++ b/src/Text/Def/TextUI/Find/IIncrementalSearch.cs
@@ -0,0 +1,127 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.IncrementalSearch
+{
+
+ /// <summary>
+ /// Defines an incremental search operation.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// The <see cref="IIncrementalSearch"/> interface is associated
+ /// with a <see cref="Microsoft.VisualStudio.Text.Editor.ITextView"/>.
+ /// </para>
+ /// <para>
+ /// After the Start() method is called, the current caret position is marked as the start of the search,
+ /// and the <see cref="AppendCharAndSearch"/> and <see cref="DeleteCharAndSearch"/> operations can be used to change the search term.
+ /// The direction of the search is set to forward by default, although this setting can be changed with the <see cref="SearchDirection"/> property.
+ /// If a matching term is found, it is selected and the caret is moved to the end of the selected word.
+ /// </para>
+ /// <para>
+ /// Every search operation returns an <see cref="IncrementalSearchResult"/>, which includes
+ /// information about the search, such as whether the search looped around the start or
+ /// end of the buffer, whether the search looped around the starting position of the search,
+ /// and whether the item was found. It is the responsibility of the caller
+ /// to pass this information to the end user.
+ /// </para>
+ /// <para>
+ /// Incremental search performs its search on the text snapshot of the <see cref="Microsoft.VisualStudio.Text.Editor.ITextView"/>. As a result, if the
+ /// result falls within a collapsed outlining region, the region will be expanded before the result is selected.
+ /// </para>
+ /// </remarks>
+ public interface IIncrementalSearch
+ {
+
+ #region Methods
+
+ /// <summary>
+ /// Starts an incremental search operation, and marks the position of the caret
+ /// as the starting position for the search.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">
+ /// An incremental search session is in progress.
+ /// To avoid raising this exception, check the <see cref="IsActive"/> property before calling
+ /// <c>Start</c>.
+ /// </exception>
+ void Start();
+
+ /// <summary>
+ /// Terminates an incremental search operation.
+ /// </summary>
+ /// <exception creg="System.InvalidOperationException">
+ /// <see cref="Dismiss"/> was called before <see cref="Start"/>. A search must be
+ /// started before it can be terminated.
+ /// </exception>
+ void Dismiss();
+
+ /// <summary>
+ /// Extends the current term being searched for by one character. If a new term is matched, it
+ /// is selected. The selection can be used to access the match.
+ /// </summary>
+ /// <param name="toAppend">
+ /// The character to append to the current search term.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IncrementalSearchResult"/> that contains information about whether the search term was found and whether
+ /// the search wrapped around the beginning or end of the buffer.
+ /// </returns>
+ IncrementalSearchResult AppendCharAndSearch(char toAppend);
+
+ /// <summary>
+ /// Removes the last character of the current search term and updates the
+ /// search results based on the new term.
+ /// </summary>
+ /// <returns>
+ /// An <see cref="IncrementalSearchResult"/> that indicates whether the new search term was found
+ /// and whether the search wrapped around the beginning or end of
+ /// the buffer.
+ /// </returns>
+ /// <exception cref="System.InvalidOperationException">
+ /// The search string is empty. To avoid this exception,
+ /// check the <see cref="SearchString"/> property before calling this method.
+ /// </exception>
+ IncrementalSearchResult DeleteCharAndSearch();
+
+ /// <summary>
+ /// Selects the next result in an incremental search operation.
+ /// The matched term will be selected.
+ /// </summary>
+ /// <returns>
+ /// An <see cref="IncrementalSearchResult"/> indicating whether the newly selected item caused a
+ /// wrap around the end or beginning of the document and whether the search looped around the first item found.
+ /// </returns>
+ IncrementalSearchResult SelectNextResult();
+
+ /// <summary>
+ /// Clears the existing search term without changing the selection.
+ /// </summary>
+ void Clear();
+
+ #endregion //Methods
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets or sets the current search term.
+ /// </summary>
+ string SearchString { get; set; }
+
+ /// <summary>
+ /// Determines whether an incremental search is in process.
+ /// </summary>
+ bool IsActive { get; }
+
+ /// <summary>
+ /// Gets or sets the direction of the incremental search.
+ /// </summary>
+ IncrementalSearchDirection SearchDirection { get; set; }
+
+ /// <summary>
+ /// Gets the <see cref="Microsoft.VisualStudio.Text.Editor.ITextView"/> associated with this search.
+ /// </summary>
+ Microsoft.VisualStudio.Text.Editor.ITextView TextView { get; }
+
+ #endregion //Public Properties
+ }
+}
diff --git a/src/Text/Def/TextUI/Find/IIncrementalSearchFactoryService.cs b/src/Text/Def/TextUI/Find/IIncrementalSearchFactoryService.cs
new file mode 100644
index 0000000..6d39dbb
--- /dev/null
+++ b/src/Text/Def/TextUI/Find/IIncrementalSearchFactoryService.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.IncrementalSearch
+{
+
+ using System.ComponentModel.Composition;
+
+ using Microsoft.VisualStudio.Text.Editor;
+
+ /// <summary>
+ /// Used to get or create an incremental search service for a given <see cref="ITextView"/>.
+ /// There will always be a maximum of one <see cref="IIncrementalSearch"/>
+ /// for a given <see cref="ITextView"/>.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IIncrementalSearchFactoryService factory = null;
+ /// </remarks>
+ public interface IIncrementalSearchFactoryService
+ {
+ /// <summary>
+ /// Gets an <see cref="IIncrementalSearch" /> for the specified <see cref="ITextView" />.
+ /// If there is no <see cref="IIncrementalSearch" /> for the view, one
+ /// will be created.
+ /// </summary>
+ /// <param name="textView">
+ /// The <see cref="ITextView"/> over which the incremental search is to be performed.
+ /// </param>
+ /// <returns>
+ /// An <see cref="IIncrementalSearch"/> associated with the <see cref="ITextView"/>.
+ /// </returns>
+ IIncrementalSearch GetIncrementalSearch(ITextView textView);
+ }
+}
diff --git a/src/Text/Def/TextUI/Find/IncrementalSearchDirection.cs b/src/Text/Def/TextUI/Find/IncrementalSearchDirection.cs
new file mode 100644
index 0000000..cf9816a
--- /dev/null
+++ b/src/Text/Def/TextUI/Find/IncrementalSearchDirection.cs
@@ -0,0 +1,22 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.IncrementalSearch
+{
+ /// <summary>
+ /// Determines the direction of the incremental search.
+ /// See <see cref="IIncrementalSearch"/> for more information.
+ /// </summary>
+ public enum IncrementalSearchDirection
+ {
+ /// <summary>
+ /// Forward search.
+ /// </summary>
+ Forward,
+
+ /// <summary>
+ ///Backward search.
+ /// </summary>
+ Backward
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Find/IncrementalSearchResult.cs b/src/Text/Def/TextUI/Find/IncrementalSearchResult.cs
new file mode 100644
index 0000000..fe43341
--- /dev/null
+++ b/src/Text/Def/TextUI/Find/IncrementalSearchResult.cs
@@ -0,0 +1,110 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.IncrementalSearch
+{
+
+ /// <summary>
+ /// Consolidates the result of an incremental search operation.
+ /// </summary>
+ /// <remarks>
+ /// This result indicates whether the item was found, whether the search
+ /// caused the cursor to wrap around the beginning or end of the buffer, and
+ /// the position of the first result.
+ /// </remarks>
+ public struct IncrementalSearchResult
+ {
+ #region Public Properties
+
+ /// <summary>
+ /// Determines whether the search wrapped around the start of the buffer to its end.
+ /// </summary>
+ /// <remarks>This is applicable only if the search direction is backward.</remarks>
+ public bool PassedStartOfBuffer { get; private set; }
+
+ /// <summary>
+ /// Determines whether the search wrapped around the end of the buffer to its beginning.
+ /// </summary>
+ /// <remarks>This is applicable only if the search direction is forward.</remarks>
+ public bool PassedEndOfBuffer { get; private set; }
+
+ /// <summary>
+ /// Determines whether the search passed the first item found.
+ /// </summary>
+ public bool PassedStartOfSearch { get; private set; }
+
+ /// <summary>
+ /// Determines whether the search for the term was successful.
+ /// </summary>
+ public bool ResultFound { get; private set; }
+
+ #endregion //Public Properties
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="IncrementalSearchResult"/> with the specified properties.
+ /// </summary>
+ /// <param name="passedEndOfBuffer"></param>
+ /// <param name="passedStartOfBuffer"></param>
+ /// <param name="passedStartOfSearch"></param>
+ /// <param name="resultFound"></param>
+ public IncrementalSearchResult(bool passedEndOfBuffer, bool passedStartOfBuffer, bool passedStartOfSearch, bool resultFound) : this()
+ {
+ PassedEndOfBuffer = passedEndOfBuffer;
+ PassedStartOfBuffer = passedStartOfBuffer;
+ PassedStartOfSearch = passedStartOfSearch;
+ ResultFound = resultFound;
+ }
+
+ #region Object Overrides
+
+ /// <summary>
+ /// Determines whether the contents of two <see cref="IncrementalSearchResult"/> objects are the same.
+ /// </summary>
+ /// <param name="obj">The object to be compared.</param>
+ /// <returns><c>true</c> if both objects have the same content, otherwise <c>false</c>.</returns>
+ public override bool Equals(object obj)
+ {
+ if (obj is IncrementalSearchResult)
+ {
+ return ((IncrementalSearchResult)obj) == this;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Determines whether the contents of two <see cref="IncrementalSearchResult"/> objects are the same.
+ /// </summary>
+ /// <returns><c>true</c> if both objects have the same content, otherwise <c>false</c>.</returns>
+ public static bool operator == (IncrementalSearchResult first, IncrementalSearchResult second)
+ {
+ return (first.PassedEndOfBuffer == second.PassedEndOfBuffer &&
+ first.PassedStartOfBuffer == second.PassedStartOfBuffer &&
+ first.PassedStartOfSearch == second.PassedStartOfSearch &&
+ first.ResultFound == second.ResultFound);
+ }
+
+ /// <summary>
+ /// Determines whether the contents of two <see cref="IncrementalSearchResult"/> objects are different.
+ /// </summary>
+ /// <returns><c>true</c> if both objects have different content, otherwise <c>false</c>.</returns>
+ public static bool operator != (IncrementalSearchResult first, IncrementalSearchResult second)
+ {
+ return !(first == second);
+ }
+
+ /// <summary>
+ /// Gets the hash code for the object.
+ /// </summary>
+ /// <returns>base class' implementation</returns>
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+
+ #endregion //Object Overrides
+
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Formatting/IAdornmentElement.cs b/src/Text/Def/TextUI/Formatting/IAdornmentElement.cs
new file mode 100644
index 0000000..34f5563
--- /dev/null
+++ b/src/Text/Def/TextUI/Formatting/IAdornmentElement.cs
@@ -0,0 +1,63 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+namespace Microsoft.VisualStudio.Text.Formatting
+{
+ /// <summary>
+ /// Represents a sequence element that consists of an adornment.
+ /// </summary>
+ public interface IAdornmentElement : ISequenceElement
+ {
+ /// <summary>
+ /// Gets the width of the adornment (in logical pixels).
+ /// </summary>
+ double Width { get; }
+
+ /// <summary>
+ /// Gets the amount of space (in logical pixels) to reserve above top of the text for the <see cref="ITextViewLine"/>.
+ /// </summary>
+ double TopSpace { get; }
+
+ /// <summary>
+ /// The distance (in logical pixel)s between the top of the adornment text and the baseline of the
+ /// <see cref="ITextViewLine"/>.
+ /// </summary>
+ /// <remarks><para>This property should be equal to <see cref="TextHeight"/> unless you plan to draw into the space between the baseline of
+ /// <see cref="ITextViewLine"/> and its TextBottom.</para>
+ /// <para>The size of the baseline affects the amount of space reserved for text on an <see cref="ITextViewLine"/>, which is used to
+ /// determine the vertical size of the caret.</para>
+ /// </remarks>
+ double Baseline { get; }
+
+ /// <summary>
+ /// Gets the height of the adornment text.
+ /// </summary>
+ /// <remarks><para>This affects the amount of space reserved for text on an <see cref="ITextViewLine"/>, which is used to
+ /// determine the vertical size of the caret.</para></remarks>
+ double TextHeight { get; }
+
+ /// <summary>
+ /// The amount of space (in logical pixels) to reserve below the bottom of the text in the <see cref="ITextViewLine"/>.
+ /// </summary>
+ double BottomSpace { get; }
+
+ /// <summary>
+ /// Gets the unique identifier associated with this adornment.
+ /// </summary>
+ /// <remarks>This ID can be passed to <see cref="ITextViewLine"/>.GetAdornmentBounds() to find the location
+ /// of this adornment on a line in the view.</remarks>
+ object IdentityTag { get; }
+
+ /// <summary>
+ /// Gets the unique identifier associated with the provider of the adornment.
+ /// </summary>
+ /// <remarks>This ID can be passed to <see cref="ITextViewLine.GetAdornmentTags"/> to find the list
+ /// off adornment identity tags located on the line.</remarks>
+ object ProviderTag { get; }
+
+ /// <summary>
+ /// Gets the <see cref="PositionAffinity"/> of the adornment.
+ /// </summary>
+ /// <remarks>This is used only when the length of the adornment element span in the source buffer is zero.</remarks>
+ PositionAffinity Affinity { get; }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Formatting/ISequenceElement.cs b/src/Text/Def/TextUI/Formatting/ISequenceElement.cs
new file mode 100644
index 0000000..025d8e6
--- /dev/null
+++ b/src/Text/Def/TextUI/Formatting/ISequenceElement.cs
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Formatting
+{
+ /// <summary>
+ /// Represents the basic element in a sequence of elements that compose an <see cref="ITextViewLine"/>.
+ /// </summary>
+ public interface ISequenceElement
+ {
+ /// <summary>
+ /// Gets the <see cref="IMappingSpan"/> of the element.
+ /// </summary>
+ IMappingSpan Span { get; }
+
+ /// <summary>
+ /// Determines whether the text in the span should be rendered in the <see cref="ITextViewLine"/>.
+ /// </summary>
+ bool ShouldRenderText { get; }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Formatting/ITextAndAdornmentCollection.cs b/src/Text/Def/TextUI/Formatting/ITextAndAdornmentCollection.cs
new file mode 100644
index 0000000..a182bba
--- /dev/null
+++ b/src/Text/Def/TextUI/Formatting/ITextAndAdornmentCollection.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Formatting
+{
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Represents a list of <see cref="ISequenceElement"/> objects generated by the <see cref="ITextAndAdornmentSequencer"/>.
+ /// </summary>
+ public interface ITextAndAdornmentCollection : IList<ISequenceElement>
+ {
+ /// <summary>
+ /// Gets the <see cref="ITextAndAdornmentSequencer"/> that generated the collection.
+ /// </summary>
+ ITextAndAdornmentSequencer Sequencer { get; }
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Formatting/ITextAndAdornmentSequencer.cs b/src/Text/Def/TextUI/Formatting/ITextAndAdornmentSequencer.cs
new file mode 100644
index 0000000..5e9477e
--- /dev/null
+++ b/src/Text/Def/TextUI/Formatting/ITextAndAdornmentSequencer.cs
@@ -0,0 +1,50 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Formatting
+{
+ using Microsoft.VisualStudio.Text.Projection;
+ using System;
+
+ /// <summary>
+ /// Creates a sequence of text and adornment elements to compose an <see cref="ITextSnapshotLine"/>.
+ /// </summary>
+ public interface ITextAndAdornmentSequencer
+ {
+ /// <summary>
+ /// Gets the <see cref="IBufferGraph"/> used by the sequencer.
+ /// </summary>
+ IBufferGraph BufferGraph { get; }
+
+ /// <summary>
+ /// Gets the visual <see cref="ITextBuffer"/> of the buffer graph.
+ /// </summary>
+ ITextBuffer TopBuffer { get; }
+
+ /// <summary>
+ /// Gets the edit buffer of the buffer graph.
+ /// </summary>
+ ITextBuffer SourceBuffer { get; }
+
+ /// <summary>
+ /// Creates a sequence of text and adornment elements that compose the specified <see cref="ITextSnapshotLine"/>.
+ /// </summary>
+ /// <param name="topLine">The <see cref="ITextSnapshotLine"/> in the <see cref="TopBuffer"/> to sequence.</param>
+ /// <param name="sourceTextSnapshot">The <see cref="ITextSnapshot"/> of the <see cref="SourceBuffer"/> that corresponds to topLine.</param>
+ /// <returns>A normalized collection of <see cref="ISequenceElement"/> objects that contain the text and adornment elements.</returns>
+ ITextAndAdornmentCollection CreateTextAndAdornmentCollection(ITextSnapshotLine topLine, ITextSnapshot sourceTextSnapshot);
+
+ /// <summary>
+ /// Creates a sequence of text and adornment elements that compose the specified <see cref="SnapshotSpan"/>.
+ /// </summary>
+ /// <param name="topSpan">The <see cref="SnapshotSpan"/> in the <see cref="TopBuffer"/> to sequence.</param>
+ /// <param name="sourceTextSnapshot">The <see cref="ITextSnapshot"/> of the <see cref="SourceBuffer"/> that corresponds to topSpan.</param>
+ /// <returns>A normalized collection of <see cref="ISequenceElement"/> objects that contain the text and adornment elements.</returns>
+ ITextAndAdornmentCollection CreateTextAndAdornmentCollection(SnapshotSpan topSpan, ITextSnapshot sourceTextSnapshot);
+
+ /// <summary>
+ /// Occurs when there has been a change in the data used by the sequencer.
+ /// </summary>
+ event EventHandler<TextAndAdornmentSequenceChangedEventArgs> SequenceChanged;
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Formatting/ITextAndAdornmentSequencerFactoryService.cs b/src/Text/Def/TextUI/Formatting/ITextAndAdornmentSequencerFactoryService.cs
new file mode 100644
index 0000000..16318f5
--- /dev/null
+++ b/src/Text/Def/TextUI/Formatting/ITextAndAdornmentSequencerFactoryService.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Formatting
+{
+ using Microsoft.VisualStudio.Text.Editor;
+
+ /// <summary>
+ /// Service to create an instance of an <see cref="ITextAndAdornmentSequencer"/>.
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// ITextAndAdornmentSequencerFactoryService factory = null;
+ /// </remarks>
+ /// </summary>
+ public interface ITextAndAdornmentSequencerFactoryService
+ {
+ /// <summary>
+ /// Creates an <see cref="ITextAndAdornmentSequencer"/> for the specified <see cref="ITextView"/>.
+ /// </summary>
+ /// <param name="view">The <see cref="ITextView"/>.</param>
+ /// <returns>The <see cref="ITextAndAdornmentSequencer"/>.</returns>
+ ITextAndAdornmentSequencer Create(ITextView view);
+ }
+}
diff --git a/src/Text/Def/TextUI/Formatting/ITextViewLine.cs b/src/Text/Def/TextUI/Formatting/ITextViewLine.cs
new file mode 100644
index 0000000..b076c2a
--- /dev/null
+++ b/src/Text/Def/TextUI/Formatting/ITextViewLine.cs
@@ -0,0 +1,492 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Formatting
+{
+ using System;
+ using System.Collections.ObjectModel;
+
+ using Microsoft.VisualStudio.Text;
+
+ /// <summary>
+ /// Represents text that has been formatted for display in a text view.
+ /// </summary>
+ /// <remarks>
+ /// <para>Most properties and parameters that are doubles correspond to coordinates or distances in the text
+ /// rendering coordinate system. In this coordinate system, x = 0.0 corresponds to the left edge of the drawing
+ /// surface onto which text is rendered (x = view.ViewportLeft corresponds to the left edge of the viewport), and y = view.ViewportTop corresponds to the top edge of the viewport. The x-coordinate increases
+ /// from left to right, and the y-coordinate increases from top to bottom. </para>
+ /// <para>The horizontal and vertical axes of the view behave differently. When the text in the view is
+ /// formatted, only the visible lines are formatted. As a result,
+ /// a viewport cannot be scrolled horizontally and vertically in the same way.</para>
+ /// <para>A viewport is scrolled horizontally by changing the left coordinate of the
+ /// viewport so that it moves with respect to the drawing surface.</para>
+ /// <para>A view can be scrolled vertically only by performing a new layout.</para>
+ /// <para>Doing a layout in the view may cause the ViewportTop property of the view to change. For example, scrolling down one line will not translate any of the visible lines.
+ /// Instead it will simply change the view's ViewportTop property (causing the lines to move on the screen even though their y-coordinates have not changed).</para>
+ /// <para>Distances in the text rendering coordinate system correspond to logical pixels. If the text rendering
+ /// surface is displayed without any scaling transform, then 1 unit in the text rendering coordinate system
+ /// corresponds to one pixel on the display.</para>
+ /// </remarks>
+ public interface ITextViewLine
+ {
+ #region Methods
+
+ /// <summary>
+ /// Gets the buffer position of the character whose character bounds contains the given x-coordinate.
+ /// </summary>
+ /// <param name="xCoordinate">The x-coordinate of the desired character.</param>
+ /// <param name="textOnly">If true, then this method will return null if <paramref name="xCoordinate"/> is over an adornment.</param>
+ /// <returns>The text buffer-based point of the character at x, or null if there is no character at that position.</returns>
+ /// <remarks>
+ /// <para>
+ /// Please note that the rightmost edge of a character bound is considered to be contained in its following character.
+ /// </para>
+ /// <para>
+ /// The rightmost edge of the last character's bounds don't map to any character.
+ /// </para>
+ /// <para>
+ /// If <paramref name="textOnly"/> is true and <paramref name="xCoordinate"/> is over an adornment, then the text position assoicated with the adornment is returned.
+ /// </para>
+ /// </remarks>
+ SnapshotPoint? GetBufferPositionFromXCoordinate(double xCoordinate, bool textOnly);
+
+ /// <summary>
+ /// Gets the buffer position of the character whose character bounds contains the given x-coordinate.
+ /// </summary>
+ /// <param name="xCoordinate">The x-coordinate of the desired character.</param>
+ /// <returns>The text buffer-based point of the character at x, or null if there is no character at that position.</returns>
+ /// <remarks>
+ /// <para>
+ /// This is equivalent to GetBufferPositionFromXCoordinate(xCoordinate, false).
+ /// </para>
+ /// </remarks>
+ SnapshotPoint? GetBufferPositionFromXCoordinate(double xCoordinate);
+
+
+
+ /// <summary>
+ /// Gets the buffer position of the character whose character bounds contains the given x-coordinate.
+ /// </summary>
+ /// <param name="xCoordinate">The x-coordinate of the desired character.</param>
+ /// <returns>The text buffer-based point of the character at x</returns>
+ /// <remarks>
+ /// <para>
+ /// If there are no characters at the provided x-coordinate, a point in virtual space will be returned.
+ /// </para>
+ /// <para>
+ /// If the provided x-coordinate is to the left of the start of the line, the buffer position of the line's
+ /// left edge will be returned.
+ /// </para>
+ /// </remarks>
+ VirtualSnapshotPoint GetVirtualBufferPositionFromXCoordinate(double xCoordinate);
+
+ /// <summary>
+ /// Gets the buffer position used if new data were to be inserted at the given x-coordinate.
+ /// </summary>
+ /// <param name="xCoordinate">The x-coordinate of the desired point.</param>
+ /// <remarks>
+ /// <para>
+ /// If there are no characters at the provided x-coordinate, a point in virtual space will be returned.
+ /// </para>
+ /// <para>
+ /// If the provided x-coordinate is to the left of the start of the line, the buffer position of the line's
+ /// left edge will be returned.
+ /// </para>
+ /// </remarks>
+ VirtualSnapshotPoint GetInsertionBufferPositionFromXCoordinate(double xCoordinate);
+
+ /// <summary>
+ /// Determines whether the specified buffer position lies within this text line.
+ /// </summary>
+ /// <param name="bufferPosition">The buffer position.</param>
+ /// <returns><c>true</c> if <paramref name="bufferPosition"/> lies within this text line, otherwise <c>false</c>.</returns>
+ /// <remarks>
+ /// This method handles the special processing required for the last line of the buffer.
+ /// </remarks>
+ bool ContainsBufferPosition(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Gets the span whose text elementindex corresponds to the given buffer position.
+ /// </summary>
+ /// <param name="bufferPosition">The buffer position.</param>
+ /// <returns>The <see cref="SnapshotSpan"/> that corresponds to the given text element.</returns>
+ SnapshotSpan GetTextElementSpan(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Calculates the bounds of the character at the specified buffer position.
+ /// </summary>
+ /// <param name="bufferPosition">
+ /// The text buffer-based index of the character.
+ /// </param>
+ /// <returns>
+ /// A <see cref="TextBounds"/> structure.
+ /// </returns>
+ /// <remarks>Bi-directional text will have a leading edge that lies to the right of its trailing edge.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferPosition"/> does not correspond to a position on this line.</exception>
+ TextBounds GetCharacterBounds(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Calculates the bounds of the character at the specified buffer position.
+ /// </summary>
+ /// <param name="bufferPosition">
+ /// The text buffer-based index of the character.
+ /// </param>
+ /// <returns>
+ /// A <see cref="TextBounds"/> structure.
+ /// </returns>
+ /// <remarks>Bi-directional text will have a leading edge that lies to the right of its trailing edge.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferPosition"/> does not correspond to a position on this line.</exception>
+ TextBounds GetCharacterBounds(VirtualSnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Calculates the bounds of the character at the specified buffer position, including any adjacent
+ /// space-negotiating adornments.
+ /// </summary>
+ /// <param name="bufferPosition">
+ /// The text buffer-based index of the character.
+ /// </param>
+ /// <returns>
+ /// A <see cref="TextBounds"/> structure.
+ /// </returns>
+ /// <remarks>Bi-directional text will have a leading edge that lies to the right of its trailing edge.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferPosition"/> does not correspond to a position on this line.</exception>
+ TextBounds GetExtendedCharacterBounds(SnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Calculates the bounds of the character at the specified virtual buffer position, including any adjacent
+ /// space-negotiating adornments.
+ /// </summary>
+ /// <param name="bufferPosition">
+ /// The text buffer-based index of the character.
+ /// </param>
+ /// <returns>
+ /// A <see cref="TextBounds"/> structure.
+ /// </returns>
+ /// <remarks>Bi-directional text will have a leading edge that lies to the right of its trailing edge.</remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferPosition"/> does not correspond to a position on this line.</exception>
+ TextBounds GetExtendedCharacterBounds(VirtualSnapshotPoint bufferPosition);
+
+ /// <summary>
+ /// Calculates the bounds of the specified adornment.
+ /// </summary>
+ /// <param name="identityTag">
+ /// The <c>IAdornmentElement.IdentityTag</c> of the adornment whose bounds should be calculated.
+ /// </param>
+ /// <returns>
+ /// A <see cref="TextBounds"/> structure if this line contains an adornment with the specified <paramref name="identityTag"/>,
+ /// otherwise null.
+ /// </returns>
+ TextBounds? GetAdornmentBounds(object identityTag);
+
+ /// <summary>
+ /// Gets a collection of <see cref="TextBounds"/> structures for the text that corresponds to the given span.
+ /// </summary>
+ /// <param name="bufferSpan">
+ /// The <see cref="SnapshotSpan"/> representing the text for which to compute the text bounds.
+ /// </param>
+ /// <returns>
+ /// A collection of <see cref="TextBounds"/> structures that contain the text specified in <paramref name="bufferSpan"/>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// If the line contains bidirectional text, the <see cref="TextBounds"/> structures that are returned may be disjoint.
+ /// </para>
+ /// <para>
+ /// The height and top of the bounds will correspond to the top and bottom of this <see cref="ITextViewLine"/>.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="bufferSpan"/> is not a legal span in the underlying text buffer.</exception>
+ Collection<TextBounds> GetNormalizedTextBounds(SnapshotSpan bufferSpan);
+
+ /// <summary>
+ /// Gets a tag that can be used to track the identity of an <see cref="ITextViewLine"/> across layouts in the view.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// If an <see cref="ITextViewLine"/> has the same identity tag as the <see cref="ITextViewLine"/> from an earlier layout,
+ /// then both text view lines correspond to the same text, even when the
+ /// text has been moved without being modifed, or when the text view lines appear at different locations
+ /// in the view.
+ /// </para>
+ /// <para>
+ /// This property can be called even when the <see cref="ITextViewLine"/> is invalid.
+ /// </para>
+ /// </remarks>
+ object IdentityTag { get; }
+
+ /// <summary>
+ /// Determines whether a <paramref name="bufferSpan"/> intersects this text line.
+ /// </summary>
+ /// <param name="bufferSpan">The buffer span.</param>
+ /// <returns><c>true</c> if <paramref name="bufferSpan"/> intersects the text line, otherwise <c>false</c>.</returns>
+ /// <remarks>
+ /// This method handles the special processing required for the last line of the buffer.
+ /// </remarks>
+ bool IntersectsBufferSpan(SnapshotSpan bufferSpan);
+
+ /// <summary>
+ /// Gets the adornments positioned on the line.
+ /// </summary>
+ /// <param name="providerTag">The identity tag of the provider.
+ /// This tag should match <c>SpaceNegotiatingAdornmentTag.ProviderTag</c>.</param>
+ /// <returns>A sequence of adornment identity tags in order of their appearance on the line. The collection is always non-null but may be empty.</returns>
+ /// <exception cref="System.ArgumentNullException"><paramref name="providerTag "/> is null.</exception>
+ ReadOnlyCollection<object> GetAdornmentTags(object providerTag);
+ #endregion // Methods
+
+ #region Properties
+
+ /// <summary>
+ /// Gets the <see cref="ITextSnapshot"/> on which this map is based.
+ /// </summary>
+ ITextSnapshot Snapshot { get; }
+
+ /// <summary>
+ /// Determines whether this <see cref="ITextViewLine"/> is the first line in the list of lines formatted for a particular
+ /// <see cref="ITextSnapshotLine"/>.
+ /// </summary>
+ /// <remarks>This property will always be <c>true</c> for lines that are not word-wrapped.</remarks>
+ bool IsFirstTextViewLineForSnapshotLine { get; }
+
+ /// <summary>
+ /// Determines whether this <see cref="ITextViewLine"/> is the last line in the list of lines formatted for a particular
+ /// <see cref="ITextSnapshotLine"/>.
+ /// </summary>
+ /// <remarks>This property will always be <c>true</c> for lines that are not word-wrapped.</remarks>
+ bool IsLastTextViewLineForSnapshotLine { get; }
+
+ /// <summary>
+ /// Gets the distance from the top of the text to the baseline text on the line.
+ /// </summary>
+ double Baseline { get; }
+
+ /// <summary>
+ /// Gets the extent of the line, excluding any line break characters.
+ /// </summary>
+ SnapshotSpan Extent { get; }
+
+ /// <summary>
+ /// Gets the <see cref="IMappingSpan"/> that corresponds to the <see cref="Extent"/> of the line.
+ /// </summary>
+ IMappingSpan ExtentAsMappingSpan { get; }
+
+ /// <summary>
+ /// Gets the extent of the line, including any line break characters.
+ /// </summary>
+ SnapshotSpan ExtentIncludingLineBreak { get; }
+
+ /// <summary>
+ /// Gets the <see cref="IMappingSpan"/> that corresponds to <see cref="ExtentIncludingLineBreak"/>.
+ /// </summary>
+ IMappingSpan ExtentIncludingLineBreakAsMappingSpan { get; }
+
+ /// <summary>
+ /// Gets the position in <see cref="Snapshot"/> of the first character in the line.
+ /// </summary>
+ SnapshotPoint Start { get; }
+
+ /// <summary>
+ /// Gets the length of the line, excluding any line break characters.
+ /// </summary>
+ int Length { get; }
+
+ /// <summary>
+ /// Gets the length of the line, including any line break characters.
+ /// </summary>
+ int LengthIncludingLineBreak { get; }
+
+ /// <summary>
+ /// Gets the position of the first character past the end of the line, excluding any
+ /// line break characters. In most cases this property references a line break character, except
+ /// for the last line in the buffer, in which case it contains a
+ /// position past the end of the buffer.
+ /// </summary>
+ SnapshotPoint End { get; }
+
+ /// <summary>
+ /// Gets the position of the first character past the end of the line, including any
+ /// line break characters In most cases this property references the first character in
+ /// the following line, unless this is the last line, in which case it contains a
+ /// position past the end of the buffer.
+ /// </summary>
+ SnapshotPoint EndIncludingLineBreak { get; }
+
+ /// <summary>
+ /// Gets the length of the line break sequence (for example, "\r\n") that appears at the end of this line.
+ /// </summary>
+ /// <value>A integer in the range [0..2].</value>
+ /// <remarks>
+ /// If this <see cref="ITextViewLine"/> corresponds to a line that was word-wrapped, then the length of its
+ /// line break will be zero. The length of the line break will also be zero for the last line in the buffer.
+ /// </remarks>
+ int LineBreakLength
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the position of the left edge of this line in the text rendering coordinate system.
+ /// </summary>
+ double Left
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the position of the top edge of this line in the text rendering coordinate system.
+ /// </summary>
+ double Top
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the distance between the top and bottom edge of this line.
+ /// </summary>
+ double Height
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the y-coordinate of the top of the text in the rendered line.
+ /// </summary>
+ double TextTop
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the y-coordinate of the bottom of the text in the rendered line.
+ /// </summary>
+ double TextBottom
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the vertical distance between the top and bottom of the text in the rendered line.
+ /// </summary>
+ double TextHeight
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the x-coordinate of the left edge of the text in the rendered line.
+ /// </summary>
+ /// <remarks>This will always be the same as <see cref="Left"/>.</remarks>
+ double TextLeft
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the x-coordinate of the right edge of the text in the rendered line.
+ /// </summary>
+ /// <remarks>This does not include the <see cref="EndOfLineWidth"/> for lines that have a line break.</remarks>
+ double TextRight
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the horizontal distance between <see cref="TextRight"/> and <see cref="TextLeft"/>.
+ /// </summary>
+ double TextWidth
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the distance between the left and right edges of this line.
+ /// </summary>
+ double Width
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the position of the bottom edge of this line in the text rendering coordinate system.
+ /// </summary>
+ double Bottom
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the position of the right edge of this line in the text rendering coordinate system.
+ /// </summary>
+ double Right
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the distance from the right edge of the last character in this line to
+ /// the end of the space of this line. This may include padding for line break
+ /// characters or for end of file characters.
+ /// </summary>
+ double EndOfLineWidth
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Get the width of the virtual spaces at the end of this line.
+ /// </summary>
+ double VirtualSpaceWidth
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Determines whether this text view line is still valid.
+ /// </summary>
+ bool IsValid
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="LineTransform"/> used to render this line.
+ /// </summary>
+ LineTransform LineTransform { get; }
+
+ /// <summary>
+ /// Gets the default <see cref="LineTransform"/> used to render this line.
+ /// </summary>
+ /// <remarks>
+ /// This is the line transform used if no other extension defines a <see cref="LineTransform"/> for the line.</remarks>
+ LineTransform DefaultLineTransform { get; }
+
+ /// <summary>
+ /// Gets the visibility state of this rendered text line with respect to the top and bottom of the view.
+ /// </summary>
+ /// <exception cref="ObjectDisposedException">This <see cref="ITextViewLine"/> has been disposed.</exception>
+ VisibilityState VisibilityState { get; }
+
+ /// <summary>
+ /// Gets the change in the top of this rendered textline between between the value of <see cref="Top"/>
+ /// in the current layout and the value of <see cref="Top"/> in the previous layout.
+ /// </summary>
+ /// <remarks>This property is 0.0 for rendered text lines that did not exist in the
+ /// previous layout.</remarks>
+ double DeltaY
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the change to this rendered textline between the current layout and
+ /// the previous layout.
+ /// </summary>
+ TextViewLineChange Change
+ {
+ get;
+ }
+
+ #endregion // Properties
+ }
+}
diff --git a/src/Text/Def/TextUI/Formatting/LineTransform.cs b/src/Text/Def/TextUI/Formatting/LineTransform.cs
new file mode 100644
index 0000000..650a510
--- /dev/null
+++ b/src/Text/Def/TextUI/Formatting/LineTransform.cs
@@ -0,0 +1,192 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Formatting
+{
+ using System;
+ using System.Collections.ObjectModel;
+
+ using Microsoft.VisualStudio.Text;
+
+ /// <summary>
+ /// Represents the transform from a formatted text line to a rendered text line.
+ /// </summary>
+ /// <remarks>
+ /// <para>Most properties and parameters that are doubles correspond to coordinates or distances in the text
+ /// rendering coordinate system. In this coordinate system, x = 0.0 corresponds to the left edge of the drawing
+ /// surface onto which text is rendered (x = view.ViewportLeft corresponds to the left edge of the viewport), and y = view.ViewportTop corresponds to the top edge of the viewport. The x-coordinate increases
+ /// from left to right, and the y-coordinate increases from top to bottom. </para>
+ /// <para>The horizontal and vertical axes of the view behave differently. When the text in the view is
+ /// formatted, only the visible lines are formatted. As a result,
+ /// a viewport cannot be scrolled horizontally and vertically in the same way.</para>
+ /// <para>A viewport is scrolled horizontally by changing the left coordinate of the
+ /// viewport so that it moves with respect to the drawing surface.</para>
+ /// <para>A view can be scrolled vertically only by performing a new layout.</para>
+ /// <para>Doing a layout in the view may cause the ViewportTop property of the view to change. For example, scrolling down one line will not translate any of the visible lines.
+ /// Instead it will simply change the view's ViewportTop property (causing the lines to move on the screen even though their y-coordinates have not changed).</para>
+ /// <para>Distances in the text rendering coordinate system correspond to logical pixels. If the text rendering
+ /// surface is displayed without any scaling transform, then 1 unit in the text rendering coordinate system
+ /// corresponds to one pixel on the display.</para>
+ /// </remarks>
+ public struct LineTransform
+ {
+ private readonly double _topSpace;
+ private readonly double _bottomSpace;
+ private readonly double _verticalScale;
+ private readonly double _right;
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="LineTransform"/>.
+ /// </summary>
+ /// <param name="verticalScale">The vertical scale factor to be applied to the text of the line, but not the space above and below the line.</param>
+ /// <remarks>
+ /// <para>All <see cref="LineTransform"/> objects on a formatted line of text are combined using the <see cref="Combine"/> operator below.
+ /// The resulting <see cref="LineTransform"/> determines the placement and scaling of the rendered line of text.</para>
+ /// </remarks>
+ public LineTransform(double verticalScale)
+ : this(0.0, 0.0, verticalScale, 0.0)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="LineTransform"/>.
+ /// </summary>
+ /// <param name="topSpace">The amount of space required above the text of the line before applying <paramref name="verticalScale"/>.</param>
+ /// <param name="bottomSpace">The amount of space required below the text of the line before applying <paramref name="verticalScale"/>.</param>
+ /// <param name="verticalScale">The vertical scale factor to be applied to the text of the line, but not the space above and below the line.</param>
+ /// <remarks>
+ /// <para>All the <see cref="LineTransform"/> objects on a formatted line of text are combined
+ /// using the <see cref="Combine"/> operator, and the combined <see cref="LineTransform"/> determines
+ /// the placement and scaling of the rendered line of text.</para>
+ /// <para>Negative <paramref name="topSpace"/> and <paramref name="bottomSpace"/> values will be ignored,
+ /// since they will always be combined with
+ /// at least one <see cref="LineTransform"/> with non-negative space requests.</para>
+ /// <para>The rendered height of a line will be
+ /// ((line text height) + <paramref name="topSpace"/> + <paramref name="bottomSpace"/>) * <paramref name="verticalScale"/>.</para>
+ /// </remarks>
+ public LineTransform(double topSpace, double bottomSpace, double verticalScale)
+ : this(topSpace, bottomSpace, verticalScale, 0.0)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="LineTransform"/>.
+ /// </summary>
+ /// <param name="topSpace">The amount of space required above the text of the line before applying <paramref name="verticalScale"/>.</param>
+ /// <param name="bottomSpace">The amount of space required below the text of the line before applying <paramref name="verticalScale"/>.</param>
+ /// <param name="verticalScale">The vertical scale factor to be applied to the text of the line and the space above and below the line.</param>
+ /// <param name="right">The x-coordinate of the right edge the line (typically the right edge of any adornment on the line that extends to the right of the line's text).</param>
+ /// <remarks>
+ /// <para>All the <see cref="LineTransform"/> objects on a formatted line of text are combined
+ /// using the <see cref="Combine"/> operator, and the combined <see cref="LineTransform"/> determines
+ /// the placement and scaling of the rendered line of text.</para>
+ /// <para>Negative <paramref name="topSpace"/> and <paramref name="bottomSpace"/> values will be ignored,
+ /// since they will always be combined with
+ /// at least one <see cref="LineTransform"/> with non-negative space requests.</para>
+ /// <para>The rendered height of a line will be
+ /// ((line text height) + <paramref name="topSpace"/> + <paramref name="bottomSpace"/>) * <paramref name="verticalScale"/>.</para>
+ /// </remarks>
+ public LineTransform(double topSpace, double bottomSpace, double verticalScale, double right)
+ {
+ if (double.IsNaN(topSpace))
+ throw new ArgumentOutOfRangeException("topSpace");
+
+ if (double.IsNaN(bottomSpace))
+ throw new ArgumentOutOfRangeException("bottomSpace");
+
+ if ((verticalScale <= 0.0) || double.IsNaN(verticalScale))
+ throw new ArgumentOutOfRangeException("verticalScale");
+
+ if ((right < 0.0) || double.IsNaN(right))
+ throw new ArgumentOutOfRangeException("right");
+
+ _topSpace = topSpace;
+ _bottomSpace = bottomSpace;
+ _verticalScale = verticalScale;
+ _right = right;
+ }
+
+ /// <summary>
+ /// Gets the amount of space required above the text of the line before applying the <see cref="VerticalScale"/> factor.
+ /// </summary>
+ public double TopSpace { get { return _topSpace; } }
+
+ /// <summary>
+ /// Gets the amount of space required below the text of the line before applying the <see cref="VerticalScale"/> factor.
+ /// </summary>
+ public double BottomSpace { get { return _bottomSpace; } }
+
+ /// <summary>
+ /// Gets the vertical scale factor to be applied to the text of the line. The scale factor does not affect
+ /// and the space above and below the line.
+ /// </summary>
+ public double VerticalScale { get { return _verticalScale; } }
+
+ /// <summary>
+ /// Gets the x-coordinate of the effective right edge of the line.
+ /// </summary>
+ public double Right { get { return _right; } }
+
+ /// <summary>
+ /// Combines two <see cref="LineTransform"/> objects.
+ /// </summary>
+ /// <param name="transform1">The first <see cref="LineTransform"/> to combine.</param>
+ /// <param name="transform2">The second <see cref="LineTransform"/> to combine.</param>
+ /// <returns>The combined <see cref="LineTransform"/>.</returns>
+ public static LineTransform Combine(LineTransform transform1, LineTransform transform2)
+ {
+ return new LineTransform(Math.Max(transform1.TopSpace, transform2.TopSpace),
+ Math.Max(transform1.BottomSpace, transform2.BottomSpace),
+ transform1.VerticalScale * transform2.VerticalScale,
+ Math.Max(transform1.Right, transform2.Right));
+ }
+
+ #region Overridden methods and operators
+
+ /// <summary>
+ /// Gets the hash code for this object.
+ /// </summary>
+ public override int GetHashCode()
+ {
+ return (_topSpace.GetHashCode() ^ _bottomSpace.GetHashCode() ^ _verticalScale.GetHashCode() ^ _right.GetHashCode());
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="LineTransform"/> objects are the same.
+ /// </summary>
+ /// <param name="obj">The object to compare for equality.</param>
+ public override bool Equals(object obj)
+ {
+ if (obj is LineTransform)
+ {
+ LineTransform other = (LineTransform)obj;
+ return this == other;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="LineTransform"/> objects are the same.
+ /// </summary>
+ public static bool operator ==(LineTransform transform1, LineTransform transform2)
+ {
+ return (transform1._topSpace == transform2._topSpace) &&
+ (transform1._bottomSpace == transform2._bottomSpace) &&
+ (transform1._verticalScale == transform2._verticalScale) &&
+ (transform1._right == transform2._right);
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="LineTransform"/> objects are different.
+ /// </summary>
+ public static bool operator !=(LineTransform transform1, LineTransform transform2)
+ {
+ return !(transform1 == transform2);
+ }
+
+ #endregion // Overridden methods and operators
+ }
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Formatting/TextAndAdornmentSequenceChangedEventArgs.cs b/src/Text/Def/TextUI/Formatting/TextAndAdornmentSequenceChangedEventArgs.cs
new file mode 100644
index 0000000..ec96620
--- /dev/null
+++ b/src/Text/Def/TextUI/Formatting/TextAndAdornmentSequenceChangedEventArgs.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Formatting
+{
+ using System;
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Provides information for the tag aggregator TagsChanged event,
+ /// and returns the span of changed tags as a mapping span.
+ /// </summary>
+ public class TextAndAdornmentSequenceChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the span over which tags have changed.
+ /// </summary>
+ public IMappingSpan Span { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="TextAndAdornmentSequenceChangedEventArgs"/> with the specified <see cref="IMappingSpan" />.
+ /// </summary>
+ /// <param name="span">The span that changed.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="span"/> is null.</exception>
+ public TextAndAdornmentSequenceChangedEventArgs(IMappingSpan span)
+ {
+ if (span == null)
+ throw new ArgumentNullException("span");
+
+ this.Span = span;
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/Formatting/TextBounds.cs b/src/Text/Def/TextUI/Formatting/TextBounds.cs
new file mode 100644
index 0000000..d1782e3
--- /dev/null
+++ b/src/Text/Def/TextUI/Formatting/TextBounds.cs
@@ -0,0 +1,288 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Formatting
+{
+ using System;
+
+ /// <summary>
+ /// The bounds of a span of text in a given text line.
+ /// </summary>
+ /// <remarks>
+ /// <para>Most properties and parameters that are doubles correspond to coordinates or distances in the text
+ /// rendering coordinate system. In this coordinate system, x = 0.0 corresponds to the left edge of the drawing
+ /// surface onto which text is rendered (x = view.ViewportLeft corresponds to the left edge of the viewport), and y = view.ViewportTop corresponds to the top edge of the viewport. The x-coordinate increases
+ /// from left to right, and the y-coordinate increases from top to bottom. </para>
+ /// <para>The horizontal and vertical axes of the view behave differently. When the text in the view is
+ /// formatted, only the visible lines are formatted. As a result,
+ /// a viewport cannot be scrolled horizontally and vertically in the same way.</para>
+ /// <para>A viewport is scrolled horizontally by changing the left coordinate of the
+ /// viewport so that it moves with respect to the drawing surface.</para>
+ /// <para>A view can be scrolled vertically only by performing a new layout.</para>
+ /// <para>Doing a layout in the view may cause the ViewportTop property of the view to change. For example, scrolling down one line will not translate any of the visible lines.
+ /// Instead it will simply change the view's ViewportTop property (causing the lines to move on the screen even though their y-coordinates have not changed).</para>
+ /// <para>Distances in the text rendering coordinate system correspond to logical pixels. If the text rendering
+ /// surface is displayed without any scaling transform, then 1 unit in the text rendering coordinate system
+ /// corresponds to one pixel on the display.</para>
+ /// </remarks>
+ public struct TextBounds
+ {
+ #region Private Members
+ private readonly double _leading;
+ private readonly double _top;
+ private readonly double _bidiWidth;
+ private readonly double _height;
+ private readonly double _textTop;
+ private readonly double _textHeight;
+ #endregion // Private Members
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="TextBounds"/>.
+ /// </summary>
+ /// <param name="leading">
+ /// The x-coordinate of the leading edge of the bounding rectangle.
+ /// </param>
+ /// <param name="top">
+ /// The y-coordinate of the top edge of the bounding rectangle.
+ /// </param>
+ /// <param name="bidiWidth">;
+ /// The distance between the leading and trailing edges of the bounding rectangle. This can be negative for right-to-left text.
+ /// </param>
+ /// <param name="height">
+ /// The height of the rectangle. The height must be non-negative.
+ /// </param>
+ /// <param name="textTop">
+ /// The top of the text, measured from the line that contains the text.
+ /// </param>
+ /// <param name="textHeight">
+ /// The height of the text, measured from the line that contains the text.
+ /// </param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="leading"/> or <paramref name="bidiWidth"/> is not a valid number, or
+ /// <paramref name="height"/> is negative or not a valid number.</exception>
+ public TextBounds(double leading, double top, double bidiWidth, double height, double textTop, double textHeight)
+ {
+ // Validate
+ if (double.IsNaN(leading))
+ throw new ArgumentOutOfRangeException("leading");
+ if (double.IsNaN(top))
+ throw new ArgumentOutOfRangeException("top");
+ if (double.IsNaN(bidiWidth))
+ throw new ArgumentOutOfRangeException("bidiWidth");
+ if (double.IsNaN(height) || (height < 0.0))
+ throw new ArgumentOutOfRangeException("height");
+ if (double.IsNaN(textTop))
+ throw new ArgumentOutOfRangeException("textTop");
+ if (double.IsNaN(textHeight) || (textHeight < 0.0))
+ throw new ArgumentOutOfRangeException("textHeight");
+
+ _leading = leading;
+ _top = top;
+ _bidiWidth = bidiWidth;
+ _height = height;
+ _textTop = textTop;
+ _textHeight = textHeight;
+ }
+
+ #region Public Properties
+
+ /// <summary>
+ /// Gets the position of the leading edge of the rectangle in the text rendering coordinate system.
+ /// </summary>
+ /// <remarks>
+ /// In right-to-left text, the leading edge is to the right of the trailing edge.
+ /// </remarks>
+ public double Leading
+ {
+ get
+ {
+ return _leading;
+ }
+ }
+
+ /// <summary>
+ /// Gets the position of the top edge of the rectangle in the text rendering coordinate system.
+ /// </summary>
+ public double Top
+ {
+ get
+ {
+ return _top;
+ }
+ }
+
+ /// <summary>
+ /// Gets the top of the text on the line containing the text.
+ /// </summary>
+ public double TextTop
+ {
+ get
+ {
+ return _textTop;
+ }
+ }
+
+ /// <summary>
+ /// Gets the distance between the leading and trailing edges of the rectangle in the text rendering coordinate system.
+ /// </summary>
+ /// <remarks>
+ /// This value will always be non-negative.
+ /// </remarks>
+ public double Width
+ {
+ get
+ {
+ return Math.Abs(_bidiWidth);
+ }
+ }
+
+ /// <summary>
+ /// Gets the distance between the top and bottom edges of the rectangle in the text rendering coordinate system.
+ /// </summary>
+ /// <remarks>
+ /// This value will always be positive.
+ /// </remarks>
+ public double Height
+ {
+ get
+ {
+ return _height;
+ }
+ }
+
+ /// <summary>
+ /// Gets the height of the text on the line containing the characters.
+ /// </summary>
+ public double TextHeight
+ {
+ get
+ {
+ return _textHeight;
+ }
+ }
+
+ /// <summary>
+ /// Gets the position of the trailing edge of the rectangle in the text rendering coordinate system.
+ /// </summary>
+ /// <remarks>
+ /// In right-to-left text, the trailing edge is positioned to the left of the leading edge.
+ /// If the text has a non-zero width end of line glyph, this property includes the
+ /// width of that character.
+ /// </remarks>
+ public double Trailing
+ {
+ get
+ {
+ return _leading + _bidiWidth;
+ }
+ }
+
+ /// <summary>
+ /// Gets the position of the bottom edge of the rectangle in the text rendering coordinate system.
+ /// </summary>
+ public double Bottom
+ {
+ get
+ {
+ return _top + _height;
+ }
+ }
+
+ /// <summary>
+ /// Gets the bottom of the text on the line containing the characters.
+ /// </summary>
+ public double TextBottom
+ {
+ get
+ {
+ return _textTop + _textHeight;
+ }
+ }
+
+ /// <summary>
+ /// Gets the position of the left edge of the rectangle in the text rendering coordinate system.
+ /// </summary>
+ public double Left
+ {
+ get
+ {
+ return _bidiWidth >= 0.0 ? _leading : (_leading + _bidiWidth);
+ }
+ }
+
+ /// <summary>
+ /// Gets the position of the right edge of the rectangle in the text rendering coordinate system.
+ /// </summary>
+ public double Right
+ {
+ get
+ {
+ return _bidiWidth >= 0.0 ? (_leading + _bidiWidth) : _leading;
+ }
+ }
+
+ /// <summary>
+ /// Returns true if the bounds correspond to a right to left character
+ /// </summary>
+ public bool IsRightToLeft
+ {
+ get
+ {
+ return _bidiWidth < 0.0;
+ }
+ }
+
+ #endregion // Public Properties
+
+ #region Overrides
+
+ /// <summary>
+ /// Converts the <see cref="TextBounds"/> object to a string.
+ /// </summary>
+ public override string ToString()
+ {
+ return string.Format(System.Globalization.CultureInfo.InvariantCulture, "[{0},{1},{2},{3}]", this.Leading, this.Top, this.Trailing, this.Bottom);
+ }
+
+ /// <summary>
+ /// Gets the hash code of the see cref="TextBounds"/> object.
+ /// </summary>
+ public override int GetHashCode()
+ {
+ return _leading.GetHashCode() ^ _top.GetHashCode() ^ _bidiWidth.GetHashCode() ^ _height.GetHashCode() ^
+ _textTop.GetHashCode() ^ _textHeight.GetHashCode();
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="TextBounds"/> objects are the same.
+ /// </summary>
+ public override bool Equals(object obj)
+ {
+ // Check for the obvious
+ if (obj == null || !(obj is TextBounds))
+ return false;
+
+ TextBounds bounds = (TextBounds)obj;
+ return bounds == this;
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="TextBounds"/> objects are the same.
+ /// </summary>
+ public static bool operator ==(TextBounds bounds1, TextBounds bounds2)
+ {
+ return (bounds1._leading == bounds2._leading && bounds1._bidiWidth == bounds2._bidiWidth &&
+ bounds1._top == bounds2._top && bounds1._height == bounds2._height &&
+ bounds1._textTop == bounds2._textTop && bounds1._textHeight == bounds2._textHeight);
+ }
+
+ /// <summary>
+ /// Determines whether two <see cref="TextBounds"/> objects are different.
+ /// </summary>
+ public static bool operator !=(TextBounds bounds1, TextBounds bounds2)
+ {
+ return !(bounds1 == bounds2);
+ }
+
+ #endregion // Overrides
+ }
+}
diff --git a/src/Text/Def/TextUI/Formatting/TextViewLineChange.cs b/src/Text/Def/TextUI/Formatting/TextViewLineChange.cs
new file mode 100644
index 0000000..5b9f131
--- /dev/null
+++ b/src/Text/Def/TextUI/Formatting/TextViewLineChange.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Formatting
+{
+ /// <summary>
+ /// Defines the possible types of change in a rendered text line between one layout and another.
+ /// </summary>
+ public enum TextViewLineChange
+ {
+ /// <summary>
+ /// No change type is specified.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// The line is new or reformatted.
+ /// </summary>
+ NewOrReformatted,
+
+ /// <summary>
+ /// The text has not changed, but some change has caused the y-coordinate to change. For example,
+ /// a line was inserted above this line, or the user scrolled the view up or down.
+ /// </summary>
+ Translated
+ };
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Formatting/VisibilityState.cs b/src/Text/Def/TextUI/Formatting/VisibilityState.cs
new file mode 100644
index 0000000..38e90f2
--- /dev/null
+++ b/src/Text/Def/TextUI/Formatting/VisibilityState.cs
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Formatting
+{
+ /// <summary>
+ /// Specifies the visibility of an <see cref="ITextViewLine"/> with respect to the visible area when the line was rendered.
+ /// </summary>
+ /// <remarks>
+ /// <para>An <see cref="ITextViewLine"/> is considered partially visible when its
+ /// bottom is equal to the top of the visible area.</para>
+ /// <para>Unattached lines are lines that were not formatted as part of a layout in the text view.</para>
+ /// </remarks>
+ public enum VisibilityState
+ {
+ /// <summary>
+ /// The line is unattached, that is, it was not formatted as part of a layout in the text view.
+ /// </summary>
+ Unattached,
+
+ /// <summary>
+ /// The line is hidden, that is, not visible inside the view. Lines are also hidden when
+ /// their bottom edge is even with the top of the view or their top edge is even with the top of the view.
+ /// </summary>
+ Hidden,
+
+ /// <summary>
+ /// The line is partially visible, that is,
+ /// some portion of the line extends above the top of the view and/or below the bottom of the view.
+ /// </summary>
+ PartiallyVisible,
+
+ /// <summary>
+ /// The line is fully visible.
+ /// </summary>
+ FullyVisible
+ };
+} \ No newline at end of file
diff --git a/src/Text/Def/TextUI/FxCopSuppressions.cs b/src/Text/Def/TextUI/FxCopSuppressions.cs
new file mode 100644
index 0000000..2243cd3
--- /dev/null
+++ b/src/Text/Def/TextUI/FxCopSuppressions.cs
@@ -0,0 +1,99 @@
+#if CODE_ANALYSIS_BASELINE
+using System.Diagnostics.CodeAnalysis;
+
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.ITextView.ViewportHeight", MessageId = "Viewport", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.ITextView.ViewportWidth", MessageId = "Viewport", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.ITextView.ViewportLeftChanged", MessageId = "Viewport", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.ITextView.ViewportHeightChanged", MessageId = "Viewport", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.ITextView.ViewportWidthChanged", MessageId = "Viewport", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.ITextView.ViewScroller", MessageId = "Scroller", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.ITextView.ViewportLeft", MessageId = "Viewport", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "type", Target = "Microsoft.VisualStudio.Text.Editor.IViewScroller", MessageId = "Scroller", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.IViewScroller.ScrollViewportVerticallyByLine(Microsoft.VisualStudio.Text.Editor.ScrollDirection):System.Void", MessageId = "Viewport", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.IViewScroller.ScrollViewportVerticallyByLine(Microsoft.VisualStudio.Text.Editor.ScrollDirection):System.Void", MessageId = "ByLine", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming","CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId="ByLines", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.IViewScroller.#ScrollViewportVerticallyByLines(Microsoft.VisualStudio.Text.Editor.ScrollDirection,System.Int32)", Justification="Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.IViewScroller.ScrollViewportVerticallyByPixels(System.Double):System.Void", MessageId = "Viewport", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.IViewScroller.ScrollViewportVerticallyByPage(Microsoft.VisualStudio.Text.Editor.ScrollDirection):System.Void", MessageId = "Viewport", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.IViewScroller.ScrollViewportHorizontallyByPixels(System.Double):System.Void", MessageId = "Viewport", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.IVerticalScrollBar.GetBufferPositionOfYCoordinate(System.Double):System.Nullable`1<System.Int32>", MessageId="0#y", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.IVerticalScrollBar.GetYCoordinateOfPosition(System.Int32):System.Double", MessageId="Coodinate", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.PredefinedTextViewRoles.Zoomable", MessageId = "Zoomable", Justification = "Spelling ok")]
+
+[module: SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.ITextSelection.#Select(Microsoft.VisualStudio.Text.SnapshotSpan,System.Boolean)", MessageId = "Select", Justification = "BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.ITextSelection.#Select(Microsoft.VisualStudio.Text.VirtualSnapshotPoint,Microsoft.VisualStudio.Text.VirtualSnapshotPoint)", MessageId = "Select", Justification = "BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.ITextSelection.#Select(Microsoft.VisualStudio.Text.VirtualSnapshotPoint,Microsoft.VisualStudio.Text.VirtualSnapshotPoint)", MessageId = "Select")]
+[module: SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.ITextSelection.#End", MessageId = "End")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.IVerticalScrollBar.#GetBufferPositionOfYCoordinate(System.Double)", MessageId = "y", Justification = "BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.TextViewLayoutChangedEventArgs.#.ctor(System.Nullable`1<Microsoft.VisualStudio.Text.Span>,Microsoft.VisualStudio.Text.ITextSnapshot,Microsoft.VisualStudio.Text.ITextSnapshot)", MessageId="", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Scope = "type", Target = "Microsoft.VisualStudio.Text.Editor.TextViewRoleAttribute", Justification = "Funky form necessary for MEF")]
+[module: SuppressMessage("Microsoft.Design", "CA1018:MarkAttributesWithAttributeUsage", Scope = "type", Target = "Microsoft.VisualStudio.Text.Editor.TextViewRoleAttribute")]
+[module: SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Scope = "type", Target = "Microsoft.VisualStudio.Text.Editor.ITextViewRoleSet")]
+
+// Operations
+[module: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.VisualStudio.Text.Operations", MessageId = "", Justification = "BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Operations.IEditorOperations.#GotoLine(System.Int32)", MessageId = "Goto", Justification = "BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Scope="member", Target="Microsoft.VisualStudio.Text.Operations.IEditorOperations.#PageUp(System.Boolean)", MessageId="Select", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tabify", Scope = "member", Target = "Microsoft.VisualStudio.Text.Operations.IEditorOperations.#Tabify()", Justification = "These names match the accepted terms for the operations")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Untabify", Scope = "member", Target = "Microsoft.VisualStudio.Text.Operations.IEditorOperations.#Untabify()", Justification = "These names match the accepted terms for the operations")]
+[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "InLine", Scope = "member", Target = "Microsoft.VisualStudio.Text.Operations.IEditorOperations.#MoveToLastNonWhiteSpaceCharacter()", Justification = "In and line refer to two words")]
+[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Operations.IEditorOperations.MoveLineUp(System.Boolean):System.Void", MessageId = "LineUp", Justification = "Spelling ok")]
+[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "NonWhite", Scope = "member", Target = "Microsoft.VisualStudio.Text.Operations.IEditorOperations.#MoveToLastNonWhiteSpaceCharacter(System.Boolean)", Justification = "Non and white are two separate words in this case")]
+[module: SuppressMessage("Microsoft.Design","CA1021:AvoidOutParameters", MessageId="1#", Scope="member", Target="Microsoft.VisualStudio.Text.Operations.IEditorOperations.#InsertTextAsBox(System.String,Microsoft.VisualStudio.Text.VirtualSnapshotPoint&,Microsoft.VisualStudio.Text.VirtualSnapshotPoint&)", Justification="This returns the corners of the box and whether or not it succeeded, so it needs out parameters.")]
+[module: SuppressMessage("Microsoft.Design","CA1021:AvoidOutParameters", MessageId="2#", Scope="member", Target="Microsoft.VisualStudio.Text.Operations.IEditorOperations.#InsertTextAsBox(System.String,Microsoft.VisualStudio.Text.VirtualSnapshotPoint&,Microsoft.VisualStudio.Text.VirtualSnapshotPoint&)", Justification="This returns the corners of the box and whether or not it succeeded, so it needs out parameters.")]
+
+// Options
+[module: SuppressMessage("Microsoft.Design","CA1020:AvoidNamespacesWithFewTypes", Scope="namespace", Target="Microsoft.VisualStudio.Text.Editor.OptionsExtensionMethods")]
+
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.ITextCaret.#MoveTo(Microsoft.VisualStudio.Text.Formatting.ITextViewLine,System.Double)", MessageId="x")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.ITextCaret.#MoveTo(Microsoft.VisualStudio.Text.Formatting.ITextViewLine,System.Double,System.Boolean)", MessageId="x")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.ITextCaret.#MoveTo(Microsoft.VisualStudio.Text.Formatting.ITextViewLine,System.Double,System.Boolean,System.Boolean)", MessageId="x")]
+
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.ITextViewLineCollection.#GetTextViewLineContainingYCoordinate(System.Double)", MessageId="y")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.VisualStudio.Text.Formatting.ITextViewLine.#GetBufferPositionFromXCoordinate(System.Double,System.Boolean)", MessageId="x")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope="member", Target="Microsoft.VisualStudio.Text.Formatting.ITextViewLine.#GetBufferPositionFromXCoordinate(System.Double)", MessageId="x")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Formatting.ITextViewLine.#GetVirtualBufferPositionFromXCoordinate(System.Double)", MessageId = "x")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Formatting.ITextViewLine.#GetInsertionBufferPositionFromXCoordinate(System.Double)", MessageId = "x")]
+[module: SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Scope = "member", Target = "Microsoft.VisualStudio.Text.Formatting.ITextViewLine.#End", MessageId = "End")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Formatting.TextBounds.#.ctor(System.Double,System.Double,System.Double,System.Double,System.Double,System.Double)", MessageId = "bidi")]
+
+//Tagging
+[module: SuppressMessage("Microsoft.Naming","CA1721:PropertyNamesShouldNotMatchGetMethods", Scope="member", Target="Microsoft.VisualStudio.Text.Tagging.SquiggleTag.#Type")]
+[module: SuppressMessage("Microsoft.Naming","CA1721:PropertyNamesShouldNotMatchGetMethods", Scope="member", Target="Microsoft.VisualStudio.Text.Tagging.TextMarkerTag.#Type")]
+[module: SuppressMessage("Microsoft.Design","CA1020:AvoidNamespacesWithFewTypes", Scope="namespace", Target="Microsoft.VisualStudio.Text.Tagging")]
+
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.CaretPosition.#.ctor(System.Int32,Microsoft.VisualStudio.Text.IMappingPoint,Microsoft.VisualStudio.Text.Editor.PositionAffinity,System.Int32,System.Double)", MessageId = "x")]
+
+[module: SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Scope="member", Target="Microsoft.VisualStudio.Text.Formatting.ITextAndAdornmentCollection.#End", MessageId="End", Justification="BASELINE: Original port of VisualStudio to ToolPlat")]
+
+
+[module: SuppressMessage("Microsoft.Naming","CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="Tagger", Scope="member", Target="Microsoft.VisualStudio.Text.Adornments.ITextMarkerProviderFactory.#GetTextMarkerTagger(Microsoft.VisualStudio.Text.ITextBuffer)", Justification="That is the accepted spelling.")]
+[module: SuppressMessage("Microsoft.Naming","CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="Tagger", Scope="member", Target="Microsoft.VisualStudio.Text.Adornments.ISquiggleProviderFactory.#GetSquiggleTagger(Microsoft.VisualStudio.Text.ITextBuffer)", Justification="That is the accepted spelling.")]
+
+[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", Scope="member", Target="Microsoft.VisualStudio.Text.Editor.ITextView.#IsMouseOverViewOrAdornments", MessageId="OverView")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tagger", Scope = "member", Target = "Microsoft.VisualStudio.Text.Tagging.IViewTaggerProvider.#CreateTagger`1(Microsoft.VisualStudio.Text.Editor.ITextView,Microsoft.VisualStudio.Text.ITextBuffer)")]
+[module: SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Scope = "member", Target = "Microsoft.VisualStudio.Text.Tagging.IViewTaggerProvider.#CreateTagger`1(Microsoft.VisualStudio.Text.Editor.ITextView,Microsoft.VisualStudio.Text.ITextBuffer)")]
+[module: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tagger", Scope = "type", Target = "Microsoft.VisualStudio.Text.Tagging.IViewTaggerProvider")]
+[module: SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Scope = "member", Target = "Microsoft.VisualStudio.Text.Tagging.IViewTagAggregatorFactoryService.#CreateTagAggregator`1(Microsoft.VisualStudio.Text.Editor.ITextView)")]
+[module: SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Scope = "member", Target = "Microsoft.VisualStudio.Text.Tagging.IViewTagAggregatorFactoryService.#CreateTagAggregator`1(Microsoft.VisualStudio.Text.Editor.ITextView,Microsoft.VisualStudio.Text.Tagging.TagAggregatorOptions)")]
+
+//IncrementalSearch
+[module: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.VisualStudio.Text.IncrementalSearch", Justification = "Merging the contents with another namespace would group objects of varying purposes into the same namespace.")]
+
+// Outlining
+[module: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.VisualStudio.Text.Outlining", MessageId = "", Justification = "BASELINE: Original port of VisualStudio to ToolPlat")]
+
+// Visible Whitespace
+[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Whitespace", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.DefaultTextViewOptions.#UseVisibleWhitespaceId", Justification = "'VisibleWhitespace' makes sense as 'Whitespace' implies the programmatic whitespace character.")]
+[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Whitespace", Scope = "member", Target = "Microsoft.VisualStudio.Text.Editor.OptionsExtensionMethods.TextViewOptionExtensions.#IsVisibleWhitespaceEnabled(Microsoft.VisualStudio.Text.Editor.IEditorOptions)", Justification = "'VisibleWhitespace' makes sense as 'Whitespace' implies the programmatic whitespace character.")]
+[module: SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", Scope = "type", Target = "Microsoft.VisualStudio.Text.Editor.UseVisibleWhitespace", Justification = "'VisibleWhitespace' makes sense as 'Whitespace' implies the programmatic whitespace character.")]
+
+// Classification
+[module: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "Microsoft.VisualStudio.Text.Classification")]
+
+// Brace Completion
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Scope = "type", Target = "Microsoft.VisualStudio.Text.BraceCompletion.BracePairAttribute", Justification = "The accessor just has a different name")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces", Scope = "type", Target = "Microsoft.VisualStudio.Text.BraceCompletion.IBraceCompletionDefaultProvider", Justification = "This interface is empty by design and just used for exporting attributes")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "OverType", Scope = "member", Target = "Microsoft.VisualStudio.Text.BraceCompletion.IBraceCompletionSession.#PreOverType(System.Boolean&)")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "OverType", Scope = "member", Target = "Microsoft.VisualStudio.Text.BraceCompletion.IBraceCompletionSession.#PostOverType()")]
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "OverType", Scope = "member", Target = "Microsoft.VisualStudio.Text.BraceCompletion.IBraceCompletionContext.#AllowOverType(Microsoft.VisualStudio.Text.BraceCompletion.IBraceCompletionSession)")]
+#endif
diff --git a/src/Text/Def/TextUI/Operations/IEditorOperations.cs b/src/Text/Def/TextUI/Operations/IEditorOperations.cs
new file mode 100644
index 0000000..5724189
--- /dev/null
+++ b/src/Text/Def/TextUI/Operations/IEditorOperations.cs
@@ -0,0 +1,930 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ using System;
+ using System.IO;
+ using Microsoft.VisualStudio.Text.Editor;
+ using Microsoft.VisualStudio.Text.Formatting;
+
+ /// <summary>
+ /// Defines operations relating to the editor.
+ /// </summary>
+ public interface IEditorOperations
+ {
+ #region Navigation Operations
+
+ /// <summary>
+ /// Selects from the given anchor point to active point, moving the caret to the new active
+ /// point of the selection. The selected span will be made visible.
+ /// </summary>
+ /// <param name="anchorPoint">The anchor point of the new selection.</param>
+ /// <param name="activePoint">The active point of the new selection and position of the caret.</param>
+ /// <remarks>This puts the selection in stream selection mode and does the minimum amount of required scrolling to ensure the selected span is visible.</remarks>
+ void SelectAndMoveCaret(VirtualSnapshotPoint anchorPoint, VirtualSnapshotPoint activePoint);
+
+ /// <summary>
+ /// Selects from the given anchor point to active point, moving the caret to the new active
+ /// point of the selection. Additionally, ensure the selection is in the given selection
+ /// mode, and make the selected span visible.
+ /// </summary>
+ /// <param name="anchorPoint">The anchor point of the new selection.</param>
+ /// <param name="activePoint">The active point of the new selection and position of the caret.</param>
+ /// <param name="selectionMode">The selection mode of the new selection.</param>
+ /// <remarks>This does the minimum amount of required scrolling to ensure the selected span is visible.</remarks>
+ void SelectAndMoveCaret(VirtualSnapshotPoint anchorPoint, VirtualSnapshotPoint activePoint, TextSelectionMode selectionMode);
+
+ /// <summary>
+ /// Selects from the given anchor point to active point, moving the caret to the new active
+ /// point of the selection. Additionally, ensure the selection is in the given selection
+ /// mode, and make the selected span visible.
+ /// </summary>
+ /// <param name="anchorPoint">The anchor point of the new selection.</param>
+ /// <param name="activePoint">The active point of the new selection and position of the caret.</param>
+ /// <param name="selectionMode">The selection mode of the new selection.</param>
+ /// <param name="scrollOptions">What, if any, scrolling is done in the view after the selection is made. If null, no scrolling is done.</param>
+ void SelectAndMoveCaret(VirtualSnapshotPoint anchorPoint, VirtualSnapshotPoint activePoint, TextSelectionMode selectionMode, EnsureSpanVisibleOptions? scrollOptions);
+
+ /// <summary>
+ /// Moves the caret to the next character.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveToNextCharacter(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret to the previous character.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveToPreviousCharacter(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret to the next word.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveToNextWord(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret to the previous word.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveToPreviousWord(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret one line up.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveLineUp(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret one line down.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveLineDown(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret one page up.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void PageUp(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret one page down.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void PageDown(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret to the end of the line.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveToEndOfLine(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret to the first column on the current line.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveToStartOfLine(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret to the first text column on the line; if the caret is already
+ /// at the first text column or there is no text, move the caret to the first column
+ /// on the line.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ /// <remarks>This is effectively the behavior of pressing the Home key</remarks>
+ void MoveToHome(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret to the start of the specified line.
+ /// </summary>
+ /// <param name="lineNumber">
+ /// The line number to which to move the caret.
+ /// </param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="lineNumber"/> is less than zero
+ /// or greater than the line number of the last line in the text buffer.</exception>
+ void GotoLine(int lineNumber);
+
+ /// <summary>
+ /// Moves the caret to the start of the document.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveToStartOfDocument(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret at the end of the document.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveToEndOfDocument(bool extendSelection);
+
+ /// <summary>
+ /// Moves the current line to the top of the view.
+ /// </summary>
+ void MoveCurrentLineToTop();
+
+ /// <summary>
+ /// Moves the current line to the bottom of the view.
+ /// </summary>
+ void MoveCurrentLineToBottom();
+
+ /// <summary>
+ /// Moves the caret to the start of the line after all white space.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveToStartOfLineAfterWhiteSpace(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret to the start of the next line after all white space.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// If the caret is on the last line, this method moves it to the start of the line after all white space.
+ /// </para>
+ /// </remarks>
+ void MoveToStartOfNextLineAfterWhiteSpace(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret to the start of the previous line after all white space.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ /// <remarks>
+ /// <para>
+ /// If the caret is on the first line, this method moves it to the start of the ine after all white space.
+ /// </para>
+ /// </remarks>
+ void MoveToStartOfPreviousLineAfterWhiteSpace(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret to just before the last non-white space character in the line.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ /// <remarks>
+ /// If the line is blank, the caret is moved to the start of the line.
+ /// </remarks>
+ void MoveToLastNonWhiteSpaceCharacter(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret to the first fully-visible line of the view.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveToTopOfView(bool extendSelection);
+
+ /// <summary>
+ /// Moves the caret to the last fully-visible line of the view.
+ /// </summary>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ void MoveToBottomOfView(bool extendSelection);
+
+ /// <summary>
+ /// Swaps the caret from its current position to the other end of the selection.
+ /// </summary>
+ void SwapCaretAndAnchor();
+
+ #endregion // Navigation Operations
+
+ #region Edit Operations
+
+ /// <summary>
+ /// Deletes a character to the left of the current caret.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool Backspace();
+
+ /// <summary>
+ /// Deletes the word to the right of the current caret position.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool DeleteWordToRight();
+
+ /// <summary>
+ /// Deletes the word to the left of the current caret position.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool DeleteWordToLeft();
+
+ /// <summary>
+ /// Deletes the line the caret is on, up to the line break character and the selection, if present.
+ /// </summary>
+ bool DeleteToEndOfLine();
+
+ /// <summary>
+ /// Deletes the line the caret is on, up to the previous line break character and the selection, if present.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool DeleteToBeginningOfLine();
+
+ /// <summary>
+ /// Deletes all empty lines or lines that contain only white space in the selection.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool DeleteBlankLines();
+
+ /// <summary>
+ /// Deletes all white space from the beginnings and ends of the selected lines, and trims internal white space.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The algorithm for this operation follows these rules:
+ /// </para>
+ /// <para>
+ /// If there is no selection, the white space around the caret is trimmed so that only one space or tab remains.
+ /// If there is only one space or tab, then this operation does nothing.
+ /// </para>
+ /// <para>
+ /// If there is a selection, then the white space at the beginning or end of a line
+ /// contained within the selection is completely deleted.
+ /// If there is at least one block of contiguous white space longer than one character
+ /// in the selection, then all white space between the first and last
+ /// non-white space characters is trimmed so that only one space or tab remains for each contiguous block.
+ /// If there are only contiguous runs of a single space or tab contained within the selection,
+ /// then all spaces and tabs in the selection are deleted.
+ /// </para>
+ /// </remarks>
+ bool DeleteHorizontalWhiteSpace();
+
+ /// <summary>
+ /// Inserts a new line at the current caret position.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool InsertNewLine();
+
+ /// <summary>
+ /// Inserts a new line at the start of the line the caret is on.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool OpenLineAbove();
+
+ /// <summary>
+ /// Inserts a new line at the end of the line the caret is on.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool OpenLineBelow();
+
+ /// <summary>
+ /// If there is a multi-line selection indents the selection, otherwise inserts a tab at the caret location.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool Indent();
+
+ /// <summary>
+ /// If there is a multi-line selection, unindents the selection. If there is a single line selection,
+ /// removes up to a tab's worth of white space from before the start of the selection. If there is no selection,
+ /// removes up to a tab's worth of white space from before the caret position.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool Unindent();
+
+ /// <summary>
+ /// If there is a multi-line selection, adds indentation to every line in the selection,
+ /// otherwise adds indentation to the line the caret is on.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool IncreaseLineIndent();
+
+ /// <summary>
+ /// If there is a multi-line selection, removes indentation from every line in the selection,
+ /// otherwise removes indentation from the line the caret is on.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool DecreaseLineIndent();
+
+ /// <summary>
+ /// Inserts the given text at the current caret position.
+ /// </summary>
+ /// <param name="text">
+ /// The text to be inserted in the buffer.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="text"/> is null.</exception>
+ bool InsertText(string text);
+
+ /// <summary>
+ /// Inserts the given text at the current caret position as a box.
+ /// </summary>
+ /// <param name="text">
+ /// The text to be inserted in the buffer. Each "line" from the text
+ /// will be written out a line at a time.
+ /// </param>
+ /// <param name="boxStart">The start of the newly inserted box.</param>
+ /// <param name="boxEnd">The end of the newly inserted box.</param>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="text"/> is null.</exception>
+ /// <remarks>
+ /// This has the same behavior as copying and pasting a box selection.
+ /// In order to insert the text as a box, the <paramref name="text" /> is
+ /// split by newlines and inserted a line at a time, each one on a successive
+ /// line below the line the caret is on (and starting at the caret's x coordinate
+ /// on each line).
+ /// </remarks>
+ bool InsertTextAsBox(string text, out VirtualSnapshotPoint boxStart, out VirtualSnapshotPoint boxEnd);
+
+ /// <summary>
+ /// Inserts the given text at the current caret position as provisional text.
+ /// </summary>
+ /// <param name="text">
+ /// The text to be inserted in the buffer.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <remarks>
+ /// Provisional text is automatically replaced by subsequent InsertText() or InsertProvisionalText() calls.
+ /// </remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="text"/> is null.</exception>
+ bool InsertProvisionalText(string text);
+
+ /// <summary>
+ /// Deletes the selection if there is one, or the next character in the buffer if one exists.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool Delete();
+
+ /// <summary>
+ /// If there is a selection, deletes all the lines touched by the selection, including line break characters.
+ /// Otherwise, deletes the line the caret is on, including the line break characters.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool DeleteFullLine();
+
+ /// <summary>
+ /// Replaces the text selection with the new text.
+ /// </summary>
+ /// <param name="text">
+ /// The new text that replaces the old selection.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="text"/> is null.</exception>
+ bool ReplaceSelection(string text);
+
+ /// <summary>
+ /// Transposes the character at the cursor with the next character.
+ /// Transposes the first two characters when the cursor is at the start of the line.
+ /// Transposes the last two characters when the cursor is at the end of the line.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool TransposeCharacter();
+
+ /// <summary>
+ /// Transposes the line containing the cursor with the next line. Transposes the last two lines when the cursor at the last line.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool TransposeLine();
+
+ /// <summary>
+ /// Transposes the current word with the next one. White space and punctuation are not treated as words.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool TransposeWord();
+
+ /// <summary>
+ /// Converts uppercase letters to lowercase in the selection. If the selection is empty, makes the next character lowercase.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool MakeLowercase();
+
+ /// <summary>
+ /// Converts lowercase letters to uppercase in the selection. If the selection is empty, makes the next character uppercase.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool MakeUppercase();
+
+ /// <summary>
+ /// Switches the case of each character in the selection. If the selection is empty, changes the case of the next character.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool ToggleCase();
+
+ /// <summary>
+ /// Converts all the characters in the selection to lowercase,
+ /// then converts the first character in each word in the selection to uppercase.
+ /// If the selection is empty, then it makes the next character uppercase.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool Capitalize();
+
+ /// <summary>
+ /// Replaces text from the given span with the new text.
+ /// </summary>
+ /// <param name="replaceSpan">The span of text to be replaced.</param>
+ /// <param name="text">
+ /// The new text.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool ReplaceText(Span replaceSpan, string text);
+
+ /// <summary>
+ /// Replaces all matching occurrences of the given string.
+ /// </summary>
+ /// <param name="searchText">
+ /// The text to match.
+ /// </param>
+ /// <param name="replaceText">
+ /// The replacement text.
+ /// </param>
+ /// <param name="matchCase">
+ /// <c>true</c> if the search should match case, otherwise <c>false</c>.
+ /// </param>
+ /// <param name="matchWholeWord">
+ /// <c>true</c> if the search should match whole words, otherwise <c>false</c>.
+ /// </param>
+ /// <param name="useRegularExpressions">
+ /// <c>true</c> if the search should use regular expressions, otherwise <c>false</c>.
+ /// </param>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="searchText"/> is null.</exception>
+ /// <exception cref="ArgumentException"> if <paramref name="useRegularExpressions"/> is true and <paramref name="searchText"/> is an invalid regular expression.</exception>
+ /// <returns>The number of matches found.</returns>
+ /// <remarks>If any of the matches found is read only, none of the matches will be replaced.</remarks>
+ int ReplaceAllMatches(string searchText, string replaceText, bool matchCase, bool matchWholeWord, bool useRegularExpressions);
+
+ /// <summary>
+ /// Inserts a file on disk into the text buffer.
+ /// </summary>
+ /// <param name="filePath">The path of the file on disk.</param>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException"><paramref name="filePath"/> is null.</exception>
+ /// <exception cref="ArgumentException"><paramref name="filePath"/> is a zero-length string,
+ /// contains only white space, or contains one or more invalid characters as defined by InvalidPathChars.</exception>
+ /// <exception cref="PathTooLongException">The specified path, file name, or both exceed the system-defined maximum length.
+ /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. </exception>
+ /// <exception cref="DirectoryNotFoundException">The specified path is invalid (for example, it is on an unmapped drive). </exception>
+ /// <exception cref="IOException">An I/O error occurred while opening the file. </exception>
+ /// <exception cref="UnauthorizedAccessException"><paramref name="filePath"/> specified a file that is read-only, or
+ /// this operation is not supported on the current platform, or
+ /// <paramref name="filePath"/> specified a directory, or
+ /// the caller does not have the required permission.</exception>
+ /// <exception cref="FileNotFoundException">The file specified in <paramref name="filePath"/> was not found.</exception>
+ /// <exception cref="NotSupportedException"><paramref name="filePath"/> is in an invalid format. </exception>
+ /// <exception cref="System.Security.SecurityException">The caller does not have the required permission.</exception>
+ bool InsertFile(string filePath);
+
+ /// <summary>
+ /// Converts the leading white space to tabs on all lines touched by the selection and caret.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// If the column position of the first non-white space character is not evenly divisible by the tab size, there will be
+ /// spaces left at the end of the line equal to the remainder of that division.
+ /// </para>
+ /// </remarks>
+ bool Tabify();
+
+ /// <summary>
+ /// Converts the leading white space to spaces of all lines touched by the selection and caret.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool Untabify();
+
+ /// <summary>
+ /// Converts spaces to tabs in the selection, or on the line the caret is on if the selection is empty.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// Only spaces immediately preceding a tab stop will be converted to tabs.
+ /// </para>
+ /// </remarks>
+ bool ConvertSpacesToTabs();
+
+ /// <summary>
+ /// Converts tabs to spaces in the selection, or on the line the caret is on if the selection is empty.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// A tab is replaced by the number of spaces equal to the distance between one tab and the next.
+ /// </para>
+ /// </remarks>
+ bool ConvertTabsToSpaces();
+
+ /// <summary>
+ /// Replaces all line endings that do not match <paramref name="replacement"/> with <paramref name="replacement"/>.
+ /// </summary>
+ /// <param name="replacement">The character sequence that all line endings will match.</param>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool NormalizeLineEndings(string replacement);
+
+ #endregion // Edit Operations
+
+ #region Selection Operations
+
+ /// <summary>
+ /// Selects the current word.
+ /// </summary>
+ void SelectCurrentWord();
+
+ /// <summary>
+ /// Selects the enclosing parent.
+ /// </summary>
+ void SelectEnclosing();
+
+ /// <summary>
+ /// Selects the first child.
+ /// </summary>
+ void SelectFirstChild();
+
+ /// <summary>
+ /// Selects the next sibling.
+ /// </summary>
+ /// <param name="extendSelection">If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.</param>
+ void SelectNextSibling(bool extendSelection);
+
+ /// <summary>
+ /// Selects the previous sibling.
+ /// </summary>
+ /// <param name="extendSelection">If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.</param>
+ void SelectPreviousSibling(bool extendSelection);
+
+ /// <summary>
+ /// Selects the given line.
+ /// </summary>
+ /// <param name="viewLine">
+ /// The line to select.
+ /// </param>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ /// <exception cref="ArgumentNullException"><paramref name="viewLine"/> is
+ /// <c>null</c></exception>
+ void SelectLine(ITextViewLine viewLine, bool extendSelection);
+
+ /// <summary>
+ /// Selects all text.
+ /// </summary>
+ void SelectAll();
+
+ /// <summary>
+ /// Extends the current selection span to the new selection end.
+ /// </summary>
+ /// <param name="newEnd">
+ /// The new character position to which the selection is to be extended.
+ /// </param>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="newEnd"/> is less than 0.</exception>
+ void ExtendSelection(int newEnd);
+
+ /// <summary>
+ /// Moves the caret to the given <paramref name="textLine"/> at the given <paramref name="horizontalOffset"/>.
+ /// </summary>
+ /// <param name="textLine">The <see cref="ITextViewLine"/> on which to place the caret.</param>
+ /// <param name="horizontalOffset">The horizontal location in the given <paramref name="textLine"/> to which to move the caret.</param>
+ /// <param name="extendSelection">
+ /// If <c>true</c>, the selection is extended when the caret is moved; if <c>false</c>, the selection is not extended.
+ /// </param>
+ /// <exception cref="ArgumentNullException"><paramref name="textLine"/> is null.</exception>
+ void MoveCaret(ITextViewLine textLine, double horizontalOffset, bool extendSelection);
+
+ /// <summary>
+ /// Resets any selection in the text.
+ /// </summary>
+ void ResetSelection();
+
+ #endregion // Selection Operations
+
+ #region Clipboard Operations
+
+ /// <summary>
+ /// Copies the selected text to the clipboard.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the clipboard operation succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <exception cref="InsufficientMemoryException"> is thrown if there is not sufficient memory to complete the operation.</exception>
+ bool CopySelection();
+
+ /// <summary>
+ /// Cuts the selected text.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit and the clipboard operation both succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <exception cref="InsufficientMemoryException"> is thrown if there is not sufficient memory to complete the operation.</exception>
+ bool CutSelection();
+
+ /// <summary>
+ /// Pastes text from the clipboard to the text buffer.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit and the clipboard operation both succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool Paste();
+
+ /// <summary>
+ /// If there is a selection present, deletes all lines touched by the selection,
+ /// including line break characters, and copies the text to the clipboard.
+ /// Otherwise, deletes the line the caret is on, including the line break characters, and copies the text to the clipboard.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit and the clipboard operation both succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <exception cref="InsufficientMemoryException"> is thrown if there is not sufficient memory to complete the operation.</exception>
+ bool CutFullLine();
+
+ /// <summary>
+ /// Determines whether a paste operation is possible.
+ /// </summary>
+ bool CanPaste
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Determines whether a delete operation is possible.
+ /// </summary>
+ bool CanDelete
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Determines whether a cut operation is possible.
+ /// </summary>
+ bool CanCut
+ {
+ get;
+ }
+
+ #endregion // Clipboard Operations
+
+ #region Scrolling Operations
+ /// <summary>
+ /// Scrolls the view up by one line and repositions the caret,
+ /// if it is scrolled off the page, to the last fully-visible
+ /// line in the view.
+ /// </summary>
+ void ScrollUpAndMoveCaretIfNecessary();
+
+ /// <summary>
+ /// Scrolls the view down by one line and repositions the caret,
+ /// if it is scrolled off the page, to the first fully-visible
+ /// line in the view.
+ /// </summary>
+ void ScrollDownAndMoveCaretIfNecessary();
+
+ /// <summary>
+ /// Scrolls the view up a page without moving the caret.
+ /// </summary>
+ void ScrollPageUp();
+
+ /// <summary>
+ /// Scrolls the view down a page without moving the caret.
+ /// </summary>
+ void ScrollPageDown();
+
+ /// <summary>
+ /// Scrolls the view one column to the left.
+ /// </summary>
+ /// <remarks>
+ /// A column is the width of a space in the default font.
+ /// </remarks>
+ void ScrollColumnLeft();
+
+ /// <summary>
+ /// Scrolls the view one column to the right.
+ /// </summary>
+ /// <remarks>
+ /// A column is the width of a space in the default font.
+ /// </remarks>
+ void ScrollColumnRight();
+
+ /// <summary>
+ /// Scrolls the line the caret is on, so that it is the last
+ /// fully-visible line in the view.
+ /// </summary>
+ void ScrollLineBottom();
+
+ /// <summary>
+ /// Scroll sthe line the caret is on, so that it is the first
+ /// fully-visible line in the view.
+ /// </summary>
+ void ScrollLineTop();
+
+ /// <summary>
+ /// Scrolls the line the caret is on, so that it is centered in the view.
+ /// </summary>
+ void ScrollLineCenter();
+
+ /// <summary>
+ /// Adds an <see cref="ITextUndoPrimitive"/> to the <see cref="ITextUndoHistory"/> for the buffer
+ /// that will revert the selection to the current state when it is undone.
+ /// </summary>
+ /// <remarks>
+ /// When performing edits that will change the selection, you can surround the edits with calls
+ /// to <see cref="AddBeforeTextBufferChangePrimitive"/> and
+ /// <see cref="AddAfterTextBufferChangePrimitive"/> to ensure that the selection
+ /// behaves correctly when the edits are undone and redone.
+ /// </remarks>
+ void AddBeforeTextBufferChangePrimitive();
+
+ /// <summary>
+ /// Adds an <see cref="ITextUndoPrimitive"/> to the <see cref="ITextUndoHistory"/> for the buffer
+ /// that will revert the selection to the current state when it is redone.
+ /// </summary>
+ /// <remarks>
+ /// When performing edits that will change the selection, you can surround the edits with calls
+ /// to <see cref="AddBeforeTextBufferChangePrimitive"/> and
+ /// <see cref="AddAfterTextBufferChangePrimitive"/> to ensure that the selection
+ /// behaves correctly when the edits are undone and redone.
+ /// </remarks>
+ void AddAfterTextBufferChangePrimitive();
+ #endregion
+
+ #region Zoom Operations
+ /// <summary>
+ /// Zooms in to the text view by a scaling factor of 10%
+ /// </summary>
+ /// <remarks>
+ /// The maximum zooming scale is 400%
+ /// </remarks>
+ void ZoomIn();
+
+ /// <summary>
+ /// Zooms out of the text view by a scaling factor of 10%
+ /// </summary>
+ /// <remarks>
+ /// The minimum zooming scale is 20%
+ /// </remarks>
+ void ZoomOut();
+
+ /// <summary>
+ /// Applies the given zoomLevel to the text view
+ /// </summary>
+ /// <param name="zoomLevel">The zoom level to apply between 20% to 400%</param>
+ void ZoomTo(double zoomLevel);
+ #endregion
+
+ #region Miscellaneous
+
+ /// <summary>
+ /// Gets a string composed of whitespace characters that would be inserted to fill the gap between
+ /// a given <see cref="VirtualSnapshotPoint"/> and the closest <see cref="SnapshotPoint"/> on the same line.
+ /// </summary>
+ /// <param name="point">The point in virtual space</param>
+ /// <remarks>
+ /// Returns an empty string if the provided <paramref name="point"/> is not in virtual space.
+ /// </remarks>
+ string GetWhitespaceForVirtualSpace(VirtualSnapshotPoint point);
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Gets the text view on which these operations work.
+ /// </summary>
+ ITextView TextView
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the options specific to this view.
+ /// </summary>
+ IEditorOptions Options
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Gets the span of the current provisional composition (null if there is no provisional composition).
+ /// </summary>
+ ITrackingSpan ProvisionalCompositionSpan { get; }
+
+ /// <summary>
+ /// Gets the selected text.
+ /// </summary>
+ /// <remarks>
+ /// In box selection mode, this will have each span of text separated by a newline
+ /// character, with an extra newline at the very end.
+ /// </remarks>
+ string SelectedText { get; }
+
+ #endregion // Properties
+ }
+}
diff --git a/src/Text/Def/TextUI/Operations/IEditorOperations2.cs b/src/Text/Def/TextUI/Operations/IEditorOperations2.cs
new file mode 100644
index 0000000..e15542c
--- /dev/null
+++ b/src/Text/Def/TextUI/Operations/IEditorOperations2.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Defines operations relating to the editor, in addition to operations defined by <see cref="IEditorOperations"/>.
+ /// </summary>
+ public interface IEditorOperations2 : IEditorOperations
+ {
+ /// <summary>
+ /// Moves the selected lines up above the line bordering the selection on top.
+ /// Moving up from the top of the file will return true, however no changes will be made.
+ /// Collapsed regions being moved, and being moved over, will remain collapsed.
+ /// Moves involving readonly regions will result in no changes being made.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded or no change was needed, otherwise <c>false</c>.
+ /// </returns>
+ bool MoveSelectedLinesUp();
+
+ /// <summary>
+ /// Moves the selected lines below the line bordering the selection on the bottom.
+ /// Moving down from the bottom of the file will return true, however no changes will be made.
+ /// Collapsed regions being moved, and being moved over, will remain collapsed.
+ /// Moves involving readonly regions will result in no changes being made.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded or no change was needed, otherwise <c>false</c>.
+ /// </returns>
+ bool MoveSelectedLinesDown();
+ }
+}
diff --git a/src/Text/Def/TextUI/Operations/IEditorOperations3.cs b/src/Text/Def/TextUI/Operations/IEditorOperations3.cs
new file mode 100644
index 0000000..10076bd
--- /dev/null
+++ b/src/Text/Def/TextUI/Operations/IEditorOperations3.cs
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ /// <summary>
+ /// Defines operations relating to the editor, in addition to operations defined by <see cref="IEditorOperations2"/>.
+ /// </summary>
+ public interface IEditorOperations3 : IEditorOperations2
+ {
+ /// <summary>
+ /// Inserts a new line at the end of the document if it's not there yet.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ bool InsertFinalNewLine();
+
+ /// <summary>
+ /// Deletes all white space from ends of the selected lines.
+ /// </summary>
+ /// <returns>
+ /// <c>true</c> if the edit succeeded, otherwise <c>false</c>.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The algorithm for this operation follows these rules:
+ /// </para>
+ /// <para>
+ /// If there is no selection, the trailing white space is deleted on all lines in the document.
+ /// </para>
+ /// <para>
+ /// If there is a selection, then the trailing white space is deleted on all lines the selection spans.
+ /// </para>
+ /// </remarks>
+ bool TrimTrailingWhiteSpace();
+ }
+}
diff --git a/src/Text/Def/TextUI/Operations/IEditorOperationsFactoryService.cs b/src/Text/Def/TextUI/Operations/IEditorOperationsFactoryService.cs
new file mode 100644
index 0000000..d1a16c4
--- /dev/null
+++ b/src/Text/Def/TextUI/Operations/IEditorOperationsFactoryService.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Operations
+{
+ using Microsoft.VisualStudio.Text.Editor;
+ using System.ComponentModel.Composition;
+
+ /// <summary>
+ /// A service that provides <see cref="IEditorOperations"/> objects.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IEditorOperationsFactoryService factory = null;
+ /// </remarks>
+ public interface IEditorOperationsFactoryService
+ {
+ /// <summary>
+ /// Gets the <see cref="IEditorOperations"/> objects for the specified <see cref="ITextView"/>.
+ /// </summary>
+ /// <param name="textView">The <see cref="ITextView"/>.</param>
+ /// <returns>The <see cref="IEditorOperations"/>. </returns>
+ IEditorOperations GetEditorOperations(ITextView textView);
+ }
+}
diff --git a/src/Text/Def/TextUI/Operations/Microsoft.VisualStudio.Text.Operations.Overview.mht b/src/Text/Def/TextUI/Operations/Microsoft.VisualStudio.Text.Operations.Overview.mht
new file mode 100644
index 0000000..d8d7033
--- /dev/null
+++ b/src/Text/Def/TextUI/Operations/Microsoft.VisualStudio.Text.Operations.Overview.mht
@@ -0,0 +1,3843 @@
+MIME-Version: 1.0
+Content-Type: multipart/related; boundary="----=_NextPart_01C88FF8.77140040"
+
+This document is a Single File Web Page, also known as a Web Archive file. If you are seeing this message, your browser or editor doesn't support Web Archive files. Please download a browser that supports Web Archive, such as Windows® Internet Explorer®.
+
+------=_NextPart_01C88FF8.77140040
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Operations.Overview.htm
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/html; charset="us-ascii"
+
+<html xmlns:v=3D"urn:schemas-microsoft-com:vml"
+xmlns:o=3D"urn:schemas-microsoft-com:office:office"
+xmlns:w=3D"urn:schemas-microsoft-com:office:word"
+xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml"
+xmlns=3D"http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=3DContent-Type content=3D"text/html; charset=3Dus-ascii">
+<meta name=3DProgId content=3DWord.Document>
+<meta name=3DGenerator content=3D"Microsoft Word 12">
+<meta name=3DOriginator content=3D"Microsoft Word 12">
+<link rel=3DFile-List
+href=3D"Microsoft.VisualStudio.Text.Operations.Overview_files/filelist.xml">
+<title>Editor Operations Subsystem</title>
+<!--[if gte mso 9]><xml>
+ <o:DocumentProperties>
+ <o:Subject>VisualStudio Shell</o:Subject>
+ <o:Author>Vijaye Raji</o:Author>
+ <o:Template>VisualStudio SDK Overview</o:Template>
+ <o:LastAuthor>Jack Tilford</o:LastAuthor>
+ <o:Revision>19</o:Revision>
+ <o:TotalTime>123</o:TotalTime>
+ <o:LastPrinted>2005-05-26T01:48:00Z</o:LastPrinted>
+ <o:Created>2007-01-05T22:37:00Z</o:Created>
+ <o:LastSaved>2008-03-27T17:51:00Z</o:LastSaved>
+ <o:Pages>2</o:Pages>
+ <o:Words>732</o:Words>
+ <o:Characters>4178</o:Characters>
+ <o:Company>Microsoft Corporation</o:Company>
+ <o:Lines>34</o:Lines>
+ <o:Paragraphs>9</o:Paragraphs>
+ <o:CharactersWithSpaces>4901</o:CharactersWithSpaces>
+ <o:Version>12.00</o:Version>
+ </o:DocumentProperties>
+</xml><![endif]-->
+<link rel=3DthemeData
+href=3D"Microsoft.VisualStudio.Text.Operations.Overview_files/themedata.thm=
+x">
+<link rel=3DcolorSchemeMapping
+href=3D"Microsoft.VisualStudio.Text.Operations.Overview_files/colorschemema=
+pping.xml">
+<!--[if gte mso 9]><xml>
+ <w:WordDocument>
+ <w:TrackMoves>false</w:TrackMoves>
+ <w:TrackFormatting/>
+ <w:PunctuationKerning/>
+ <w:ValidateAgainstSchemas/>
+ <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
+ <w:IgnoreMixedContent>false</w:IgnoreMixedContent>
+ <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
+ <w:DoNotPromoteQF/>
+ <w:LidThemeOther>EN-US</w:LidThemeOther>
+ <w:LidThemeAsian>X-NONE</w:LidThemeAsian>
+ <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
+ <w:Compatibility>
+ <w:BreakWrappedTables/>
+ <w:SnapToGridInCell/>
+ <w:WrapTextWithPunct/>
+ <w:UseAsianBreakRules/>
+ <w:DontGrowAutofit/>
+ <w:SplitPgBreakAndParaMark/>
+ <w:DontVertAlignCellWithSp/>
+ <w:DontBreakConstrainedForcedTables/>
+ <w:DontVertAlignInTxbx/>
+ <w:Word11KerningPairs/>
+ <w:CachedColBalance/>
+ </w:Compatibility>
+ <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
+ <m:mathPr>
+ <m:mathFont m:val=3D"Cambria Math"/>
+ <m:brkBin m:val=3D"before"/>
+ <m:brkBinSub m:val=3D"&#45;-"/>
+ <m:smallFrac m:val=3D"off"/>
+ <m:dispDef/>
+ <m:lMargin m:val=3D"0"/>
+ <m:rMargin m:val=3D"0"/>
+ <m:defJc m:val=3D"centerGroup"/>
+ <m:wrapIndent m:val=3D"1440"/>
+ <m:intLim m:val=3D"subSup"/>
+ <m:naryLim m:val=3D"undOvr"/>
+ </m:mathPr></w:WordDocument>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <w:LatentStyles DefLockedState=3D"false" DefUnhideWhenUsed=3D"false"
+ DefSemiHidden=3D"false" DefQFormat=3D"false" DefPriority=3D"1"
+ LatentStyleCount=3D"267">
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+Normal"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+heading 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+heading 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+heading 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+heading 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 7"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 8"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 9"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"footnote text"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"annotation text"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+caption"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"footnote referenc=
+e"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"annotation refere=
+nce"/>
+ <w:LsdException Locked=3D"false" QFormat=3D"true" Name=3D"Title"/>
+ <w:LsdException Locked=3D"false" QFormat=3D"true" Name=3D"Subtitle"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Hyperlink"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D"=
+Strong"/>
+ <w:LsdException Locked=3D"false" QFormat=3D"true" Name=3D"Emphasis"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"HTML Top of Form"=
+/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"HTML Bottom of Fo=
+rm"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Normal (Web)"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Normal Table"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"annotation subjec=
+t"/>
+ <w:LsdException Locked=3D"false" Priority=3D"99" Name=3D"No List"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Outline List 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Outline List 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Outline List 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Simple 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Simple 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Simple 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Classic 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Classic 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Classic 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Classic 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Colorful 1"=
+/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Colorful 2"=
+/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Colorful 3"=
+/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Columns 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 7"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid 8"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 7"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table List 8"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table 3D effects =
+1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table 3D effects =
+2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table 3D effects =
+3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Contemporar=
+y"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Elegant"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Professiona=
+l"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Subtle 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Subtle 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Web 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Web 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Web 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Balloon Text"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Grid"/>
+ <w:LsdException Locked=3D"false" Priority=3D"0" Name=3D"Table Theme"/>
+ <w:LsdException Locked=3D"false" Priority=3D"99" SemiHidden=3D"true"
+ Name=3D"Placeholder Text"/>
+ <w:LsdException Locked=3D"false" Priority=3D"2" QFormat=3D"true" Name=3D"=
+No Spacing"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"99" SemiHidden=3D"true" Name=
+=3D"Revision"/>
+ <w:LsdException Locked=3D"false" Priority=3D"34" QFormat=3D"true"
+ Name=3D"List Paragraph"/>
+ <w:LsdException Locked=3D"false" Priority=3D"29" QFormat=3D"true" Name=3D=
+"Quote"/>
+ <w:LsdException Locked=3D"false" Priority=3D"30" QFormat=3D"true"
+ Name=3D"Intense Quote"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 1"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 2"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 3"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 4"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 5"/>
+ <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Accen=
+t 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Accen=
+t 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading 1=
+ Accent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading 2=
+ Accent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Accent=
+ 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shading=
+ Accent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid Ac=
+cent 6"/>
+ <w:LsdException Locked=3D"false" Priority=3D"19" QFormat=3D"true"
+ Name=3D"Subtle Emphasis"/>
+ <w:LsdException Locked=3D"false" Priority=3D"21" QFormat=3D"true"
+ Name=3D"Intense Emphasis"/>
+ <w:LsdException Locked=3D"false" Priority=3D"31" QFormat=3D"true"
+ Name=3D"Subtle Reference"/>
+ <w:LsdException Locked=3D"false" Priority=3D"32" QFormat=3D"true"
+ Name=3D"Intense Reference"/>
+ <w:LsdException Locked=3D"false" Priority=3D"33" QFormat=3D"true" Name=3D=
+"Book Title"/>
+ <w:LsdException Locked=3D"false" Priority=3D"37" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" Name=3D"Bibliography"/>
+ <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true"
+ UnhideWhenUsed=3D"true" QFormat=3D"true" Name=3D"TOC Heading"/>
+ </w:LatentStyles>
+</xml><![endif]-->
+<style>
+<!--
+ /* Font Definitions */
+ @font-face
+ {font-family:PMingLiU;
+ panose-1:2 2 5 0 0 0 0 0 0 0;
+ mso-font-alt:\65B0\7D30\660E\9AD4;
+ mso-font-charset:136;
+ mso-generic-font-family:roman;
+ mso-font-pitch:variable;
+ mso-font-signature:-1610611969 684719354 22 0 1048577 0;}
+@font-face
+ {font-family:"Cambria Math";
+ panose-1:2 4 5 3 5 4 6 3 2 4;
+ mso-font-charset:1;
+ mso-generic-font-family:roman;
+ mso-font-format:other;
+ mso-font-pitch:variable;
+ mso-font-signature:0 0 0 0 0 0;}
+@font-face
+ {font-family:Calibri;
+ panose-1:2 15 5 2 2 2 4 3 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:-1610611985 1073750139 0 0 159 0;}
+@font-face
+ {font-family:Tahoma;
+ panose-1:2 11 6 4 3 5 4 4 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:-520082689 -1073717157 41 0 66047 0;}
+@font-face
+ {font-family:"Trebuchet MS";
+ panose-1:2 11 6 3 2 2 2 2 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:647 0 0 0 159 0;}
+@font-face
+ {font-family:"Lucida Console";
+ panose-1:2 11 6 9 4 5 4 2 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:modern;
+ mso-font-pitch:fixed;
+ mso-font-signature:-2147482993 6144 0 0 31 0;}
+@font-face
+ {font-family:Consolas;
+ panose-1:2 11 6 9 2 2 4 3 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:modern;
+ mso-font-pitch:fixed;
+ mso-font-signature:-1610611985 1073750091 0 0 159 0;}
+@font-face
+ {font-family:Verdana;
+ panose-1:2 11 6 4 3 5 4 4 2 4;
+ mso-font-charset:0;
+ mso-generic-font-family:swiss;
+ mso-font-pitch:variable;
+ mso-font-signature:-1593833729 1073750107 16 0 415 0;}
+@font-face
+ {font-family:"\@PMingLiU";
+ panose-1:2 2 5 0 0 0 0 0 0 0;
+ mso-font-charset:136;
+ mso-generic-font-family:roman;
+ mso-font-pitch:variable;
+ mso-font-signature:-1610611969 684719354 22 0 1048577 0;}
+ /* Style Definitions */
+ p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-parent:"";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+h1
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-link:"Heading 1 Char";
+ mso-style-next:Normal;
+ margin-top:6.0pt;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-line-height-alt:14.0pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:1;
+ font-size:20.0pt;
+ mso-bidi-font-size:16.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:minor-fareast;
+ mso-bidi-font-family:Arial;
+ color:#666699;
+ mso-font-kerning:16.0pt;
+ font-weight:normal;
+ mso-bidi-font-weight:bold;}
+h2
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-parent:"";
+ mso-style-link:"Heading 2 Char";
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ mso-outline-level:2;
+ font-size:14.0pt;
+ font-family:"Trebuchet MS","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:minor-fareast;
+ mso-bidi-font-family:Arial;
+ color:#5F5F5F;
+ letter-spacing:2.0pt;}
+h3
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-parent:"Heading 4";
+ mso-style-link:"Heading 3 Char";
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:3;
+ font-size:14.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:minor-fareast;
+ color:#FF6600;
+ font-weight:normal;
+ mso-bidi-font-weight:bold;}
+h4
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-link:"Heading 4 Char";
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:4;
+ font-size:11.0pt;
+ mso-bidi-font-size:14.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:minor-fareast;
+ mso-bidi-font-family:"Times New Roman";
+ color:olive;}
+p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText
+ {mso-style-unhide:no;
+ mso-style-link:"Footnote Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoCommentText, li.MsoCommentText, div.MsoCommentText
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-link:"Comment Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoHeader, li.MsoHeader, div.MsoHeader
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-link:"Header Char";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.25in right 6.5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoFooter, li.MsoFooter, div.MsoFooter
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-link:"Footer Char";
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ tab-stops:center 3.25in right 6.5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoCaption, li.MsoCaption, div.MsoCaption
+ {mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ font-weight:bold;}
+span.MsoFootnoteReference
+ {mso-style-unhide:no;
+ vertical-align:super;}
+span.MsoCommentReference
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-ansi-font-size:8.0pt;
+ mso-bidi-font-size:8.0pt;}
+p.MsoListBullet, li.MsoListBullet, div.MsoListBullet
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.25in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l3 level1 lfo1;
+ tab-stops:list .25in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBulletCxSpFirst, li.MsoListBulletCxSpFirst, div.MsoListBulletCxSpF=
+irst
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.25in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l3 level1 lfo1;
+ tab-stops:list .25in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBulletCxSpMiddle, li.MsoListBulletCxSpMiddle, div.MsoListBulletCxS=
+pMiddle
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.25in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l3 level1 lfo1;
+ tab-stops:list .25in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBulletCxSpLast, li.MsoListBulletCxSpLast, div.MsoListBulletCxSpLast
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.25in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l3 level1 lfo1;
+ tab-stops:list .25in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet2, li.MsoListBullet2, div.MsoListBullet2
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l2 level1 lfo2;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet2CxSpFirst, li.MsoListBullet2CxSpFirst, div.MsoListBullet2Cx=
+SpFirst
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l2 level1 lfo2;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet2CxSpMiddle, li.MsoListBullet2CxSpMiddle, div.MsoListBullet2=
+CxSpMiddle
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l2 level1 lfo2;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet2CxSpLast, li.MsoListBullet2CxSpLast, div.MsoListBullet2CxSp=
+Last
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l2 level1 lfo2;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet3, li.MsoListBullet3, div.MsoListBullet3
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.75in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l1 level1 lfo3;
+ tab-stops:list .75in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet3CxSpFirst, li.MsoListBullet3CxSpFirst, div.MsoListBullet3Cx=
+SpFirst
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.75in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l1 level1 lfo3;
+ tab-stops:list .75in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet3CxSpMiddle, li.MsoListBullet3CxSpMiddle, div.MsoListBullet3=
+CxSpMiddle
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.75in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l1 level1 lfo3;
+ tab-stops:list .75in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListBullet3CxSpLast, li.MsoListBullet3CxSpLast, div.MsoListBullet3CxSp=
+Last
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.75in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l1 level1 lfo3;
+ tab-stops:list .75in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListNumber2, li.MsoListNumber2, div.MsoListNumber2
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l0 level1 lfo4;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListNumber2CxSpFirst, li.MsoListNumber2CxSpFirst, div.MsoListNumber2Cx=
+SpFirst
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l0 level1 lfo4;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListNumber2CxSpMiddle, li.MsoListNumber2CxSpMiddle, div.MsoListNumber2=
+CxSpMiddle
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l0 level1 lfo4;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListNumber2CxSpLast, li.MsoListNumber2CxSpLast, div.MsoListNumber2CxSp=
+Last
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ text-indent:-.25in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ mso-list:l0 level1 lfo4;
+ tab-stops:list .5in;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+a:link, span.MsoHyperlink
+ {mso-style-unhide:no;
+ color:blue;
+ text-decoration:underline;
+ text-underline:single;}
+a:visited, span.MsoHyperlinkFollowed
+ {mso-style-priority:1;
+ mso-style-unhide:no;
+ color:purple;
+ mso-themecolor:followedhyperlink;
+ text-decoration:underline;
+ text-underline:single;}
+p.MsoCommentSubject, li.MsoCommentSubject, div.MsoCommentSubject
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-parent:"Comment Text";
+ mso-style-link:"Comment Subject Char";
+ mso-style-next:"Comment Text";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ font-weight:bold;}
+p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
+ {mso-style-noshow:yes;
+ mso-style-unhide:no;
+ mso-style-link:"Balloon Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:8.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";}
+p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Verdana","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListParagraphCxSpFirst, li.MsoListParagraphCxSpFirst, div.MsoListParag=
+raphCxSpFirst
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Verdana","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListParagraphCxSpMiddle, li.MsoListParagraphCxSpMiddle, div.MsoListPar=
+agraphCxSpMiddle
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Verdana","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoListParagraphCxSpLast, li.MsoListParagraphCxSpLast, div.MsoListParagra=
+phCxSpLast
+ {mso-style-priority:34;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Verdana","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.MsoQuote, li.MsoQuote, div.MsoQuote
+ {mso-style-priority:29;
+ mso-style-unhide:no;
+ mso-style-qformat:yes;
+ mso-style-link:"Quote Char";
+ mso-style-next:Normal;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:black;
+ font-style:italic;}
+span.Heading1Char
+ {mso-style-name:"Heading 1 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 1";
+ mso-ansi-font-size:20.0pt;
+ mso-bidi-font-size:16.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-ascii-font-family:Tahoma;
+ mso-hansi-font-family:Tahoma;
+ mso-bidi-font-family:Arial;
+ color:#666699;
+ mso-font-kerning:16.0pt;
+ mso-bidi-font-weight:bold;}
+span.Heading2Char
+ {mso-style-name:"Heading 2 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 2";
+ mso-ansi-font-size:13.0pt;
+ mso-bidi-font-size:13.0pt;
+ font-family:"Cambria","serif";
+ mso-ascii-font-family:Cambria;
+ mso-ascii-theme-font:major-latin;
+ mso-fareast-font-family:"Times New Roman";
+ mso-fareast-theme-font:major-fareast;
+ mso-hansi-font-family:Cambria;
+ mso-hansi-theme-font:major-latin;
+ mso-bidi-font-family:"Times New Roman";
+ mso-bidi-theme-font:major-bidi;
+ color:#4F81BD;
+ mso-themecolor:accent1;
+ font-weight:bold;}
+span.Heading4Char
+ {mso-style-name:"Heading 4 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 4";
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:14.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-ascii-font-family:Tahoma;
+ mso-hansi-font-family:Tahoma;
+ mso-bidi-font-family:Tahoma;
+ color:olive;
+ mso-ansi-language:EN-US;
+ mso-fareast-language:EN-US;
+ mso-bidi-language:AR-SA;
+ font-weight:bold;}
+span.Heading3Char
+ {mso-style-name:"Heading 3 Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Heading 3";
+ mso-ansi-font-size:14.0pt;
+ mso-bidi-font-size:14.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-ascii-font-family:Tahoma;
+ mso-hansi-font-family:Tahoma;
+ mso-bidi-font-family:Tahoma;
+ color:#FF6600;
+ mso-ansi-language:EN-US;
+ mso-fareast-language:EN-US;
+ mso-bidi-language:AR-SA;
+ mso-bidi-font-weight:bold;}
+span.FootnoteTextChar
+ {mso-style-name:"Footnote Text Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Footnote Text";
+ mso-ansi-font-size:11.0pt;}
+span.CommentTextChar
+ {mso-style-name:"Comment Text Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Comment Text";}
+span.HeaderChar
+ {mso-style-name:"Header Char";
+ mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Header;
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;}
+span.FooterChar
+ {mso-style-name:"Footer Char";
+ mso-style-priority:1;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Footer;
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;}
+span.CommentSubjectChar
+ {mso-style-name:"Comment Subject Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-parent:"Comment Text Char";
+ mso-style-link:"Comment Subject";
+ font-weight:bold;}
+span.BalloonTextChar
+ {mso-style-name:"Balloon Text Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Balloon Text";
+ mso-ansi-font-size:8.0pt;
+ mso-bidi-font-size:8.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-ascii-font-family:Tahoma;
+ mso-hansi-font-family:Tahoma;
+ mso-bidi-font-family:Tahoma;}
+span.QuoteChar
+ {mso-style-name:"Quote Char";
+ mso-style-priority:29;
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Quote;
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ color:black;
+ font-style:italic;}
+p.Heading0, li.Heading0, div.Heading0
+ {mso-style-name:"Heading 0";
+ mso-style-unhide:no;
+ mso-style-parent:"Heading 1";
+ margin-top:6.0pt;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-line-height-alt:14.0pt;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:1;
+ font-size:28.0pt;
+ mso-bidi-font-size:16.0pt;
+ font-family:"Tahoma","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:Arial;
+ color:#006699;
+ mso-font-kerning:16.0pt;
+ mso-bidi-font-weight:bold;}
+p.SubHeading, li.SubHeading, div.SubHeading
+ {mso-style-name:SubHeading;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ color:maroon;
+ font-weight:bold;
+ mso-bidi-font-weight:normal;}
+span.CodeCharChar
+ {mso-style-name:"Code Char Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Code;
+ mso-ansi-font-size:9.0pt;
+ mso-bidi-font-size:9.0pt;
+ font-family:"Lucida Console";
+ mso-ascii-font-family:"Lucida Console";
+ mso-hansi-font-family:"Lucida Console";
+ mso-no-proof:yes;}
+p.Code, li.Code, div.Code
+ {mso-style-name:Code;
+ mso-style-unhide:no;
+ mso-style-link:"Code Char Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:3.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ mso-layout-grid-align:none;
+ text-autospace:none;
+ font-size:9.0pt;
+ font-family:"Lucida Console";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ mso-no-proof:yes;}
+span.NoteChar
+ {mso-style-name:"Note Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:Note;
+ mso-ansi-font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ background:#F3F3F3;
+ font-style:italic;
+ mso-bidi-font-style:normal;}
+p.Note, li.Note, div.Note
+ {mso-style-name:Note;
+ mso-style-unhide:no;
+ mso-style-link:"Note Char";
+ margin-top:0in;
+ margin-right:.2in;
+ margin-bottom:12.0pt;
+ margin-left:.2in;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ background:#F3F3F3;
+ border:none;
+ mso-border-top-alt:.5pt;
+ mso-border-left-alt:.5pt;
+ mso-border-bottom-alt:1.5pt;
+ mso-border-right-alt:1.5pt;
+ mso-border-color-alt:windowtext;
+ mso-border-style-alt:solid;
+ padding:0in;
+ mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt;
+ font-size:11.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ font-style:italic;
+ mso-bidi-font-style:normal;}
+p.Style2, li.Style2, div.Style2
+ {mso-style-name:Style2;
+ mso-style-unhide:no;
+ mso-style-parent:"";
+ mso-style-next:Normal;
+ margin:0in;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ background:#F9FFF3;
+ border:none;
+ mso-border-top-alt:.5pt;
+ mso-border-left-alt:.5pt;
+ mso-border-bottom-alt:1.5pt;
+ mso-border-right-alt:1.5pt;
+ mso-border-color-alt:windowtext;
+ mso-border-style-alt:solid;
+ padding:0in;
+ mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt;
+ font-size:9.0pt;
+ font-family:Consolas;
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";
+ mso-no-proof:yes;}
+p.Style3, li.Style3, div.Style3
+ {mso-style-name:Style3;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:12.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan;
+ background:#F5FAF4;
+ mso-layout-grid-align:none;
+ text-autospace:none;
+ border:none;
+ mso-border-alt:solid windowtext 1.0pt;
+ padding:0in;
+ mso-padding-alt:1.0pt 4.0pt 1.0pt 4.0pt;
+ mso-border-shadow:yes;
+ font-size:9.0pt;
+ font-family:Consolas;
+ mso-fareast-font-family:PMingLiU;
+ mso-bidi-font-family:"Times New Roman";
+ mso-fareast-language:ZH-CN;
+ mso-no-proof:yes;}
+span.DescriptionTextChar
+ {mso-style-name:"Description Text Char";
+ mso-style-unhide:no;
+ mso-style-locked:yes;
+ mso-style-link:"Description Text";}
+p.DescriptionText, li.DescriptionText, div.DescriptionText
+ {mso-style-name:"Description Text";
+ mso-style-unhide:no;
+ mso-style-link:"Description Text Char";
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.25in;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Calibri","sans-serif";
+ mso-fareast-font-family:"Times New Roman";
+ mso-bidi-font-family:"Times New Roman";}
+p.Issue, li.Issue, div.Issue
+ {mso-style-name:Issue;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:0in;
+ mso-pagination:widow-orphan lines-together;
+ border:none;
+ mso-border-alt:solid navy 1.5pt;
+ padding:0in;
+ mso-padding-alt:1.0pt 1.0pt 1.0pt 1.0pt;
+ mso-border-shadow:yes;
+ font-size:10.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";
+ color:red;
+ font-style:italic;
+ mso-bidi-font-style:normal;}
+p.msolistparagraph0, li.msolistparagraph0, div.msolistparagraph0
+ {mso-style-name:msolistparagraph;
+ mso-style-unhide:no;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";}
+p.msolistparagraph0CxSpFirst, li.msolistparagraph0CxSpFirst, div.msolistpar=
+agraph0CxSpFirst
+ {mso-style-name:msolistparagraphCxSpFirst;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";}
+p.msolistparagraph0CxSpMiddle, li.msolistparagraph0CxSpMiddle, div.msolistp=
+aragraph0CxSpMiddle
+ {mso-style-name:msolistparagraphCxSpMiddle;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:0in;
+ margin-left:.5in;
+ margin-bottom:.0001pt;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";}
+p.msolistparagraph0CxSpLast, li.msolistparagraph0CxSpLast, div.msolistparag=
+raph0CxSpLast
+ {mso-style-name:msolistparagraphCxSpLast;
+ mso-style-unhide:no;
+ mso-style-type:export-only;
+ margin-top:0in;
+ margin-right:0in;
+ margin-bottom:6.0pt;
+ margin-left:.5in;
+ mso-add-space:auto;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ mso-bidi-font-size:12.0pt;
+ font-family:"Times New Roman","serif";
+ mso-fareast-font-family:"Times New Roman";}
+.MsoChpDefault
+ {mso-style-type:export-only;
+ mso-default-props:yes;
+ font-size:10.0pt;
+ mso-ansi-font-size:10.0pt;
+ mso-bidi-font-size:10.0pt;
+ mso-ascii-font-family:Calibri;
+ mso-hansi-font-family:Calibri;}
+ /* Page Definitions */
+ @page
+ {mso-footnote-separator:url("Microsoft.VisualStudio.Text.Operations.Overvi=
+ew_files/header.htm") fs;
+ mso-footnote-continuation-separator:url("Microsoft.VisualStudio.Text.Opera=
+tions.Overview_files/header.htm") fcs;
+ mso-endnote-separator:url("Microsoft.VisualStudio.Text.Operations.Overview=
+_files/header.htm") es;
+ mso-endnote-continuation-separator:url("Microsoft.VisualStudio.Text.Operat=
+ions.Overview_files/header.htm") ecs;}
+@page Section1
+ {size:8.5in 11.0in;
+ margin:1.0in 1.25in 1.0in 1.25in;
+ mso-header-margin:.5in;
+ mso-footer-margin:.5in;
+ mso-even-header:url("Microsoft.VisualStudio.Text.Operations.Overview_files=
+/header.htm") eh1;
+ mso-header:url("Microsoft.VisualStudio.Text.Operations.Overview_files/head=
+er.htm") h1;
+ mso-footer:url("Microsoft.VisualStudio.Text.Operations.Overview_files/head=
+er.htm") f1;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+ /* List Definitions */
+ @list l0
+ {mso-list-id:-129;
+ mso-list-type:simple;
+ mso-list-template-ids:-1739002844;}
+@list l0:level1
+ {mso-level-style-link:"List Number 2";
+ mso-level-tab-stop:.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l1
+ {mso-list-id:-126;
+ mso-list-type:simple;
+ mso-list-template-ids:-1045901690;}
+@list l1:level1
+ {mso-level-number-format:bullet;
+ mso-level-style-link:"List Bullet 3";
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.75in;
+ mso-level-number-position:left;
+ margin-left:.75in;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l2
+ {mso-list-id:-125;
+ mso-list-type:simple;
+ mso-list-template-ids:-1069260336;}
+@list l2:level1
+ {mso-level-number-format:bullet;
+ mso-level-style-link:"List Bullet 2";
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l3
+ {mso-list-id:-119;
+ mso-list-type:simple;
+ mso-list-template-ids:1390696726;}
+@list l3:level1
+ {mso-level-number-format:bullet;
+ mso-level-style-link:"List Bullet";
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.25in;
+ mso-level-number-position:left;
+ margin-left:.25in;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l4
+ {mso-list-id:782309382;
+ mso-list-type:hybrid;
+ mso-list-template-ids:-2130535516 67698689 67698691 67698693 67698689 6769=
+8691 67698693 67698689 67698691 67698693;}
+@list l4:level1
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l4:level2
+ {mso-level-tab-stop:1.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level3
+ {mso-level-tab-stop:1.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level4
+ {mso-level-tab-stop:2.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level5
+ {mso-level-tab-stop:2.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level6
+ {mso-level-tab-stop:3.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level7
+ {mso-level-tab-stop:3.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level8
+ {mso-level-tab-stop:4.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l4:level9
+ {mso-level-tab-stop:4.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5
+ {mso-list-id:907811759;
+ mso-list-type:hybrid;
+ mso-list-template-ids:2147251200 67698689 67698691 67698693 67698689 67698=
+691 67698693 67698689 67698691 67698693;}
+@list l5:level1
+ {mso-level-number-format:bullet;
+ mso-level-text:\F0B7;
+ mso-level-tab-stop:.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;
+ font-family:Symbol;}
+@list l5:level2
+ {mso-level-tab-stop:1.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level3
+ {mso-level-tab-stop:1.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level4
+ {mso-level-tab-stop:2.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level5
+ {mso-level-tab-stop:2.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level6
+ {mso-level-tab-stop:3.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level7
+ {mso-level-tab-stop:3.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level8
+ {mso-level-tab-stop:4.0in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+@list l5:level9
+ {mso-level-tab-stop:4.5in;
+ mso-level-number-position:left;
+ text-indent:-.25in;}
+ol
+ {margin-bottom:0in;}
+ul
+ {margin-bottom:0in;}
+-->
+</style>
+<!--[if gte mso 10]>
+<style>
+ /* Style Definitions */
+ table.MsoNormalTable
+ {mso-style-name:"Table Normal";
+ mso-tstyle-rowband-size:0;
+ mso-tstyle-colband-size:0;
+ mso-style-noshow:yes;
+ mso-style-priority:99;
+ mso-style-qformat:yes;
+ mso-style-parent:"";
+ mso-padding-alt:0in 5.4pt 0in 5.4pt;
+ mso-para-margin:0in;
+ mso-para-margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Calibri","sans-serif";}
+table.MsoTableGrid
+ {mso-style-name:"Table Grid";
+ mso-tstyle-rowband-size:0;
+ mso-tstyle-colband-size:0;
+ mso-style-unhide:no;
+ border:solid windowtext 1.0pt;
+ mso-border-alt:solid windowtext .5pt;
+ mso-padding-alt:0in 5.4pt 0in 5.4pt;
+ mso-border-insideh:.5pt solid windowtext;
+ mso-border-insidev:.5pt solid windowtext;
+ mso-para-margin:0in;
+ mso-para-margin-bottom:.0001pt;
+ line-height:14.0pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Calibri","sans-serif";}
+</style>
+<![endif]--><!--[if gte mso 9]><xml>
+ <o:shapedefaults v:ext=3D"edit" spidmax=3D"8194"/>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <o:shapelayout v:ext=3D"edit">
+ <o:idmap v:ext=3D"edit" data=3D"1"/>
+ </o:shapelayout></xml><![endif]-->
+</head>
+
+<body lang=3DEN-US link=3Dblue vlink=3Dpurple style=3D'tab-interval:.5in'>
+
+<div class=3DSection1>
+
+<p class=3DHeading0>Editor Operations Subsystem</p>
+
+<div style=3D'mso-element:para-border-div;border:none;border-bottom:solid w=
+indowtext 1.0pt;
+mso-border-bottom-alt:solid windowtext .75pt;padding:0in 0in 1.0pt 0in'>
+
+<p class=3DMsoNormal style=3D'border:none;mso-border-bottom-alt:solid windo=
+wtext .75pt;
+padding:0in;mso-padding-alt:0in 0in 1.0pt 0in'><o:p>&nbsp;</o:p></p>
+
+</div>
+
+<h1><a name=3D"_Toc76978452"></a><a name=3D"_Toc151974416"></a><a
+name=3D"_Toc151973942"></a><a name=3D"_Toc149118079"></a><a name=3D"_Toc149=
+118215"></a><a
+name=3D"_Toc149118380"></a><a name=3D"_Toc149118641"></a><a name=3D"_Toc151=
+873508"></a><a
+name=3D"_Toc151873650"></a><a name=3D"_Toc151974258"></a><a name=3D"_Toc153=
+684427"></a><a
+name=3D"_Toc151892155"></a><a name=3D"_Toc151886240"></a><a name=3D"_Toc151=
+886043"></a><a
+name=3D"_Toc153700829"></a><a name=3D"_Toc151442559"></a><a name=3D"_Toc155=
+080032"></a><a
+name=3D"_Toc149120311"></a><a name=3D"_Toc152403723"></a><a name=3D"_Toc149=
+637917"><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+"Times New Roman"'>Overview</span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></span></a><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-fareast-font-family:=
+"Times New Roman"'><o:p></o:p></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></h1>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'>This
+document provides a conceptual overview of the </span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><i style=3D'mso-bidi-font-style:normal'=
+><span
+style=3D'font-family:"Verdana","sans-serif"'>Operations</span></i> subsyste=
+m.
+This subsystem provides services and public types to perform operations on =
+the editor.
+These are broken down into three separate areas that are described in great=
+er
+detail below:</span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoListBullet2CxSpFirst><span style=3D'mso-bookmark:_Toc15240372=
+3'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><![if !supportLists]><span
+style=3D'font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-fa=
+mily:
+Symbol'><span style=3D'mso-list:Ignore'>&middot;<span style=3D'font:7.0pt "=
+Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span></span><![endif]>Editor Operations</span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></span></span></span></p>
+
+<p class=3DMsoListBullet2CxSpMiddle><span style=3D'mso-bookmark:_Toc1524037=
+23'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><![if !supportLists]><span
+style=3D'font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-fa=
+mily:
+Symbol'><span style=3D'mso-list:Ignore'>&middot;<span style=3D'font:7.0pt "=
+Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span></span><![endif]>Text Navigation</span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></p>
+
+<p class=3DMsoListBullet2CxSpMiddle><span style=3D'mso-bookmark:_Toc1524037=
+23'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><![if !supportLists]><span
+style=3D'font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-fa=
+mily:
+Symbol'><span style=3D'mso-list:Ignore'>&middot;<span style=3D'font:7.0pt "=
+Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span></span><![endif]>Find Logic</span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></span></span></p>
+
+<p class=3DMsoListBullet2CxSpLast><span style=3D'mso-bookmark:_Toc152403723=
+'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><![if !supportLists]><span
+style=3D'font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-fa=
+mily:
+Symbol'><span style=3D'mso-list:Ignore'>&middot;<span style=3D'font:7.0pt "=
+Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span></span><![endif]>TextBuffer Undo Manager</span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></p>
+
+<h1><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><a name=3D"_Toc124327313"></a><a
+name=3D"_Toc149637918"><span style=3D'mso-bookmark:_Toc124327313'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>Editor Operations</span=
+></span></a></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></h1>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>The Editor Operations area of the </sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><i
+style=3D'mso-bidi-font-style:normal'><span style=3D'font-family:"Verdana","=
+sans-serif"'>Operations</span></i>
+subsystem is concerned with providing operations that can be performed upon=
+ the
+ITextView of an editor.</span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>There are five categories of operation=
+s that
+are implemented:</span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></p>
+
+<ul style=3D'margin-top:0in' type=3Ddisc>
+ <li class=3DMsoNormal style=3D'margin-bottom:6.0pt;line-height:normal;mso-=
+list:
+ l5 level1 lfo5;tab-stops:list .5in'><span style=3D'mso-bookmark:_Toc15=
+2403723'><span
+ style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc1=
+55080032'><span
+ style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc1=
+53700829'><span
+ style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc1=
+51886240'><span
+ style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc1=
+53684427'><span
+ style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc1=
+51873650'><span
+ style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc1=
+49118641'><span
+ style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc1=
+49118215'><span
+ style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc1=
+51973942'><span
+ style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc7=
+6978452'><span
+ style=3D'mso-bookmark:_Toc124327313'></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span><a
+ href=3D"#_Navigation_Operations"><span style=3D'mso-bookmark:_Toc15240=
+3723'><span
+ style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc1=
+55080032'><span
+ style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc1=
+53700829'><span
+ style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc1=
+51886240'><span
+ style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc1=
+53684427'><span
+ style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc1=
+51873650'><span
+ style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc1=
+49118641'><span
+ style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc1=
+49118215'><span
+ style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc1=
+51973942'><span
+ style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc7=
+6978452'><span
+ style=3D'mso-bookmark:_Toc124327313'><span style=3D'mso-ascii-font-fam=
+ily:
+ Calibri;mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;
+ mso-hansi-theme-font:minor-latin'>Navigation Operations</span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span><span
+ style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc1=
+49120311'><span
+ style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc1=
+51442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc12=
+4327313'></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/a><span
+ style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc1=
+49120311'><span
+ style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc1=
+51442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc12=
+4327313'><span
+ style=3D'mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-lati=
+n;
+ mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin'><o:p><=
+/o:p></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></li>
+</ul>
+
+<ul style=3D'margin-top:0in' type=3Ddisc>
+ <li class=3DMsoNormal style=3D'margin-bottom:6.0pt;line-height:normal;mso-=
+list:
+ l4 level1 lfo6;tab-stops:list .5in'><span style=3D'mso-bookmark:_Toc15=
+2403723'><span
+ style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc1=
+55080032'><span
+ style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc1=
+53700829'><span
+ style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc1=
+51886240'><span
+ style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc1=
+53684427'><span
+ style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc1=
+51873650'><span
+ style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc1=
+49118641'><span
+ style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc1=
+49118215'><span
+ style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc1=
+51973942'><span
+ style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc7=
+6978452'><span
+ style=3D'mso-bookmark:_Toc124327313'></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span><a
+ href=3D"#_Edit_Operations"><span style=3D'mso-bookmark:_Toc152403723'>=
+<span
+ style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc1=
+55080032'><span
+ style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc1=
+53700829'><span
+ style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc1=
+51886240'><span
+ style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc1=
+53684427'><span
+ style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc1=
+51873650'><span
+ style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc1=
+49118641'><span
+ style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc1=
+49118215'><span
+ style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc1=
+51973942'><span
+ style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc7=
+6978452'><span
+ style=3D'mso-bookmark:_Toc124327313'><span style=3D'mso-ascii-font-fam=
+ily:
+ Calibri;mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;
+ mso-hansi-theme-font:minor-latin'>Edit Operations</span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span><span
+ style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc1=
+49120311'><span
+ style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc1=
+51442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc12=
+4327313'></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/a><span
+ style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc1=
+49120311'><span
+ style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc1=
+51442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc12=
+4327313'><span
+ style=3D'mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-lati=
+n;
+ mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin'><o:p><=
+/o:p></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></li>
+ <li class=3DMsoNormal style=3D'margin-bottom:6.0pt;line-height:normal;mso-=
+list:
+ l4 level1 lfo6;tab-stops:list .5in'><span style=3D'mso-bookmark:_Toc15=
+2403723'><span
+ style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc1=
+55080032'><span
+ style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc1=
+53700829'><span
+ style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc1=
+51886240'><span
+ style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc1=
+53684427'><span
+ style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc1=
+51873650'><span
+ style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc1=
+49118641'><span
+ style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc1=
+49118215'><span
+ style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc1=
+51973942'><span
+ style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc7=
+6978452'><span
+ style=3D'mso-bookmark:_Toc124327313'></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span><a
+ href=3D"#_Selection_Operations"><span style=3D'mso-bookmark:_Toc152403=
+723'><span
+ style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc1=
+55080032'><span
+ style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc1=
+53700829'><span
+ style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc1=
+51886240'><span
+ style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc1=
+53684427'><span
+ style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc1=
+51873650'><span
+ style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc1=
+49118641'><span
+ style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc1=
+49118215'><span
+ style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc1=
+51973942'><span
+ style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc7=
+6978452'><span
+ style=3D'mso-bookmark:_Toc124327313'><span style=3D'mso-ascii-font-fam=
+ily:
+ Calibri;mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;
+ mso-hansi-theme-font:minor-latin'>Selection Operations</span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span><span
+ style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc1=
+49120311'><span
+ style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc1=
+51442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc12=
+4327313'></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/a><span
+ style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc1=
+49120311'><span
+ style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc1=
+51442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc12=
+4327313'><span
+ style=3D'mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-lati=
+n;
+ mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin'><o:p><=
+/o:p></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></li>
+ <li class=3DMsoNormal style=3D'margin-bottom:6.0pt;line-height:normal;mso-=
+list:
+ l4 level1 lfo6;tab-stops:list .5in'><span style=3D'mso-bookmark:_Toc15=
+2403723'><span
+ style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc1=
+55080032'><span
+ style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc1=
+53700829'><span
+ style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc1=
+51886240'><span
+ style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc1=
+53684427'><span
+ style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc1=
+51873650'><span
+ style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc1=
+49118641'><span
+ style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc1=
+49118215'><span
+ style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc1=
+51973942'><span
+ style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc7=
+6978452'><span
+ style=3D'mso-bookmark:_Toc124327313'></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span><a
+ href=3D"#_Clipboard_Operations"><span style=3D'mso-bookmark:_Toc152403=
+723'><span
+ style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc1=
+55080032'><span
+ style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc1=
+53700829'><span
+ style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc1=
+51886240'><span
+ style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc1=
+53684427'><span
+ style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc1=
+51873650'><span
+ style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc1=
+49118641'><span
+ style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc1=
+49118215'><span
+ style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc1=
+51973942'><span
+ style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc7=
+6978452'><span
+ style=3D'mso-bookmark:_Toc124327313'><span style=3D'mso-ascii-font-fam=
+ily:
+ Calibri;mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;
+ mso-hansi-theme-font:minor-latin'>Clipboard Operations</span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span><span
+ style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc1=
+49120311'><span
+ style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc1=
+51442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc12=
+4327313'></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/a><span
+ style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc1=
+49120311'><span
+ style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc1=
+51442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc12=
+4327313'><span
+ style=3D'mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-lati=
+n;
+ mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin'><o:p><=
+/o:p></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></li>
+ <li class=3DMsoNormal style=3D'margin-bottom:6.0pt;line-height:normal;mso-=
+list:
+ l4 level1 lfo6;tab-stops:list .5in'><span style=3D'mso-bookmark:_Toc15=
+2403723'><span
+ style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc1=
+55080032'><span
+ style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc1=
+53700829'><span
+ style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc1=
+51886240'><span
+ style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc1=
+53684427'><span
+ style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc1=
+51873650'><span
+ style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc1=
+49118641'><span
+ style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc1=
+49118215'><span
+ style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc1=
+51973942'><span
+ style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc7=
+6978452'><span
+ style=3D'mso-bookmark:_Toc124327313'></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span><a
+ href=3D"#_Editor_PropertyOperations"><span style=3D'mso-bookmark:_Toc1=
+52403723'><span
+ style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc1=
+55080032'><span
+ style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc1=
+53700829'><span
+ style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc1=
+51886240'><span
+ style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc1=
+53684427'><span
+ style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc1=
+51873650'><span
+ style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc1=
+49118641'><span
+ style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc1=
+49118215'><span
+ style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc1=
+51973942'><span
+ style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc7=
+6978452'><span
+ style=3D'mso-bookmark:_Toc124327313'><span style=3D'mso-ascii-font-fam=
+ily:
+ Calibri;mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;
+ mso-hansi-theme-font:minor-latin'>Editor Property Operations</span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span></span><span
+ style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc1=
+49120311'><span
+ style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc1=
+51442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc12=
+4327313'></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/a><span
+ style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc1=
+49120311'><span
+ style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc1=
+51442559'><span
+ style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc1=
+51886043'><span
+ style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc1=
+51892155'><span
+ style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc1=
+51974258'><span
+ style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc1=
+51873508'><span
+ style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc1=
+49118380'><span
+ style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc1=
+49118079'><span
+ style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc1=
+51974416'><span
+ style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc12=
+4327313'><span
+ style=3D'mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-lati=
+n;
+ mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin'><o:p><=
+/o:p></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></li>
+</ul>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>Editor Operations also define a set of=
+ command
+handlers and keybindings that hook up the editor operations with the Nautil=
+us
+Command and Input subsystem</span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><a
+name=3D"_Navigation_Operations"></a><span style=3D'mso-fareast-font-family:=
+"Times New Roman"'><span
+style=3D'mso-spacerun:yes'>&nbsp;</span><a name=3D"_Toc149637920">Navigation
+Operations</a><o:p></o:p></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'><a
+name=3D"_IEditorOperationsProvider_Definitio"></a>This category of operatio=
+ns is
+concerned with caret movement (for example, moving the caret to the end of =
+the
+current line, moving it to the start of the document, page up, page down, e=
+tc).
+Since these operations do not alter text in the editor, they are not undo
+aware.</span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><a
+name=3D"_Edit_Operations"></a><span style=3D'mso-fareast-font-family:"Times=
+ New Roman"'><span
+style=3D'mso-spacerun:yes'>&nbsp;</span><a name=3D"_Toc149637921">Edit Oper=
+ations</a><o:p></o:p></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>This category of operations is concern=
+ed
+with text manipulation (for example, deleting text, inserting text, indenti=
+ng
+tabs, etc). These operations alter text, they are undo aware. Undo aware
+operations take in an UndoHistory input parameter, which they will use to
+create UndoTransactions..</span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><a
+name=3D"_Selection_Operations"></a><span style=3D'mso-fareast-font-family:"=
+Times New Roman"'><span
+style=3D'mso-spacerun:yes'>&nbsp;</span><a name=3D"_Toc149637922">Selection
+Operations</a><o:p></o:p></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>This category of operations is concern=
+ed
+with selection manipulation (for example, selecting all text in the editor,
+extending selections, resetting selections, etc). Since these operations do=
+ not
+alter text in the editor, they are not undo aware.</span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><a
+name=3D"_Clipboard_Operations"></a><span style=3D'mso-fareast-font-family:"=
+Times New Roman"'><span
+style=3D'mso-spacerun:yes'>&nbsp;</span><a name=3D"_Toc149637923">Clipboard
+Operations</a><o:p></o:p></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>This category of operations is concern=
+ed
+with utilizing the clipboard. For example, cut, copy, and paste. They also
+contain operations that tell you whether the clipboard operations (cut and
+paste) is currently allowed (the editor may be in read-only mode). Some of
+these operations alter text, namely cut and paste. Hence, these methods are
+undo aware<a name=3D"_Editor_PropertyOperations"></a>, and take in an UndoH=
+istory
+input parameter.</span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'><span
+style=3D'mso-spacerun:yes'>&nbsp;</span><a name=3D"_Toc149637924">Editor Pr=
+operty
+Operations</a><o:p></o:p></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>This category of operations is concern=
+ed with
+getting and setting properties on the editor. For example, the tab size used
+for indenting operations, the overwrite mode, the ITextView that the operat=
+ions
+are bound to, etc. Since these operations do not alter to text in the edito=
+r,
+they are not undo aware.</span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></p>
+
+<h1><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><a
+name=3D"_Toc149637925"><span style=3D'mso-fareast-font-family:"Times New Ro=
+man"'>Text
+Navigation</span></a></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></h1>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>The Text Navigation area of </span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><b
+style=3D'mso-bidi-font-weight:normal'><i style=3D'mso-bidi-font-style:norma=
+l'><span
+style=3D'font-family:"Verdana","sans-serif"'>Operations</span></i></b> subs=
+ystem
+is concerned with providing text navigation operations on a given ITextBuff=
+er.</span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><a
+name=3D"_The_ITextStructureNavigator_Interfa"></a><span style=3D'mso-fareas=
+t-font-family:
+"Times New Roman"'>ITextStructureNavigator<o:p></o:p></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>Defines methods which navigate over te=
+xt in
+the given ITextBuffer for a supported IContentType.</span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span><a
+name=3D"_The_TextExtent_Class"></a><span style=3D'mso-bookmark:_Toc15240372=
+3'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'><span style=3D'mso-ascii-font-family:C=
+alibri;
+mso-ascii-theme-font:minor-latin;mso-hansi-font-family:Calibri;mso-hansi-th=
+eme-font:
+minor-latin'><o:p></o:p></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'>TextExtent<o:p></o:p></=
+span></span></span></span></span></span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>Encapsulates information about the ext=
+ent of
+a word. Apart from the extent location, also provides the method IsSignific=
+ant,
+which gets the significance of the text extent. The significance determines
+whether the word is significant. Insignificant words should be ignored duri=
+ng
+navigation operations.</span></span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></p>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>For example, suppose whitespace consti=
+tutes
+word boundaries. A word consisting of purely whitespace is therefore
+insignificant. If we have the sentence &#8220;abc<span
+style=3D'mso-spacerun:yes'>&nbsp;&nbsp; </span>efg&#8221;, and your caret i=
+s at
+b, the move caret to next word operation should take you to e, skipping the
+whitespace between the two words.</span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><a
+name=3D"_The_ITextStructureNavigatorCache_In"></a>ITextStructureNavigatorPr=
+ovider</span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>This is the extension point clients im=
+plement
+to provide an </span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><span
+style=3D'mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;
+mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin'>ITextStruct=
+ureNavigators
+for a particular ContentType. The Operations subsystem implements one navig=
+ator
+for the </span>&#8220;text&#8221; ContentType.</span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></p>
+
+<h1><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><a
+name=3D"_The_ITextStructureNavigatorFactory_"></a><a
+name=3D"_The_ITextStructureNavigatorFactoryP"></a>Text Search</span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></h1>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>The Text Search area of the </span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><i
+style=3D'mso-bidi-font-style:normal'><span style=3D'font-family:"Verdana","=
+sans-serif"'>Operations</span></i>
+subsystem is concerned with providing a search engine that clients may use =
+to
+perform searches on an ITextBuffer.</span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><a
+name=3D"_The_IFindLogic_Interface"></a>ITextSearchService</span></span></sp=
+an></span></span></span></span></span></span></span></span></span></span></=
+span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><span
+style=3D'mso-bidi-font-family:Tahoma;color:#FF6600'><o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></h2>
+
+<p class=3DMsoNormal style=3D'margin-bottom:0in;margin-bottom:.0001pt'><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'>Thi
+is an engine which supports searching for text in a ITextBuffer. </span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><span
+style=3D'mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;
+mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin'>The find op=
+tion
+&#8220;</span>Regular Expressions&#8221;use the .Net Regular Expression eng=
+ine
+for search and replace. The find option &#8220;Match Whole Word&#8221; makes
+use of Text Navigation of the Operations subsystem to determine the extent =
+of a
+word.<a name=3D"_The_IFindLogicProvider_Interface"></a></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></span></span></span></span></span></span></p>
+
+<p class=3DMsoNormal style=3D'margin-bottom:0in;margin-bottom:.0001pt'><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><span
+style=3D'mso-ascii-font-family:Calibri;mso-ascii-theme-font:minor-latin;
+mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin'><o:p>&nbsp;=
+</o:p></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></span></span></span></sp=
+an></p>
+
+<h1><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><a
+name=3D"_Toc149637936"><span style=3D'mso-fareast-font-family:"Times New Ro=
+man"'>TextBuffer
+Undo Manager</span></a></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><span
+style=3D'mso-fareast-font-family:"Times New Roman"'><o:p></o:p></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></h1>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>The TextBuffer Undo Manager area of th=
+e </span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span></span></span></span></span></span></span><span
+style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:_Toc149120=
+311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><i
+style=3D'mso-bidi-font-style:normal'><span style=3D'font-family:"Verdana","=
+sans-serif"'>Operations</span></i>
+subsystem is concerned with managing Undo for a ITextBuffer.</span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></p>
+
+<h2><span style=3D'mso-bookmark:_Toc152403723'><span style=3D'mso-bookmark:=
+_Toc149120311'><span
+style=3D'mso-bookmark:_Toc155080032'><span style=3D'mso-bookmark:_Toc151442=
+559'><span
+style=3D'mso-bookmark:_Toc153700829'><span style=3D'mso-bookmark:_Toc151886=
+043'><span
+style=3D'mso-bookmark:_Toc151886240'><span style=3D'mso-bookmark:_Toc151892=
+155'><span
+style=3D'mso-bookmark:_Toc153684427'><span style=3D'mso-bookmark:_Toc151974=
+258'><span
+style=3D'mso-bookmark:_Toc151873650'><span style=3D'mso-bookmark:_Toc151873=
+508'><span
+style=3D'mso-bookmark:_Toc149118641'><span style=3D'mso-bookmark:_Toc149118=
+380'><span
+style=3D'mso-bookmark:_Toc149118215'><span style=3D'mso-bookmark:_Toc149118=
+079'><span
+style=3D'mso-bookmark:_Toc151973942'><span style=3D'mso-bookmark:_Toc151974=
+416'><span
+style=3D'mso-bookmark:_Toc76978452'><span style=3D'mso-bookmark:_Toc1243273=
+13'><a
+name=3D"_The_ITextBufferUndoManager_Interfac"></a>ITextBufferUndoManager</s=
+pan></span></span></span></span></span></span></span></span></span></span><=
+/span></span></span></span></span></span></span></span></span></h2>
+
+<p class=3DMsoNormal><span style=3D'mso-bookmark:_Toc152403723'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'>An ITextBufferUndoManager manages undo=
+ for a
+given ITextBuffer. This includes:</span></span></span></span></span></span>=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></p>
+
+<p class=3DMsoListBullet2CxSpFirst><span style=3D'mso-bookmark:_Toc15240372=
+3'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'><![if !supportLists]><span style=3D'fo=
+nt-family:
+Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol'><span
+style=3D'mso-list:Ignore'>&middot;<span style=3D'font:7.0pt "Times New Roma=
+n"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span></span><![endif]>Registering an UndoHistory for a ITextBuffer=
+</span></span></span></span></span></span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoListBullet2CxSpMiddle><span style=3D'mso-bookmark:_Toc1524037=
+23'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'><![if !supportLists]><span style=3D'fo=
+nt-family:
+Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol'><span
+style=3D'mso-list:Ignore'>&middot;<span style=3D'font:7.0pt "Times New Roma=
+n"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span></span><![endif]>Listen to Change events from the ITextBuffer,
+and for each ITextBuffer Change, create an UndoTransaction on the ITextBuff=
+er&#8217;s
+UndoHistory so that the ITextBuffer Change will be undoable.</span></span><=
+/span></span></span></span></span></span></span></span></span></span></span=
+></span></span></span></span></span></span></span></p>
+
+<p class=3DMsoListBullet2CxSpLast><span style=3D'mso-bookmark:_Toc152403723=
+'><span
+style=3D'mso-bookmark:_Toc149120311'><span style=3D'mso-bookmark:_Toc155080=
+032'><span
+style=3D'mso-bookmark:_Toc151442559'><span style=3D'mso-bookmark:_Toc153700=
+829'><span
+style=3D'mso-bookmark:_Toc151886043'><span style=3D'mso-bookmark:_Toc151886=
+240'><span
+style=3D'mso-bookmark:_Toc151892155'><span style=3D'mso-bookmark:_Toc153684=
+427'><span
+style=3D'mso-bookmark:_Toc151974258'><span style=3D'mso-bookmark:_Toc151873=
+650'><span
+style=3D'mso-bookmark:_Toc151873508'><span style=3D'mso-bookmark:_Toc149118=
+641'><span
+style=3D'mso-bookmark:_Toc149118380'><span style=3D'mso-bookmark:_Toc149118=
+215'><span
+style=3D'mso-bookmark:_Toc149118079'><span style=3D'mso-bookmark:_Toc151973=
+942'><span
+style=3D'mso-bookmark:_Toc151974416'><span style=3D'mso-bookmark:_Toc769784=
+52'><span
+style=3D'mso-bookmark:_Toc124327313'><![if !supportLists]><span style=3D'fo=
+nt-family:
+Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family:Symbol'><span
+style=3D'mso-list:Ignore'>&middot;<span style=3D'font:7.0pt "Times New Roma=
+n"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+</span></span></span><![endif]>Provide assessors for clients to gain access=
+ to
+the ITextBuffer that the undo manager works on top of, and the UndoHistory =
+that
+is registered for that ITextBuffer.</span></span></span></span></span></spa=
+n></span></span></span></span></span></span></span></span></span></span></s=
+pan></span></span></span><a
+name=3D"_The_ITextBufferUndoManagerProvider_"></a></p>
+
+</div>
+
+</body>
+
+</html>
+
+------=_NextPart_01C88FF8.77140040
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Operations.Overview_files/themedata.thmx
+Content-Transfer-Encoding: base64
+Content-Type: application/vnd.ms-officetheme
+
+UEsDBBQABgAIAAAAIQCCirwT+gAAABwCAAATAAAAW0NvbnRlbnRfVHlwZXNdLnhtbKyRy2rDMBBF
+94X+g9C22HK6KKXYzqJJd30s0g8Y5LEtao+ENAnJ33fsuFC6CC10IxBizpl7Va6P46AOGJPzVOlV
+XmiFZH3jqKv0++4pu9cqMVADgyes9AmTXtfXV+XuFDApmaZU6Z45PBiTbI8jpNwHJHlpfRyB5Ro7
+E8B+QIfmtijujPXESJzxxNB1+SoLRNegeoPILzCKx7Cg8Pv5DCSAmAtYq8czYVqi0hDC4CywRDAH
+an7oM9+2zmLj7X4UaT6DF9jNBDO/XGD1P+ov5wZb2A+stkfp4lx/xCH9LdtSay6Tc/7Uu5AuGC6X
+t7Rh5r+tPwEAAP//AwBQSwMEFAAGAAgAAAAhAKXWp+fAAAAANgEAAAsAAABfcmVscy8ucmVsc4SP
+z2rDMAyH74W9g9F9UdLDGCV2L6WQQy+jfQDhKH9oIhvbG+vbT8cGCrsIhKTv96k9/q6L+eGU5yAW
+mqoGw+JDP8to4XY9v3+CyYWkpyUIW3hwhqN727VfvFDRozzNMRulSLYwlRIPiNlPvFKuQmTRyRDS
+SkXbNGIkf6eRcV/XH5ieGeA2TNP1FlLXN2Cuj6jJ/7PDMMyeT8F/ryzlRQRuN5RMaeRioagv41O9
+kKhlqtQe0LW4+db9AQAA//8DAFBLAwQUAAYACAAAACEAa3mWFoMAAACKAAAAHAAAAHRoZW1lL3Ro
+ZW1lL3RoZW1lTWFuYWdlci54bWwMzE0KwyAQQOF9oXeQ2TdjuyhFYrLLrrv2AEOcGkHHoNKf29fl
+44M3zt8U1ZtLDVksnAcNimXNLoi38Hwspxuo2kgcxSxs4ccV5ul4GMm0jRPfSchzUX0j1ZCFrbXd
+INa1K9Uh7yzdXrkkaj2LR1fo0/cp4kXrKyYKAjj9AQAA//8DAFBLAwQUAAYACAAAACEAlrWt4pYG
+AABQGwAAFgAAAHRoZW1lL3RoZW1lL3RoZW1lMS54bWzsWU9v2zYUvw/YdyB0b2MndhoHdYrYsZst
+TRvEboceaYmW2FCiQNJJfRva44ABw7phhxXYbYdhW4EW2KX7NNk6bB3Qr7BHUpLFWF6SNtiKrT4k
+Evnj+/8eH6mr1+7HDB0SISlP2l79cs1DJPF5QJOw7d0e9i+teUgqnASY8YS0vSmR3rWN99+7itdV
+RGKCYH0i13Hbi5RK15eWpA/DWF7mKUlgbsxFjBW8inApEPgI6MZsablWW12KMU08lOAYyN4aj6lP
+0FCT9DZy4j0Gr4mSesBnYqBJE2eFwQYHdY2QU9llAh1i1vaAT8CPhuS+8hDDUsFE26uZn7e0cXUJ
+r2eLmFqwtrSub37ZumxBcLBseIpwVDCt9xutK1sFfQNgah7X6/W6vXpBzwCw74OmVpYyzUZ/rd7J
+aZZA9nGedrfWrDVcfIn+ypzMrU6n02xlsliiBmQfG3P4tdpqY3PZwRuQxTfn8I3OZre76uANyOJX
+5/D9K63Vhos3oIjR5GAOrR3a72fUC8iYs+1K+BrA12oZfIaCaCiiS7MY80QtirUY3+OiDwANZFjR
+BKlpSsbYhyju4ngkKNYM8DrBpRk75Mu5Ic0LSV/QVLW9D1MMGTGj9+r596+eP0XHD54dP/jp+OHD
+4wc/WkLOqm2chOVVL7/97M/HH6M/nn7z8tEX1XhZxv/6wye//Px5NRDSZybOiy+f/PbsyYuvPv39
+u0cV8E2BR2X4kMZEopvkCO3zGBQzVnElJyNxvhXDCNPyis0klDjBmksF/Z6KHPTNKWaZdxw5OsS1
+4B0B5aMKeH1yzxF4EImJohWcd6LYAe5yzjpcVFphR/MqmXk4ScJq5mJSxu1jfFjFu4sTx7+9SQp1
+Mw9LR/FuRBwx9xhOFA5JQhTSc/yAkArt7lLq2HWX+oJLPlboLkUdTCtNMqQjJ5pmi7ZpDH6ZVukM
+/nZss3sHdTir0nqLHLpIyArMKoQfEuaY8TqeKBxXkRzimJUNfgOrqErIwVT4ZVxPKvB0SBhHvYBI
+WbXmlgB9S07fwVCxKt2+y6axixSKHlTRvIE5LyO3+EE3wnFahR3QJCpjP5AHEKIY7XFVBd/lbobo
+d/ADTha6+w4ljrtPrwa3aeiINAsQPTMR2pdQqp0KHNPk78oxo1CPbQxcXDmGAvji68cVkfW2FuJN
+2JOqMmH7RPldhDtZdLtcBPTtr7lbeJLsEQjz+Y3nXcl9V3K9/3zJXZTPZy20s9oKZVf3DbYpNi1y
+vLBDHlPGBmrKyA1pmmQJ+0TQh0G9zpwOSXFiSiN4zOq6gwsFNmuQ4OojqqJBhFNosOueJhLKjHQo
+UcolHOzMcCVtjYcmXdljYVMfGGw9kFjt8sAOr+jh/FxQkDG7TWgOnzmjFU3grMxWrmREQe3XYVbX
+Qp2ZW92IZkqdw61QGXw4rxoMFtaEBgRB2wJWXoXzuWYNBxPMSKDtbvfe3C3GCxfpIhnhgGQ+0nrP
++6hunJTHirkJgNip8JE+5J1itRK3lib7BtzO4qQyu8YCdrn33sRLeQTPvKTz9kQ6sqScnCxBR22v
+1VxuesjHadsbw5kWHuMUvC51z4dZCBdDvhI27E9NZpPlM2+2csXcJKjDNYW1+5zCTh1IhVRbWEY2
+NMxUFgIs0Zys/MtNMOtFKWAj/TWkWFmDYPjXpAA7uq4l4zHxVdnZpRFtO/ualVI+UUQMouAIjdhE
+7GNwvw5V0CegEq4mTEXQL3CPpq1tptzinCVd+fbK4Ow4ZmmEs3KrUzTPZAs3eVzIYN5K4oFulbIb
+5c6vikn5C1KlHMb/M1X0fgI3BSuB9oAP17gCI52vbY8LFXGoQmlE/b6AxsHUDogWuIuFaQgquEw2
+/wU51P9tzlkaJq3hwKf2aYgEhf1IRYKQPShLJvpOIVbP9i5LkmWETESVxJWpFXtEDgkb6hq4qvd2
+D0UQ6qaaZGXA4E7Gn/ueZdAo1E1OOd+cGlLsvTYH/unOxyYzKOXWYdPQ5PYvRKzYVe16szzfe8uK
+6IlZm9XIswKYlbaCVpb2rynCObdaW7HmNF5u5sKBF+c1hsGiIUrhvgfpP7D/UeEz+2VCb6hDvg+1
+FcGHBk0Mwgai+pJtPJAukHZwBI2THbTBpElZ02atk7ZavllfcKdb8D1hbC3ZWfx9TmMXzZnLzsnF
+izR2ZmHH1nZsoanBsydTFIbG+UHGOMZ80ip/deKje+DoLbjfnzAlTTDBNyWBofUcmDyA5LcczdKN
+vwAAAP//AwBQSwMEFAAGAAgAAAAhAA3RkJ+2AAAAGwEAACcAAAB0aGVtZS90aGVtZS9fcmVscy90
+aGVtZU1hbmFnZXIueG1sLnJlbHOEj00KwjAUhPeCdwhvb9O6EJEm3YjQrdQDhOQ1DTY/JFHs7Q2u
+LAguh2G+mWm7l53JE2My3jFoqhoIOumVcZrBbbjsjkBSFk6J2TtksGCCjm837RVnkUsoTSYkUigu
+MZhyDidKk5zQilT5gK44o49W5CKjpkHIu9BI93V9oPGbAXzFJL1iEHvVABmWUJr/s/04GolnLx8W
+Xf5RQXPZhQUoosbM4CObqkwEylu6usTfAAAA//8DAFBLAQItABQABgAIAAAAIQCCirwT+gAAABwC
+AAATAAAAAAAAAAAAAAAAAAAAAABbQ29udGVudF9UeXBlc10ueG1sUEsBAi0AFAAGAAgAAAAhAKXW
+p+fAAAAANgEAAAsAAAAAAAAAAAAAAAAAKwEAAF9yZWxzLy5yZWxzUEsBAi0AFAAGAAgAAAAhAGt5
+lhaDAAAAigAAABwAAAAAAAAAAAAAAAAAFAIAAHRoZW1lL3RoZW1lL3RoZW1lTWFuYWdlci54bWxQ
+SwECLQAUAAYACAAAACEAlrWt4pYGAABQGwAAFgAAAAAAAAAAAAAAAADRAgAAdGhlbWUvdGhlbWUv
+dGhlbWUxLnhtbFBLAQItABQABgAIAAAAIQAN0ZCftgAAABsBAAAnAAAAAAAAAAAAAAAAAJsJAAB0
+aGVtZS90aGVtZS9fcmVscy90aGVtZU1hbmFnZXIueG1sLnJlbHNQSwUGAAAAAAUABQBdAQAAlgoA
+AAAA
+
+------=_NextPart_01C88FF8.77140040
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Operations.Overview_files/colorschememapping.xml
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/xml
+
+<?xml version=3D"1.0" encoding=3D"UTF-8" standalone=3D"yes"?>
+<a:clrMap xmlns:a=3D"http://schemas.openxmlformats.org/drawingml/2006/main"=
+ bg1=3D"lt1" tx1=3D"dk1" bg2=3D"lt2" tx2=3D"dk2" accent1=3D"accent1" accent=
+2=3D"accent2" accent3=3D"accent3" accent4=3D"accent4" accent5=3D"accent5" a=
+ccent6=3D"accent6" hlink=3D"hlink" folHlink=3D"folHlink"/>
+------=_NextPart_01C88FF8.77140040
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Operations.Overview_files/header.htm
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/html; charset="us-ascii"
+
+<html xmlns:v=3D"urn:schemas-microsoft-com:vml"
+xmlns:o=3D"urn:schemas-microsoft-com:office:office"
+xmlns:w=3D"urn:schemas-microsoft-com:office:word"
+xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml"
+xmlns=3D"http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=3DContent-Type content=3D"text/html; charset=3Dus-ascii">
+<meta name=3DProgId content=3DWord.Document>
+<meta name=3DGenerator content=3D"Microsoft Word 12">
+<meta name=3DOriginator content=3D"Microsoft Word 12">
+<link id=3DMain-File rel=3DMain-File
+href=3D"../Microsoft.VisualStudio.Text.Operations.Overview.htm">
+<![if IE]>
+<base
+href=3D"file:///C:\515CB117\Microsoft.VisualStudio.Text.Operations.Overview=
+_files\header.htm"
+id=3D"webarch_temp_base_tag">
+<![endif]>
+</head>
+
+<body lang=3DEN-US link=3Dblue vlink=3Dpurple>
+
+<div style=3D'mso-element:footnote-separator' id=3Dfs>
+
+<p class=3DMsoNormal><span style=3D'mso-special-character:footnote-separato=
+r'><![if !supportFootnotes]>
+
+<hr align=3Dleft size=3D1 width=3D"33%">
+
+<![endif]></span></p>
+
+</div>
+
+<div style=3D'mso-element:footnote-continuation-separator' id=3Dfcs>
+
+<p class=3DMsoNormal><span style=3D'mso-special-character:footnote-continua=
+tion-separator'><![if !supportFootnotes]>
+
+<hr align=3Dleft size=3D1>
+
+<![endif]></span></p>
+
+</div>
+
+<div style=3D'mso-element:endnote-separator' id=3Des>
+
+<p class=3DMsoNormal><span style=3D'mso-special-character:footnote-separato=
+r'><![if !supportFootnotes]>
+
+<hr align=3Dleft size=3D1 width=3D"33%">
+
+<![endif]></span></p>
+
+</div>
+
+<div style=3D'mso-element:endnote-continuation-separator' id=3Decs>
+
+<p class=3DMsoNormal><span style=3D'mso-special-character:footnote-continua=
+tion-separator'><![if !supportFootnotes]>
+
+<hr align=3Dleft size=3D1>
+
+<![endif]></span></p>
+
+</div>
+
+<div style=3D'mso-element:header' id=3Deh1>
+
+<p class=3DMsoNormal><o:p>&nbsp;</o:p></p>
+
+</div>
+
+<div style=3D'mso-element:header' id=3Dh1>
+
+<p class=3DMsoNormal><o:p>&nbsp;</o:p></p>
+
+</div>
+
+<div style=3D'mso-element:footer' id=3Df1>
+
+<p class=3DMsoNormal><o:p>&nbsp;</o:p></p>
+
+</div>
+
+</body>
+
+</html>
+
+------=_NextPart_01C88FF8.77140040
+Content-Location: file:///C:/515CB117/Microsoft.VisualStudio.Text.Operations.Overview_files/filelist.xml
+Content-Transfer-Encoding: quoted-printable
+Content-Type: text/xml; charset="utf-8"
+
+<xml xmlns:o=3D"urn:schemas-microsoft-com:office:office">
+ <o:MainFile HRef=3D"../Microsoft.VisualStudio.Text.Operations.Overview.htm=
+"/>
+ <o:File HRef=3D"themedata.thmx"/>
+ <o:File HRef=3D"colorschememapping.xml"/>
+ <o:File HRef=3D"header.htm"/>
+ <o:File HRef=3D"filelist.xml"/>
+</xml>
+------=_NextPart_01C88FF8.77140040--
diff --git a/src/Text/Def/TextUI/Outlining/ICollapsible.cs b/src/Text/Def/TextUI/Outlining/ICollapsible.cs
new file mode 100644
index 0000000..5d629de
--- /dev/null
+++ b/src/Text/Def/TextUI/Outlining/ICollapsible.cs
@@ -0,0 +1,55 @@
+namespace Microsoft.VisualStudio.Text.Outlining
+{
+ using Microsoft.VisualStudio.Text.Projection;
+ using Microsoft.VisualStudio.Text.Tagging;
+ using System;
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Represents a span that may be collapsed.
+ /// </summary>
+ public interface ICollapsible
+ {
+ /// <summary>
+ /// Gets the extent of this collapsible region.
+ /// </summary>
+ ITrackingSpan Extent { get; }
+
+ /// <summary>
+ /// Determines whether this outlining region is collapsed.
+ /// </summary>
+ bool IsCollapsed { get; }
+
+ /// <summary>
+ /// Determines whether this region can be collapsed.
+ /// </summary>
+ bool IsCollapsible { get; }
+
+ /// <summary>
+ /// Gets the data object for the collapsed UI.
+ /// </summary>
+ object CollapsedForm { get; }
+
+ /// <summary>
+ /// Gets the data object for the collapsed UI tooltip.
+ /// </summary>
+ object CollapsedHintForm { get; }
+
+ /// <summary>
+ /// Gets the <see cref="IOutliningRegionTag"/> that was used to produce this collapsible region.
+ /// </summary>
+ IOutliningRegionTag Tag { get; }
+ }
+
+ /// <summary>
+ /// Represents a collapsed <see cref="ICollapsible" />.
+ /// </summary>
+ public interface ICollapsed : ICollapsible
+ {
+ /// <summary>
+ /// Enumerates the children of this collapsed region that are also collapsed.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown if this collapsed region has been expanded.</exception>
+ IEnumerable<ICollapsed> CollapsedChildren { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Outlining/IOutliningManager.cs b/src/Text/Def/TextUI/Outlining/IOutliningManager.cs
new file mode 100644
index 0000000..51b5b85
--- /dev/null
+++ b/src/Text/Def/TextUI/Outlining/IOutliningManager.cs
@@ -0,0 +1,154 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Outlining
+{
+ using Microsoft.VisualStudio.Text.Editor;
+ using System;
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Provides outlining functionality.
+ /// </summary>
+ /// <remarks>
+ /// <para>Any methods that take <see cref="SnapshotSpan"/> objects are spans of the
+ /// edit buffer in the view model of a view. This buffer can also be retrieved from
+ /// the TextBuffer property of an <see cref="ITextView"/>.</para>
+ /// <para>This outlining manager is provided by <see cref="IOutliningManagerService"/>.</para>
+ /// </remarks>
+ public interface IOutliningManager : IDisposable
+ {
+ /// <summary>
+ /// Gets all the collapsed regions that intersect the given span.
+ /// </summary>
+ /// <param name="span">The span.</param>
+ /// <returns>A sorted sequence of collapsed regions.</returns>
+ IEnumerable<ICollapsed> GetCollapsedRegions(SnapshotSpan span);
+
+ /// <summary>
+ /// Gets all the collapsed regions that intersect the given span.
+ /// </summary>
+ /// <param name="span">The span.</param>
+ /// <param name="exposedRegionsOnly">If <c>true</c>, this returns only top-level regions (regions that aren't inside another collapsed region).</param>
+ /// <returns>A sorted sequence of collapsed regions.</returns>
+ IEnumerable<ICollapsed> GetCollapsedRegions(SnapshotSpan span, bool exposedRegionsOnly);
+
+ /// <summary>
+ /// Gets all the collapsed regions that intersect the given collection of spans.
+ /// </summary>
+ /// <param name="spans">The collection of spans.</param>
+ /// <returns>A sorted sequence of collapsed regions.</returns>
+ IEnumerable<ICollapsed> GetCollapsedRegions(NormalizedSnapshotSpanCollection spans);
+
+ /// <summary>
+ /// Gets all the collapsed regions that intersect the given collection of spans.
+ /// </summary>
+ /// <param name="spans">The collection of spans.</param>
+ /// <param name="exposedRegionsOnly">If <c>true</c>, this returns only top-level regions (regions that aren't inside another collapsed region).</param>
+ /// <returns>A sorted sequence of collapsed regions.</returns>
+ IEnumerable<ICollapsed> GetCollapsedRegions(NormalizedSnapshotSpanCollection spans, bool exposedRegionsOnly);
+
+ /// <summary>
+ /// Gets all the regions that intersect the given span, whether or not they are collapsed.
+ /// </summary>
+ /// <param name="span">The span.</param>
+ /// <returns>A sorted sequence of all intersecting collapsible regions.</returns>
+ IEnumerable<ICollapsible> GetAllRegions(SnapshotSpan span);
+
+ /// <summary>
+ /// Gets all the regions that intersect the given span, whether or not they are collapsed.
+ /// </summary>
+ /// <param name="span">The span.</param>
+ /// <param name="exposedRegionsOnly">If <c>true</c>, this returns only top-level regions (regions that aren't inside another collapsed region).</param>
+ /// <returns>A sorted sequence of all intersecting collapsible regions.</returns>
+ IEnumerable<ICollapsible> GetAllRegions(SnapshotSpan span, bool exposedRegionsOnly);
+
+ /// <summary>
+ /// Gets all the regions that intersect the given collection of spans, whether or not they are collapsed.
+ /// </summary>
+ /// <param name="spans">The collection of spans.</param>
+ /// <returns>A sorted sequence of all intersecting collapsible regions.</returns>
+ IEnumerable<ICollapsible> GetAllRegions(NormalizedSnapshotSpanCollection spans);
+
+ /// <summary>
+ /// Gets all the regions that intersect the given collection of spans, whether or not they are collapsed.
+ /// </summary>
+ /// <param name="spans">The collection of spans.</param>
+ /// <param name="exposedRegionsOnly">If <c>true</c>, this returns only top-level regions (regions that aren't inside another collapsed region).</param>
+ /// <returns>A sorted sequence of all intersecting collapsible regions.</returns>
+ IEnumerable<ICollapsible> GetAllRegions(NormalizedSnapshotSpanCollection spans, bool exposedRegionsOnly);
+
+ /// <summary>
+ /// Occurs when the set of <see cref="ICollapsible"/> regions on the corresponding elision buffer changes.
+ /// </summary>
+ /// <remarks>Not raised when the collapsed state of any <see cref="ICollapsible"/> changes.</remarks>
+ event EventHandler<RegionsChangedEventArgs> RegionsChanged;
+
+ /// <summary>
+ /// Occurs when an <see cref="ICollapsed"/> region is expanded.
+ /// </summary>
+ /// <remarks>This event is not raised when the set of <see cref="ICollapsible" /> regions on the corresponding
+ /// elision buffer changes.</remarks>
+ event EventHandler<RegionsExpandedEventArgs> RegionsExpanded;
+
+ /// <summary>
+ /// Occurs when an <see cref="ICollapsible"/> region is collapsed.
+ /// </summary>
+ /// <remarks>Not raised when the set of <see cref="ICollapsible" /> regions on the corresponding
+ /// elision buffer changes.</remarks>
+ event EventHandler<RegionsCollapsedEventArgs> RegionsCollapsed;
+
+ /// <summary>
+ /// Occurs when outlining has been enabled or disabled.
+ /// </summary>
+ event EventHandler<OutliningEnabledEventArgs> OutliningEnabledChanged;
+
+ #region Collapsing and Expanding
+
+ /// <summary>
+ /// Expands the collapsible span.
+ /// </summary>
+ /// <returns>The newly-expanded span.</returns>
+ ICollapsible Expand(ICollapsed collapsible);
+
+ /// <summary>
+ /// Tries to collapse a given region.
+ /// </summary>
+ /// <returns>The newly collapsed span if successful, otherwise null.</returns>
+ /// <remarks>
+ /// There are two cases in which this method can fail to collapse the region:
+ /// <para>The region is already collapsed.</para>
+ /// <para>The region is partially obscured because another collapsed region partially covers it.</para>
+ /// </remarks>
+ ICollapsed TryCollapse(ICollapsible collapsible);
+
+ /// <summary>
+ /// Collapses all regions that match the specified predicate.
+ /// </summary>
+ /// <param name="span">The regions that intersect this span.</param>
+ /// <param name="match">The predicate to match.</param>
+ /// <returns>The newly-collapsed regions.</returns>
+ /// <remarks>
+ /// The <paramref name="match"/> predicate may be passed regions that cannot actually be collapsed, due
+ /// to the region being partially obscured by another already collapsed region (either pre-existing or collapsed
+ /// in an earlier call to the predicate). The elements of the returned enumeration do accurately track
+ /// the regions that were collapsed, so they may differ from the elements for which the predicate returned <c>true</c>.
+ /// </remarks>
+ IEnumerable<ICollapsed> CollapseAll(SnapshotSpan span, Predicate<ICollapsible> match);
+
+ /// <summary>
+ /// Expands all the regions that match the specified predicate.
+ /// </summary>
+ /// <param name="match">The predicate to match.</param>
+ /// <param name="span">The regions that intersect this span.</param>
+ /// <returns>The newly-expanded regions.</returns>
+ IEnumerable<ICollapsible> ExpandAll(SnapshotSpan span, Predicate<ICollapsed> match);
+
+ #endregion
+
+ /// <summary>
+ /// Determines whether outlining is enabled.
+ /// </summary>
+ bool Enabled { get; set; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Outlining/IOutliningManagerService.cs b/src/Text/Def/TextUI/Outlining/IOutliningManagerService.cs
new file mode 100644
index 0000000..ebd4867
--- /dev/null
+++ b/src/Text/Def/TextUI/Outlining/IOutliningManagerService.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Outlining
+{
+ using Microsoft.VisualStudio.Text.Editor;
+ using System;
+
+ /// <summary>
+ /// Provides the <see cref="IOutliningManager"/> for a given view model.
+ /// </summary>
+ /// <remarks>
+ /// This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IOutliningManagerService outliningManager = null;
+ /// </remarks>
+ public interface IOutliningManagerService
+ {
+ /// <summary>
+ /// Gets an <see cref="IOutliningManager" /> for the given view.
+ /// </summary>
+ /// <remarks>
+ /// The outlining manager is available only for views that have the <see cref="PredefinedTextViewRoles.Structured"/> role.
+ /// </remarks>
+ /// <param name="textView">The <see cref="ITextView"/> from which to get the outlining manager.</param>
+ /// <returns>A valid outlining manager if the view model supports outlining,
+ /// otherwise null.</returns>
+ /// <exception cref="ArgumentNullException"><paramref name="textView"/> is null.</exception>
+ IOutliningManager GetOutliningManager(ITextView textView);
+ }
+}
diff --git a/src/Text/Def/TextUI/Outlining/OutliningEnabledEventArgs.cs b/src/Text/Def/TextUI/Outlining/OutliningEnabledEventArgs.cs
new file mode 100644
index 0000000..fa0cd2c
--- /dev/null
+++ b/src/Text/Def/TextUI/Outlining/OutliningEnabledEventArgs.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Outlining
+{
+ using System;
+
+ /// <summary>
+ /// Provides information for the <see cref="IOutliningManager.OutliningEnabledChanged" /> event.
+ /// </summary>
+ /// <remarks>
+ /// The event is raised when outlining has been enabled or disabled.
+ /// </remarks>
+ public class OutliningEnabledEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Determines whether outlining has been enabled or disabled.
+ /// </summary>
+ public bool Enabled { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="OutliningEnabledEventArgs"/> for the specified change.
+ /// </summary>
+ /// <param name="enabled"><c>true</c> if outlining has been enabled, <c>false</c> if it has been disabled.</param>
+ public OutliningEnabledEventArgs(bool enabled)
+ {
+ this.Enabled = enabled;
+ }
+ }
+}
+
diff --git a/src/Text/Def/TextUI/Outlining/RegionsChangedEventArgs.cs b/src/Text/Def/TextUI/Outlining/RegionsChangedEventArgs.cs
new file mode 100644
index 0000000..923c15b
--- /dev/null
+++ b/src/Text/Def/TextUI/Outlining/RegionsChangedEventArgs.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Outlining
+{
+ using System;
+
+ /// <summary>
+ /// Provides information for the <see cref="IOutliningManager.RegionsChanged" /> event.
+ /// </summary>
+ /// <remarks>
+ /// Provides the <see cref="SnapshotSpan"/> over which <see cref="ICollapsible"/> regions were added or
+ /// removed. Call GetAllRegions to get the current set of <see cref="ICollapsible"/> regions over the affected snapshot span.
+ /// </remarks>
+ public class RegionsChangedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the <see cref="SnapshotSpan"/> over which collapsible spans have changed.
+ /// </summary>
+ public SnapshotSpan AffectedSpan { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="RegionsChangedEventArgs"/> with the specified <see cref="SnapshotSpan" />.
+ /// </summary>
+ /// <param name="affectedSpan">The <see cref="SnapshotSpan"/> over which collapsible regions have changed.</param>
+ public RegionsChangedEventArgs (SnapshotSpan affectedSpan)
+ {
+ this.AffectedSpan = affectedSpan;
+ }
+ }
+}
+
diff --git a/src/Text/Def/TextUI/Outlining/RegionsCollapsedEventArgs.cs b/src/Text/Def/TextUI/Outlining/RegionsCollapsedEventArgs.cs
new file mode 100644
index 0000000..f882383
--- /dev/null
+++ b/src/Text/Def/TextUI/Outlining/RegionsCollapsedEventArgs.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Outlining
+{
+ using System;
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Provides information for the <see cref="IOutliningManager.RegionsCollapsed" /> event.
+ /// </summary>
+ /// <remarks>
+ /// Provides the <see cref="ICollapsed"/> regions that are now collapsed.
+ /// </remarks>
+ public class RegionsCollapsedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the <see cref="ICollapsed" /> regions that are now collapsed.
+ /// </summary>
+ public IEnumerable<ICollapsed> CollapsedRegions { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="RegionsCollapsedEventArgs"/> with the specified <see cref="ICollapsed" /> regions.
+ /// </summary>
+ /// <param name="collapsedRegions">The newly-collapsed regions.</param>
+ public RegionsCollapsedEventArgs(IEnumerable<ICollapsed> collapsedRegions)
+ {
+ this.CollapsedRegions = collapsedRegions;
+ }
+ }
+}
+
diff --git a/src/Text/Def/TextUI/Outlining/RegionsExpandedEventArgs.cs b/src/Text/Def/TextUI/Outlining/RegionsExpandedEventArgs.cs
new file mode 100644
index 0000000..b2dc4e5
--- /dev/null
+++ b/src/Text/Def/TextUI/Outlining/RegionsExpandedEventArgs.cs
@@ -0,0 +1,47 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Outlining
+{
+ using System;
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// Provides information for the <see cref="IOutliningManager.RegionsExpanded" /> event.
+ /// </summary>
+ /// <remarks>
+ /// Provides the <see cref="ICollapsible"/> regions that are now expanded.
+ /// </remarks>
+ public class RegionsExpandedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the <see cref="ICollapsible"/> regions which are now expanded.
+ /// </summary>
+ public IEnumerable<ICollapsible> ExpandedRegions { get; private set; }
+
+ /// <summary>
+ /// <c>true</c> if the regions are being expanded because they are being removed.
+ /// </summary>
+ public bool RemovalPending { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="RegionsExpandedEventArgs"/> with the specified <see cref="ICollapsible"/> regions, assuming that they are not also being removed.
+ /// </summary>
+ /// <param name="expandedRegions">The newly-expanded regions.</param>
+ public RegionsExpandedEventArgs (IEnumerable<ICollapsible> expandedRegions) : this(expandedRegions, false)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of <see cref="RegionsExpandedEventArgs"/> with the specified <see cref="ICollapsible"/> regions.
+ /// </summary>
+ /// <param name="expandedRegions">The newly-expanded regions.</param>
+ /// <param name="removalPending">If these regions are being expanded as part of being removed.</param>
+ public RegionsExpandedEventArgs (IEnumerable<ICollapsible> expandedRegions, bool removalPending)
+ {
+ this.ExpandedRegions = expandedRegions;
+ this.RemovalPending = removalPending;
+ }
+ }
+}
+
diff --git a/src/Text/Def/TextUI/Strings.Designer.cs b/src/Text/Def/TextUI/Strings.Designer.cs
new file mode 100644
index 0000000..ad9b2b5
--- /dev/null
+++ b/src/Text/Def/TextUI/Strings.Designer.cs
@@ -0,0 +1,81 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:2.0.50727.1433
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Microsoft.VisualStudio.Text.Editor {
+ 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", "2.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Strings {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Strings() {
+ }
+
+ /// <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("Microsoft.VisualStudio.Text.Editor.Strings", typeof(Strings).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 Buffer mismatch between oldSnapsnot and newSnapshot..
+ /// </summary>
+ internal static string BufferMismatch {
+ get {
+ return ResourceManager.GetString("BufferMismatch", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to oldSnapshot&apos;s version is not older than newSnapshot&apos;s version..
+ /// </summary>
+ internal static string VersionError {
+ get {
+ return ResourceManager.GetString("VersionError", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/Strings.resx b/src/Text/Def/TextUI/Strings.resx
new file mode 100644
index 0000000..279c501
--- /dev/null
+++ b/src/Text/Def/TextUI/Strings.resx
@@ -0,0 +1,126 @@
+<?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="BufferMismatch" xml:space="preserve">
+ <value>Buffer mismatch between oldSnapshot and newSnapshot.</value>
+ </data>
+ <data name="VersionError" xml:space="preserve">
+ <value>oldSnapshot's version is not older than newSnapshot's version.</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/src/Text/Def/TextUI/Tagging/IViewTagAggregatorFactoryService.cs b/src/Text/Def/TextUI/Tagging/IViewTagAggregatorFactoryService.cs
new file mode 100644
index 0000000..5e0ca39
--- /dev/null
+++ b/src/Text/Def/TextUI/Tagging/IViewTagAggregatorFactoryService.cs
@@ -0,0 +1,36 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using Microsoft.VisualStudio.Text.Editor;
+
+ /// <summary>
+ /// A service that creates an <see cref="ITagAggregator&lt;T&gt;"/> for an <see cref="ITextView"/>.
+ /// This is a MEF component part, and should be imported as follows:
+ /// [Import]
+ /// IViewLevelTagAggregatorFactoryService factory = null;
+ /// </summary>
+ public interface IViewTagAggregatorFactoryService
+ {
+ /// <summary>
+ /// Creates a tag aggregator for the specified <see cref="ITextView"/> that aggregates
+ /// tags of the given type.
+ /// </summary>
+ /// <param name="textView">The <see cref="ITextView"/> with which to get the <see cref="ITagAggregator&lt;T&gt;"/>.</param>
+ /// <typeparam name="T">The type of tag to aggregate.</typeparam>
+ /// <returns>The <see cref="ITagAggregator&lt;T&gt;"/> of the correct type for <paramref name="textView"/>.</returns>
+ /// <remarks>The ITagAggregatorr&lt;T&gt;.DispatchedTagsChanged event will be raised on the thread used to create the tag aggregator.</remarks>
+ ITagAggregator<T> CreateTagAggregator<T>(ITextView textView) where T : ITag;
+
+ /// <summary>
+ /// Creates a tag aggregator for the specified <see cref="ITextView"/> and with the given options that aggregates
+ /// tags of the given type.
+ /// </summary>
+ /// <param name="textView">The <see cref="ITextView"/> with which to get the <see cref="ITagAggregator&lt;T&gt;"/>.</param>
+ /// <param name="options">The options to use for the newly created aggregator.</param>
+ /// <typeparam name="T">The type of tag to aggregate.</typeparam>
+ /// <returns>The <see cref="ITagAggregator&lt;T&gt;"/> of the correct type for <paramref name="textView"/>.</returns>
+ ITagAggregator<T> CreateTagAggregator<T>(ITextView textView, TagAggregatorOptions options) where T : ITag;
+ }
+}
diff --git a/src/Text/Def/TextUI/Tagging/IViewTaggerProvider.cs b/src/Text/Def/TextUI/Tagging/IViewTaggerProvider.cs
new file mode 100644
index 0000000..49b9aaa
--- /dev/null
+++ b/src/Text/Def/TextUI/Tagging/IViewTaggerProvider.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using Microsoft.VisualStudio.Text.Editor;
+
+ /// <summary>
+ /// Creates an <see cref="ITagger&lt;T&gt;"/> for a given buffer.
+ /// </summary>
+ /// <remarks>This is a MEF component part, and implementers must use the following attributes:
+ /// [Export(nameSource=typeof(ITaggerProvider))]
+ /// Exports must specify at least one content type attribute and at least one tag type attribute. Exports may
+ /// optionally specify a TextViewRole; if no TextViewRole is specified, the tagger applies to views with any roles.
+ /// </remarks>
+ public interface IViewTaggerProvider
+ {
+ /// <summary>
+ /// Creates a tag provider for the specified view and buffer.
+ /// </summary>
+ /// <param name="textView">The <see cref="ITextView"/>.</param>
+ /// <param name="buffer">The <see cref="ITextBuffer"/>.</param>
+ /// <typeparam name="T">The type of the tag.</typeparam>
+ ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag;
+ }
+}
diff --git a/src/Text/Def/TextUI/Tags/BlockTag.cs b/src/Text/Def/TextUI/Tags/BlockTag.cs
new file mode 100644
index 0000000..ebffbdf
--- /dev/null
+++ b/src/Text/Def/TextUI/Tags/BlockTag.cs
@@ -0,0 +1,98 @@
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using Microsoft.VisualStudio.Text.Adornments;
+
+ /// <summary>
+ /// An implementation of <see cref="IBlockTag" />.
+ /// </summary>
+ public abstract class BlockTag : IBlockTag
+ {
+ public BlockTag(SnapshotSpan span, SnapshotSpan statementSpan, IBlockTag parent, string type, bool isCollapsible, bool isDefaultCollapsed, bool isImplementation, object collapsedForm, object collapsedHintForm)
+ {
+ this.Span = span;
+ this.Level = (parent == null) ? 0 : (parent.Level + 1);
+ this.StatementSpan = statementSpan;
+ this.Parent = parent;
+ this.Type = type;
+ this.IsCollapsible = isCollapsible;
+ this.IsDefaultCollapsed = isDefaultCollapsed;
+ this.IsImplementation = isImplementation;
+ this.CollapsedForm = collapsedForm;
+ this.CollapsedHintForm = collapsedHintForm;
+ }
+
+ /// <summary>
+ /// Gets the span of the structural block.
+ /// </summary>
+ public virtual SnapshotSpan Span { get; set; }
+
+ /// <summary>
+ /// Gets the level of nested-ness of the structural block.
+ /// </summary>
+ public virtual int Level { get; }
+
+ /// <summary>
+ /// Gets the span of the statement that control the structral block.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// For example, in the following snippet of code,
+ /// <code>
+ /// if (condition1 &amp;&amp;
+ /// condition2) // comment
+ /// {
+ /// something;
+ /// }
+ /// </code>
+ /// this.StatementSpan would extend from the start of the "if" to the end of comment.
+ /// this.Span would extend from before the "{" to the end of the "}".
+ /// </para>
+ /// </remarks>
+ public virtual SnapshotSpan StatementSpan { get; set; }
+
+ /// <summary>
+ /// Gets the hierarchical parent of the structural block.
+ /// </summary>
+ public virtual IBlockTag Parent { get; }
+
+ /// <summary>
+ /// Determines the semantic type of the structural block.
+ /// <remarks>
+ /// See <see cref="PredefinedStructureTypes"/> for the canonical types.
+ /// Use <see cref="PredefinedStructureTypes.Nonstructural"/> for blocks that will not have any visible affordance
+ /// (but will be used for outlining).
+ /// </remarks>
+ /// </summary>
+ public virtual string Type { get; }
+
+ /// <summary>
+ /// Determines whether a block can be collapsed.
+ /// </summary>
+ public virtual bool IsCollapsible { get; }
+
+ /// <summary>
+ /// Determines whether a block is collapsed by default.
+ /// </summary>
+ public virtual bool IsDefaultCollapsed { get; }
+
+ /// <summary>
+ /// Determines whether a block is an block region.
+ /// </summary>
+ /// <remarks>
+ /// Implementation blocks are the blocks of code following a method definition.
+ /// They are used for commands such as the Visual Studio Collapse to Definition command,
+ /// which hides the implementation block and leaves only the method definition exposed.
+ /// </remarks>
+ public virtual bool IsImplementation { get; }
+
+ /// <summary>
+ /// Gets the data object for the collapsed UI. If the default is set, returns null.
+ /// </summary>
+ public virtual object CollapsedForm { get; }
+
+ /// <summary>
+ /// Gets the data object for the collapsed UI tooltip. If the default is set, returns null.
+ /// </summary>
+ public virtual object CollapsedHintForm { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Tags/ErrorTag.cs b/src/Text/Def/TextUI/Tags/ErrorTag.cs
new file mode 100644
index 0000000..43228bf
--- /dev/null
+++ b/src/Text/Def/TextUI/Tags/ErrorTag.cs
@@ -0,0 +1,53 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using System;
+ using System.Text;
+
+ using Microsoft.VisualStudio.Text.Adornments;
+
+ /// <summary>
+ /// An implementation of <see cref="IErrorTag" />.
+ /// </summary>
+ public class ErrorTag : IErrorTag
+ {
+ /// <summary>
+ /// Initializes a new instance of a <see cref="ErrorTag"/> of the specified type.
+ /// </summary>
+ /// <param name="errorType">The type of error to use.</param>
+ /// <param name="toolTipContent">The tooltip content to display. May be null.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="errorType"/> is null.</exception>
+ public ErrorTag(string errorType, object toolTipContent)
+ {
+ if (errorType == null)
+ throw new ArgumentNullException("errorType");
+
+ ErrorType = errorType;
+ ToolTipContent = toolTipContent;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="ErrorTag"/> of the specified type with no tooltip content.
+ /// </summary>
+ /// <param name="errorType">The type of error to use,</param>
+ public ErrorTag(string errorType) : this(errorType, null) { }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="ErrorTag"/> of type SyntaxError with no tooltip content.
+ /// </summary>
+ public ErrorTag() : this(PredefinedErrorTypeNames.SyntaxError, null) { }
+
+ /// <summary>
+ /// Gets the type of error to use.
+ /// </summary>
+ public string ErrorType { get; private set; }
+
+ /// <summary>
+ /// Gets the content to use when displaying a tooltip for this error.
+ /// This property may be null.
+ /// </summary>
+ public object ToolTipContent { get; private set; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Tags/IBlockTag.cs b/src/Text/Def/TextUI/Tags/IBlockTag.cs
new file mode 100644
index 0000000..684db50
--- /dev/null
+++ b/src/Text/Def/TextUI/Tags/IBlockTag.cs
@@ -0,0 +1,84 @@
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using Microsoft.VisualStudio.Text.Adornments;
+
+ /// <summary>
+ /// Represents a structural code block, which is used for vertical structural line adornments.
+ /// </summary>
+ public interface IBlockTag : ITag
+ {
+ /// <summary>
+ /// Gets the span of the structural block.
+ /// </summary>
+ SnapshotSpan Span { get; }
+
+ /// <summary>
+ /// Gets the level of nested-ness of the structural block.
+ /// </summary>
+ int Level { get; }
+
+ /// <summary>
+ /// Gets the span of the statement that control the structral block.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// For example, in the following snippet of code,
+ /// <code>
+ /// if (condition1 &amp;&amp;
+ /// condition2) // comment
+ /// {
+ /// something;
+ /// }
+ /// </code>
+ /// this.StatementSpan would extend from the start of the "if" to the end of comment.
+ /// this.Span would extend from before the "{" to the end of the "}".
+ /// </para>
+ /// </remarks>
+ SnapshotSpan StatementSpan { get; }
+
+ /// <summary>
+ /// Gets the hierarchical parent of the structural block.
+ /// </summary>
+ IBlockTag Parent { get; }
+
+ /// <summary>
+ /// Determines the semantic type of the structural block.
+ /// <remarks>
+ /// See <see cref="PredefinedStructureTypes"/> for the canonical types.
+ /// Use <see cref="PredefinedStructureTypes.Nonstructural"/> for blocks that will not have any visible affordance
+ /// (but will be used for outlining).
+ /// </remarks>
+ /// </summary>
+ string Type { get; }
+
+ /// <summary>
+ /// Determines whether a block can be collapsed.
+ /// </summary>
+ bool IsCollapsible { get; }
+
+ /// <summary>
+ /// Determines whether a block is collapsed by default.
+ /// </summary>
+ bool IsDefaultCollapsed { get; }
+
+ /// <summary>
+ /// Determines whether a block is an implementation block.
+ /// </summary>
+ /// <remarks>
+ /// Implementation blocks are the blocks of code following a method definition.
+ /// They are used for commands such as the Visual Studio Collapse to Definition command,
+ /// which hides the implementation block and leaves only the method definition exposed.
+ /// </remarks>
+ bool IsImplementation { get; }
+
+ /// <summary>
+ /// Gets the data object for the collapsed UI. If the default is set, returns null.
+ /// </summary>
+ object CollapsedForm { get; }
+
+ /// <summary>
+ /// Gets the data object for the collapsed UI tooltip. If the default is set, returns null.
+ /// </summary>
+ object CollapsedHintForm { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Tags/IErrorTag.cs b/src/Text/Def/TextUI/Tags/IErrorTag.cs
new file mode 100644
index 0000000..9f7446d
--- /dev/null
+++ b/src/Text/Def/TextUI/Tags/IErrorTag.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using System;
+ using System.Text;
+
+ using Microsoft.VisualStudio.Text.Adornments;
+
+ /// <summary>
+ /// Represents an error, which is used to place squiggle adornments on the view.
+ /// </summary>
+ public interface IErrorTag : ITag
+ {
+ /// <summary>
+ /// Gets the type of error to use.
+ /// </summary>
+ string ErrorType { get; }
+
+ /// <summary>
+ /// Gets the content to use when displaying a tooltip for this error.
+ /// This property may be null.
+ /// </summary>
+ object ToolTipContent { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Tags/IOutliningRegionTag.cs b/src/Text/Def/TextUI/Tags/IOutliningRegionTag.cs
new file mode 100644
index 0000000..7a62186
--- /dev/null
+++ b/src/Text/Def/TextUI/Tags/IOutliningRegionTag.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// Provides a tag for outlining regions.
+ /// </summary>
+ public interface IOutliningRegionTag : ITag
+ {
+ /// <summary>
+ /// Determines whether the region is collapsed by default.
+ /// </summary>
+ bool IsDefaultCollapsed { get; }
+
+ /// <summary>
+ /// Determines whether a region is an implementation region.
+ /// </summary>
+ /// <remarks>
+ /// Implementation regions are the blocks of code following a method definition.
+ /// They are used for commands such as the Visual Studio Collapse to Definition command,
+ /// which hides the implementation region and leaves only the method definition exposed.
+ /// </remarks>
+ bool IsImplementation { get; }
+
+ /// <summary>
+ /// Gets the data object for the collapsed UI. If the default is set, returns null.
+ /// </summary>
+ object CollapsedForm { get; }
+
+ /// <summary>
+ /// Gets the data object for the collapsed UI tooltip. If the default is set, returns null.
+ /// </summary>
+ object CollapsedHintForm { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Tags/IOverviewMarkTag.cs b/src/Text/Def/TextUI/Tags/IOverviewMarkTag.cs
new file mode 100644
index 0000000..ec8d6a3
--- /dev/null
+++ b/src/Text/Def/TextUI/Tags/IOverviewMarkTag.cs
@@ -0,0 +1,16 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// Provides the information needed to render a mark in the overview margin.
+ /// </summary>
+ public interface IOverviewMarkTag : ITag
+ {
+ /// <summary>
+ /// Gets the name of the EditorFormatDefinition whose background color is used to draw the mark.
+ /// </summary>
+ string MarkKindName { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Tags/ITextMarkerTag.cs b/src/Text/Def/TextUI/Tags/ITextMarkerTag.cs
new file mode 100644
index 0000000..cd26b6d
--- /dev/null
+++ b/src/Text/Def/TextUI/Tags/ITextMarkerTag.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// Represents the text marker tag, which is used to place text marker adornments on a view.
+ /// </summary>
+ public interface ITextMarkerTag : ITag
+ {
+ /// <summary>
+ /// Gets the type of adornment to use.
+ /// </summary>
+ string Type { get; }
+ }
+}
diff --git a/src/Text/Def/TextUI/Tags/OutliningRegionTag.cs b/src/Text/Def/TextUI/Tags/OutliningRegionTag.cs
new file mode 100644
index 0000000..ecf6cf0
--- /dev/null
+++ b/src/Text/Def/TextUI/Tags/OutliningRegionTag.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// Represents a tag for outlining regions.
+ /// </summary>
+ public class OutliningRegionTag : IOutliningRegionTag
+ {
+ #region IOutliningRegionTag Members
+ /// <summary>
+ /// Determines whether the region is collapsed by default.
+ /// </summary>
+ public bool IsDefaultCollapsed { get; private set; }
+
+ /// <summary>
+ /// Determines whether a region is an implementation region.
+ /// </summary>
+ /// <remarks>
+ /// Implementation regions are the blocks of code following a method definition.
+ /// They are used for commands such as the Visual Studio Collapse to Definition command,
+ /// which hides the implementation region and leaves only the method definition exposed.
+ /// </remarks>
+ public bool IsImplementation { get; private set; }
+
+ /// <summary>
+ /// Gets the data object for the collapsed UI. If the default is set, returns null.
+ /// </summary>
+ public object CollapsedForm { get; private set; }
+
+ /// <summary>
+ /// Gets the data object for the collapsed UI tooltip. If the default is set, returns null.
+ /// </summary>
+ public object CollapsedHintForm { get; private set; }
+
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="OutliningRegionTag"/>.
+ /// </summary>
+ public OutliningRegionTag()
+ : this(false, false, null, null)
+ { }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="OutliningRegionTag"/> with the specified objects.
+ /// </summary>
+ public OutliningRegionTag(object collapsedForm, object collapsedHintForm)
+ : this(false, false, collapsedForm, collapsedHintForm)
+ { }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="OutliningRegionTag"/> with the specified default collapsed state.
+ /// </summary>
+ public OutliningRegionTag(bool isDefaultCollapsed, bool isImplementation, object collapsedForm, object collapsedHintForm)
+ {
+ IsDefaultCollapsed = isDefaultCollapsed;
+ IsImplementation = isImplementation;
+ CollapsedForm = collapsedForm;
+ CollapsedHintForm = collapsedHintForm;
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/Tags/OverviewMarkTag.cs b/src/Text/Def/TextUI/Tags/OverviewMarkTag.cs
new file mode 100644
index 0000000..beb299c
--- /dev/null
+++ b/src/Text/Def/TextUI/Tags/OverviewMarkTag.cs
@@ -0,0 +1,30 @@
+// Copyright (c) Microsoft Corporation
+// All rights reserved
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// An implementation of <see cref="IOverviewMarkTag" />.
+ /// </summary>
+ public class OverviewMarkTag : IOverviewMarkTag
+ {
+ readonly string _markKindName;
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="OverviewMarkTag"/> of the specified kind.
+ /// </summary>
+ /// <param name="markKindName">The name of the EditorFormatDefinition whose background color is used to draw the mark.</param>
+ public OverviewMarkTag(string markKindName)
+ {
+ _markKindName = markKindName;
+ }
+
+ /// <summary>
+ /// Gets the name of the EditorFormatDefinition whose background color is used to draw the mark.
+ /// </summary>
+ public string MarkKindName
+ {
+ get { return _markKindName; }
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/Tags/SpaceNegotiatingAdornmentTag.cs b/src/Text/Def/TextUI/Tags/SpaceNegotiatingAdornmentTag.cs
new file mode 100644
index 0000000..bf301ea
--- /dev/null
+++ b/src/Text/Def/TextUI/Tags/SpaceNegotiatingAdornmentTag.cs
@@ -0,0 +1,84 @@
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ using Microsoft.VisualStudio.Text.Formatting;
+
+ /// <summary>
+ /// Represents a tag for a space-negotiating adornment. The tag is used to provide space
+ /// for positioning the adornment in a view.
+ /// </summary>
+ /// <remarks>
+ /// The units used in properties like <see cref="Width"/> and <see cref="TopSpace"/> are those used in the presentation technology.
+ /// </remarks>
+ public class SpaceNegotiatingAdornmentTag : ITag
+ {
+ /// <summary>
+ /// Gets the width of the adornment.
+ /// </summary>
+ public double Width { get; private set; }
+
+ /// <summary>
+ /// Gets the amount of space needed between the top of the text in the <see cref="ITextViewLine"/> and the top of the <see cref="ITextViewLine"/>.
+ /// </summary>
+ public double TopSpace { get; private set; }
+
+ /// <summary>
+ /// Gets the baseline of the space-negotiating adornment.
+ /// </summary>
+ public double Baseline { get; private set; }
+
+ /// <summary>
+ /// Gets the height of the text portion of the space-negotiating adornment.
+ /// </summary>
+ public double TextHeight { get; private set; }
+
+ /// <summary>
+ /// Gets the amount of space needed between the bottom of the text in the <see cref="ITextViewLine"/> and the botton of the <see cref="ITextViewLine"/>.
+ /// </summary>
+ public double BottomSpace { get; private set; }
+
+ /// <summary>
+ /// Gets the <see cref="PositionAffinity"/> of the space-negotiating adornment.
+ /// </summary>
+ /// <remarks>
+ /// This property is only used for adornments that do not replace text.
+ /// An adornment does not replace text if its tag has a zero-length span on the view's text buffer.
+ /// </remarks>
+ public PositionAffinity Affinity { get; private set; }
+
+ /// <summary>
+ /// Gets a unique object associated with the space-negotiating adornment, which is used by <see cref="ITextViewLine"/>.GetAdornmentBounds.
+ /// </summary>
+ public object IdentityTag { get; private set; }
+
+ /// <summary>
+ /// Gets a unique object that identifies the provider of the adornment.
+ /// </summary>
+ /// <remarks>
+ /// This object is used to get adornments by calling <see cref="ITextViewLine.GetAdornmentTags"/>.
+ /// </remarks>
+ public object ProviderTag { get; private set; }
+
+ /// <summary>
+ /// Initializes a new instance of a <see cref="SpaceNegotiatingAdornmentTag"/> with the specified properties.
+ /// </summary>
+ /// <param name="width">The width of the tag in pixels.</param>
+ /// <param name="topSpace">The space needed between the top of the text in the <see cref="ITextViewLine"/> and the top of the <see cref="ITextViewLine"/>.</param>
+ /// <param name="baseline">The baseline of the space-negotiating adornment.</param>
+ /// <param name="textHeight">The height in pixels of the text portion of the space-negotiating adornment.</param>
+ /// <param name="bottomSpace">The space needed between the bottom of the text in the <see cref="ITextViewLine"/> and the botton of the <see cref="ITextViewLine"/>.</param>
+ /// <param name="affinity">The <see cref="PositionAffinity"/> of the space-negotiating adornment.</param>
+ /// <param name="identityTag">A unique object associated with the space-negotiating adornment, used by <see cref="ITextViewLine"/>.GetAdornmentBounds.</param>
+ /// <param name="providerTag">A unique object identifying the provider of the adornment, used by <see cref="ITextViewLine.GetAdornmentTags"/>).</param>
+ public SpaceNegotiatingAdornmentTag(double width, double topSpace, double baseline, double textHeight, double bottomSpace, PositionAffinity affinity, object identityTag, object providerTag)
+ {
+ this.Width = width;
+ this.TopSpace = topSpace;
+ this.Baseline = baseline;
+ this.TextHeight = textHeight;
+ this.BottomSpace = bottomSpace;
+ this.Affinity = affinity;
+ this.IdentityTag = identityTag;
+ this.ProviderTag = providerTag;
+ }
+ }
+}
diff --git a/src/Text/Def/TextUI/Tags/TextMarkerTag.cs b/src/Text/Def/TextUI/Tags/TextMarkerTag.cs
new file mode 100644
index 0000000..443805a
--- /dev/null
+++ b/src/Text/Def/TextUI/Tags/TextMarkerTag.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace Microsoft.VisualStudio.Text.Tagging
+{
+ /// <summary>
+ /// Represents the text marker tag, which is used to place text marker adornments on a view.
+ /// </summary>
+ public class TextMarkerTag : ITextMarkerTag
+ {
+ /// <summary>
+ /// Initializes a new instance of a <see cref="TextMarkerTag"/> of the given type.
+ /// </summary>
+ /// <param name="type">The type of text marker to use.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="type"/> is null.</exception>
+ public TextMarkerTag(string type)
+ {
+ if (type == null)
+ throw new ArgumentNullException("type");
+
+ Type = type;
+ }
+
+ /// <summary>
+ /// Gets the type of adornment to use.
+ /// </summary>
+ public string Type { get; private set; }
+ }
+}
diff --git a/src/Text/Def/TextUI/TextUI.csproj b/src/Text/Def/TextUI/TextUI.csproj
new file mode 100644
index 0000000..e961140
--- /dev/null
+++ b/src/Text/Def/TextUI/TextUI.csproj
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="BuildProps">
+ <BuildPropsFile>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), Build.props))\Build.props</BuildPropsFile>
+ </PropertyGroup>
+ <Import Project="$(BuildPropsFile)" Condition="'$(BuildProps_Imported)'!='True' AND Exists('$(BuildPropsFile)') AND '$(VisualStudioDir)'==''" />
+ <Import Project="..\Platform.Settings.targets" />
+ <Import Project="$(PlatformPath)\Tools\Targets\Platform.Settings.Selector.targets" />
+ <PropertyGroup>
+ <AssemblyName>Microsoft.VisualStudio.Text.UI</AssemblyName>
+ <OutputPath>$(BinariesDirectory)\bin\$(BuildArchitecture)</OutputPath>
+ <OutputType>Library</OutputType>
+ <SignAssemblyAttribute>true</SignAssemblyAttribute>
+ <UseVsVersion>true</UseVsVersion>
+ <AssemblyAttributeClsCompliant>true</AssemblyAttributeClsCompliant>
+ <GenerateAssemblyRefs>true</GenerateAssemblyRefs>
+ <NoWarn>649;436;$(NoWarn)</NoWarn>
+ <GeneratedModuleId>Microsoft.VisualStudio.Text.UI</GeneratedModuleId>
+ <GeneratedModuleVersion>$(VsAssemblyVersion)</GeneratedModuleVersion>
+ <BuildArchitecturesAllowed>$(BuildArchitecturesAllowed);amd64;arm</BuildArchitecturesAllowed>
+ </PropertyGroup>
+ <!-- IDE specific Information -->
+ <PropertyGroup>
+ <ProjectGuid>{9E66473A-ECFF-4834-8ACF-A22EC2CB5A36}</ProjectGuid>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="Adornments\BlockContext.cs" />
+ <Compile Include="Adornments\ErrorTypeDefinition.cs" />
+ <Compile Include="Adornments\IBlockContext.cs" />
+ <Compile Include="Adornments\IBlockContextSource.cs" />
+ <Compile Include="Adornments\IBlockContextProvider.cs" />
+ <Compile Include="Adornments\IErrorProviderFactory.cs" />
+ <Compile Include="Adornments\ITextMarkerProviderFactory.cs" />
+ <Compile Include="Adornments\IToolTipProvider.cs" />
+ <Compile Include="Adornments\IToolTipProviderFactory.cs" />
+ <Compile Include="Adornments\PopupStyles.cs" />
+ <Compile Include="Adornments\PredefinedErrorTypeNames.cs" />
+ <Compile Include="Adornments\PredefinedStructureTypes.cs" />
+ <Compile Include="Adornments\StructureAdornmentStyle.cs" />
+ <Compile Include="BraceCompletion\BracePairAttribute.cs" />
+ <Compile Include="BraceCompletion\IBraceCompletionDefaultProvider.cs" />
+ <Compile Include="BraceCompletion\IBraceCompletionSession.cs" />
+ <Compile Include="BraceCompletion\IBraceCompletionSessionProvider.cs" />
+ <Compile Include="BraceCompletion\IBraceCompletionContext.cs" />
+ <Compile Include="BraceCompletion\IBraceCompletionContextProvider.cs" />
+ <Compile Include="Classification\IViewClassifierAggregatorService.cs" />
+ <Compile Include="AssemblyInfo.cs" />
+ <Compile Include="DifferenceViewer\DifferenceHighlightMode.cs" />
+ <Compile Include="DifferenceViewer\DifferenceHighlightMode2.cs" />
+ <Compile Include="DifferenceViewer\DifferenceViewerOptions.cs" />
+ <Compile Include="DifferenceViewer\DifferenceViewerRoles.cs" />
+ <Compile Include="DifferenceViewer\DifferenceViewMode.cs" />
+ <Compile Include="DifferenceViewer\DifferenceViewType.cs" />
+ <Compile Include="DifferenceViewer\IDifferenceViewer.cs" />
+ <Compile Include="EditorOptions\ViewOptions.cs" />
+ <Compile Include="Editor\CaretPosition.cs" />
+ <Compile Include="Editor\CaretPositionChangedEventArgs.cs" />
+ <Compile Include="Editor\IScrollMap.cs" />
+ <Compile Include="Editor\IScrollMapFactoryService.cs" />
+ <Compile Include="Editor\ISmartIndent.cs" />
+ <Compile Include="Editor\ISmartIndentProvider.cs" />
+ <Compile Include="Editor\ISmartIndentationService.cs" />
+ <Compile Include="Editor\ITextCaret.cs" />
+ <Compile Include="Editor\ITextSelection.cs" />
+ <Compile Include="Editor\ITextView.cs" />
+ <Compile Include="Editor\ITextViewLineCollection.cs" />
+ <Compile Include="Editor\ITextViewMargin.cs" />
+ <Compile Include="Editor\ITextViewModel.cs" />
+ <Compile Include="Editor\ITextViewModelProvider.cs" />
+ <Compile Include="Editor\ITextViewRoleSet.cs" />
+ <Compile Include="Editor\IVerticalFractionMap.cs" />
+ <Compile Include="Editor\IVerticalScrollBar.cs" />
+ <Compile Include="Editor\IViewScroller.cs" />
+ <Compile Include="Editor\MarginContainerAttribute.cs" />
+ <Compile Include="Editor\MouseHoverAttribute.cs" />
+ <Compile Include="Editor\MouseHoverEventArgs.cs" />
+ <Compile Include="Editor\PredefinedMarginNames.cs" />
+ <Compile Include="Editor\PredefinedTextViewRoles.cs" />
+ <Compile Include="Editor\ReplacesAttribute.cs" />
+ <Compile Include="Editor\ScrollDirection.cs" />
+ <Compile Include="Editor\TextSelectionMode.cs" />
+ <Compile Include="Editor\TextViewCreatedEventArgs.cs" />
+ <Compile Include="Editor\TextViewLayoutChangedEventArgs.cs" />
+ <Compile Include="Editor\TextViewRoleAttribute.cs" />
+ <Compile Include="Editor\ViewRelativePosition.cs" />
+ <Compile Include="Editor\ViewState.cs" />
+ <Compile Include="Editor\WordWrapStyles.cs" />
+ <Compile Include="EditorOptions\ViewOptionDefinition.cs" />
+ <Compile Include="Editor\ZoomConstants.cs" />
+ <Compile Include="Formatting\IAdornmentElement.cs" />
+ <Compile Include="Formatting\ISequenceElement.cs" />
+ <Compile Include="Formatting\ITextAndAdornmentCollection.cs" />
+ <Compile Include="Formatting\ITextAndAdornmentSequencer.cs" />
+ <Compile Include="Formatting\ITextAndAdornmentSequencerFactoryService.cs" />
+ <Compile Include="Formatting\ITextViewLine.cs" />
+ <Compile Include="Formatting\LineTransform.cs" />
+ <Compile Include="Formatting\TextBounds.cs" />
+ <Compile Include="Formatting\TextAndAdornmentSequenceChangedEventArgs.cs" />
+ <Compile Include="Formatting\TextViewLineChange.cs" />
+ <Compile Include="Formatting\VisibilityState.cs" />
+ <Compile Include="FxCopSuppressions.cs" />
+ <Compile Include="Find\IIncrementalSearch.cs" />
+ <Compile Include="Find\IIncrementalSearchFactoryService.cs" />
+ <Compile Include="Find\IncrementalSearchResult.cs" />
+ <Compile Include="Find\IncrementalSearchDirection.cs" />
+ <Compile Include="Operations\IEditorOperations.cs" />
+ <Compile Include="Operations\IEditorOperations2.cs" />
+ <Compile Include="Operations\IEditorOperations3.cs" />
+ <Compile Include="Operations\IEditorOperationsFactoryService.cs" />
+ <Compile Include="Outlining\ICollapsible.cs" />
+ <Compile Include="Outlining\IOutliningManager.cs" />
+ <Compile Include="Outlining\IOutliningManagerService.cs" />
+ <Compile Include="Outlining\OutliningEnabledEventArgs.cs" />
+ <Compile Include="Outlining\RegionsCollapsedEventArgs.cs" />
+ <Compile Include="Outlining\RegionsExpandedEventArgs.cs" />
+ <Compile Include="Outlining\RegionsChangedEventArgs.cs" />
+ <Compile Include="Tagging\IViewTagAggregatorFactoryService.cs" />
+ <Compile Include="Tagging\IViewTaggerProvider.cs" />
+ <EmbeddedResource Include="Strings.resx">
+ <LogicalName>Microsoft.VisualStudio.Text.Editor.Strings.resources</LogicalName>
+ <ManifestResourceName>Microsoft.VisualStudio.Text.Editor.Strings.resources</ManifestResourceName>
+ <SubType>Designer</SubType>
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Strings.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <Compile Include="Strings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Strings.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Tags\BlockTag.cs" />
+ <Compile Include="Tags\IBlockTag.cs" />
+ <Compile Include="Tags\IOutliningRegionTag.cs" />
+ <Compile Include="Tags\OutliningRegionTag.cs" />
+ <Compile Include="Tags\OverviewMarkTag.cs" />
+ <Compile Include="Tags\ErrorTag.cs" />
+ <Compile Include="Tags\IErrorTag.cs" />
+ <Compile Include="Tags\IOverviewMarkTag.cs" />
+ <Compile Include="Tags\TextMarkerTag.cs" />
+ <Compile Include="Tags\ITextMarkerTag.cs" />
+ <Compile Include="Tags\SpaceNegotiatingAdornmentTag.cs" />
+ <Reference Include="PresentationCore" />
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.Composition" />
+ <CopyFile Include="Operations\Microsoft.VisualStudio.Text.Operations.Overview.mht">
+ <DestFolder>$(SuiteBinPath)\PlatformOverviews</DestFolder>
+ <Visible>false</Visible>
+ </CopyFile>
+ <ProjectReference Include="..\..\..\Core\Def\CoreUtility.csproj">
+ <Project>{BA3DD7EC-3F13-4400-A3A9-96AD425B3369}</Project>
+ <Name>CoreUtility</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\TextData\TextData.csproj">
+ <Project>{80A00E91-51E5-471C-80BA-0D863987ECC7}</Project>
+ <Name>TextData %28Text\Def\TextData\TextData%29</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\TextLogic\TextLogic.csproj">
+ <Project>{26FAFDBB-9C63-4F92-A176-6E350178DB67}</Project>
+ <Name>TextLogic %28Text\Def\TextLogic\TextLogic%29</Name>
+ </ProjectReference>
+ <None Include="Diagrams\BasePrimitives.cd" />
+ <None Include="Diagrams\Editor.cd" />
+ </ItemGroup>
+ <ItemGroup>
+ <PublishPartLinked Include="$(OutputPath)\$(AssemblyName).dll">
+ <Visibility>Inter</Visibility>
+ <FileType>Reference</FileType>
+ <DoNotCopyPDB>true</DoNotCopyPDB>
+ </PublishPartLinked>
+ </ItemGroup>
+ <!--Import the targets-->
+ <Import Project="$(PlatformPath)\Tools\Targets\Platform.Imports.targets" />
+ <PropertyGroup>
+ <CopyToSuiteBin>true</CopyToSuiteBin>
+ </PropertyGroup>
+</Project> \ No newline at end of file