Version 2.17.0-109.0.dev

Merge commit '7a0f27f24198b8189dcc3ddb53d413cb0feedbd3' into 'dev'
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 4e9864a..7b19889 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -3118,6 +3118,7 @@
   
   
   
+  
 <dl><dt class="typeDefinition"><a name="type_AddContentOverlay">AddContentOverlay: object</a></dt><dd>
     <p>
       A directive to begin overlaying the contents of a file. The supplied
@@ -3479,6 +3480,27 @@
           The label associated with this range that should be displayed to the
           user.
         </p>
+      </dd></dl></dd><dt class="typeDefinition"><a name="type_CompletionCaseMatchingMode">CompletionCaseMatchingMode: String</a></dt><dd>
+    <p>
+      An enumeration of the character case matching modes that the user may set in the client.
+    </p>
+    
+  <dl><dt class="value">FIRST_CHAR</dt><dd>
+        
+        <p>
+          Match the first character case only when filtering completions, the default for this
+          enumeration.
+        </p>
+      </dd><dt class="value">ALL_CHARS</dt><dd>
+        
+        <p>
+          Match all character cases when filtering completion lists.
+        </p>
+      </dd><dt class="value">NONE</dt><dd>
+        
+        <p>
+          Do not match character cases when filtering completion lists.
+        </p>
       </dd></dl></dd><dt class="typeDefinition"><a name="type_CompletionId">CompletionId: String</a></dt><dd>
     
     <p>
@@ -6116,7 +6138,7 @@
   TODO: TBD
 </p>
 <h2 class="domain"><a name="index">Index</a></h2>
-<h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li><li><a href="#request_server.cancelRequest">cancelRequest</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.log">log</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.closingLabels">closingLabels</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li><li><a href="#request_completion.setSubscriptions">setSubscriptions</a></li><li><a href="#request_completion.registerLibraryPaths">registerLibraryPaths</a></li><li><a href="#request_completion.getSuggestionDetails">getSuggestionDetails</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li><li><a href="#notification_completion.availableSuggestions">availableSuggestions</a></li><li><a href="#notification_completion.existingImports">existingImports</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getPostfixCompletion">getPostfixCompletion</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.getSuggestions">getSuggestions</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li><li><a href="#request_diagnostic.getServerPort">getServerPort</a></li></ul></div><h4>flutter (<a href="#domain_flutter">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_flutter.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_flutter.outline">outline</a></li></ul></div></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_AvailableSuggestion">AvailableSuggestion</a></li><li><a href="#type_AvailableSuggestionRelevanceTag">AvailableSuggestionRelevanceTag</a></li><li><a href="#type_AvailableSuggestionSet">AvailableSuggestionSet</a></li><li><a href="#type_BulkFix">BulkFix</a></li><li><a href="#type_BulkFixDetail">BulkFixDetail</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_ClosingLabel">ClosingLabel</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionMode">CompletionMode</a></li><li><a href="#type_CompletionService">CompletionService</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_DiagnosticMessage">DiagnosticMessage</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementDeclaration">ElementDeclaration</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_ExistingImport">ExistingImport</a></li><li><a href="#type_ExistingImports">ExistingImports</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FlutterOutline">FlutterOutline</a></li><li><a href="#type_FlutterOutlineAttribute">FlutterOutlineAttribute</a></li><li><a href="#type_FlutterOutlineKind">FlutterOutlineKind</a></li><li><a href="#type_FlutterService">FlutterService</a></li><li><a href="#type_FlutterWidgetProperty">FlutterWidgetProperty</a></li><li><a href="#type_FlutterWidgetPropertyEditor">FlutterWidgetPropertyEditor</a></li><li><a href="#type_FlutterWidgetPropertyEditorKind">FlutterWidgetPropertyEditorKind</a></li><li><a href="#type_FlutterWidgetPropertyValue">FlutterWidgetPropertyValue</a></li><li><a href="#type_FlutterWidgetPropertyValueEnumItem">FlutterWidgetPropertyValueEnumItem</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_ImportedElementSet">ImportedElementSet</a></li><li><a href="#type_ImportedElements">ImportedElements</a></li><li><a href="#type_IncludedSuggestionRelevanceTag">IncludedSuggestionRelevanceTag</a></li><li><a href="#type_IncludedSuggestionSet">IncludedSuggestionSet</a></li><li><a href="#type_KytheEntry">KytheEntry</a></li><li><a href="#type_KytheVName">KytheVName</a></li><li><a href="#type_LibraryPathSet">LibraryPathSet</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PostfixTemplateDescriptor">PostfixTemplateDescriptor</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a></li><li><a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></li><li><a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></li><li><a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_EXTRACT_WIDGET">EXTRACT_WIDGET</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
+<h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li><li><a href="#request_server.cancelRequest">cancelRequest</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.log">log</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.closingLabels">closingLabels</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li><li><a href="#request_completion.setSubscriptions">setSubscriptions</a></li><li><a href="#request_completion.registerLibraryPaths">registerLibraryPaths</a></li><li><a href="#request_completion.getSuggestionDetails">getSuggestionDetails</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li><li><a href="#notification_completion.availableSuggestions">availableSuggestions</a></li><li><a href="#notification_completion.existingImports">existingImports</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getPostfixCompletion">getPostfixCompletion</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.getSuggestions">getSuggestions</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li><li><a href="#request_diagnostic.getServerPort">getServerPort</a></li></ul></div><h4>flutter (<a href="#domain_flutter">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_flutter.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_flutter.outline">outline</a></li></ul></div></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_AvailableSuggestion">AvailableSuggestion</a></li><li><a href="#type_AvailableSuggestionRelevanceTag">AvailableSuggestionRelevanceTag</a></li><li><a href="#type_AvailableSuggestionSet">AvailableSuggestionSet</a></li><li><a href="#type_BulkFix">BulkFix</a></li><li><a href="#type_BulkFixDetail">BulkFixDetail</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_ClosingLabel">ClosingLabel</a></li><li><a href="#type_CompletionCaseMatchingMode">CompletionCaseMatchingMode</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionMode">CompletionMode</a></li><li><a href="#type_CompletionService">CompletionService</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_DiagnosticMessage">DiagnosticMessage</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementDeclaration">ElementDeclaration</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_ExistingImport">ExistingImport</a></li><li><a href="#type_ExistingImports">ExistingImports</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FlutterOutline">FlutterOutline</a></li><li><a href="#type_FlutterOutlineAttribute">FlutterOutlineAttribute</a></li><li><a href="#type_FlutterOutlineKind">FlutterOutlineKind</a></li><li><a href="#type_FlutterService">FlutterService</a></li><li><a href="#type_FlutterWidgetProperty">FlutterWidgetProperty</a></li><li><a href="#type_FlutterWidgetPropertyEditor">FlutterWidgetPropertyEditor</a></li><li><a href="#type_FlutterWidgetPropertyEditorKind">FlutterWidgetPropertyEditorKind</a></li><li><a href="#type_FlutterWidgetPropertyValue">FlutterWidgetPropertyValue</a></li><li><a href="#type_FlutterWidgetPropertyValueEnumItem">FlutterWidgetPropertyValueEnumItem</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_ImportedElementSet">ImportedElementSet</a></li><li><a href="#type_ImportedElements">ImportedElements</a></li><li><a href="#type_IncludedSuggestionRelevanceTag">IncludedSuggestionRelevanceTag</a></li><li><a href="#type_IncludedSuggestionSet">IncludedSuggestionSet</a></li><li><a href="#type_KytheEntry">KytheEntry</a></li><li><a href="#type_KytheVName">KytheVName</a></li><li><a href="#type_LibraryPathSet">LibraryPathSet</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PostfixTemplateDescriptor">PostfixTemplateDescriptor</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a></li><li><a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></li><li><a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></li><li><a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_EXTRACT_WIDGET">EXTRACT_WIDGET</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
 
 
 </body></html>
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 3baa946..6847dd0 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -138,6 +138,8 @@
 const String COMPLETION_NOTIFICATION_RESULTS_RESULTS = 'results';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS = 'completion.getSuggestions';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS2 = 'completion.getSuggestions2';
+const String COMPLETION_REQUEST_GET_SUGGESTIONS2_COMPLETION_CASE_MATCHING_MODE =
+    'completionCaseMatchingMode';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS2_COMPLETION_MODE =
     'completionMode';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS2_FILE = 'file';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 98395e9..d5a90a6 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -4215,6 +4215,68 @@
       );
 }
 
