File: Parser\ParseXml.vb
Web Access
Project: src\roslyn\src\Compilers\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.vbproj (Microsoft.CodeAnalysis.VisualBasic)
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.

Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices
Imports Microsoft.CodeAnalysis.Syntax.InternalSyntax
Imports InternalSyntaxFactory = Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax.SyntaxFactory

'
'============ Methods for parsing portions of executable statements ==
'

Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax

    Partial Friend Class Parser

        ' File: Parser.cpp
        ' Lines: 13261 - 13261
        ' Expression* .Parser::ParseXmlExpression( [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlExpression() As XmlNodeSyntax
            Debug.Assert(CurrentToken.Kind = SyntaxKind.LessThanToken OrElse
                 CurrentToken.Kind = SyntaxKind.LessThanGreaterThanToken OrElse
                 CurrentToken.Kind = SyntaxKind.LessThanSlashToken OrElse
                 CurrentToken.Kind = SyntaxKind.BeginCDataToken OrElse
                 CurrentToken.Kind = SyntaxKind.LessThanExclamationMinusMinusToken OrElse
                 CurrentToken.Kind = SyntaxKind.LessThanQuestionToken, "ParseXmlMarkup called on the wrong token.")

            ' The < token must be reset because a VB scanned < might following trivia attached to it.
            ResetCurrentToken(ScannerState.Content)

            Dim Result As XmlNodeSyntax = Nothing

            If CurrentToken.Kind = SyntaxKind.LessThanQuestionToken Then
                Result = ParseXmlDocument()
            Else
                Result = ParseXmlElement(ScannerState.VB)
            End If

            Result = AdjustTriviaForMissingTokens(Result)
            Result = TransitionFromXmlToVB(Result)
            Return Result
        End Function

        ' File: Parser.cpp
        ' Lines: 13370 - 13370
        ' Expression* .Parser::ParseXmlDocument( [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlDocument() As XmlNodeSyntax
            Debug.Assert(CurrentToken.Kind = SyntaxKind.LessThanQuestionToken, "ParseXmlDocument called on wrong token")
            Dim whitespaceChecker As New XmlWhitespaceChecker()

            Dim nextToken = PeekNextToken(ScannerState.Element)

            If nextToken.Kind = SyntaxKind.XmlNameToken AndAlso DirectCast(nextToken, XmlNameTokenSyntax).PossibleKeywordKind = SyntaxKind.XmlKeyword Then

                ' // Read the document version and encoding
                Dim prologue = ParseXmlDeclaration()
                prologue = DirectCast(whitespaceChecker.Visit(prologue), XmlDeclarationSyntax)

                ' // Read PI's and comments

                Dim node As VisualBasicSyntaxNode = prologue
                Dim precedingMisc = ParseXmlMisc(True, whitespaceChecker, node)
                prologue = DirectCast(node, XmlDeclarationSyntax)
                Dim body As XmlNodeSyntax

                ' // Get root element
                ' // This is either a single xml expression hole or an xml element
                Select Case CurrentToken.Kind
                    Case SyntaxKind.LessThanToken
                        body = ParseXmlElement(ScannerState.Misc)

                    Case SyntaxKind.LessThanPercentEqualsToken
                        body = ParseXmlEmbedded(ScannerState.Misc)

                    Case Else
                        ' Expected a root element or an embedded expression
                        body = SyntaxFactory.XmlEmptyElement(DirectCast(HandleUnexpectedToken(SyntaxKind.LessThanToken), PunctuationSyntax),
                                                           SyntaxFactory.XmlName(Nothing, DirectCast(InternalSyntaxFactory.MissingToken(SyntaxKind.XmlNameToken), XmlNameTokenSyntax)),
                                                           Nothing,
                                                           InternalSyntaxFactory.MissingPunctuation(SyntaxKind.SlashGreaterThanToken))

                End Select

                ' // More PI's and comments
                node = body
                Dim followingMisc = ParseXmlMisc(False, whitespaceChecker, node)
                body = DirectCast(node, XmlNodeSyntax)

                Return SyntaxFactory.XmlDocument(prologue, precedingMisc, body, followingMisc)
            Else

                ' // Parse Xml Processing Instruction
                Return ParseXmlProcessingInstruction(ScannerState.VB, whitespaceChecker)

            End If
        End Function

        ' File: Parser.cpp
        ' Lines: 13425 - 13425
        ' XmlDocumentExpression* .Parser::ParseXmlDecl( [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlDeclaration() As XmlDeclarationSyntax
            Debug.Assert(CurrentToken.Kind = SyntaxKind.LessThanQuestionToken AndAlso
                              PeekNextToken(ScannerState.Element).Kind = SyntaxKind.XmlNameToken AndAlso
                              DirectCast(PeekNextToken(ScannerState.Element), XmlNameTokenSyntax).PossibleKeywordKind = SyntaxKind.XmlKeyword, "ParseXmlDecl called on the wrong token.")

            Dim beginPrologue = DirectCast(CurrentToken, PunctuationSyntax)
            GetNextToken(ScannerState.Element)

            Dim nameToken As XmlNameTokenSyntax = Nothing
            VerifyExpectedToken(SyntaxKind.XmlNameToken, nameToken, ScannerState.Element)

            Dim encodingIndex = 0
            Dim standaloneIndex = 0
            Dim foundVersion = False
            Dim foundEncoding = False
            Dim foundStandalone = False
            Dim nodes(3) As VisualBasicSyntaxNode
            Dim i As Integer = 0

            nodes(i) = _scanner.MakeKeyword(nameToken)
            i += 1

            Do
                Dim nextOption As XmlDeclarationOptionSyntax

                Select Case CurrentToken.Kind
                    Case SyntaxKind.XmlNameToken
                        Dim optionName = DirectCast(CurrentToken, XmlNameTokenSyntax)

                        Select Case optionName.ToString
                            Case "version"
                                nextOption = ParseXmlDeclarationOption()
                                If foundVersion Then
                                    nextOption = ReportSyntaxError(nextOption, ERRID.ERR_DuplicateXmlAttribute, optionName.ToString)
                                    nodes(i - 1) = nodes(i - 1).AddTrailingSyntax(nextOption)
                                    Exit Select
                                End If

                                foundVersion = True
                                Debug.Assert(i = 1)

                                If foundEncoding OrElse foundStandalone Then
                                    nextOption = ReportSyntaxError(nextOption, ERRID.ERR_VersionMustBeFirstInXmlDecl, "", "", optionName.ToString)
                                End If

                                If nextOption.Value.TextTokens.Node Is Nothing OrElse nextOption.Value.TextTokens.Node.ToFullString <> "1.0" Then
                                    nextOption = ReportSyntaxError(nextOption, ERRID.ERR_InvalidAttributeValue1, "1.0")
                                End If

                                nodes(i) = nextOption
                                i += 1

                            Case "encoding"
                                nextOption = ParseXmlDeclarationOption()
                                If foundEncoding Then
                                    nextOption = ReportSyntaxError(nextOption, ERRID.ERR_DuplicateXmlAttribute, optionName.ToString)
                                    nodes(i - 1) = nodes(i - 1).AddTrailingSyntax(nextOption)
                                    Exit Select
                                End If

                                foundEncoding = True

                                If foundStandalone Then
                                    nextOption = ReportSyntaxError(nextOption, ERRID.ERR_AttributeOrder, "encoding", "standalone")
                                    nodes(i - 1) = nodes(i - 1).AddTrailingSyntax(nextOption)
                                    Exit Select
                                ElseIf Not foundVersion Then
                                    nodes(i - 1) = nodes(i - 1).AddTrailingSyntax(nextOption)
                                    Exit Select
                                End If

                                Debug.Assert(i = 2)
                                encodingIndex = i
                                nodes(i) = nextOption
                                i += 1

                            Case "standalone"
                                nextOption = ParseXmlDeclarationOption()
                                If foundStandalone Then
                                    nextOption = ReportSyntaxError(nextOption, ERRID.ERR_DuplicateXmlAttribute, optionName.ToString)
                                    nodes(i - 1) = nodes(i - 1).AddTrailingSyntax(nextOption)
                                    Exit Select
                                End If

                                foundStandalone = True

                                If Not foundVersion Then
                                    nodes(i - 1) = nodes(i - 1).AddTrailingSyntax(nextOption)
                                    Exit Select
                                End If

                                Dim stringValue = If(nextOption.Value.TextTokens.Node IsNot Nothing, nextOption.Value.TextTokens.Node.ToFullString, "")
                                If stringValue <> "yes" AndAlso stringValue <> "no" Then
                                    nextOption = ReportSyntaxError(nextOption, ERRID.ERR_InvalidAttributeValue2, "yes", "no")
                                End If

                                Debug.Assert(i = 2 OrElse i = 3)
                                standaloneIndex = i
                                nodes(i) = nextOption
                                i += 1

                            Case Else
                                nextOption = ParseXmlDeclarationOption()
                                nextOption = ReportSyntaxError(nextOption, ERRID.ERR_IllegalAttributeInXmlDecl, "", "", nextOption.Name.ToString)
                                nodes(i - 1) = nodes(i - 1).AddTrailingSyntax(nextOption)

                        End Select

                    Case SyntaxKind.LessThanPercentEqualsToken
                        nextOption = ParseXmlDeclarationOption()
                        nodes(i - 1) = nodes(i - 1).AddTrailingSyntax(nextOption)

                    Case Else
                        Exit Do

                End Select
            Loop

            Dim unexpected As CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of SyntaxToken) = Nothing
            If CurrentToken.Kind <> SyntaxKind.QuestionGreaterThanToken Then
                unexpected = ResyncAt(ScannerState.Element, {SyntaxKind.EndOfXmlToken,
                                                             SyntaxKind.QuestionGreaterThanToken,
                                                             SyntaxKind.LessThanToken,
                                                             SyntaxKind.LessThanPercentEqualsToken,
                                                             SyntaxKind.LessThanExclamationMinusMinusToken})
            End If

            Dim endPrologue As PunctuationSyntax = Nothing
            VerifyExpectedToken(SyntaxKind.QuestionGreaterThanToken, endPrologue, ScannerState.Content)

            If unexpected.Node IsNot Nothing Then
                endPrologue = endPrologue.AddLeadingSyntax(unexpected, ERRID.ERR_ExpectedXmlName)
            End If

            Debug.Assert(foundVersion = (nodes(1) IsNot Nothing))

            If nodes(1) Is Nothing Then
                Dim version = SyntaxFactory.XmlDeclarationOption(DirectCast(InternalSyntaxFactory.MissingToken(SyntaxKind.XmlNameToken), XmlNameTokenSyntax),
                                                    InternalSyntaxFactory.MissingPunctuation(SyntaxKind.EqualsToken),
                                                    CreateMissingXmlString())
                nodes(1) = ReportSyntaxError(version, ERRID.ERR_MissingVersionInXmlDecl)
            End If

            Return SyntaxFactory.XmlDeclaration(beginPrologue,
                                              TryCast(nodes(0), KeywordSyntax),
                                              TryCast(nodes(1), XmlDeclarationOptionSyntax),
                                              If(encodingIndex = 0, Nothing, TryCast(nodes(encodingIndex), XmlDeclarationOptionSyntax)),
                                              If(standaloneIndex = 0, Nothing, TryCast(nodes(standaloneIndex), XmlDeclarationOptionSyntax)),
                                              endPrologue)
        End Function

        ' File: Parser.cpp
        ' Lines: 13813 - 13813
        ' Expression* .Parser::ParseXmlAttribute( [ bool AllowNameAsExpression ] [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlDeclarationOption() As XmlDeclarationOptionSyntax
            Debug.Assert(IsToken(CurrentToken,
                                 SyntaxKind.XmlNameToken,
                                 SyntaxKind.LessThanPercentEqualsToken,
                                 SyntaxKind.EqualsToken,
                                 SyntaxKind.SingleQuoteToken,
                                 SyntaxKind.DoubleQuoteToken),
                             "ParseXmlPrologueOption called on wrong token.")

            Dim result As XmlDeclarationOptionSyntax = Nothing
            Dim name As XmlNameTokenSyntax = Nothing
            Dim equals As PunctuationSyntax = Nothing
            Dim value As XmlStringSyntax = Nothing

            Dim hasPrecedingWhitespace = PrevToken.GetTrailingTrivia.ContainsWhitespaceTrivia() OrElse CurrentToken.GetLeadingTrivia.ContainsWhitespaceTrivia

            VerifyExpectedToken(SyntaxKind.XmlNameToken, name, ScannerState.Element)

            If Not hasPrecedingWhitespace Then
                name = ReportSyntaxError(name, ERRID.ERR_ExpectedXmlWhiteSpace)
            End If

            If CurrentToken.Kind = SyntaxKind.LessThanPercentEqualsToken Then
                ' // <%= expr %>
                Dim exp = ParseXmlEmbedded(ScannerState.Element)
                name = name.AddTrailingSyntax(exp, ERRID.ERR_EmbeddedExpression)
            End If

            Dim skipped As CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of SyntaxToken) = Nothing
            If Not VerifyExpectedToken(SyntaxKind.EqualsToken, equals, ScannerState.Element) Then
                skipped = ResyncAt(ScannerState.Element,
                                   {SyntaxKind.SingleQuoteToken,
                                    SyntaxKind.DoubleQuoteToken,
                                    SyntaxKind.LessThanPercentEqualsToken,
                                    SyntaxKind.QuestionGreaterThanToken,
                                    SyntaxKind.EndOfXmlToken})

                equals = equals.AddTrailingSyntax(skipped)
            End If

            Select Case CurrentToken.Kind
                Case SyntaxKind.SingleQuoteToken,
                      SyntaxKind.DoubleQuoteToken
                    value = ParseXmlString(ScannerState.Element)

                Case SyntaxKind.LessThanPercentEqualsToken
                    ' // <%= expr %>
                    Dim exp = ParseXmlEmbedded(ScannerState.Element)
                    value = AddLeadingSyntax(CreateMissingXmlString(), exp, ERRID.ERR_EmbeddedExpression)

                Case Else
                    value = CreateMissingXmlString()
            End Select

            result = SyntaxFactory.XmlDeclarationOption(name, equals, value)

            Return result
        End Function

        ' File: Parser.cpp
        ' Lines: 13452 - 13452
        ' ExpressionList** .Parser::ParseXmlMisc( [ _Inout_ ParseTree::ExpressionList** Prev ] [ bool IsProlog ] [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlMisc(IsProlog As Boolean, whitespaceChecker As XmlWhitespaceChecker, ByRef outerNode As VisualBasicSyntaxNode) As CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of XmlNodeSyntax)
            Dim Content = Me._pool.Allocate(Of XmlNodeSyntax)()

            While True
                Dim result As XmlNodeSyntax = Nothing

                Select Case (CurrentToken.Kind)

                    Case SyntaxKind.BadToken
                        Dim badToken = DirectCast(CurrentToken, BadTokenSyntax)
                        Dim skipped As GreenNode
                        If badToken.SubKind = SyntaxSubKind.BeginDocTypeToken Then
                            skipped = ParseXmlDocType(ScannerState.Misc)
                        Else
                            skipped = badToken
                            GetNextToken(ScannerState.Misc)
                        End If
                        Dim count = Content.Count
                        If count > 0 Then
                            Content(count - 1) = Content(count - 1).AddTrailingSyntax(skipped, ERRID.ERR_DTDNotSupported)
                        Else
                            outerNode = outerNode.AddTrailingSyntax(skipped, ERRID.ERR_DTDNotSupported)
                        End If

                    Case SyntaxKind.LessThanExclamationMinusMinusToken
                        result = ParseXmlComment(ScannerState.Misc)

                    Case SyntaxKind.LessThanQuestionToken
                        result = ParseXmlProcessingInstruction(ScannerState.Misc, whitespaceChecker)

                    Case Else
                        Exit While

                End Select

                If result IsNot Nothing Then
                    Content.Add(result)
                End If

            End While

            Dim ContentList = Content.ToList
            Me._pool.Free(Content)

            Return ContentList
        End Function

        Private Function ParseXmlDocType(enclosingState As ScannerState) As GreenNode
            Debug.Assert(CurrentToken.Kind = SyntaxKind.BadToken AndAlso
                         DirectCast(CurrentToken, BadTokenSyntax).SubKind = SyntaxSubKind.BeginDocTypeToken, "ParseDTD called on wrong token.")

            Dim builder = SyntaxListBuilder(Of GreenNode).Create()

            Dim beginDocType = DirectCast(CurrentToken, BadTokenSyntax)
            builder.Add(beginDocType)

            Dim name As XmlNameTokenSyntax = Nothing

            GetNextToken(ScannerState.DocType)
            VerifyExpectedToken(SyntaxKind.XmlNameToken, name, ScannerState.DocType)
            builder.Add(name)

            ParseExternalID(builder)

            ParseInternalSubSet(builder)

            Dim greaterThan As PunctuationSyntax = Nothing
            VerifyExpectedToken(SyntaxKind.GreaterThanToken, greaterThan, enclosingState)
            builder.Add(greaterThan)

            Return builder.ToList().Node
        End Function

        Private Sub ParseExternalID(builder As SyntaxListBuilder(Of GreenNode))

            If CurrentToken.Kind = SyntaxKind.XmlNameToken Then

                Dim name = DirectCast(CurrentToken, XmlNameTokenSyntax)

                Select Case name.ToString
                    Case "SYSTEM"
                        builder.Add(name)
                        GetNextToken(ScannerState.DocType)
                        Dim systemLiteral = ParseXmlString(ScannerState.DocType)
                        builder.Add(systemLiteral)

                    Case "PUBLIC"
                        builder.Add(name)
                        GetNextToken(ScannerState.DocType)
                        Dim publicLiteral = ParseXmlString(ScannerState.DocType)
                        builder.Add(publicLiteral)
                        Dim systemLiteral = ParseXmlString(ScannerState.DocType)
                        builder.Add(systemLiteral)

                End Select
            End If

        End Sub

        Private Sub ParseInternalSubSet(builder As SyntaxListBuilder(Of GreenNode))
            Dim unexpected As CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of SyntaxToken) = Nothing
            If CurrentToken.Kind <> SyntaxKind.BadToken OrElse DirectCast(CurrentToken, BadTokenSyntax).SubKind <> SyntaxSubKind.OpenBracketToken Then
                unexpected = ResyncAt(ScannerState.DocType, {SyntaxKind.BadToken,
                                                            SyntaxKind.GreaterThanToken,
                                                            SyntaxKind.LessThanToken,
                                                            SyntaxKind.LessThanExclamationMinusMinusToken,
                                                            SyntaxKind.BeginCDataToken,
                                                            SyntaxKind.LessThanPercentEqualsToken,
                                                            SyntaxKind.EndOfXmlToken})

                If unexpected.Node IsNot Nothing Then
                    builder.Add(unexpected.Node)
                End If
            End If

            If CurrentToken.Kind = SyntaxKind.BadToken AndAlso DirectCast(CurrentToken, BadTokenSyntax).SubKind = SyntaxSubKind.OpenBracketToken Then

                'Assume we're on the '['

                builder.Add(CurrentToken)

                GetNextToken(ScannerState.DocType)

                If CurrentToken.Kind = SyntaxKind.BadToken AndAlso DirectCast(CurrentToken, BadTokenSyntax).SubKind = SyntaxSubKind.LessThanExclamationToken Then
                    builder.Add(CurrentToken)
                    GetNextToken(ScannerState.DocType)
                    ParseXmlMarkupDecl(builder)
                End If

                If CurrentToken.Kind <> SyntaxKind.BadToken OrElse DirectCast(CurrentToken, BadTokenSyntax).SubKind <> SyntaxSubKind.CloseBracketToken Then
                    unexpected = ResyncAt(ScannerState.DocType, {SyntaxKind.BadToken,
                                                                SyntaxKind.GreaterThanToken,
                                                                SyntaxKind.LessThanToken,
                                                                SyntaxKind.LessThanExclamationMinusMinusToken,
                                                                SyntaxKind.BeginCDataToken,
                                                                SyntaxKind.LessThanPercentEqualsToken,
                                                                SyntaxKind.EndOfXmlToken})
                    If unexpected.Node IsNot Nothing Then
                        builder.Add(unexpected.Node)
                    End If
                End If

                'Assume we're on the ']'
                builder.Add(CurrentToken)
                GetNextToken(ScannerState.DocType)

            End If

        End Sub

        Private Sub ParseXmlMarkupDecl(builder As SyntaxListBuilder(Of GreenNode))

            Do
                Select Case CurrentToken.Kind
                    Case SyntaxKind.BadToken
                        builder.Add(CurrentToken)
                        Dim badToken = DirectCast(CurrentToken, BadTokenSyntax)
                        GetNextToken(ScannerState.DocType)
                        If badToken.SubKind = SyntaxSubKind.LessThanExclamationToken Then
                            ParseXmlMarkupDecl(builder)
                        End If

                    Case SyntaxKind.LessThanQuestionToken
                        Dim xmlPI = ParseXmlProcessingInstruction(ScannerState.DocType, Nothing)
                        builder.Add(xmlPI)

                    Case SyntaxKind.LessThanExclamationMinusMinusToken
                        Dim xmlComment = ParseXmlComment(ScannerState.DocType)
                        builder.Add(xmlComment)

                    Case SyntaxKind.GreaterThanToken
                        builder.Add(CurrentToken)
                        GetNextToken(ScannerState.DocType)
                        Return

                    Case SyntaxKind.EndOfFileToken,
                         SyntaxKind.EndOfXmlToken
                        Return

                    Case Else
                        builder.Add(CurrentToken)
                        GetNextToken(ScannerState.DocType)
                End Select

            Loop
        End Sub

        ' File: Parser.cpp
        ' Lines: 13624 - 13624
        ' XmlElementExpression* .Parser::ParseXmlElement( [ _In_opt_ ParseTree::XmlElementExpression* Parent ] [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlElementStartTag(enclosingState As ScannerState) As XmlNodeSyntax
            Debug.Assert(CurrentToken.Kind = SyntaxKind.LessThanToken, "ParseXmlElement call on wrong token.")

            Dim lessThan As PunctuationSyntax = DirectCast(CurrentToken, PunctuationSyntax)
            GetNextToken(ScannerState.Element)

            ' /* AllowExpr */' /* IsBracketed */' 
            Dim Name = ParseXmlQualifiedName(False, True, ScannerState.Element, ScannerState.Element)

            Dim nameIsFollowedByWhitespace = Name.HasTrailingTrivia

            Dim Attributes = ParseXmlAttributes(Not nameIsFollowedByWhitespace, Name)
            Dim greaterThan As PunctuationSyntax = Nothing
            Dim endEmptyElementToken As PunctuationSyntax = Nothing

            Select Case (CurrentToken.Kind)

                Case SyntaxKind.GreaterThanToken
                    ' Element with content
                    greaterThan = DirectCast(CurrentToken, PunctuationSyntax)
                    GetNextToken(ScannerState.Content)

                    Return SyntaxFactory.XmlElementStartTag(lessThan, Name, Attributes, greaterThan)

                Case SyntaxKind.SlashGreaterThanToken
                    ' Empty element
                    endEmptyElementToken = DirectCast(CurrentToken, PunctuationSyntax)
                    GetNextToken(enclosingState)

                    Return SyntaxFactory.XmlEmptyElement(lessThan, Name, Attributes, endEmptyElementToken)

                Case SyntaxKind.SlashToken
                    ' Looks like an empty element but  / followed by '>' is an error when there is whitespace between the tokens.
                    If PeekNextToken(ScannerState.Element).Kind = SyntaxKind.GreaterThanToken Then

                        Dim divideToken As SyntaxToken = CurrentToken

                        GetNextToken(ScannerState.Element)

                        greaterThan = DirectCast(CurrentToken, PunctuationSyntax)

                        GetNextToken(enclosingState)

                        Dim unexpectedSyntax = New CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of SyntaxToken)(
                            CodeAnalysis.Syntax.InternalSyntax.SyntaxList.List(divideToken, greaterThan))

                        endEmptyElementToken = AddLeadingSyntax(New PunctuationSyntax(SyntaxKind.SlashGreaterThanToken, "", Nothing, Nothing),
                                                                unexpectedSyntax,
                                                                ERRID.ERR_IllegalXmlWhiteSpace)

                        Return SyntaxFactory.XmlEmptyElement(lessThan, Name, Attributes, endEmptyElementToken)
                    Else
                        ' Try to resync to recovery from a bad parse
                        Return ResyncXmlElement(enclosingState, lessThan, Name, Attributes)
                    End If

                Case Else
                    ' Try to resync to recovery from a bad parse
                    Return ResyncXmlElement(enclosingState, lessThan, Name, Attributes)

            End Select

        End Function

        ' File: Parser.cpp
        ' Lines: 13624 - 13624
        ' XmlElementExpression* .Parser::ParseXmlElement( [ _In_opt_ ParseTree::XmlElementExpression* Parent ] [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlElement(enclosingState As ScannerState) As XmlNodeSyntax
            Debug.Assert(IsToken(CurrentToken,
                                 SyntaxKind.LessThanToken,
                                 SyntaxKind.LessThanGreaterThanToken,
                                 SyntaxKind.LessThanSlashToken,
                                 SyntaxKind.BeginCDataToken,
                                 SyntaxKind.LessThanExclamationMinusMinusToken,
                                 SyntaxKind.LessThanQuestionToken,
                                 SyntaxKind.LessThanPercentEqualsToken,
                                 SyntaxKind.XmlTextLiteralToken,
                                 SyntaxKind.BadToken),
                             "ParseXmlElement call on wrong token.")

            Dim xml As XmlNodeSyntax = Nothing
            Dim contexts As New List(Of XmlContext)
            Dim endElement As XmlElementEndTagSyntax
            Dim nextState = enclosingState
            Dim whitespaceChecker As New XmlWhitespaceChecker()

            Do

                Select Case CurrentToken.Kind

                    Case SyntaxKind.LessThanToken
                        Dim nextTokenIsSlash As Boolean = PeekNextToken(ScannerState.Element).Kind = SyntaxKind.SlashToken

                        If nextTokenIsSlash Then
                            ' While </ is a single token, parse this as </ and report an error.
                            GoTo LessThanSlashTokenCase
                        End If

                        xml = ParseXmlElementStartTag(nextState)
                        xml = DirectCast(whitespaceChecker.Visit(xml), XmlNodeSyntax)

                        If xml.Kind = SyntaxKind.XmlElementStartTag Then
                            Dim startElement = DirectCast(xml, XmlElementStartTagSyntax)
                            contexts.Push(New XmlContext(_pool, startElement))
                            nextState = ScannerState.Content
                            Continue Do
                        End If

                    Case SyntaxKind.LessThanSlashToken