+/// CompletionCaseMatchingMode
+///
+/// enum {
+///   FIRST_CHAR
+///   ALL_CHARS
+///   NONE
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class CompletionCaseMatchingMode implements Enum {
+  /// Match the first character case only when filtering completions, the
+  /// default for this enumeration.
+  static const CompletionCaseMatchingMode FIRST_CHAR =
+      CompletionCaseMatchingMode._('FIRST_CHAR');
+
+  /// Match all character cases when filtering completion lists.
+  static const CompletionCaseMatchingMode ALL_CHARS =
+      CompletionCaseMatchingMode._('ALL_CHARS');
+
+  /// Do not match character cases when filtering completion lists.
+  static const CompletionCaseMatchingMode NONE =
+      CompletionCaseMatchingMode._('NONE');
+
+  /// A list containing all of the enum values that are defined.
+  static const List<CompletionCaseMatchingMode> VALUES =
+      <CompletionCaseMatchingMode>[FIRST_CHAR, ALL_CHARS, NONE];
+
+  @override
+  final String name;
+
+  const CompletionCaseMatchingMode._(this.name);
+
+  factory CompletionCaseMatchingMode(String name) {
+    switch (name) {
+      case 'FIRST_CHAR':
+        return FIRST_CHAR;
+      case 'ALL_CHARS':
+        return ALL_CHARS;
+      case 'NONE':
+        return NONE;
+    }
+    throw Exception('Illegal enum value: $name');
+  }
+
+  factory CompletionCaseMatchingMode.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
+    if (json is String) {
+      try {
+        return CompletionCaseMatchingMode(json);
+      } catch (_) {
+        // Fall through
+      }
+    }
+    throw jsonDecoder.mismatch(jsonPath, 'CompletionCaseMatchingMode', json);
+  }
+
+  @override
+  String toString() => 'CompletionCaseMatchingMode.$name';
+
+  String toJson() => name;
+}
+
 /// completion.existingImports params
 ///
 /// {
@@ -4683,6 +4745,7 @@
 ///   "file": FilePath
 ///   "offset": int
 ///   "maxResults": int
+///   "completionCaseMatchingMode": optional CompletionCaseMatchingMode
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -4698,6 +4761,10 @@
   /// to true.
   int maxResults;
 
+  /// The mode of code completion being invoked. If no value is provided,
+  /// MATCH_FIRST_CHAR will be assumed.
+  CompletionCaseMatchingMode? completionCaseMatchingMode;
+
   /// The mode of code completion being invoked. If no value is provided, BASIC
   /// will be assumed. BASIC is also the only currently supported.
   CompletionMode? completionMode;
@@ -4714,7 +4781,10 @@
   int? timeout;
 
   CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults,
-      {this.completionMode, this.invocationCount, this.timeout});
+      {this.completionCaseMatchingMode,
+      this.completionMode,
+      this.invocationCount,
+      this.timeout});
 
   factory CompletionGetSuggestions2Params.fromJson(
       JsonDecoder jsonDecoder, String jsonPath, Object? json) {
@@ -4739,6 +4809,13 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'maxResults');
       }
+      CompletionCaseMatchingMode? completionCaseMatchingMode;
+      if (json.containsKey('completionCaseMatchingMode')) {
+        completionCaseMatchingMode = CompletionCaseMatchingMode.fromJson(
+            jsonDecoder,
+            jsonPath + '.completionCaseMatchingMode',
+            json['completionCaseMatchingMode']);
+      }
       CompletionMode? completionMode;
       if (json.containsKey('completionMode')) {
         completionMode = CompletionMode.fromJson(
@@ -4754,6 +4831,7 @@
         timeout = jsonDecoder.decodeInt(jsonPath + '.timeout', json['timeout']);
       }
       return CompletionGetSuggestions2Params(file, offset, maxResults,
+          completionCaseMatchingMode: completionCaseMatchingMode,
           completionMode: completionMode,
           invocationCount: invocationCount,
           timeout: timeout);
@@ -4774,6 +4852,11 @@
     result['file'] = file;
     result['offset'] = offset;
     result['maxResults'] = maxResults;
+    var completionCaseMatchingMode = this.completionCaseMatchingMode;
+    if (completionCaseMatchingMode != null) {
+      result['completionCaseMatchingMode'] =
+          completionCaseMatchingMode.toJson();
+    }
     var completionMode = this.completionMode;
     if (completionMode != null) {
       result['completionMode'] = completionMode.toJson();
@@ -4803,6 +4886,7 @@
       return file == other.file &&
           offset == other.offset &&
           maxResults == other.maxResults &&
+          completionCaseMatchingMode == other.completionCaseMatchingMode &&
           completionMode == other.completionMode &&
           invocationCount == other.invocationCount &&
           timeout == other.timeout;
@@ -4815,6 +4899,7 @@
         file,
         offset,
         maxResults,
+        completionCaseMatchingMode,
         completionMode,
         invocationCount,
         timeout,
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index c12b23d..fddcbfa 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -993,6 +993,11 @@
   ///   suggestions after filtering is greater than the maxResults, then
   ///   isIncomplete is set to true.
   ///
+  /// completionCaseMatchingMode: CompletionCaseMatchingMode (optional)
+  ///
+  ///   The mode of code completion being invoked. If no value is provided,
+  ///   MATCH_FIRST_CHAR will be assumed.
+  ///
   /// Returns
   ///
   /// replacementOffset: int
@@ -1029,10 +1034,12 @@
   ///   requested maxResults.
   Future<CompletionGetSuggestions2Result> sendCompletionGetSuggestions2(
       String file, int offset, int maxResults,
-      {CompletionMode? completionMode,
+      {CompletionCaseMatchingMode? completionCaseMatchingMode,
+      CompletionMode? completionMode,
       int? invocationCount,
       int? timeout}) async {
     var params = CompletionGetSuggestions2Params(file, offset, maxResults,
+            completionCaseMatchingMode: completionCaseMatchingMode,
             completionMode: completionMode,
             invocationCount: invocationCount,
             timeout: timeout)
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 3e1ed40..ddf2b9b 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -230,6 +230,16 @@
 final Matcher isClosingLabel = LazyMatcher(() => MatchesJsonObject(
     'ClosingLabel', {'offset': isInt, 'length': isInt, 'label': isString}));
 
+/// CompletionCaseMatchingMode
+///
+/// enum {
+///   FIRST_CHAR
+///   ALL_CHARS
+///   NONE
+/// }
+final Matcher isCompletionCaseMatchingMode = MatchesEnum(
+    'CompletionCaseMatchingMode', ['FIRST_CHAR', 'ALL_CHARS', 'NONE']);
+
 /// CompletionId
 ///
 /// String
@@ -2148,17 +2158,19 @@
 ///   "file": FilePath
 ///   "offset": int
 ///   "maxResults": int
+///   "completionCaseMatchingMode": optional CompletionCaseMatchingMode
 /// }
-final Matcher isCompletionGetSuggestions2Params = LazyMatcher(() =>
-    MatchesJsonObject('completion.getSuggestions2 params', {
-      'file': isFilePath,
-      'offset': isInt,
-      'maxResults': isInt
-    }, optionalFields: {
-      'completionMode': isCompletionMode,
-      'invocationCount': isInt,
-      'timeout': isInt
-    }));
+final Matcher isCompletionGetSuggestions2Params =
+    LazyMatcher(() => MatchesJsonObject('completion.getSuggestions2 params', {
+          'file': isFilePath,
+          'offset': isInt,
+          'maxResults': isInt
+        }, optionalFields: {
+          'completionCaseMatchingMode': isCompletionCaseMatchingMode,
+          'completionMode': isCompletionMode,
+          'invocationCount': isInt,
+          'timeout': isInt
+        }));
 
 /// completion.getSuggestions2 result
 ///
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 3d8e563..59da953 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -440,6 +440,8 @@
    * @param offset The offset within the file at which suggestions are to be made.
    * @param maxResults The maximum number of suggestions to return. If the number of suggestions
    *         after filtering is greater than the maxResults, then isIncomplete is set to true.
+   * @param completionCaseMatchingMode The mode of code completion being invoked. If no value is
+   *         provided, MATCH_FIRST_CHAR will be assumed.
    * @param completionMode The mode of code completion being invoked. If no value is provided, BASIC
    *         will be assumed. BASIC is also the only currently supported.
    * @param invocationCount The number of times that the user has invoked code completion at the same
@@ -449,7 +451,7 @@
    *         field is intended to be used for benchmarking, and usually should not be provided, so
    *         that the default timeout is used.
    */
-  public void completion_getSuggestions2(String file, int offset, int maxResults, String completionMode, int invocationCount, int timeout, GetSuggestions2Consumer consumer);
+  public void completion_getSuggestions2(String file, int offset, int maxResults, String completionCaseMatchingMode, String completionMode, int invocationCount, int timeout, GetSuggestions2Consumer consumer);
 
   /**
    * {@code completion.registerLibraryPaths}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionCaseMatchingMode.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionCaseMatchingMode.java
new file mode 100644
index 0000000..3a4dc2a
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionCaseMatchingMode.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+/**
+ * An enumeration of the character case matching modes that the user may set in the client.
+ *
+ * @coverage dart.server.generated.types
+ */
+public class CompletionCaseMatchingMode {
+
+  /**
+   * Match the first character case only when filtering completions, the default for this
+   * enumeration.
+   */
+  public static final String FIRST_CHAR = "FIRST_CHAR";
+
+  /**
+   * Match all character cases when filtering completion lists.
+   */
+  public static final String ALL_CHARS = "ALL_CHARS";
+
+  /**
+   * Do not match character cases when filtering completion lists.
+   */
+  public static final String NONE = "NONE";
+
+}
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 51f35a4..7210871 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -1507,6 +1507,13 @@
           then <tt>isIncomplete</tt> is set to <tt>true</tt>.
         </p>
       </field>
+      <field name="completionCaseMatchingMode" optional="true">
+        <ref>CompletionCaseMatchingMode</ref>
+        <p>
+          The mode of code completion being invoked. If no value is provided,
+          <tt>MATCH_FIRST_CHAR</tt> will be assumed.
+        </p>
+      </field>
       <field name="completionMode" experimental="true" optional="true">
         <ref>CompletionMode</ref>
         <p>
@@ -4146,6 +4153,32 @@
       </value>
     </enum>
   </type>
+  <type name="CompletionCaseMatchingMode">
+    <p>
+      An enumeration of the character case matching modes that the user may set in the client.
+    </p>
+    <enum>
+      <value>
+        <code>FIRST_CHAR</code>
+        <p>
+          Match the first character case only when filtering completions, the default for this
+          enumeration.
+        </p>
+      </value>
+      <value>
+        <code>ALL_CHARS</code>
+        <p>
+          Match all character cases when filtering completion lists.
+        </p>
+      </value>
+      <value>
+        <code>NONE</code>
+        <p>
+          Do not match character cases when filtering completion lists.
+        </p>
+      </value>
+    </enum>
+  </type>
   <type name="RuntimeCompletionExpression">
     <p>
       An expression for which we want to know its runtime type.
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index 3baa946..6847dd0 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -138,6 +138,8 @@
 const String COMPLETION_NOTIFICATION_RESULTS_RESULTS = 'results';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS = 'completion.getSuggestions';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS2 = 'completion.getSuggestions2';
+const String COMPLETION_REQUEST_GET_SUGGESTIONS2_COMPLETION_CASE_MATCHING_MODE =
+    'completionCaseMatchingMode';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS2_COMPLETION_MODE =
     'completionMode';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS2_FILE = 'file';
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
index 413c551..484915e 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -4215,6 +4215,68 @@
       );
 }
 
+/// CompletionCaseMatchingMode
+///
+/// enum {
+///   FIRST_CHAR
+///   ALL_CHARS
+///   NONE
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class CompletionCaseMatchingMode implements Enum {
+  /// Match the first character case only when filtering completions, the
+  /// default for this enumeration.
+  static const CompletionCaseMatchingMode FIRST_CHAR =
+      CompletionCaseMatchingMode._('FIRST_CHAR');
+
+  /// Match all character cases when filtering completion lists.
+  static const CompletionCaseMatchingMode ALL_CHARS =
+      CompletionCaseMatchingMode._('ALL_CHARS');
+
+  /// Do not match character cases when filtering completion lists.
+  static const CompletionCaseMatchingMode NONE =
+      CompletionCaseMatchingMode._('NONE');
+
+  /// A list containing all of the enum values that are defined.
+  static const List<CompletionCaseMatchingMode> VALUES =
+      <CompletionCaseMatchingMode>[FIRST_CHAR, ALL_CHARS, NONE];
+
+  @override
+  final String name;
+
+  const CompletionCaseMatchingMode._(this.name);
+
+  factory CompletionCaseMatchingMode(String name) {
+    switch (name) {
+      case 'FIRST_CHAR':
+        return FIRST_CHAR;
+      case 'ALL_CHARS':
+        return ALL_CHARS;
+      case 'NONE':
+        return NONE;
+    }
+    throw Exception('Illegal enum value: $name');
+  }
+
+  factory CompletionCaseMatchingMode.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object? json) {
+    if (json is String) {
+      try {
+        return CompletionCaseMatchingMode(json);
+      } catch (_) {
+        // Fall through
+      }
+    }
+    throw jsonDecoder.mismatch(jsonPath, 'CompletionCaseMatchingMode', json);
+  }
+
+  @override
+  String toString() => 'CompletionCaseMatchingMode.$name';
+
+  String toJson() => name;
+}
+
 /// completion.existingImports params
 ///
 /// {
@@ -4683,6 +4745,7 @@
 ///   "file": FilePath
 ///   "offset": int
 ///   "maxResults": int
+///   "completionCaseMatchingMode": optional CompletionCaseMatchingMode
 /// }
 ///
 /// Clients may not extend, implement or mix-in this class.
@@ -4698,6 +4761,10 @@
   /// to true.
   int maxResults;
 
+  /// The mode of code completion being invoked. If no value is provided,
+  /// MATCH_FIRST_CHAR will be assumed.
+  CompletionCaseMatchingMode? completionCaseMatchingMode;
+
   /// The mode of code completion being invoked. If no value is provided, BASIC
   /// will be assumed. BASIC is also the only currently supported.
   CompletionMode? completionMode;
@@ -4714,7 +4781,10 @@
   int? timeout;
 
   CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults,
-      {this.completionMode, this.invocationCount, this.timeout});
+      {this.completionCaseMatchingMode,
+      this.completionMode,
+      this.invocationCount,
+      this.timeout});
 
   factory CompletionGetSuggestions2Params.fromJson(
       JsonDecoder jsonDecoder, String jsonPath, Object? json) {
@@ -4739,6 +4809,13 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, 'maxResults');
       }