LessThanSlashTokenCase:
                        endElement = ParseXmlElementEndTag(nextState)
                        endElement = DirectCast(whitespaceChecker.Visit(endElement), XmlElementEndTagSyntax)

                        If contexts.Count > 0 Then
                            xml = CreateXmlElement(contexts, endElement)

                        Else
                            Dim missingLessThan = InternalSyntaxFactory.MissingPunctuation(SyntaxKind.LessThanToken)
                            Dim missingXmlNameToken = DirectCast(InternalSyntaxFactory.MissingToken(SyntaxKind.XmlNameToken), XmlNameTokenSyntax)
                            Dim missingName = SyntaxFactory.XmlName(Nothing, missingXmlNameToken)
                            Dim missingGreaterThan = InternalSyntaxFactory.MissingPunctuation(SyntaxKind.GreaterThanToken)
                            Dim startElement = SyntaxFactory.XmlElementStartTag(missingLessThan, missingName, Nothing, missingGreaterThan)

                            contexts.Push(New XmlContext(_pool, startElement))
                            xml = contexts.Peek.CreateElement(endElement)
                            xml = ReportSyntaxError(xml, ERRID.ERR_XmlEndElementNoMatchingStart)
                            contexts.Pop()
                        End If

                    Case SyntaxKind.LessThanExclamationMinusMinusToken
                        xml = ParseXmlComment(nextState)

                    Case SyntaxKind.LessThanQuestionToken
                        xml = ParseXmlProcessingInstruction(nextState, whitespaceChecker)
                        xml = DirectCast(whitespaceChecker.Visit(xml), XmlProcessingInstructionSyntax)

                    Case SyntaxKind.BeginCDataToken
                        xml = ParseXmlCData(nextState)

                    Case SyntaxKind.LessThanPercentEqualsToken
                        xml = ParseXmlEmbedded(nextState)
                        If contexts.Count = 0 Then
                            xml = ReportSyntaxError(xml, ERRID.ERR_EmbeddedExpression)
                        End If

                    Case SyntaxKind.XmlTextLiteralToken,
                        SyntaxKind.XmlEntityLiteralToken,
                        SyntaxKind.DocumentationCommentLineBreakToken

                        Dim newKind As SyntaxKind
                        Dim textTokens = _pool.Allocate(Of XmlTextTokenSyntax)()
                        Do
                            textTokens.Add(DirectCast(CurrentToken, XmlTextTokenSyntax))
                            GetNextToken(nextState)

                            newKind = CurrentToken.Kind
                        Loop While newKind = SyntaxKind.XmlTextLiteralToken OrElse
                            newKind = SyntaxKind.XmlEntityLiteralToken OrElse
                            newKind = SyntaxKind.DocumentationCommentLineBreakToken

                        Dim textResult = textTokens.ToList
                        _pool.Free(textTokens)
                        xml = SyntaxFactory.XmlText(textResult)

                    Case SyntaxKind.BadToken
                        Dim badToken = DirectCast(CurrentToken, BadTokenSyntax)

                        If badToken.SubKind = SyntaxSubKind.BeginDocTypeToken Then
                            Dim docTypeTrivia = ParseXmlDocType(ScannerState.Element)
                            xml = SyntaxFactory.XmlText(InternalSyntaxFactory.MissingToken(SyntaxKind.XmlTextLiteralToken))
                            xml = xml.AddLeadingSyntax(docTypeTrivia, ERRID.ERR_DTDNotSupported)
                        Else
                            ' Let ParseXmlEndELement do the resync
                            Exit Do
                        End If

                    Case Else
                        ' Let ParseXmlEndELement do the resync
                        Exit Do

                End Select

                If contexts.Count > 0 Then
                    contexts.Peek.Add(xml)
                Else
                    Exit Do
                End If
            Loop

            ' Recover from improperly terminated element.
            ' Close all contexts and return

            If contexts.Count > 0 Then
                Do
                    endElement = ParseXmlElementEndTag(nextState)
                    xml = CreateXmlElement(contexts, endElement)
                    If contexts.Count > 0 Then
                        contexts.Peek().Add(xml)
                    Else
                        Exit Do
                    End If
                Loop
            End If

            ResetCurrentToken(enclosingState)
            Return xml
        End Function

        Private Function CreateXmlElement(contexts As List(Of XmlContext), endElement As XmlElementEndTagSyntax) As XmlNodeSyntax

            Dim i = contexts.MatchEndElement(endElement.Name)
            Dim element As XmlNodeSyntax

            If i >= 0 Then

                ' Close any xml element that was not matched
                Dim last = contexts.Count - 1
                Do While last > i
                    Dim missingEndElement = SyntaxFactory.XmlElementEndTag(DirectCast(HandleUnexpectedToken(SyntaxKind.LessThanSlashToken), PunctuationSyntax),
                                                                 ReportSyntaxError(InternalSyntaxFactory.XmlName(Nothing, SyntaxFactory.XmlNameToken("", SyntaxKind.XmlNameToken, Nothing, Nothing)), ERRID.ERR_ExpectedXmlName),
                                                                 DirectCast(HandleUnexpectedToken(SyntaxKind.GreaterThanToken), PunctuationSyntax))

                    Dim xml = contexts.Peek.CreateElement(missingEndElement, ErrorFactory.ErrorInfo(ERRID.ERR_MissingXmlEndTag))
                    contexts.Pop()
                    If contexts.Count > 0 Then
                        contexts.Peek().Add(xml)
                    Else
                        Exit Do
                    End If
                    last -= 1
                Loop

                If endElement.IsMissing Then
                    element = contexts.Peek.CreateElement(endElement, ErrorFactory.ErrorInfo(ERRID.ERR_MissingXmlEndTag))
                Else
                    element = contexts.Peek.CreateElement(endElement)
                End If

            Else
                ' Not match was found
                ' Just close the current xml element

                'TODO - Consider whether the current element should be closed or create a missing start tag to match this dangling end tag.

                Dim prefix = ""
                Dim colon = ""
                Dim localName = ""

                Dim nameExpr = contexts.Peek().StartElement.Name
                If nameExpr.Kind = SyntaxKind.XmlName Then
                    Dim name = DirectCast(nameExpr, XmlNameSyntax)
                    If name.Prefix IsNot Nothing Then
                        prefix = name.Prefix.Name.Text
                        colon = ":"
                    End If
                    localName = name.LocalName.Text
                End If

                endElement = ReportSyntaxError(endElement, ERRID.ERR_MismatchedXmlEndTag, prefix, colon, localName)
                element = contexts.Peek.CreateElement(endElement, ErrorFactory.ErrorInfo(ERRID.ERR_MissingXmlEndTag))
            End If

            contexts.Pop()
            Return element
        End Function

        Private Function ResyncXmlElement(state As ScannerState, lessThan As PunctuationSyntax, Name As XmlNodeSyntax, attributes As CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of XmlNodeSyntax)) As XmlNodeSyntax

            Dim unexpectedSyntax = ResyncAt(ScannerState.Element,
                                            {SyntaxKind.SlashGreaterThanToken,
                                             SyntaxKind.GreaterThanToken,
                                             SyntaxKind.LessThanToken,
                                             SyntaxKind.LessThanSlashToken,
                                             SyntaxKind.LessThanPercentEqualsToken,
                                             SyntaxKind.BeginCDataToken,
                                             SyntaxKind.LessThanExclamationMinusMinusToken,
                                             SyntaxKind.LessThanQuestionToken,
                                             SyntaxKind.EndOfXmlToken})

            Dim greaterThan As PunctuationSyntax

            'TODO - Don't add an error if the unexpectedSyntax already has errors.
            Select Case CurrentToken.Kind
                Case SyntaxKind.SlashGreaterThanToken
                    Dim endEmptyElementToken = DirectCast(CurrentToken, PunctuationSyntax)
                    If unexpectedSyntax.Node IsNot Nothing Then
                        endEmptyElementToken = AddLeadingSyntax(endEmptyElementToken, unexpectedSyntax, ERRID.ERR_ExpectedGreater)
                    End If
                    GetNextToken(state)

                    Return SyntaxFactory.XmlEmptyElement(lessThan, Name, attributes, endEmptyElementToken)

                Case SyntaxKind.GreaterThanToken
                    greaterThan = DirectCast(CurrentToken, PunctuationSyntax)
                    GetNextToken(ScannerState.Content)
                    If unexpectedSyntax.Node IsNot Nothing Then
                        greaterThan = AddLeadingSyntax(greaterThan, unexpectedSyntax, ERRID.ERR_ExpectedGreater)
                    End If

                    Return SyntaxFactory.XmlElementStartTag(lessThan, Name, attributes, greaterThan)

                Case Else
                    ' Try to avoid spurious missing '>' error message. Only report error if no skipped text
                    ' and attributes are error free.
                    greaterThan = InternalSyntaxFactory.MissingPunctuation(SyntaxKind.GreaterThanToken)

                    If unexpectedSyntax.Node Is Nothing Then
                        If Not (attributes.Node IsNot Nothing AndAlso attributes.Node.ContainsDiagnostics) Then
                            greaterThan = ReportSyntaxError(greaterThan, ERRID.ERR_ExpectedGreater)
                        End If
                    Else
                        greaterThan = AddLeadingSyntax(greaterThan, unexpectedSyntax, ERRID.ERR_Syntax)
                    End If

                    Return SyntaxFactory.XmlElementStartTag(lessThan, Name, attributes, greaterThan)
            End Select

        End Function

        Private Function ResyncXmlContent() As XmlNodeSyntax
            Dim result As XmlTextSyntax

            Dim unexpectedSyntax = ResyncAt(ScannerState.Content,
                                            {SyntaxKind.LessThanToken,
                                             SyntaxKind.LessThanSlashToken,
                                             SyntaxKind.LessThanPercentEqualsToken,
                                             SyntaxKind.BeginCDataToken,
                                             SyntaxKind.LessThanExclamationMinusMinusToken,
                                             SyntaxKind.LessThanQuestionToken,
                                             SyntaxKind.EndOfXmlToken,
                                             SyntaxKind.XmlTextLiteralToken,
                                             SyntaxKind.XmlEntityLiteralToken})
            Dim currentKind = CurrentToken.Kind
            If currentKind = SyntaxKind.XmlTextLiteralToken OrElse
                currentKind = SyntaxKind.DocumentationCommentLineBreakToken OrElse
                currentKind = SyntaxKind.XmlEntityLiteralToken Then

                result = SyntaxFactory.XmlText(CurrentToken)
                GetNextToken(ScannerState.Content)
            Else
                result = SyntaxFactory.XmlText(HandleUnexpectedToken(SyntaxKind.XmlTextLiteralToken))
            End If

            If result.ContainsDiagnostics Then
                result = AddLeadingSyntax(result, unexpectedSyntax)
            Else
                result = AddLeadingSyntax(result, unexpectedSyntax, ERRID.ERR_Syntax)
            End If
            Return result
        End Function

        ' File: Parser.cpp
        ' Lines: 13695 - 13695
        ' XmlElementExpression* .Parser::ParseXmlEndElement( [ _Inout_ ParseTree::XmlElementExpression* Result ] [ Token* StartToken ] [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlElementEndTag(nextState As ScannerState) As XmlElementEndTagSyntax

            Dim beginEndElement As PunctuationSyntax = Nothing
            Dim name As XmlNameSyntax = Nothing
            Dim greaterToken As PunctuationSyntax = Nothing
            Dim unexpected As CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of SyntaxToken) = Nothing

            If CurrentToken.Kind <> SyntaxKind.LessThanSlashToken Then
                unexpected = ResyncAt(ScannerState.Content,
                                      {SyntaxKind.LessThanToken,
                                      SyntaxKind.LessThanSlashToken,
                                      SyntaxKind.EndOfXmlToken})
            End If

            If Not VerifyExpectedToken(SyntaxKind.LessThanSlashToken, beginEndElement, ScannerState.EndElement) Then

                ' Check for '<' followed by '/'.  This is an error because whitespace is not allowed between the tokens.
                If CurrentToken.Kind = SyntaxKind.LessThanToken Then
                    Dim lessThan = DirectCast(CurrentToken, PunctuationSyntax)
                    Dim slashToken As SyntaxToken = PeekNextToken(ScannerState.EndElement)

                    If slashToken.Kind = SyntaxKind.SlashToken Then
                        If lessThan.HasTrailingTrivia Or slashToken.HasLeadingTrivia Then
                            beginEndElement = AddLeadingSyntax(beginEndElement,
                                CodeAnalysis.Syntax.InternalSyntax.SyntaxList.List(lessThan, slashToken),
                                ERRID.ERR_IllegalXmlWhiteSpace)
                        Else
                            beginEndElement = DirectCast(InternalSyntaxFactory.Token(lessThan.GetLeadingTrivia,
                                                                      SyntaxKind.LessThanSlashToken,
                                                                      slashToken.GetTrailingTrivia,
                                                                      lessThan.Text & slashToken.Text),
                                                                  PunctuationSyntax)
                        End If

                        GetNextToken(ScannerState.EndElement)
                        GetNextToken(ScannerState.EndElement)
                    End If
                End If
            End If

            If unexpected.Node IsNot Nothing Then
                If unexpected.Node.ContainsDiagnostics Then
                    beginEndElement = beginEndElement.AddLeadingSyntax(unexpected)
                Else
                    beginEndElement = AddLeadingSyntax(beginEndElement, unexpected, ERRID.ERR_ExpectedLT)
                End If
            End If

            If CurrentToken.Kind = SyntaxKind.XmlNameToken Then
                ' /* AllowExpr */' /* IsBracketed */' 
                name = DirectCast(ParseXmlQualifiedName(False, False, ScannerState.EndElement, ScannerState.EndElement), XmlNameSyntax)
            End If

            VerifyExpectedToken(SyntaxKind.GreaterThanToken, greaterToken, nextState)

            Return SyntaxFactory.XmlElementEndTag(beginEndElement, name, greaterToken)

        End Function

        ' File: Parser.cpp
        ' Lines: 13770 - 13770
        ' ExpressionList* .Parser::ParseXmlAttributes( [ bool AllowNameAsExpression ] [ _Inout_ bool& ErrorInConstruct ] )

        Private Function ParseXmlAttributes(requireLeadingWhitespace As Boolean, xmlElementName As XmlNodeSyntax) As CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of XmlNodeSyntax)

            Dim Attributes = Me._pool.Allocate(Of XmlNodeSyntax)()

            Do
                Select Case CurrentToken.Kind
                    Case SyntaxKind.XmlNameToken,
                        SyntaxKind.LessThanPercentEqualsToken,
                        SyntaxKind.EqualsToken,
                        SyntaxKind.SingleQuoteToken,
                        SyntaxKind.DoubleQuoteToken

                        Dim attribute = ParseXmlAttribute(requireLeadingWhitespace, AllowNameAsExpression:=True, xmlElementName:=xmlElementName)
                        Debug.Assert(attribute IsNot Nothing)

                        requireLeadingWhitespace = Not attribute.HasTrailingTrivia
                        Attributes.Add(attribute)

                    Case Else
                        Exit Do

                End Select
            Loop

            Dim result = Attributes.ToList
            Me._pool.Free(Attributes)
            Return result
        End Function

        ' File: Parser.cpp
        ' Lines: 13813 - 13813
        ' Expression* .Parser::ParseXmlAttribute( [ bool AllowNameAsExpression ] [ _Inout_ bool& ErrorInConstruct ] )
        Friend Function ParseXmlAttribute(requireLeadingWhitespace As Boolean, AllowNameAsExpression As Boolean, xmlElementName As XmlNodeSyntax) As XmlNodeSyntax
            Debug.Assert(IsToken(CurrentToken,
                                 SyntaxKind.XmlNameToken,
                                 SyntaxKind.LessThanPercentEqualsToken,
                                 SyntaxKind.EqualsToken,
                                 SyntaxKind.SingleQuoteToken,
                                 SyntaxKind.DoubleQuoteToken),
                             "ParseXmlAttribute called on wrong token.")

            Dim Result As XmlNodeSyntax = Nothing

            If CurrentToken.Kind = SyntaxKind.XmlNameToken OrElse
                (AllowNameAsExpression AndAlso CurrentToken.Kind = SyntaxKind.LessThanPercentEqualsToken) OrElse
                CurrentToken.Kind = SyntaxKind.EqualsToken OrElse
                CurrentToken.Kind = SyntaxKind.SingleQuoteToken OrElse
                CurrentToken.Kind = SyntaxKind.DoubleQuoteToken Then

                ' /* AllowExpr */' /* IsBracketed */' 
                Dim Name = ParseXmlQualifiedName(requireLeadingWhitespace, True, ScannerState.Element, ScannerState.Element)

                If CurrentToken.Kind = SyntaxKind.EqualsToken Then

                    Dim equals = DirectCast(CurrentToken, PunctuationSyntax)

                    GetNextToken(ScannerState.Element)

                    Dim value As XmlNodeSyntax = Nothing
                    If CurrentToken.Kind = SyntaxKind.LessThanPercentEqualsToken Then
                        ' // <%= expr %>
                        value = ParseXmlEmbedded(ScannerState.Element)
                        Result = SyntaxFactory.XmlAttribute(Name, equals, value)

                    ElseIf Not Me._scanner.IsScanningXmlDoc OrElse
                                Not TryParseXmlCrefAttributeValue(Name, equals, Result) AndAlso
                                Not TryParseXmlNameAttributeValue(Name, equals, Result, xmlElementName) Then

                        ' Try parsing as a string (quoted or unquoted)
                        value = ParseXmlString(ScannerState.Element)
                        Result = SyntaxFactory.XmlAttribute(Name, equals, value)
                    End If

                ElseIf Name.Kind = SyntaxKind.XmlEmbeddedExpression Then
                    ' // In this case, the Name is some expression which may evaluate to an attribute
                    Result = Name

                Else
                    ' // Names must be followed by an "="

                    Dim value As XmlNodeSyntax
                    If CurrentToken.Kind <> SyntaxKind.SingleQuoteToken AndAlso
                        CurrentToken.Kind <> SyntaxKind.DoubleQuoteToken Then

                        Dim missingQuote = DirectCast(InternalSyntaxFactory.MissingToken(SyntaxKind.SingleQuoteToken), PunctuationSyntax)
                        value = SyntaxFactory.XmlString(missingQuote, Nothing, missingQuote)
                    Else
                        ' Case of quoted string without attribute name
                        ' Try parsing as a string (quoted or unquoted)
                        value = ParseXmlString(ScannerState.Element)
                    End If

                    Result = SyntaxFactory.XmlAttribute(Name, DirectCast(HandleUnexpectedToken(SyntaxKind.EqualsToken), PunctuationSyntax), value)
                End If

            End If

            Return Result
        End Function

        Private Function ElementNameIsOneFromTheList(xmlElementName As XmlNodeSyntax, ParamArray names() As String) As Boolean
            If xmlElementName Is Nothing OrElse xmlElementName.Kind <> SyntaxKind.XmlName Then
                Return False
            End If

            Dim xmlName = DirectCast(xmlElementName, XmlNameSyntax)
            If xmlName.Prefix IsNot Nothing Then
                Return False
            End If

            For Each name In names
                If DocumentationCommentXmlNames.ElementEquals(xmlName.LocalName.Text, name, True) Then
                    Return True
                End If
            Next
            Return False
        End Function

        Private Function TryParseXmlCrefAttributeValue(name As XmlNodeSyntax, equals As PunctuationSyntax, <Out> ByRef crefAttribute As XmlNodeSyntax) As Boolean
            Debug.Assert(Me._scanner.IsScanningXmlDoc)

            If name.Kind <> SyntaxKind.XmlName Then
                Return False
            End If

            Dim xmlName = DirectCast(name, XmlNameSyntax)
            If xmlName.Prefix IsNot Nothing OrElse
                    Not DocumentationCommentXmlNames.AttributeEquals(xmlName.LocalName.Text,
                                                                     DocumentationCommentXmlNames.CrefAttributeName) Then
                Return False
            End If

            ' NOTE: we don't check the parent, seems 'cref' attribute is supported 
            ' NOTE: for any nodes even user-defined ones

            Dim state As ScannerState
            Dim startQuote As PunctuationSyntax

            If CurrentToken.Kind = SyntaxKind.SingleQuoteToken Then
                state = If(CurrentToken.Text = "'"c, ScannerState.SingleQuotedString, ScannerState.SmartSingleQuotedString)
                startQuote = DirectCast(CurrentToken, PunctuationSyntax)
            ElseIf CurrentToken.Kind = SyntaxKind.DoubleQuoteToken Then
                state = If(CurrentToken.Text = """"c, ScannerState.QuotedString, ScannerState.SmartQuotedString)
                startQuote = DirectCast(CurrentToken, PunctuationSyntax)
            Else
                Return False
            End If

            ' If we have any problems with parsing the name we want to restore the scanner and 
            ' fall back to a regular attribute scenario
            Dim restorePoint As Scanner.RestorePoint = Me._scanner.CreateRestorePoint()

            Dim nextToken = Me.PeekNextToken(state)
            If Not (nextToken.Kind = SyntaxKind.XmlTextLiteralToken OrElse nextToken.Kind = SyntaxKind.XmlEntityLiteralToken) Then
                GoTo lFailed
            End If

            Dim text As String = nextToken.Text.Trim()
            If text.Length >= 2 AndAlso text(0) <> ":" AndAlso text(1) = ":" Then
                GoTo lFailed
            End If

            ' The code above is supposed to reflect how Dev11 detects and verifies 'cref' attribute on the node
            ' See also: XmlDocFile.cpp, XMLDocNode::VerifyCRefAttributeOnNode(...)

            ' Eat the quotation mark, note that default context is being used here...
            GetNextToken()

            ' The next portion of attribute value should be parsed as Name

            Dim crefReference As CrefReferenceSyntax

            ' If can be either a VB intrinsic type or a proper optionally qualified name
            ' See also: XmlDocFile.cpp, XMLDocNode::PerformActualBinding
            If SyntaxFacts.IsPredefinedTypeKeyword(Me.CurrentToken.Kind) Then
                Dim type As PredefinedTypeSyntax = SyntaxFactory.PredefinedType(DirectCast(CurrentToken, KeywordSyntax))

                ' We need to move to the next token as ParseName(...) does 
                GetNextToken()

                crefReference = SyntaxFactory.CrefReference(type, Nothing, Nothing)

            Else
                crefReference = Me.TryParseCrefReference()
            End If

            If crefReference Is Nothing Then
                GoTo lFailed
            End If

            ' We need to reset the current token and possibly peeked tokens because those 
            ' were created using default scanner state, but we want to see from this 
            ' point tokens received using custom scanner state saved in 'state'
            Me.ResetCurrentToken(state)

            Do
                Select Case Me.CurrentToken.Kind
                    Case SyntaxKind.SingleQuoteToken,
                         SyntaxKind.DoubleQuoteToken

                        Dim endQuote = DirectCast(CurrentToken, PunctuationSyntax)
                        GetNextToken(ScannerState.Element)
                        crefAttribute = SyntaxFactory.XmlCrefAttribute(xmlName, equals, startQuote, crefReference, endQuote)
                        Return True

                    Case SyntaxKind.XmlTextLiteralToken,
                         SyntaxKind.XmlEntityLiteralToken

                        Dim token As SyntaxToken = CurrentToken

                        If TriviaChecker.HasInvalidTrivia(token) Then
                            GoTo lFailed
                        End If

                        crefReference = crefReference.AddTrailingSyntax(token)
                        crefReference.ClearFlags(GreenNode.NodeFlags.ContainsDiagnostics)
                        GetNextToken(state)
                        Continue Do

                    Case SyntaxKind.EndOfXmlToken,
                         SyntaxKind.EndOfFileToken

                        Dim endQuote = DirectCast(InternalSyntaxFactory.MissingToken(startQuote.Kind), PunctuationSyntax)
                        crefAttribute = SyntaxFactory.XmlCrefAttribute(xmlName, equals, startQuote, crefReference, endQuote)
                        Return True

                End Select
                Exit Do
            Loop

lFailed:
            restorePoint.Restore()
            Me.ResetCurrentToken(ScannerState.Element)
            Return False
        End Function

        Friend Function TryParseCrefReference() As CrefReferenceSyntax
            ' Mandatory name part
            Dim name As TypeSyntax = TryParseCrefOptionallyQualifiedName()
            Debug.Assert(name IsNot Nothing)

            Dim signature As CrefSignatureSyntax = Nothing
            Dim asClause As SimpleAsClauseSyntax = Nothing

            If CurrentToken.Kind = SyntaxKind.OpenParenToken AndAlso name.Kind <> SyntaxKind.PredefinedType Then
                ' Optional signature and As clause
                signature = TryParseCrefReferenceSignature()
                Debug.Assert(signature IsNot Nothing)

                ' NOTE: 'As' clause is only allowed if signature specified
                If CurrentToken.Kind = SyntaxKind.AsKeyword Then
                    Dim asKeyword As KeywordSyntax = DirectCast(CurrentToken, KeywordSyntax)
                    GetNextToken()

                    Dim returnType As TypeSyntax = ParseGeneralType()
                    Debug.Assert(returnType IsNot Nothing)

                    asClause = SyntaxFactory.SimpleAsClause(asKeyword, Nothing, returnType)
                End If
            End If

            Dim result As CrefReferenceSyntax = SyntaxFactory.CrefReference(name, signature, asClause)

            ' Even if there are diagnostics in name we don't report them, they will be 
            ' reported later in Documentation comment binding
            If result.ContainsDiagnostics Then
                result.ClearFlags(GreenNode.NodeFlags.ContainsDiagnostics)
            End If

            Return result
        End Function

        Friend Function TryParseCrefReferenceSignature() As CrefSignatureSyntax
            '('
            Debug.Assert(CurrentToken.Kind = SyntaxKind.OpenParenToken)
            Dim openParen As PunctuationSyntax = DirectCast(CurrentToken, PunctuationSyntax)
            GetNextToken()

            Dim signatureTypes = _pool.AllocateSeparated(Of CrefSignaturePartSyntax)()
            Dim firstType As Boolean = True

            Do
                Dim currToken As SyntaxToken = Me.CurrentToken

                If currToken.Kind <> SyntaxKind.CloseParenToken AndAlso currToken.Kind <> SyntaxKind.CommaToken AndAlso Not firstType Then
                    ' In case we expect ')' or ',' but don't find one, we consider this an end of 
                    ' the signature, add a missing '(' and exit parsing 
                    currToken = InternalSyntaxFactory.MissingToken(SyntaxKind.CloseParenToken)
                End If

                If currToken.Kind = SyntaxKind.CloseParenToken Then
                    ' ')', we are done
                    Dim closeParen As PunctuationSyntax = DirectCast(currToken, PunctuationSyntax)
                    If Not currToken.IsMissing Then
                        ' Only move to the next token if this is a non-missing one
                        GetNextToken()
                    End If

                    Dim typeArguments As CodeAnalysis.Syntax.InternalSyntax.SeparatedSyntaxList(Of CrefSignaturePartSyntax) = signatureTypes.ToList
                    _pool.Free(signatureTypes)

                    Return SyntaxFactory.CrefSignature(openParen, typeArguments, closeParen)
                End If

                If firstType Then
                    firstType = False
                Else
                    Debug.Assert(CurrentToken.Kind = SyntaxKind.CommaToken)
                    signatureTypes.AddSeparator(CurrentToken)
                    GetNextToken()
                End If

                Dim modifier As KeywordSyntax = Nothing
                While CurrentToken.Kind = SyntaxKind.ByValKeyword OrElse CurrentToken.Kind = SyntaxKind.ByRefKeyword
                    If modifier Is Nothing Then
                        ' The first one
                        modifier = DirectCast(CurrentToken, KeywordSyntax)
                    Else
                        ' Add diagnostics for all other modifiers
                        modifier = modifier.AddTrailingSyntax(CurrentToken, ERRID.ERR_InvalidParameterSyntax)
                    End If

                    GetNextToken()
                End While

                Dim typeName As TypeSyntax = ParseGeneralType(allowEmptyGenericArguments:=False)
                Debug.Assert(typeName IsNot Nothing)

                signatureTypes.Add(SyntaxFactory.CrefSignaturePart(modifier, typeName))
            Loop

            Throw ExceptionUtilities.Unreachable
        End Function

        Friend Function TryParseCrefOperatorName() As CrefOperatorReferenceSyntax
            Dim operatorKeyword As KeywordSyntax = DirectCast(CurrentToken, KeywordSyntax)
            Debug.Assert(operatorKeyword.Kind = SyntaxKind.OperatorKeyword)
            GetNextToken()

            Dim keyword As KeywordSyntax = Nothing
            Dim operatorToken As SyntaxToken

            If TryTokenAsContextualKeyword(CurrentToken, keyword) Then
                operatorToken = keyword
            Else
                operatorToken = CurrentToken
            End If

            Dim operatorKind As SyntaxKind = operatorToken.Kind

            If SyntaxFacts.IsOperatorStatementOperatorToken(operatorKind) Then
                GetNextToken()
            Else
                operatorToken = ReportSyntaxError(InternalSyntaxFactory.MissingToken(SyntaxKind.PlusToken), ERRID.ERR_UnknownOperator)
            End If

            Return SyntaxFactory.CrefOperatorReference(operatorKeyword, operatorToken)
        End Function

        Friend Function TryParseCrefOptionallyQualifiedName() As TypeSyntax
            Dim result As NameSyntax = Nothing

            ' Parse head: Either a GlobalName or a SimpleName.
            If CurrentToken.Kind = SyntaxKind.GlobalKeyword Then
                result = SyntaxFactory.GlobalName(DirectCast(CurrentToken, KeywordSyntax))
                GetNextToken()

            ElseIf CurrentToken.Kind = SyntaxKind.ObjectKeyword Then
                ' Dev11 treats type 'object' quite in a weird way, thus [cref="object"] and 
                ' [cref="system.object"] will both be resolved into "T:System.Object", but 
                ' while [cref="system.object.tostring"] is resolved into "M:System.Object.ToString", 
                ' [cref="object.tostring"] produces an error. We fix this in Roslyn
                result = SyntaxFactory.IdentifierName(
                            Me._scanner.MakeIdentifier(
                                DirectCast(Me.CurrentToken, KeywordSyntax)))
                GetNextToken()

            ElseIf CurrentToken.Kind = SyntaxKind.OperatorKeyword Then
                ' Operator reference like 'Operator+(...)' cannot be followed by 'dot'
                Return TryParseCrefOperatorName()

            ElseIf CurrentToken.Kind = SyntaxKind.NewKeyword Then
                ' Constructor reference like 'New(...)' cannot be followed by 'dot'
                Return ParseSimpleName(
                    allowGenericArguments:=False,
                    allowGenericsWithoutOf:=False,
                    disallowGenericArgumentsOnLastQualifiedName:=True,
                    allowKeyword:=True,
                    nonArrayName:=False,
                    allowEmptyGenericArguments:=False,
                    allowNonEmptyGenericArguments:=True)

            Else
                Debug.Assert(Not SyntaxFacts.IsPredefinedTypeKeyword(CurrentToken.Kind))

                result = ParseSimpleName(
                    allowGenericArguments:=True,
                    allowGenericsWithoutOf:=False,
                    disallowGenericArgumentsOnLastQualifiedName:=False,
                    allowKeyword:=False,
                    nonArrayName:=False,
                    allowEmptyGenericArguments:=False,
                    allowNonEmptyGenericArguments:=True)
            End If

            Debug.Assert(result IsNot Nothing)

            ' Parse tail: A sequence of zero or more [dot SimpleName].
            While CurrentToken.Kind = SyntaxKind.DotToken
                Dim dotToken As PunctuationSyntax = DirectCast(CurrentToken, PunctuationSyntax)
                GetNextToken()

                If CurrentToken.Kind = SyntaxKind.OperatorKeyword Then
                    ' Operator reference like 'Clazz.Operator+(...)' cannot be followed by 'dot'
                    Dim operatorReference As CrefOperatorReferenceSyntax = TryParseCrefOperatorName()
                    Debug.Assert(operatorReference IsNot Nothing)
                    Return SyntaxFactory.QualifiedCrefOperatorReference(result, dotToken, operatorReference)

                Else
                    Dim simpleName As SimpleNameSyntax =
                        ParseSimpleName(
                            allowGenericArguments:=True,
                            allowGenericsWithoutOf:=False,
                            disallowGenericArgumentsOnLastQualifiedName:=False,
                            allowKeyword:=True,
                            nonArrayName:=False,
                            allowEmptyGenericArguments:=False,
                            allowNonEmptyGenericArguments:=True)

                    result = SyntaxFactory.QualifiedName(result, dotToken, simpleName)
                End If
            End While

            Return result
        End Function

        Private Function TryParseXmlNameAttributeValue(name As XmlNodeSyntax, equals As PunctuationSyntax, <Out> ByRef nameAttribute As XmlNodeSyntax, xmlElementName As XmlNodeSyntax) As Boolean
            Debug.Assert(Me._scanner.IsScanningXmlDoc)

            If name.Kind <> SyntaxKind.XmlName Then
                Return False
            End If

            Dim xmlName = DirectCast(name, XmlNameSyntax)
            If xmlName.Prefix IsNot Nothing OrElse
                    Not DocumentationCommentXmlNames.AttributeEquals(xmlName.LocalName.Text,
                                                                     DocumentationCommentXmlNames.NameAttributeName) Then
                Return False
            End If

            If Not ElementNameIsOneFromTheList(xmlElementName,
                                             DocumentationCommentXmlNames.ParameterElementName,
                                             DocumentationCommentXmlNames.ParameterReferenceElementName,
                                             DocumentationCommentXmlNames.TypeParameterElementName,
                                             DocumentationCommentXmlNames.TypeParameterReferenceElementName) Then
                Return False
            End If

            Dim state As ScannerState
            Dim startQuote As PunctuationSyntax

            If CurrentToken.Kind = SyntaxKind.SingleQuoteToken Then
                state = If(CurrentToken.Text = "'"c, ScannerState.SingleQuotedString, ScannerState.SmartSingleQuotedString)
                startQuote = DirectCast(CurrentToken, PunctuationSyntax)
            ElseIf CurrentToken.Kind = SyntaxKind.DoubleQuoteToken Then
                state = If(CurrentToken.Text = """"c, ScannerState.QuotedString, ScannerState.SmartQuotedString)
                startQuote = DirectCast(CurrentToken, PunctuationSyntax)
            Else
                Return False
            End If

            ' If we have any problems with parsing the name we want to restore the scanner and 
            ' fall back to a regular attribute scenario
            Dim restorePoint As Scanner.RestorePoint = Me._scanner.CreateRestorePoint()

            ' Eat the quotation mark, note that default context is being used here...
            GetNextToken()

            Dim identToken As SyntaxToken = CurrentToken
            If identToken.Kind <> SyntaxKind.IdentifierToken Then
                If identToken.IsKeyword Then
                    identToken = Me._scanner.MakeIdentifier(DirectCast(Me.CurrentToken, KeywordSyntax))
                Else
                    GoTo lFailed
                End If
            End If

            If identToken.ContainsDiagnostics() Then
                GoTo lFailed
            End If

            If TriviaChecker.HasInvalidTrivia(identToken) Then
                GoTo lFailed
            End If

            ' Move to the next token which is supposed to be a closing quote
            GetNextToken(state)

            Dim closingToken As SyntaxToken = Me.CurrentToken
            If closingToken.Kind = SyntaxKind.SingleQuoteToken OrElse closingToken.Kind = SyntaxKind.DoubleQuoteToken Then
                Dim endQuote = DirectCast(CurrentToken, PunctuationSyntax)
                GetNextToken(ScannerState.Element)
                nameAttribute = SyntaxFactory.XmlNameAttribute(xmlName,
                                                               equals,
                                                               startQuote,
                                                               SyntaxFactory.IdentifierName(DirectCast(identToken, IdentifierTokenSyntax)),
                                                               endQuote)
                Return True
            End If

lFailed:
            restorePoint.Restore()
            Me.ResetCurrentToken(ScannerState.Element)
            Return False
        End Function

        ''' <summary>
        ''' Checks if the resulting Cref or Name attribute value has valid trivia
        ''' Note, this may be applicable not only to regular trivia, but also to syntax 
        ''' nodes added to trivia when the parser was recovering from errors
        ''' </summary>
        Private Class TriviaChecker

            Private Sub New()
            End Sub

            Public Shared Function HasInvalidTrivia(node As GreenNode) As Boolean
                Return SyntaxNodeOrTokenHasInvalidTrivia(node)
            End Function

            Private Shared Function SyntaxNodeOrTokenHasInvalidTrivia(node As GreenNode) As Boolean
                If node IsNot Nothing Then
                    Dim token As SyntaxToken = TryCast(node, SyntaxToken)
                    If token IsNot Nothing Then
                        If IsInvalidTrivia(token.GetLeadingTrivia) OrElse IsInvalidTrivia(token.GetTrailingTrivia) Then
                            Return True
                        End If

                    ElseIf SyntaxNodeHasInvalidTrivia(node) Then
                        Return True
                    End If
                End If
                Return False
            End Function

            Private Shared Function SyntaxNodeHasInvalidTrivia(node As GreenNode) As Boolean
                For index = 0 To node.SlotCount - 1
                    If SyntaxNodeOrTokenHasInvalidTrivia(node.GetSlot(index)) Then
                        Return True
                    End If
                Next
                Return False
            End Function

            Private Shared Function IsInvalidTrivia(node As GreenNode) As Boolean
                If node IsNot Nothing Then
                    Select Case node.RawKind
                        Case SyntaxKind.List
                            For index = 0 To node.SlotCount - 1
                                If IsInvalidTrivia(node.GetSlot(index)) Then
                                    Return True
                                End If
                            Next

                        Case SyntaxKind.WhitespaceTrivia
                            ' TODO: The following is simplified, need to be revised
                            Dim whitespace As String = DirectCast(node, SyntaxTrivia).Text
                            For Each ch In whitespace
                                If ch <> " "c AndAlso ch <> ChrW(9) Then
                                    Return True
                                End If
                            Next

                        Case SyntaxKind.SkippedTokensTrivia
                            If SyntaxNodeOrTokenHasInvalidTrivia(DirectCast(node, SkippedTokensTriviaSyntax).Tokens.Node) Then
                                Return True
                            End If

                        Case Else
                            Return True

                    End Select

                End If
                Return False
            End Function
        End Class

        ' File: Parser.cpp
        ' Lines: 13931 - 13931
        ' Expression* .Parser::ParseXmlQualifiedName( [ bool AllowExpr ] [ bool IsBracketed ] [ bool IsElementName ] [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlQualifiedName(
            requireLeadingWhitespace As Boolean,
            allowExpr As Boolean,
            stateForName As ScannerState,
            nextState As ScannerState
        ) As XmlNodeSyntax
            Select Case (CurrentToken.Kind)

                Case SyntaxKind.XmlNameToken
                    Return ParseXmlQualifiedName(requireLeadingWhitespace, stateForName, nextState)

                Case SyntaxKind.LessThanPercentEqualsToken
                    If allowExpr Then
                        ' // <%= expr %>
                        Return ParseXmlEmbedded(nextState)
                    End If

            End Select

            ResetCurrentToken(nextState)
            Return ReportExpectedXmlName()
        End Function

        Private Function ParseXmlQualifiedName(requireLeadingWhitespace As Boolean, stateForName As ScannerState, nextState As ScannerState) As XmlNodeSyntax

            Dim hasPrecedingWhitespace = requireLeadingWhitespace AndAlso
                (PrevToken.GetTrailingTrivia.ContainsWhitespaceTrivia() OrElse CurrentToken.GetLeadingTrivia.ContainsWhitespaceTrivia)

            Dim localName = DirectCast(CurrentToken, XmlNameTokenSyntax)
            GetNextToken(stateForName)

            If requireLeadingWhitespace AndAlso Not hasPrecedingWhitespace Then
                localName = ReportSyntaxError(localName, ERRID.ERR_ExpectedXmlWhiteSpace)
            End If

            Dim prefix As XmlPrefixSyntax = Nothing

            If CurrentToken.Kind = SyntaxKind.ColonToken Then

                Dim colon As PunctuationSyntax = DirectCast(CurrentToken, PunctuationSyntax)
                GetNextToken(stateForName)
                prefix = SyntaxFactory.XmlPrefix(localName, colon)

                If CurrentToken.Kind = SyntaxKind.XmlNameToken Then

                    localName = DirectCast(CurrentToken, XmlNameTokenSyntax)
                    GetNextToken(stateForName)

                    If colon.HasTrailingTrivia OrElse
                        localName.HasLeadingTrivia Then

                        localName = ReportSyntaxError(localName, ERRID.ERR_ExpectedXmlName)
                    End If

                Else
                    localName = ReportSyntaxError(InternalSyntaxFactory.XmlNameToken("", SyntaxKind.XmlNameToken, Nothing, Nothing), ERRID.ERR_ExpectedXmlName)

                End If

            End If

            Dim name = SyntaxFactory.XmlName(prefix, localName)
            ResetCurrentToken(nextState)
            Return name
        End Function

        ''' <summary>
        ''' Checks if the given <paramref name="node"/> is a colon trivia whose string representation is the COLON (U+003A) character from ASCII range
        ''' (specifically excluding cases when it is the FULLWIDTH COLON (U+FF1A) character).
        ''' See also: http://fileformat.info/info/unicode/char/FF1A
        ''' </summary>
        ''' <param name="node">A VB syntax node to check.</param>
        Private Shared Function IsAsciiColonTrivia(node As VisualBasicSyntaxNode) As Boolean
            Return node.Kind = SyntaxKind.ColonTrivia AndAlso node.ToString() = ":"
        End Function

        Private Function ParseXmlQualifiedNameVB() As XmlNameSyntax

            If Not IsValidXmlQualifiedNameToken(CurrentToken) Then
                Return ReportExpectedXmlName()
            End If

            Dim localName = ToXmlNameToken(CurrentToken)
            GetNextToken(ScannerState.VB)

            Dim prefix As XmlPrefixSyntax = Nothing

            ' Because this token was scanned in VB mode, it may have colon token trivia on the end. Because the colon may
            ' be part of an Xml name remove the colon from the trivia if it exists. Also, get the next token in Element state
            ' so that the colon appears as a normal token. A colon may come after the identifier if and only if it is the only
            ' trivia following the identifier.  If there is any trivia before the colon then the colon should stay as trivia
            ' and be interpreted as a colon token terminator.  If there is any trivia following the colon, this is an error.
            ' Note that only the COLON (U+003A) character, but not the FULLWIDTH COLON (U+FF1A), may be a part of an XML name, 
            ' although they both may be represented by a node with kind SyntaxKind.ColonTrivia.

            Dim trailingTrivia = New CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of VisualBasicSyntaxNode)(localName.GetTrailingTrivia())
            If trailingTrivia.Count > 0 AndAlso IsAsciiColonTrivia(trailingTrivia(0)) Then

                Debug.Assert(trailingTrivia.Last.Kind = SyntaxKind.ColonTrivia)
                Debug.Assert(CurrentToken.FullWidth = 0)

                ' Remove trailing colon trivia from the identifier
                trailingTrivia = trailingTrivia.GetStartOfTrivia(trailingTrivia.Count - 1)
                localName = SyntaxFactory.XmlNameToken(localName.Text, localName.PossibleKeywordKind, localName.GetLeadingTrivia(), trailingTrivia.Node).WithDiagnostics(localName.GetDiagnostics())

                ' Get the colon as an Xml colon token, then transition back to VB.
                ResetCurrentToken(ScannerState.Element)
                Dim colon = DirectCast(CurrentToken, PunctuationSyntax)
                GetNextToken(ScannerState.Element)
                colon = TransitionFromXmlToVB(colon)

                prefix = SyntaxFactory.XmlPrefix(localName, colon)
                localName = Nothing

                If trailingTrivia.Count = 0 AndAlso Not colon.HasTrailingTrivia() AndAlso
                    IsValidXmlQualifiedNameToken(CurrentToken) Then

                    localName = ToXmlNameToken(CurrentToken)
                    GetNextToken(ScannerState.VB)
                End If

                If localName Is Nothing Then
                    localName = ReportSyntaxError(InternalSyntaxFactory.XmlNameToken("", SyntaxKind.XmlNameToken, Nothing, Nothing), ERRID.ERR_ExpectedXmlName)
                End If
            End If

            Return SyntaxFactory.XmlName(prefix, localName)
        End Function

        Private Shared Function IsValidXmlQualifiedNameToken(token As SyntaxToken) As Boolean
            Return token.Kind = SyntaxKind.IdentifierToken OrElse TryCast(token, KeywordSyntax) IsNot Nothing
        End Function

        Private Function ToXmlNameToken(token As SyntaxToken) As XmlNameTokenSyntax

            If token.Kind = SyntaxKind.IdentifierToken Then
                Dim id = DirectCast(token, IdentifierTokenSyntax)
                Dim name = SyntaxFactory.XmlNameToken(id.Text, id.PossibleKeywordKind, token.GetLeadingTrivia(), token.GetTrailingTrivia())

                ' Xml names should not be escaped
                If id.IsBracketed Then
                    name = ReportSyntaxError(name, ERRID.ERR_ExpectedXmlName)
                Else
                    name = VerifyXmlNameToken(name)
                End If

                Return name

            Else
                ' This is the keyword case
                Debug.Assert(TryCast(token, KeywordSyntax) IsNot Nothing)
                Return SyntaxFactory.XmlNameToken(token.Text, token.Kind, token.GetLeadingTrivia(), token.GetTrailingTrivia())

            End If
        End Function

        Private Shared Function VerifyXmlNameToken(tk As XmlNameTokenSyntax) As XmlNameTokenSyntax
            Dim text = tk.ValueText

            If Not String.IsNullOrEmpty(text) Then
                If Not isStartNameChar(text(0)) Then
                    Dim ch = text(0)
                    Return ReportSyntaxError(tk,
                        ERRID.ERR_IllegalXmlStartNameChar,
                        ch,
                        "0x" & Convert.ToInt32(ch).ToString("X4"))
                End If

                For Each ch In text
                    If Not isNameChar(ch) Then
                        Return ReportSyntaxError(tk,
                            ERRID.ERR_IllegalXmlNameChar,
                            ch,
                            "0x" & Convert.ToInt32(ch).ToString("X4"))
                    End If
                Next
            End If

            Return tk
        End Function

        Friend Function ParseRestOfDocCommentContent(nodesSoFar As CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of GreenNode)) As CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of XmlNodeSyntax)
            Dim content = Me._pool.Allocate(Of XmlNodeSyntax)()

            For Each node In nodesSoFar.Nodes
                content.Add(DirectCast(node, XmlNodeSyntax))
            Next

            If CurrentToken.Kind = SyntaxKind.EndOfXmlToken Then
                GetNextToken(ScannerState.Content)

                If CurrentToken.Kind = SyntaxKind.DocumentationCommentLineBreakToken Then
                    Dim tempNodes = ParseXmlContent(ScannerState.Content)
                    Debug.Assert(tempNodes.Nodes.Length = 1)

                    For Each node In tempNodes.Nodes
                        content.Add(node)
                    Next
                End If
            End If

            Dim result = content.ToList
            Me._pool.Free(content)

            Return result
        End Function

        ' File: Parser.cpp
        ' Lines: 14004 - 14004
        ' ExpressionList* .Parser::ParseXmlContent( [ _Inout_ ParseTree::XmlElementExpression* Parent ] [ _Inout_ bool& ErrorInConstruct ] )
        Friend Function ParseXmlContent(state As ScannerState) As CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of XmlNodeSyntax)
            Debug.Assert(IsToken(CurrentToken,
                                 SyntaxKind.XmlTextLiteralToken,
                                 SyntaxKind.DocumentationCommentLineBreakToken,
                                 SyntaxKind.XmlEntityLiteralToken,
                                 SyntaxKind.LessThanToken,
                                 SyntaxKind.LessThanSlashToken,
                                 SyntaxKind.LessThanExclamationMinusMinusToken,
                                 SyntaxKind.LessThanQuestionToken,
                                 SyntaxKind.LessThanPercentEqualsToken,
                                 SyntaxKind.BeginCDataToken,
                                 SyntaxKind.EndCDataToken,
                                 SyntaxKind.EndOfFileToken,
                                 SyntaxKind.EndOfXmlToken,
                                 SyntaxKind.BadToken),
                             "ParseXmlContent called on wrong token.")

            Dim Content = Me._pool.Allocate(Of XmlNodeSyntax)()
            Dim whitespaceChecker As New XmlWhitespaceChecker()
            Dim xml As XmlNodeSyntax

            Do
                Select Case (CurrentToken.Kind)

                    Case SyntaxKind.LessThanToken
                        xml = ParseXmlElement(ScannerState.Content)

                    Case SyntaxKind.LessThanSlashToken
                        xml = ReportSyntaxError(ParseXmlElementEndTag(ScannerState.Content), ERRID.ERR_XmlEndElementNoMatchingStart)

                    Case SyntaxKind.LessThanExclamationMinusMinusToken
                        xml = ParseXmlComment(ScannerState.Content)

                    Case SyntaxKind.LessThanQuestionToken
                        xml = ParseXmlProcessingInstruction(ScannerState.Content, whitespaceChecker)

                    Case SyntaxKind.BeginCDataToken
                        xml = ParseXmlCData(ScannerState.Content)

                    Case SyntaxKind.LessThanPercentEqualsToken
                        xml = ParseXmlEmbedded(ScannerState.Content)

                    Case SyntaxKind.XmlTextLiteralToken,
                        SyntaxKind.XmlEntityLiteralToken,
                        SyntaxKind.DocumentationCommentLineBreakToken

                        Dim newKind As SyntaxKind
                        Dim textTokens = _pool.Allocate(Of XmlTextTokenSyntax)()
                        Do
                            textTokens.Add(DirectCast(CurrentToken, XmlTextTokenSyntax))
                            GetNextToken(ScannerState.Content)

                            newKind = CurrentToken.Kind
                        Loop While newKind = SyntaxKind.XmlTextLiteralToken OrElse
                            newKind = SyntaxKind.XmlEntityLiteralToken OrElse
                            newKind = SyntaxKind.DocumentationCommentLineBreakToken

                        Dim textResult = textTokens.ToList
                        _pool.Free(textTokens)
                        xml = SyntaxFactory.XmlText(textResult)

                    Case SyntaxKind.EndOfFileToken,
                         SyntaxKind.EndOfXmlToken
                        Exit Do

                    Case SyntaxKind.BadToken
                        Dim badToken = DirectCast(CurrentToken, BadTokenSyntax)

                        If badToken.SubKind = SyntaxSubKind.BeginDocTypeToken Then
                            Dim docTypeTrivia = ParseXmlDocType(ScannerState.Element)
                            xml = SyntaxFactory.XmlText(InternalSyntaxFactory.MissingToken(SyntaxKind.XmlTextLiteralToken))
                            xml = xml.AddLeadingSyntax(docTypeTrivia, ERRID.ERR_DTDNotSupported)
                        Else
                            ' Let resync handle it
                            GoTo TryResync
                        End If

                    Case Else
TryResync:
                        ' when parsing XmlDoc there may not be outer context to take care of garbage
                        If state = ScannerState.Content Then
                            xml = ResyncXmlContent()
                        Else
                            Exit Do
                        End If

                End Select

                Content.Add(xml)
            Loop

            Dim result = Content.ToList
            Me._pool.Free(Content)

            Return result
        End Function

        ' File: Parser.cpp
        ' Lines: 14078 - 14078
        ' Expression* .Parser::ParseXmlPI( [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlProcessingInstruction(nextState As ScannerState, whitespaceChecker As XmlWhitespaceChecker) As XmlProcessingInstructionSyntax
            Debug.Assert(CurrentToken.Kind = SyntaxKind.LessThanQuestionToken, "ParseXmlPI called on the wrong token.")

            Dim beginProcessingInstruction = DirectCast(CurrentToken, PunctuationSyntax)

            GetNextToken(ScannerState.Element)

            'TODO - handle whitespace between begin and name. This check is also needed for xml document declaration
            ' Consider adding a special state for the xml document/pi that does not add trivia to tokens.

            Dim name As XmlNameTokenSyntax = Nothing

            'TODO - name has to allow :. Dev10 puts a fully qualified name here.
            If Not VerifyExpectedToken(SyntaxKind.XmlNameToken, name, ScannerState.StartProcessingInstruction) Then

                ' In case there wasn't a name in the PI and the scanner returned another token from the element state,
                ' the current token must be reset to a processing instruction token.
                ResetCurrentToken(ScannerState.StartProcessingInstruction)

            End If

            If name.Text.Length = 3 AndAlso String.Equals(name.Text, "xml", StringComparison.OrdinalIgnoreCase) Then
                name = ReportSyntaxError(name, ERRID.ERR_IllegalProcessingInstructionName, name.Text)
            End If

            Dim textToken As XmlTextTokenSyntax = Nothing
            Dim values = _pool.Allocate(Of XmlTextTokenSyntax)()

            If CurrentToken.Kind = SyntaxKind.XmlTextLiteralToken OrElse CurrentToken.Kind = SyntaxKind.DocumentationCommentLineBreakToken Then
                textToken = DirectCast(CurrentToken, XmlTextTokenSyntax)

                If Not name.IsMissing AndAlso
                    Not name.GetTrailingTrivia.ContainsWhitespaceTrivia() AndAlso
                    Not textToken.GetLeadingTrivia.ContainsWhitespaceTrivia() Then
                    textToken = ReportSyntaxError(textToken, ERRID.ERR_ExpectedXmlWhiteSpace)
                End If

                Do
                    values.Add(textToken)
                    GetNextToken(ScannerState.ProcessingInstruction)
                    If CurrentToken.Kind <> SyntaxKind.XmlTextLiteralToken AndAlso CurrentToken.Kind <> SyntaxKind.DocumentationCommentLineBreakToken Then
                        Exit Do
                    End If
                    textToken = DirectCast(CurrentToken, XmlTextTokenSyntax)
                Loop
            End If

            Dim endProcessingInstruction As PunctuationSyntax = Nothing
            VerifyExpectedToken(SyntaxKind.QuestionGreaterThanToken, endProcessingInstruction, nextState)

            Dim result = SyntaxFactory.XmlProcessingInstruction(beginProcessingInstruction, name, values.ToList, endProcessingInstruction)

            result = DirectCast(whitespaceChecker.Visit(result), XmlProcessingInstructionSyntax)

            _pool.Free(values)

            Return result
        End Function

        ' File: Parser.cpp
        ' Lines: 14119 - 14119
        ' Expression* .Parser::ParseXmlCData( [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlCData(nextState As ScannerState) As XmlCDataSectionSyntax
            Debug.Assert(CurrentToken.Kind = SyntaxKind.BeginCDataToken, "ParseXmlCData called on the wrong token.")

            Dim beginCData = DirectCast(CurrentToken, PunctuationSyntax)

            GetNextToken(ScannerState.CData)

            Dim values = _pool.Allocate(Of XmlTextTokenSyntax)()

            Do While CurrentToken.Kind = SyntaxKind.XmlTextLiteralToken OrElse CurrentToken.Kind = SyntaxKind.DocumentationCommentLineBreakToken
                values.Add(DirectCast(CurrentToken, XmlTextTokenSyntax))
                GetNextToken(ScannerState.CData)
            Loop

            Dim endCData As PunctuationSyntax = Nothing
            VerifyExpectedToken(SyntaxKind.EndCDataToken, endCData, nextState)

            Dim result = values.ToList
            _pool.Free(values)

            Return SyntaxFactory.XmlCDataSection(beginCData, result, endCData)
        End Function

        ' File: Parser.cpp
        ' Lines: 14134 - 14134
        ' Expression* .Parser::ParseXmlComment( [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlComment(nextState As ScannerState) As XmlNodeSyntax
            Debug.Assert(CurrentToken.Kind = SyntaxKind.LessThanExclamationMinusMinusToken, "ParseXmlComment called on wrong token.")

            Dim beginComment As PunctuationSyntax = DirectCast(CurrentToken, PunctuationSyntax)
            GetNextToken(ScannerState.Comment)

            Dim values = _pool.Allocate(Of XmlTextTokenSyntax)()

            Do While CurrentToken.Kind = SyntaxKind.XmlTextLiteralToken OrElse CurrentToken.Kind = SyntaxKind.DocumentationCommentLineBreakToken
                Dim textToken = DirectCast(CurrentToken, XmlTextTokenSyntax)
                If textToken.Text.Length = 2 AndAlso textToken.Text = "--" Then
                    textToken = ReportSyntaxError(textToken, ERRID.ERR_IllegalXmlCommentChar)
                End If
                values.Add(textToken)
                GetNextToken(ScannerState.Comment)
            Loop

            Dim endComment As PunctuationSyntax = Nothing
            VerifyExpectedToken(SyntaxKind.MinusMinusGreaterThanToken, endComment, nextState)

            Dim result = values.ToList
            _pool.Free(values)

            Return SyntaxFactory.XmlComment(beginComment, result, endComment)
        End Function

        ' File: Parser.cpp
        ' Lines: 14209 - 14209
        ' Expression* .Parser::ParseXmlString( [ _Out_ ParseTree::XmlAttributeExpression* Attribute ] [ _Inout_ bool& ErrorInConstruct ] )
        Friend Function ParseXmlString(nextState As ScannerState) As XmlStringSyntax

            Dim state As ScannerState
            Dim startQuote As PunctuationSyntax

            If CurrentToken.Kind = SyntaxKind.SingleQuoteToken Then
                state = If(CurrentToken.Text = "'"c, ScannerState.SingleQuotedString, ScannerState.SmartSingleQuotedString)
                startQuote = DirectCast(CurrentToken, PunctuationSyntax)
                GetNextToken(state)
            ElseIf CurrentToken.Kind = SyntaxKind.DoubleQuoteToken Then
                state = If(CurrentToken.Text = """"c, ScannerState.QuotedString, ScannerState.SmartQuotedString)
                startQuote = DirectCast(CurrentToken, PunctuationSyntax)
                GetNextToken(state)
            Else
                ' this is not a quote.
                ' Let's parse the stuff as if it is quoted, but complain that quote is missing
                state = ScannerState.UnQuotedString
                startQuote = DirectCast(InternalSyntaxFactory.MissingToken(SyntaxKind.SingleQuoteToken), PunctuationSyntax)
                startQuote = ReportSyntaxError(startQuote, ERRID.ERR_StartAttributeValue)
                ResetCurrentToken(state)
            End If

            Dim list = _pool.Allocate(Of XmlTextTokenSyntax)()
            Do
                Dim kind = CurrentToken.Kind

                Select Case kind
                    Case SyntaxKind.SingleQuoteToken,
                        SyntaxKind.DoubleQuoteToken

                        Dim endQuote = DirectCast(CurrentToken, PunctuationSyntax)

                        GetNextToken(nextState)

                        Dim result = SyntaxFactory.XmlString(startQuote, list.ToList, endQuote)
                        _pool.Free(list)

                        Return result

                    Case SyntaxKind.XmlTextLiteralToken,
                        SyntaxKind.XmlEntityLiteralToken,
                        SyntaxKind.DocumentationCommentLineBreakToken

                        list.Add(DirectCast(CurrentToken, XmlTextTokenSyntax))

                    Case Else
                        ' error. This happens on EndOfText and BadChar. Let the caller deal with this.
                        ' TODO: is this ok?
                        Dim endQuote = HandleUnexpectedToken(startQuote.Kind)

                        Dim result = SyntaxFactory.XmlString(startQuote, list.ToList, DirectCast(endQuote, PunctuationSyntax))
                        _pool.Free(list)

                        Return result
                End Select
                GetNextToken(state)
            Loop
        End Function

        ' File: Parser.cpp
        ' Lines: 14379 - 14379
        ' Expression* .Parser::ParseXmlEmbedded( [ bool AllowEmbedded ] [ _Inout_ bool& ErrorInConstruct ] )
        Private Function ParseXmlEmbedded(enclosingState As ScannerState) As XmlEmbeddedExpressionSyntax
            Debug.Assert(CurrentToken.Kind = SyntaxKind.LessThanPercentEqualsToken, "ParseXmlEmbedded called on wrong token")

            Dim beginXmlEmbedded As PunctuationSyntax = DirectCast(CurrentToken, PunctuationSyntax)
            GetNextToken(enclosingState)
            beginXmlEmbedded = TransitionFromXmlToVB(beginXmlEmbedded)
            TryEatNewLine(ScannerState.VB)

            Dim value = ParseExpressionCore()

            Dim endXmlEmbedded As PunctuationSyntax = Nothing
            If Not TryEatNewLineAndGetToken(SyntaxKind.PercentGreaterThanToken, endXmlEmbedded, createIfMissing:=False, state:=enclosingState) Then
                Dim skippedTokens = Me._pool.Allocate(Of SyntaxToken)()

                ResyncAt(skippedTokens, ScannerState.VB, {SyntaxKind.PercentGreaterThanToken,
                                        SyntaxKind.GreaterThanToken,
                                        SyntaxKind.LessThanToken,
                                        SyntaxKind.LessThanPercentEqualsToken,
                                        SyntaxKind.LessThanQuestionToken,
                                        SyntaxKind.BeginCDataToken,
                                        SyntaxKind.LessThanExclamationMinusMinusToken,
                                        SyntaxKind.LessThanSlashToken})

                If CurrentToken.Kind = SyntaxKind.PercentGreaterThanToken Then
                    endXmlEmbedded = DirectCast(CurrentToken, PunctuationSyntax)
                    GetNextToken(enclosingState)
                Else
                    endXmlEmbedded = DirectCast(HandleUnexpectedToken(SyntaxKind.PercentGreaterThanToken), PunctuationSyntax)
                End If

                Dim unexpectedSyntax = skippedTokens.ToList()
                Me._pool.Free(skippedTokens)

                If unexpectedSyntax.Node IsNot Nothing Then
                    endXmlEmbedded = AddLeadingSyntax(endXmlEmbedded, unexpectedSyntax, ERRID.ERR_Syntax)
                End If
            End If

            Dim result = SyntaxFactory.XmlEmbeddedExpression(beginXmlEmbedded, value, endXmlEmbedded)
            result = AdjustTriviaForMissingTokens(result)
            result = TransitionFromVBToXml(enclosingState, result)
            Return result
        End Function

    End Class

    Friend Class XmlWhitespaceChecker
        Inherits VisualBasicSyntaxRewriter

        <Flags()>
        Friend Enum TriviaCheck
            None = 0
            ProhibitLeadingTrivia = 1
            ProhibitTrailingTrivia = 2
        End Enum

        Friend Structure WhiteSpaceOptions
            Friend _parentKind As SyntaxKind
            Friend _triviaCheck As TriviaCheck
        End Structure

        Private _options As WhiteSpaceOptions

        Public Sub New()
        End Sub

        Public Overrides Function VisitXmlDeclaration(node As XmlDeclarationSyntax) As VisualBasicSyntaxNode
            Dim anyChanges As Boolean = False
            Dim saveOptions = _options

            _options._triviaCheck = TriviaCheck.ProhibitTrailingTrivia
            Dim lessThanQuestionToken = DirectCast(Visit(node.LessThanQuestionToken), PunctuationSyntax)
            If node._lessThanQuestionToken IsNot lessThanQuestionToken Then anyChanges = True

            _options._triviaCheck = TriviaCheck.ProhibitLeadingTrivia
            Dim xmlKeyword = DirectCast(Visit(node.XmlKeyword), KeywordSyntax)
            If node._xmlKeyword IsNot xmlKeyword Then anyChanges = True

            _options = saveOptions

            If anyChanges Then
                Return New XmlDeclarationSyntax(node.Kind, node.GetDiagnostics, node.GetAnnotations, lessThanQuestionToken, xmlKeyword, node.Version, node.Encoding, node.Standalone, node.QuestionGreaterThanToken)
            Else
                Return node
            End If
        End Function

        Public Overrides Function VisitXmlElementStartTag(node As XmlElementStartTagSyntax) As VisualBasicSyntaxNode
            Dim anyChanges As Boolean = False

            Dim saveOptions = _options

            _options._parentKind = SyntaxKind.XmlElementStartTag
            _options._triviaCheck = TriviaCheck.ProhibitTrailingTrivia

            Dim lessThanToken = DirectCast(VisitSyntaxToken(node.LessThanToken), PunctuationSyntax)
            If node.LessThanToken IsNot lessThanToken Then anyChanges = True

            _options._triviaCheck = TriviaCheck.ProhibitLeadingTrivia
            Dim name As XmlNodeSyntax = DirectCast(Visit(node.Name), XmlNodeSyntax)
            If node.Name IsNot name Then anyChanges = True

            _options._triviaCheck = TriviaCheck.None

            Dim attributes = VisitList(node.Attributes)
            If node.Attributes.Node IsNot attributes.Node Then anyChanges = True

            _options = saveOptions

            If anyChanges Then
                Return InternalSyntaxFactory.XmlElementStartTag(lessThanToken, name, attributes, node.GreaterThanToken)
            End If

            Return node
        End Function

        Public Overrides Function VisitXmlEmptyElement(node As XmlEmptyElementSyntax) As VisualBasicSyntaxNode
            Dim anyChanges As Boolean = False

            Dim saveOptions = _options

            _options._parentKind = SyntaxKind.XmlElementStartTag
            _options._triviaCheck = TriviaCheck.ProhibitTrailingTrivia

            Dim lessThanToken = DirectCast(VisitSyntaxToken(node.LessThanToken), PunctuationSyntax)
            If node.LessThanToken IsNot lessThanToken Then anyChanges = True

            _options._triviaCheck = TriviaCheck.ProhibitLeadingTrivia

            Dim name As XmlNodeSyntax = DirectCast(Visit(node.Name), XmlNodeSyntax)
            If node.Name IsNot name Then anyChanges = True

            _options._triviaCheck = TriviaCheck.None

            Dim attributes = VisitList(node.Attributes)
            If node.Attributes.Node IsNot attributes.Node Then anyChanges = True

            _options = saveOptions

            If anyChanges Then
                Return InternalSyntaxFactory.XmlEmptyElement(lessThanToken, name, attributes, node.SlashGreaterThanToken)
            End If

            Return node
        End Function

        Public Overrides Function VisitXmlElementEndTag(node As XmlElementEndTagSyntax) As VisualBasicSyntaxNode
            Dim anyChanges As Boolean = False

            Dim saveOptions = _options

            _options._parentKind = SyntaxKind.XmlElementStartTag
            _options._triviaCheck = TriviaCheck.ProhibitTrailingTrivia

            Dim LessThanSlashToken = DirectCast(VisitSyntaxToken(node.LessThanSlashToken), PunctuationSyntax)
            If node.LessThanSlashToken IsNot LessThanSlashToken Then anyChanges = True

            Dim name As XmlNameSyntax = DirectCast(Visit(node.Name), XmlNameSyntax)
            If node.Name IsNot name Then anyChanges = True

            _options = saveOptions

            If anyChanges Then
                Return InternalSyntaxFactory.XmlElementEndTag(LessThanSlashToken, name, node.GreaterThanToken)
            End If

            Return node
        End Function

        Public Overrides Function VisitXmlProcessingInstruction(node As XmlProcessingInstructionSyntax) As VisualBasicSyntaxNode
            Dim anyChanges As Boolean = False

            Dim saveOptions = _options
            _options._triviaCheck = TriviaCheck.ProhibitTrailingTrivia
            Dim lessThanQuestionToken = DirectCast(VisitSyntaxToken(node.LessThanQuestionToken), PunctuationSyntax)
            If node.LessThanQuestionToken IsNot lessThanQuestionToken Then anyChanges = True

            'Prohibit trivia before pi name
            _options._triviaCheck = TriviaCheck.ProhibitLeadingTrivia
            Dim nameNew As XmlNameTokenSyntax = DirectCast(VisitSyntaxToken(node.Name), XmlNameTokenSyntax)
            If node.Name IsNot nameNew Then anyChanges = True
            _options = saveOptions

            If anyChanges Then
                Return New XmlProcessingInstructionSyntax(node.Kind,
                                                          node.GetDiagnostics,
                                                          node.GetAnnotations,
                                                          lessThanQuestionToken,
                                                          nameNew,
                                                          node.TextTokens.Node,
                                                          node.QuestionGreaterThanToken)
            Else
                Return node
            End If
        End Function

        Public Overrides Function VisitXmlNameAttribute(node As XmlNameAttributeSyntax) As VisualBasicSyntaxNode
            Dim anyChanges As Boolean = False
            ' Only check the name for trivia.

            Dim saveOptions = _options
            _options._parentKind = SyntaxKind.XmlNameAttribute
            Dim nameNew As XmlNameSyntax = DirectCast(Visit(node.Name), XmlNameSyntax)
            If node.Name IsNot nameNew Then anyChanges = True
            _options = saveOptions

            If anyChanges Then
                Return New XmlNameAttributeSyntax(node.Kind, node.GetDiagnostics, node.GetAnnotations, nameNew, node.EqualsToken, node.StartQuoteToken, node.Reference, node.EndQuoteToken)
            Else
                Return node
            End If
        End Function

        Public Overrides Function VisitXmlCrefAttribute(node As XmlCrefAttributeSyntax) As VisualBasicSyntaxNode
            Dim anyChanges As Boolean = False
            ' Only check the name for trivia.

            Dim saveOptions = _options
            _options._parentKind = SyntaxKind.XmlCrefAttribute
            Dim nameNew As XmlNameSyntax = DirectCast(Visit(node.Name), XmlNameSyntax)
            If node.Name IsNot nameNew Then anyChanges = True
            _options = saveOptions

            If anyChanges Then
                Return New XmlCrefAttributeSyntax(node.Kind, node.GetDiagnostics, node.GetAnnotations, nameNew, node.EqualsToken, node.StartQuoteToken, node.Reference, node.EndQuoteToken)
            Else
                Return node
            End If
        End Function

        Public Overrides Function VisitXmlAttribute(node As XmlAttributeSyntax) As VisualBasicSyntaxNode
            Dim anyChanges As Boolean = False
            ' Only check the name for trivia.

            Dim saveOptions = _options
            _options._parentKind = SyntaxKind.XmlAttribute
            Dim nameNew As XmlNodeSyntax = DirectCast(Visit(node.Name), XmlNodeSyntax)
            If node.Name IsNot nameNew Then anyChanges = True
            _options = saveOptions

            If anyChanges Then
                Return New XmlAttributeSyntax(node.Kind, node.GetDiagnostics, node.GetAnnotations, nameNew, node.EqualsToken, node.Value)
            Else
                Return node
            End If
        End Function

        Public Overrides Function VisitXmlBracketedName(node As XmlBracketedNameSyntax) As VisualBasicSyntaxNode
            Dim anyChanges As Boolean = False

            Dim saveOptions = _options

            _options._parentKind = SyntaxKind.XmlBracketedName
            _options._triviaCheck = TriviaCheck.ProhibitTrailingTrivia

            Dim lessThanToken = DirectCast(VisitSyntaxToken(node.LessThanToken), PunctuationSyntax)
            If node.LessThanToken IsNot lessThanToken Then anyChanges = True

            Dim name As XmlNodeSyntax = DirectCast(Visit(node.Name), XmlNodeSyntax)
            If node.Name IsNot name Then anyChanges = True

            _options._triviaCheck = TriviaCheck.ProhibitLeadingTrivia
            Dim greaterThanToken = DirectCast(VisitSyntaxToken(node.GreaterThanToken), PunctuationSyntax)
            If node.GreaterThanToken IsNot greaterThanToken Then anyChanges = True
            _options = saveOptions

            If anyChanges Then
                Return InternalSyntaxFactory.XmlBracketedName(lessThanToken, DirectCast(name, XmlNameSyntax), greaterThanToken)
            Else
                Return node
            End If
        End Function

        Public Overrides Function VisitXmlName(node As XmlNameSyntax) As VisualBasicSyntaxNode
            Dim anyChanges As Boolean = False

            Dim prefix As XmlPrefixSyntax = DirectCast(Visit(node.Prefix), XmlPrefixSyntax)
            If node.Prefix IsNot prefix Then anyChanges = True
            Dim localName As XmlNameTokenSyntax
            Dim saveOptions = _options

            ' Prohibit trivia depending on parent context
            Select Case _options._parentKind
                Case SyntaxKind.XmlAttribute,
                     SyntaxKind.XmlCrefAttribute,
                     SyntaxKind.XmlNameAttribute

                    If node.Prefix IsNot Nothing Then
                        _options._triviaCheck = TriviaCheck.ProhibitLeadingTrivia
                    Else
                        _options._triviaCheck = TriviaCheck.None
                    End If

                Case SyntaxKind.XmlBracketedName
                    _options._triviaCheck = TriviaCheck.ProhibitLeadingTrivia Or TriviaCheck.ProhibitTrailingTrivia

                Case Else
                    _options._triviaCheck = TriviaCheck.ProhibitLeadingTrivia
            End Select

            If _options._triviaCheck <> TriviaCheck.None Then
                localName = DirectCast(VisitSyntaxToken(node.LocalName), XmlNameTokenSyntax)
                If node.LocalName IsNot localName Then anyChanges = True
            Else
                localName = node.LocalName
            End If

            _options = saveOptions

            If anyChanges Then
                Return New XmlNameSyntax(node.Kind, node.GetDiagnostics, node.GetAnnotations, prefix, localName)
            Else
                Return node
            End If
        End Function

        Public Overrides Function VisitXmlPrefix(node As XmlPrefixSyntax) As VisualBasicSyntaxNode
            Dim anyChanges As Boolean = False

            ' Prohibit trailing trivia if prefix is an attribute name and both leading and trailing trivia if prefix is an element name
            Dim saveOptions = _options
            _options._triviaCheck = If(_options._parentKind = SyntaxKind.XmlAttribute, TriviaCheck.ProhibitTrailingTrivia, TriviaCheck.ProhibitLeadingTrivia Or TriviaCheck.ProhibitTrailingTrivia)
            Dim name = DirectCast(VisitSyntaxToken(node.Name), XmlNameTokenSyntax)
            If node.Name IsNot name Then anyChanges = True
            ' Prohibit both leading and trailing trivia around the ':'
            _options._triviaCheck = TriviaCheck.ProhibitLeadingTrivia Or TriviaCheck.ProhibitTrailingTrivia
            Dim colon As PunctuationSyntax = DirectCast(VisitSyntaxToken(node.ColonToken), PunctuationSyntax)
            If node.ColonToken IsNot colon Then anyChanges = True
            _options = saveOptions

            If anyChanges Then
                Return New XmlPrefixSyntax(node.Kind, node.GetDiagnostics, node.GetAnnotations, name, colon)
            Else
                Return node
            End If
        End Function

        Public Overrides Function VisitSyntaxToken(token As SyntaxToken) As SyntaxToken
            If token Is Nothing Then
                Return Nothing
            End If

            Dim anyChanges As Boolean = False
            Dim leadingTrivia As GreenNode = Nothing
            Dim trailingTrivia As GreenNode = Nothing

            ' For whitespace checking, only look at '<', '</', <%= and ':' tokens.
            ' i.e.
            '   < a >
            '   <a :b>
            '   <a: b>
            '   </ a>
            '   <<%=

            Select Case token.Kind
                Case SyntaxKind.XmlNameToken,
                     SyntaxKind.XmlKeyword,
                     SyntaxKind.LessThanToken,
                     SyntaxKind.LessThanSlashToken,
                     SyntaxKind.LessThanQuestionToken,
                     SyntaxKind.LessThanPercentEqualsToken,
                     SyntaxKind.ColonToken

                    leadingTrivia = token.GetLeadingTrivia
                    If (_options._triviaCheck And TriviaCheck.ProhibitLeadingTrivia) = TriviaCheck.ProhibitLeadingTrivia Then
                        Dim newleadingTrivia = VisitList(New CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of VisualBasicSyntaxNode)(leadingTrivia)).Node
                        If newleadingTrivia IsNot leadingTrivia Then
                            anyChanges = True
                            leadingTrivia = newleadingTrivia
                        End If
                    End If

                    trailingTrivia = token.GetTrailingTrivia
                    If (_options._triviaCheck And TriviaCheck.ProhibitTrailingTrivia) = TriviaCheck.ProhibitTrailingTrivia Then
                        Dim newTrailingTrivia = VisitList(New CodeAnalysis.Syntax.InternalSyntax.SyntaxList(Of VisualBasicSyntaxNode)(trailingTrivia)).Node
                        If newTrailingTrivia IsNot trailingTrivia Then
                            anyChanges = True
                            trailingTrivia = newTrailingTrivia
                        End If
                    End If

            End Select

            If anyChanges Then
                Select Case token.Kind
                    Case SyntaxKind.XmlNameToken

                        Dim node = DirectCast(token, XmlNameTokenSyntax)
                        Return New XmlNameTokenSyntax(node.Kind, node.GetDiagnostics, node.GetAnnotations, node.Text, leadingTrivia, trailingTrivia, node.PossibleKeywordKind)

                    Case SyntaxKind.XmlKeyword

                        Dim node = DirectCast(token, KeywordSyntax)
                        Return New KeywordSyntax(node.Kind, node.GetDiagnostics, node.GetAnnotations, node.Text, leadingTrivia, trailingTrivia)

                    Case SyntaxKind.LessThanToken,
                         SyntaxKind.LessThanSlashToken,
                         SyntaxKind.LessThanQuestionToken,
                         SyntaxKind.LessThanPercentEqualsToken,
                         SyntaxKind.ColonToken

                        Dim node = DirectCast(token, PunctuationSyntax)
                        Return New PunctuationSyntax(node.Kind, node.GetDiagnostics, node.GetAnnotations, node.Text, leadingTrivia, trailingTrivia)
                End Select
            End If

            Return token
        End Function

        Public Overrides Function VisitSyntaxTrivia(trivia As SyntaxTrivia) As SyntaxTrivia
            If trivia.Kind = SyntaxKind.WhitespaceTrivia OrElse trivia.Kind = SyntaxKind.EndOfLineTrivia Then
                Return DirectCast(trivia.AddError(ErrorFactory.ErrorInfo(ERRID.ERR_IllegalXmlWhiteSpace)), SyntaxTrivia)
            End If
            Return trivia
        End Function
    End Class

    Friend Structure XmlContext
        Private ReadOnly _start As XmlElementStartTagSyntax
        Private ReadOnly _content As SyntaxListBuilder(Of XmlNodeSyntax)
        Private ReadOnly _pool As SyntaxListPool

        Public Sub New(pool As SyntaxListPool, start As XmlElementStartTagSyntax)
            _pool = pool
            _start = start
            _content = _pool.Allocate(Of XmlNodeSyntax)()
        End Sub

        Public Sub Add(xml As XmlNodeSyntax)
            _content.Add(xml)
        End Sub

        Public ReadOnly Property StartElement As XmlElementStartTagSyntax
            Get
                Return _start
            End Get
        End Property

        Public Function CreateElement(endElement As XmlElementEndTagSyntax) As XmlNodeSyntax
            Debug.Assert(endElement IsNot Nothing)

            Dim contentList = _content.ToList
            _pool.Free(_content)

            Return InternalSyntaxFactory.XmlElement(_start, contentList, endElement)
        End Function

        Public Function CreateElement(endElement As XmlElementEndTagSyntax, diagnostic As DiagnosticInfo) As XmlNodeSyntax
            Debug.Assert(endElement IsNot Nothing)

            Dim contentList = _content.ToList
            _pool.Free(_content)

            Return InternalSyntaxFactory.XmlElement(DirectCast(_start.AddError(diagnostic), XmlElementStartTagSyntax), contentList, endElement)
        End Function

    End Structure

    Friend Module XmlContextExtensions
        <Extension()>
        Friend Sub Push(this As List(Of XmlContext), context As XmlContext)
            this.Add(context)
        End Sub

        <Extension()>
        Friend Function Pop(this As List(Of XmlContext)) As XmlContext
            Dim last = this.Count - 1
            Dim context = this(last)
            this.RemoveAt(last)
            Return context
        End Function

        <Extension()>
        Friend Function Peek(this As List(Of XmlContext), Optional i As Integer = 0) As XmlContext
            Dim last = this.Count - 1
            Return this(last - i)
        End Function

        <Extension()>
        Friend Function MatchEndElement(this As List(Of XmlContext), name As XmlNameSyntax) As Integer
            Debug.Assert(name Is Nothing OrElse name.Kind = SyntaxKind.XmlName)

            Dim last = this.Count - 1
            If name Is Nothing Then
                ' An empty name matches anything
                Return last
            End If

            Dim i = last
            Do While i >= 0
                Dim context = this(i)
                Dim nameExpr = context.StartElement.Name

                If nameExpr.Kind = SyntaxKind.XmlName Then

                    Dim startName = DirectCast(nameExpr, XmlNameSyntax)

                    If startName.LocalName.Text = name.LocalName.Text Then

                        Dim startPrefix = startName.Prefix
                        Dim endPrefix = name.Prefix

                        If startPrefix Is endPrefix Then
                            Exit Do
                        End If

                        If startPrefix IsNot Nothing AndAlso endPrefix IsNot Nothing Then
                            If startPrefix.Name.Text = endPrefix.Name.Text Then
                                Exit Do
                            End If
                        End If

                    End If
                End If

                i -= 1
            Loop

            Return i
        End Function
    End Module

End Namespace