+      CompletionCaseMatchingMode? completionCaseMatchingMode;
+      if (json.containsKey('completionCaseMatchingMode')) {
+        completionCaseMatchingMode = CompletionCaseMatchingMode.fromJson(
+            jsonDecoder,
+            jsonPath + '.completionCaseMatchingMode',
+            json['completionCaseMatchingMode']);
+      }
       CompletionMode? completionMode;
       if (json.containsKey('completionMode')) {
         completionMode = CompletionMode.fromJson(
@@ -4754,6 +4831,7 @@
         timeout = jsonDecoder.decodeInt(jsonPath + '.timeout', json['timeout']);
       }
       return CompletionGetSuggestions2Params(file, offset, maxResults,
+          completionCaseMatchingMode: completionCaseMatchingMode,
           completionMode: completionMode,
           invocationCount: invocationCount,
           timeout: timeout);
@@ -4774,6 +4852,11 @@
     result['file'] = file;
     result['offset'] = offset;
     result['maxResults'] = maxResults;
+    var completionCaseMatchingMode = this.completionCaseMatchingMode;
+    if (completionCaseMatchingMode != null) {
+      result['completionCaseMatchingMode'] =
+          completionCaseMatchingMode.toJson();
+    }
     var completionMode = this.completionMode;
     if (completionMode != null) {
       result['completionMode'] = completionMode.toJson();
@@ -4803,6 +4886,7 @@
       return file == other.file &&
           offset == other.offset &&
           maxResults == other.maxResults &&
+          completionCaseMatchingMode == other.completionCaseMatchingMode &&
           completionMode == other.completionMode &&
           invocationCount == other.invocationCount &&
           timeout == other.timeout;
@@ -4815,6 +4899,7 @@
         file,
         offset,
         maxResults,
+        completionCaseMatchingMode,
         completionMode,
         invocationCount,
         timeout,
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 271c7c6..9491945 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -31,7 +31,6 @@
 import 'elements/entities.dart';
 import 'enqueue.dart' show Enqueuer, EnqueueTask, ResolutionEnqueuer;
 import 'environment.dart';
-import 'frontend_strategy.dart';
 import 'inferrer/abstract_value_domain.dart' show AbstractValueStrategy;
 import 'inferrer/trivial.dart' show TrivialAbstractValueStrategy;
 import 'inferrer/powersets/wrapped.dart' show WrappedAbstractValueStrategy;
@@ -71,7 +70,7 @@
   final api.CompilerInput provider;
   final api.CompilerDiagnostics handler;
 
-  FrontendStrategy frontendStrategy;
+  KernelFrontendStrategy frontendStrategy;
   BackendStrategy backendStrategy;
   CompilerDiagnosticReporter _reporter;
   Map<Entity, WorldImpact> _impactCache;
@@ -455,7 +454,6 @@
     processQueue(
         frontendStrategy.elementEnvironment, resolutionEnqueuer, mainFunction,
         onProgress: showResolutionProgress);
-    frontendStrategy.onResolutionEnd();
     resolutionEnqueuer.logSummary(reporter.log);
 
     _reporter.reportSuppressedMessagesSummary();
@@ -477,7 +475,7 @@
         .addAll(result.moduleLibraries.map((module) => CodeLocation(module)));
     selfTask.measureSubtask('runModularAnalysis', () {
       var included = result.moduleLibraries.toSet();
-      var elementMap = (frontendStrategy as KernelFrontendStrategy).elementMap;
+      var elementMap = frontendStrategy.elementMap;
       var moduleData = computeModuleData(result.component, included, options,
           reporter, environment, elementMap);
       if (compilationFailed) return;
diff --git a/pkg/compiler/lib/src/frontend_strategy.dart b/pkg/compiler/lib/src/frontend_strategy.dart
deleted file mode 100644
index 3fc6ccc..0000000
--- a/pkg/compiler/lib/src/frontend_strategy.dart
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.frontend_strategy;
-
-import 'common.dart';
-import 'common/elements.dart';
-import 'common/tasks.dart';
-import 'compiler.dart' show Compiler;
-import 'deferred_load/deferred_load.dart' show DeferredLoadTask;
-import 'elements/entities.dart';
-import 'enqueue.dart';
-import 'ir/modular.dart';
-import 'js_backend/native_data.dart';
-import 'js_backend/no_such_method_registry.dart';
-import 'kernel/loader.dart';
-import 'universe/world_impact.dart';
-
-/// Strategy pattern that defines the connection between the input format and
-/// the resolved element model.
-abstract class FrontendStrategy {
-  /// Registers a set of loaded libraries with this strategy.
-  void registerLoadedLibraries(KernelResult result);
-
-  void registerModuleData(List<ModuleData> data);
-
-  /// Returns the [ElementEnvironment] for the element model used in this
-  /// strategy.
-  ElementEnvironment get elementEnvironment;
-
-  /// Returns the [CommonElements] for the element model used in this
-  /// strategy.
-  CommonElements get commonElements;
-
-  NativeBasicData get nativeBasicData;
-
-  /// Creates a [DeferredLoadTask] for the element model used in this strategy.
-  DeferredLoadTask createDeferredLoadTask(Compiler compiler);
-
-  /// Support for classifying `noSuchMethod` implementations.
-  NoSuchMethodRegistry get noSuchMethodRegistry;
-
-  /// Called before processing of the resolution queue is started.
-  void onResolutionStart();
-
-  ResolutionEnqueuer createResolutionEnqueuer(
-      CompilerTask task, Compiler compiler);
-
-  /// Called when the resolution queue has been closed.
-  void onResolutionEnd();
-
-  /// Computes the main function from [mainLibrary] adding additional world
-  /// impact to [impactBuilder].
-  FunctionEntity computeMain(WorldImpactBuilder impactBuilder);
-
-  /// Creates a [SourceSpan] from [spannable] in context of [currentElement].
-  SourceSpan spanFromSpannable(Spannable spannable, Entity currentElement);
-}
-
-/// Class that performs the mechanics to investigate annotations in the code.
-abstract class AnnotationProcessor {
-  void extractNativeAnnotations(LibraryEntity library);
-
-  void extractJsInteropAnnotations(LibraryEntity library);
-}
diff --git a/pkg/compiler/lib/src/js_backend/backend_usage.dart b/pkg/compiler/lib/src/js_backend/backend_usage.dart
index 6f87f10..08f17ce 100644
--- a/pkg/compiler/lib/src/js_backend/backend_usage.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_usage.dart
@@ -6,8 +6,8 @@
 import '../common/elements.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
-import '../frontend_strategy.dart';
 import '../ir/runtime_type_analysis.dart';
+import '../kernel/kernel_strategy.dart';
 import '../serialization/serialization.dart';
 import '../universe/feature.dart';
 import '../util/util.dart' show Setlet;
@@ -104,7 +104,7 @@
 }
 
 class BackendUsageBuilderImpl implements BackendUsageBuilder {
-  final FrontendStrategy _frontendStrategy;
+  final KernelFrontendStrategy _frontendStrategy;
   // TODO(johnniwinther): Remove the need for these.
   Setlet<FunctionEntity> _globalFunctionDependencies;
   Setlet<ClassEntity> _globalClassDependencies;
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index ba76698..c4d6943 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -22,7 +22,6 @@
 import '../elements/names.dart';
 import '../elements/types.dart';
 import '../environment.dart';
-import '../frontend_strategy.dart';
 import '../ir/annotations.dart';
 import '../ir/constants.dart';
 import '../ir/element_map.dart';
@@ -39,6 +38,7 @@
 import '../js_backend/namer.dart';
 import '../js_backend/native_data.dart';
 import '../js_model/locals.dart';
+import '../kernel/kernel_strategy.dart';
 import '../kernel/dart2js_target.dart';
 import '../native/behavior.dart';
 import '../native/resolver.dart';
@@ -103,7 +103,7 @@
   final Map<ir.TreeNode, Local> localFunctionMap = {};
 
   BehaviorBuilder _nativeBehaviorBuilder;
-  final FrontendStrategy _frontendStrategy;
+  final KernelFrontendStrategy _frontendStrategy;
 
   Map<KMember, Map<ir.Expression, TypeMap>> typeMapsForTesting;
 
diff --git a/pkg/compiler/lib/src/kernel/kernel_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
index 8cebfcb..dcd7fb2 100644
--- a/pkg/compiler/lib/src/kernel/kernel_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_strategy.dart
@@ -18,7 +18,6 @@
 import '../elements/entities.dart';
 import '../enqueue.dart';
 import '../environment.dart' as env;
-import '../frontend_strategy.dart';
 import '../ir/annotations.dart';
 import '../ir/closure.dart' show ClosureScopeModel;
 import '../ir/impact.dart';
@@ -52,7 +51,7 @@
 
 /// Front end strategy that loads '.dill' files and builds a resolved element
 /// model from kernel IR nodes.
-class KernelFrontendStrategy extends FrontendStrategy {
+class KernelFrontendStrategy {
   final NativeBasicDataBuilderImpl nativeBasicDataBuilder =
       NativeBasicDataBuilderImpl();
   NativeBasicData _nativeBasicData;
@@ -81,7 +80,7 @@
 
   KFieldAnalysis _fieldAnalysis;
 
-  @override
+  /// Support for classifying `noSuchMethod` implementations.
   NoSuchMethodRegistry noSuchMethodRegistry;
 
   KernelFrontendStrategy(this._compilerTask, this._options,
@@ -99,7 +98,7 @@
 
   KFieldAnalysis get fieldAnalysisForTesting => _fieldAnalysis;
 
-  @override
+  /// Called before processing of the resolution queue is started.
   void onResolutionStart() {
     // TODO(johnniwinther): Avoid the compiler.elementEnvironment.getThisType
     // calls. Currently needed to ensure resolution of the classes for various
@@ -134,7 +133,6 @@
     });
   }
 
-  @override
   ResolutionEnqueuer createResolutionEnqueuer(
       CompilerTask task, Compiler compiler) {
     RuntimeTypesNeedBuilder rtiNeedBuilder = _createRuntimeTypesNeedBuilder();
@@ -223,10 +221,6 @@
         annotationsData);
   }
 
-  @override
-  void onResolutionEnd() {}
-
-  @override
   NativeBasicData get nativeBasicData {
     if (_nativeBasicData == null) {
       _nativeBasicData = nativeBasicDataBuilder.close(elementEnvironment);
@@ -238,7 +232,7 @@
     return _nativeBasicData;
   }
 
-  @override
+  /// Registers a set of loaded libraries with this strategy.
   void registerLoadedLibraries(KernelResult kernelResult) {
     _elementMap.addComponent(kernelResult.component);
     _irAnnotationData = processAnnotations(
@@ -257,7 +251,6 @@
     }
   }
 
-  @override
   void registerModuleData(List<ModuleData> data) {
     if (data == null) {
       _modularStrategy = KernelModularStrategy(_compilerTask, _elementMap);
@@ -271,19 +264,23 @@
 
   ModularStrategy get modularStrategyForTesting => _modularStrategy;
 
-  @override
-  ElementEnvironment get elementEnvironment => _elementMap.elementEnvironment;
+  /// Returns the [ElementEnvironment] for the element model used in this
+  /// strategy.
+  KernelElementEnvironment get elementEnvironment =>
+      _elementMap.elementEnvironment;
 
-  @override
-  CommonElements get commonElements => _elementMap.commonElements;
+  /// Returns the [CommonElements] for the element model used in this
+  /// strategy.
+  KCommonElements get commonElements => _elementMap.commonElements;
 
   KernelToElementMap get elementMap => _elementMap;
 
-  @override
+  /// Creates a [DeferredLoadTask] for the element model used in this strategy.
   DeferredLoadTask createDeferredLoadTask(Compiler compiler) =>
       DeferredLoadTask(compiler, _elementMap);
 
-  @override
+  /// Computes the main function from [mainLibrary] adding additional world
+  /// impact to [impactBuilder].
   FunctionEntity computeMain(WorldImpactBuilder impactBuilder) {
     return elementEnvironment.mainFunction;
   }
@@ -297,7 +294,7 @@
   RuntimeTypesNeedBuilder get runtimeTypesNeedBuilderForTesting =>
       _runtimeTypesNeedBuilder;
 
-  @override
+  /// Creates a [SourceSpan] from [spannable] in context of [currentElement].
   SourceSpan spanFromSpannable(Spannable spannable, Entity currentElement) {
     return _elementMap.getSourceSpan(spannable, currentElement);
   }
diff --git a/pkg/compiler/lib/src/kernel/native_basic_data.dart b/pkg/compiler/lib/src/kernel/native_basic_data.dart
index d058403..ed4a83d 100644
--- a/pkg/compiler/lib/src/kernel/native_basic_data.dart
+++ b/pkg/compiler/lib/src/kernel/native_basic_data.dart
@@ -8,14 +8,13 @@
 import '../common/elements.dart';
 import '../constants/values.dart';
 import '../elements/entities.dart';
-import '../frontend_strategy.dart';
 import '../ir/annotations.dart';
 import '../js_backend/native_data.dart';
 import '../native/resolver.dart';
 
 import 'element_map_impl.dart';
 
-class KernelAnnotationProcessor implements AnnotationProcessor {
+class KernelAnnotationProcessor {
   final KernelToElementMapImpl elementMap;
   final NativeBasicDataBuilder _nativeBasicDataBuilder;
   final IrAnnotationData annotationData;
@@ -24,7 +23,6 @@
       this.elementMap, this._nativeBasicDataBuilder, this.annotationData)
       : assert(annotationData != null);
 
-  @override
   void extractNativeAnnotations(LibraryEntity library) {
     KElementEnvironment elementEnvironment = elementMap.elementEnvironment;
 
@@ -57,7 +55,6 @@
     return annotationName;
   }
 
-  @override
   void extractJsInteropAnnotations(LibraryEntity library) {
     // Unused reporter, add back in if uncommenting report lines down below.
     // DiagnosticReporter reporter = elementMap.reporter;
diff --git a/pkg/compiler/lib/src/ssa/interceptor_finalizer.dart b/pkg/compiler/lib/src/ssa/interceptor_finalizer.dart
index 2c20593..b8dcd74 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_finalizer.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_finalizer.dart
@@ -49,6 +49,9 @@
   }
 
   @override
+  bool validPostcondition(HGraph graph) => true;
+
+  @override
   visitBasicBlock(HBasicBlock node) {
     HInstruction instruction = node.first;
     while (instruction != null) {
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index b52be9d..c474639 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -47,6 +47,9 @@
   }
 
   @override
+  bool validPostcondition(HGraph graph) => true;
+
+  @override
   void visitBasicBlock(HBasicBlock node) {
     currentBlock = node;
 
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index fe51fdd..d7433a0 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -39,12 +39,14 @@
 import 'nodes.dart';
 import 'types.dart';
 import 'types_propagation.dart';
+import 'validate.dart' show NoUnusedPhiValidator;
 import 'value_range_analyzer.dart';
 import 'value_set.dart';
 
 abstract class OptimizationPhase {
   String get name;
   void visitGraph(HGraph graph);
+  bool validPostcondition(HGraph graph);
 }
 
 class SsaOptimizerTask extends CompilerTask {
@@ -70,6 +72,8 @@
       measureSubtask(phase.name, () => phase.visitGraph(graph));
       codegen.tracer.traceGraph(phase.name, graph);
       assert(graph.isValid(), 'Graph not valid after ${phase.name}');
+      assert(phase.validPostcondition(graph),
+          'Graph does not satify phase postcondition after ${phase.name}');
     }
 
     SsaCodeMotion codeMotion;
@@ -244,6 +248,9 @@
   }
 
   @override
+  bool validPostcondition(HGraph graph) => true;
+
+  @override
   visitBasicBlock(HBasicBlock block) {
     simplifyPhis(block);
     HInstruction instruction = block.first;
@@ -2518,6 +2525,11 @@
   }
 
   @override
+  bool validPostcondition(HGraph graph) {
+    return NoUnusedPhiValidator.containsNoUnusedPhis(graph);
+  }
+
+  @override
   void visitBasicBlock(HBasicBlock block) {
     bool isDeadBlock = analyzer.isDeadBlock(block);
     block.isLive = !isDeadBlock;
@@ -2827,27 +2839,33 @@
       }
     }
 
-    // Remove phis that are not live.
-    // Traverse in reverse order to remove phis with no uses before the
-    // phis that they might use.
-    // NOTICE: Doesn't handle circular references, but we don't currently
-    // create any.
-    List<HBasicBlock> blocks = graph.blocks;
-    for (int i = blocks.length - 1; i >= 0; i--) {
-      HBasicBlock block = blocks[i];
-      HPhi current = block.phis.first;
-      HPhi next = null;
-      while (current != null) {
-        next = current.next;
-        if (!livePhis.contains(current)
-            // TODO(ahe): Not sure the following is correct.
-            &&
-            current.usedBy.isEmpty) {
-          block.removePhi(current);
-        }
-        current = next;
-      }
+    // Collect dead phis.
+    List<HPhi> deadPhis = [];
+    for (final block in graph.blocks) {
+      block.forEachPhi((phi) {
+        if (!livePhis.contains(phi)) deadPhis.add(phi);
+      });
     }
+
+    // Two-phase removal, phase 1: unlink all the input nodes.
+    for (final phi in deadPhis) {
+      for (final input in phi.inputs) {
+        input.removeUser(phi);
+      }
+      phi.inputs.clear();
+    }
+
+    // Two-phase removal, phase 2: remove the now-disconnected phis.
+    for (final phi in deadPhis) {
+      assert(phi.inputs.isEmpty);
+      assert(phi.usedBy.isEmpty);
+      phi.block.removePhi(phi);
+    }
+  }
+
+  @override
+  bool validPostcondition(HGraph graph) {
+    return NoUnusedPhiValidator.containsNoUnusedPhis(graph);
   }
 }
 
@@ -2903,6 +2921,9 @@
       }
     }
   }
+
+  @override
+  bool validPostcondition(HGraph graph) => true;
 }
 
 class GvnWorkItem {
@@ -2933,6 +2954,9 @@
     } while (!workQueue.isEmpty);
   }
 
+  @override
+  bool validPostcondition(HGraph graph) => true;
+
   void moveLoopInvariantCode(HGraph graph) {
     for (int i = graph.blocks.length - 1; i >= 0; i--) {
       HBasicBlock block = graph.blocks[i];
@@ -3158,6 +3182,9 @@
   }
 
   @override
+  bool validPostcondition(HGraph graph) => true;
+
+  @override
   void visitBasicBlock(HBasicBlock block) {
     List<HBasicBlock> successors = block.successors;
 
@@ -3261,6 +3288,9 @@
     visitDominatorTree(graph);
   }
 
+  @override
+  bool validPostcondition(HGraph graph) => true;
+
   // Update users of [input] that are dominated by [:dominator.first:]
   // to use [TypeKnown] of [input] instead. As the type information depends
   // on the control flow, we mark the inserted [HTypeKnown] nodes as
@@ -3444,6 +3474,9 @@
   }
 
   @override
+  bool validPostcondition(HGraph graph) => true;
+
+  @override
   void visitBasicBlock(HBasicBlock block) {
     final predecessors = block.predecessors;
     final indegree = predecessors.length;
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index a8ff036..5a88ac3 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -71,6 +71,9 @@
   }
 
   @override
+  bool validPostcondition(HGraph graph) => true;
+
+  @override
   visitBasicBlock(HBasicBlock block) {
     if (block.isLoopHeader()) {
       block.forEachPhi((HPhi phi) {
diff --git a/pkg/compiler/lib/src/ssa/validate.dart b/pkg/compiler/lib/src/ssa/validate.dart
index 251368b..04c7f00 100644
--- a/pkg/compiler/lib/src/ssa/validate.dart
+++ b/pkg/compiler/lib/src/ssa/validate.dart
@@ -220,3 +220,28 @@
     }
   }
 }
+
+/// Validate that the graph contains no unused phi nodes.
+///
+///     assert(NoUnusedPhiValidator.containsNoUnusedPhis(graph));
+class NoUnusedPhiValidator extends HGraphVisitor {
+  bool isValid = true;
+
+  static bool containsNoUnusedPhis(HGraph graph) {
+    final validator = NoUnusedPhiValidator();
+    validator.visitDominatorTree(graph);
+    return validator.isValid;
+  }
+
+  @override
+  void visitBasicBlock(HBasicBlock block) {
+    block.forEachPhi(visitPhi);
+  }
+
+  void visitPhi(HPhi phi) {
+    if (phi.usedBy.isEmpty) {
+      print('Unused $phi in B${phi.block.id}');
+      isValid = false;
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
index 2b20fa4..d84928d 100644
--- a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
+++ b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
@@ -665,6 +665,9 @@
     optimizer.ranges = ranges;
   }
 
+  @override
+  bool validPostcondition(HGraph graph) => true;
+
   void removeRangeConversion() {
     conversions.forEach((HRangeConversion instruction) {
       instruction.block.rewrite(instruction, instruction.inputs[0]);
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
index 1038d97..c171029 100644
--- a/pkg/nnbd_migration/lib/instrumentation.dart
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -242,6 +242,7 @@
   alwaysNullableType,
   angularAnnotation,
   argumentErrorCheckNotNull,
+  builtValueNullableAnnotation,
   callTearOff,
   compoundAssignment,
   // See [DummyOrigin].
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index bac0513..164c4aa 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -29,6 +29,7 @@
 import 'package:nnbd_migration/src/expression_checks.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
 import 'package:nnbd_migration/src/nullability_node_target.dart';
+import 'package:nnbd_migration/src/utilities/built_value_transformer.dart';
 import 'package:nnbd_migration/src/utilities/completeness_tracker.dart';
 import 'package:nnbd_migration/src/utilities/hint_utils.dart';
 import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
@@ -1330,6 +1331,14 @@
 
   @override
   DecoratedType? visitMethodDeclaration(MethodDeclaration node) {
+    if (BuiltValueTransformer.findNullableAnnotation(node) != null) {
+      _graph.makeNullable(
+          _variables!
+              .decoratedElementType(node.declaredElement!.declaration)
+              .returnType!
+              .node!,
+          BuiltValueNullableOrigin(source, node));
+    }
     _handleExecutableDeclaration(node, node.declaredElement!, node.metadata,
         node.returnType, node.parameters, null, node.body, null);
     _dispatch(node.typeParameters);
diff --git a/pkg/nnbd_migration/lib/src/edge_origin.dart b/pkg/nnbd_migration/lib/src/edge_origin.dart
index 58ffe89..ff7d8ce 100644
--- a/pkg/nnbd_migration/lib/src/edge_origin.dart
+++ b/pkg/nnbd_migration/lib/src/edge_origin.dart
@@ -98,6 +98,17 @@
   EdgeOriginKind get kind => EdgeOriginKind.argumentErrorCheckNotNull;
 }
 
+/// Edge origin resulting from a use of built_value's `@nullable` annotation.
+class BuiltValueNullableOrigin extends EdgeOrigin {
+  BuiltValueNullableOrigin(Source? source, AstNode node) : super(source, node);
+
+  @override
+  String get description => 'method is marked with the `@nullable` annotation';
+
+  @override
+  EdgeOriginKind get kind => EdgeOriginKind.builtValueNullableAnnotation;
+}
+
 /// An edge origin used for edges that originated because of a tear-off of
 /// `call` on a function type.
 class CallTearOffOrigin extends EdgeOrigin {
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index e46d892..8ebe8d5 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -35,6 +35,7 @@
 import 'package:nnbd_migration/src/edit_plan.dart';
 import 'package:nnbd_migration/src/fix_aggregator.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:nnbd_migration/src/utilities/built_value_transformer.dart';
 import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
 import 'package:nnbd_migration/src/utilities/resolution_utils.dart';
 import 'package:nnbd_migration/src/utilities/where_or_null_transformer.dart';
@@ -1245,25 +1246,13 @@
 
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
-    if (node.isGetter && node.isAbstract) {
-      for (var annotation in node.metadata) {
-        if (annotation.arguments == null) {
-          var element = annotation.element;
-          if (element is PropertyAccessorElement &&
-              element.name == 'nullable') {
-            if (element.enclosingElement is CompilationUnitElement) {
-              if (element.library.source.uri.toString() ==
-                  'package:built_value/built_value.dart') {
-                var info = AtomicEditInfo(
-                    NullabilityFixDescription.removeNullableAnnotation, {});
-                (_fixBuilder._getChange(node) as NodeChangeForMethodDeclaration)
-                  ..annotationToRemove = annotation
-                  ..removeAnnotationInfo = info;
-              }
-            }
-          }
-        }
-      }
+    var nullableAnnotation = BuiltValueTransformer.findNullableAnnotation(node);
+    if (nullableAnnotation != null) {
+      var info = AtomicEditInfo(
+          NullabilityFixDescription.removeNullableAnnotation, {});
+      (_fixBuilder._getChange(node) as NodeChangeForMethodDeclaration)
+        ..annotationToRemove = nullableAnnotation
+        ..removeAnnotationInfo = info;
     }
     super.visitMethodDeclaration(node);
   }
diff --git a/pkg/nnbd_migration/lib/src/utilities/built_value_transformer.dart b/pkg/nnbd_migration/lib/src/utilities/built_value_transformer.dart
new file mode 100644
index 0000000..c4ed06f
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/utilities/built_value_transformer.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+
+class BuiltValueTransformer {
+  static Annotation? findNullableAnnotation(MethodDeclaration node) {
+    if (node.isGetter && node.isAbstract) {
+      for (var annotation in node.metadata) {
+        if (annotation.arguments == null) {
+          var element = annotation.element;
+          if (element is PropertyAccessorElement &&
+              element.name == 'nullable') {
+            if (element.enclosingElement is CompilationUnitElement) {
+              if (element.library.source.uri.toString() ==
+                  'package:built_value/built_value.dart') {
+                return annotation;
+              }
+            }
+          }
+        }
+      }
+    }
+    return null;
+  }
+}
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 8efdc63..de6b5bb 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -977,6 +977,26 @@
         {path1: file1, path2: file2}, {path1: expected1, path2: anything});
   }
 
+  Future<void> test_built_value_nullable_getter_interface_only() async {
+    addBuiltValuePackage();
+    var content = '''
+import 'package:built_value/built_value.dart';
+
+abstract class Foo {
+  @nullable
+  int get value;
+}
+''';
+    var expected = '''
+import 'package:built_value/built_value.dart';
+
+abstract class Foo {
+  int? get value;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_call_already_migrated_extension() async {
     var content = '''
 import 'already_migrated.dart';
diff --git a/pkg/vm_service/test/breakpoint_in_enhanced_enums_test.dart b/pkg/vm_service/test/breakpoint_in_enhanced_enums_test.dart
new file mode 100644
index 0000000..ebedeeb
--- /dev/null
+++ b/pkg/vm_service/test/breakpoint_in_enhanced_enums_test.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// SharedOptions=--enable-experiment=enhanced-enums
+
+// ignore_for_file: experiment_not_enabled
+// @dart=2.17
+
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+const int LINE_A = 24;
+const int LINE_B = LINE_A + 11;
+const int LINE_C = LINE_B + 4;
+const int LINE_D = LINE_C + 4;
+const int LINE_E = LINE_D + 5;
+const int LINE_F = LINE_E + 4;
+const int LINE_G = LINE_F + 5;
+const int LINE_H = LINE_G + 4;
+
+mixin M on Object {
+  int mixedInMethod() {
+    print('mixedInMethod'); // LINE_A
+    return 0;
+  }
+}
+
+enum E with M {
+  e1,
+  e2,
+  e3;
+
+  void instanceMethod() {
+    print('instanceMethod'); // LINE_B
+  }
+
+  static void staticMethod() {
+    print('staticMethod'); // LINE_C
+  }
+
+  int get getter {
+    print('getter'); // LINE_D
+    return 0;
+  }
+
+  set setter(int x) {
+    print('setter'); // LINE_E
+  }
+
+  static int get staticGetter {
+    print('staticGetter'); // LINE_F
+    return 0;
+  }
+
+  static set staticSetter(int x) {
+    print('staticSetter'); // LINE_G
+  }
+
+  String toString() {
+    print('overriden toString'); // LINE_H
+    return '';
+  }
+}
+
+void testMain() {
+  E.staticMethod();
+  E.staticGetter;
+  E.staticSetter = 42;
+  final e = E.e1;
+  e.mixedInMethod();
+  e.instanceMethod();
+  e.getter;
+  e.setter = 42;
+  e.toString();
+}
+
+const lines = <int>[
+  LINE_C,
+  LINE_F,
+  LINE_G,
+  LINE_A,
+  LINE_B,
+  LINE_D,
+  LINE_E,
+  LINE_H,
+];
+
+const fileName = 'breakpoint_in_enhanced_enums_test.dart';
+final expected = <String>[
+  for (final line in lines) '$fileName:$line:5',
+];
+
+final stops = <String>[];
+
+final tests = <IsolateTest>[
+  hasPausedAtStart,
+  for (final line in lines) setBreakpointAtLine(line),
+  resumeProgramRecordingStops(stops, false),
+  checkRecordedStops(stops, expected),
+];
+
+main([args = const <String>[]]) => runIsolateTests(
+      args,
+      tests,
+      fileName,
+      testeeConcurrent: testMain,
+      pause_on_start: true,
+      pause_on_exit: true,
+      experiments: ['enhanced-enums'],
+    );
diff --git a/pkg/vm_service/test/enhanced_enum_test.dart b/pkg/vm_service/test/enhanced_enum_test.dart
new file mode 100644
index 0000000..633caa5
--- /dev/null
+++ b/pkg/vm_service/test/enhanced_enum_test.dart
@@ -0,0 +1,296 @@
+// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// SharedOptions=--enable-experiment=enhanced-enums
+
+// ignore_for_file: experiment_not_enabled
+// @dart=2.17
+
+import 'dart:developer';
+
+import 'package:test/test.dart';
+import 'package:vm_service/vm_service.dart';
+
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+class I1 {
+  int interfaceMethod1() => 0;
+  int get interfaceGetter1 => 0;
+  set interfaceSetter1(int value) {}
+}
+
+abstract class I2 {
+  int interfaceMethod2();
+  int get interfaceGetter2;
+  set interfaceSetter2(int value);
+}
+
+mixin M on Object {
+  int mixedInMethod() => 42;
+}
+
+enum E with M implements I1, I2 {
+  e1,
+  e2,
+  e3;
+
+  int interfaceMethod1() => 42;
+  int get interfaceGetter1 => 42;
+  set interfaceSetter1(int value) {}
+  int interfaceMethod2() => 42;
+  int get interfaceGetter2 => 42;
+  set interfaceSetter2(int value) {}
+
+  static int staticMethod() => 42;
+  static int get staticGetter => _staticField;
+  static set staticSetter(int x) => _staticField = x;
+  static int _staticField = 0;
+}
+
+enum F<T> {
+  f1<int>(1),
+  f2('foo'),
+  f3(<String, dynamic>{});
+
+  const F(this.value);
+
+  void debugMethod() {
+    debugger();
+  }
+
+  final T value;
+
+  String toString() => 'OVERRIDE ${value.toString()}';
+}
+
+void testMain() {
+  debugger();
+  F.f1.debugMethod();
+}
+
+Future<void> expectError(func) async {
+  bool gotException = false;
+  try {
+    await func();
+    fail('Failed to throw');
+  } on RPCError catch (e) {
+    expect(e.code, 113); // Compile time error.
+    gotException = true;
+  }
+  expect(gotException, true);
+}
+
+late final String isolateId;
+late final Isolate isolate;
+late final String rootLibraryId;
+late final Class enumECls;
+late final String enumEClsId;
+late final Class enumFCls;
+late final String enumFClsId;
+
+final tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (VmService service, IsolateRef isolateRef) async {
+    // Initialization.
+    isolateId = isolateRef.id!;
+    isolate = await service.getIsolate(isolateId);
+    rootLibraryId = isolate.rootLib!.id!;
+    final rootLibrary = await service.getObject(
+      isolateId,
+      rootLibraryId,
+    ) as Library;
+
+    final enumERef = rootLibrary.classes!.firstWhere((c) => c.name == 'E');
+    enumECls = await service.getObject(isolateId, enumERef.id!) as Class;
+    enumEClsId = enumECls.id!;
+
+    final enumFRef = rootLibrary.classes!.firstWhere((c) => c.name == 'F');
+    enumFCls = await service.getObject(isolateId, enumFRef.id!) as Class;
+    enumFClsId = enumFCls.id!;
+  },
+  (VmService service, _) async {
+    // Check all functions and fields are found.
+    expect(
+      enumECls.functions!.map((f) => f.name),
+      containsAll([
+        'e1',
+        'e2',
+        'e3',
+        'values',
+        'toString',
+        'interfaceSetter1=',
+        'interfaceGetter1',
+        'interfaceSetter2=',
+        'interfaceGetter2',
+        'interfaceMethod1',
+        'interfaceMethod2',
+        'staticGetter',
+        'staticSetter=',
+      ]),
+    );
+    expect(
+      enumECls.fields!.map((f) => f.name),
+      containsAll([
+        'e1',
+        'e2',
+        'e3',
+        'values',
+        '_staticField',
+      ]),
+    );
+  },
+  (VmService service, _) async {
+    // Ensure attempting to create an instance of an Enum fails.
+    await expectError(() => service.evaluate(isolateId, rootLibraryId, 'E()'));
+    await expectError(
+      () => service.evaluate(isolateId, rootLibraryId, 'E(10, "staticGetter")'),
+    );
+  },
+  (VmService service, _) async {
+    // Ensure we can evaluate enum values in the context of the enum Class.
+    dynamic result = await service.evaluate(isolateId, enumEClsId, 'e1');
+    expect(result, isA<InstanceRef>());
+    expect(result.classRef.name, 'E');
+    result = await service.evaluate(isolateId, result.id!, 'name');
+    expect(result.valueAsString, 'e1');
+
+    result = await service.evaluate(isolateId, enumEClsId, 'e2');
+    expect(result, isA<InstanceRef>());
+    expect(result.classRef.name, 'E');
+    result = await service.evaluate(isolateId, result.id!, 'name');
+    expect(result.valueAsString, 'e2');
+
+    result = await service.evaluate(isolateId, enumEClsId, 'e3');
+    expect(result, isA<InstanceRef>());
+    expect(result.classRef.name, 'E');
+    result = await service.evaluate(isolateId, result.id!, 'name');
+    expect(result.valueAsString, 'e3');
+  },
+  (VmService service, _) async {
+    // Ensure we can evaluate enum values in the context of the library.
+    dynamic result = await service.evaluate(isolateId, rootLibraryId, 'E.e1');
+    expect(result, isA<InstanceRef>());
+    expect(result.classRef.name, 'E');
+    result = await service.evaluate(isolateId, result.id!, 'name');
+    expect(result.valueAsString, 'e1');
+
+    result = await service.evaluate(isolateId, rootLibraryId, 'E.e2');
+    expect(result, isA<InstanceRef>());
+    expect(result.classRef.name, 'E');
+    result = await service.evaluate(isolateId, result.id!, 'name');
+    expect(result.valueAsString, 'e2');
+
+    result = await service.evaluate(isolateId, rootLibraryId, 'E.e3');
+    expect(result, isA<InstanceRef>());
+    expect(result.classRef.name, 'E');
+    result = await service.evaluate(isolateId, result.id!, 'name');
+    expect(result.valueAsString, 'e3');
+  },
+  (VmService service, _) async {
+    // Ensure we can evaluate instance getters and methods.
+    dynamic e1 = await service.evaluate(isolateId, enumEClsId, 'e1');
+    expect(e1, isA<InstanceRef>());
+    final e1Id = e1.id!;
+
+    dynamic result = await service.evaluate(isolateId, e1Id, 'interfaceGetter1');
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, '42');
+
+    result = await service.evaluate(isolateId, e1Id, 'interfaceGetter2');
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, '42');
+
+    result = await service.evaluate(isolateId, e1Id, 'interfaceMethod1()');
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, '42');
+
+    result = await service.evaluate(isolateId, e1Id, 'interfaceMethod2()');
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, '42');
+
+    result = await service.evaluate(isolateId, e1Id, 'mixedInMethod()');
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, '42');
+
+    result = await service.evaluate(isolateId, e1Id, 'toString()');
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, 'E.e1');
+  },
+  (VmService service, _) async {
+    // Ensure we can evaluate static getters and methods.
+    dynamic result = await service.evaluate(isolateId, enumEClsId, 'staticGetter');
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, '0');
+
+    result = await service.evaluate(isolateId, enumEClsId, 'staticMethod()');
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, '42');
+  },
+  (VmService service, _) async {
+    // Ensure we can invoke instance methods.
+    dynamic e1 = await service.evaluate(isolateId, enumEClsId, 'e1');
+    expect(e1, isA<InstanceRef>());
+    final e1Id = e1.id!;
+
+    dynamic result = await service.invoke(isolateId, e1Id, 'interfaceMethod1', []);
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, '42');
+
+    result = await service.invoke(isolateId, e1Id, 'interfaceMethod2', []);
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, '42');
+
+    result = await service.invoke(isolateId, e1Id, 'mixedInMethod', []);
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, '42');
+
+    result = await service.invoke(isolateId, e1Id, 'toString', []);
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, 'E.e1');
+  },
+  (VmService service, _) async {
+    // Ensure we can invoke static methods.
+    dynamic result = await service.evaluate(isolateId, enumEClsId, 'staticMethod()');
+    expect(result, isA<InstanceRef>());
+    expect(result.valueAsString, '42');
+  },
+  (VmService service, _) async {
+    // Ensure we can evaluate enums user defined properties.
+    dynamic result = await service.evaluate(isolateId, rootLibraryId, 'F.f1');
+    expect(result, isA<InstanceRef>());
+    expect(result.classRef.name, 'F');
+    result = await service.evaluate(isolateId, result.id!, 'value');
+    expect(result.valueAsString, '1');
+
+    result = await service.evaluate(isolateId, rootLibraryId, 'F.f2');
+    expect(result, isA<InstanceRef>());
+    expect(result.classRef.name, 'F');
+    result = await service.evaluate(isolateId, result.id!, 'value');
+    expect(result.valueAsString, 'foo');
+
+    result = await service.evaluate(isolateId, rootLibraryId, 'F.f3');
+    expect(result, isA<InstanceRef>());
+    expect(result.classRef.name, 'F');
+    result = await service.evaluate(isolateId, result.id!, 'value');
+    expect(result.kind, 'Map');
+  },
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  (VmService service, _) async {
+    dynamic result = await service.evaluateInFrame(isolateId, 0, 'T.toString()');
+    expect(result.valueAsString, 'int');
+
+    result = await service.evaluateInFrame(isolateId, 0, 'value');
+    expect(result.kind, 'Int');
+  },
+];
+
+main([args = const <String>[]]) => runIsolateTests(
+      args,
+      tests,
+      'enhanced_enum_test.dart',
+      testeeConcurrent: testMain,
+      experiments: ['enhanced-enums'],
+    );
diff --git a/tools/VERSION b/tools/VERSION
index eeb0ced..dd3a291 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 108
+PRERELEASE 109
 PRERELEASE_PATCH 0
\ No newline at end of file