File: Operations\VisualBasicOperationFactory.vb
Web Access
Project: src\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.Collections.Concurrent
Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports ReferenceEqualityComparer = Roslyn.Utilities.ReferenceEqualityComparer
 
Namespace Microsoft.CodeAnalysis.Operations
    Partial Friend NotInheritable Class VisualBasicOperationFactory
 
        Private _lazyPlaceholderToParentMap As ConcurrentDictionary(Of BoundValuePlaceholderBase, BoundNode) = Nothing
 
        Private ReadOnly _semanticModel As SemanticModel
 
        Public Sub New(semanticModel As SemanticModel)
            _semanticModel = semanticModel
        End Sub
 
        ''' <summary>
        ''' Returns <code>Nothing</code> if parent is not known.
        ''' </summary>
        Private Function TryGetParent(placeholder As BoundValuePlaceholderBase) As BoundNode
            Dim knownParent As BoundNode = Nothing
 
            If _lazyPlaceholderToParentMap IsNot Nothing AndAlso
               _lazyPlaceholderToParentMap.TryGetValue(placeholder, knownParent) Then
                Return knownParent
            End If
 
            Return Nothing
        End Function
 
        Private Sub RecordParent(placeholderOpt As BoundValuePlaceholderBase, parent As BoundNode)
            Debug.Assert(parent IsNot Nothing)
 
            If placeholderOpt Is Nothing Then
                Return
            End If
 
            If _lazyPlaceholderToParentMap Is Nothing Then
                Threading.Interlocked.CompareExchange(_lazyPlaceholderToParentMap,
                                                      New ConcurrentDictionary(Of BoundValuePlaceholderBase, BoundNode)(concurrencyLevel:=2, capacity:=10, comparer:=ReferenceEqualityComparer.Instance),
                                                      Nothing)
            End If
 
            Dim knownParent = _lazyPlaceholderToParentMap.GetOrAdd(placeholderOpt, parent)
            Debug.Assert(knownParent Is parent)
        End Sub
 
        Public Function Create(boundNode As BoundNode) As IOperation
            If boundNode Is Nothing Then
                Return Nothing
            End If
 
            ' A BoundUserDefined conversion is always the operand of a BoundConversion, and is handled
            ' by the BoundConversion creation. We should never receive one in this top level create call.
            Debug.Assert(boundNode.Kind <> BoundKind.UserDefinedConversion)
 
            Select Case boundNode.Kind
                Case BoundKind.AssignmentOperator
                    Return CreateBoundAssignmentOperatorOperation(DirectCast(boundNode, BoundAssignmentOperator))
                Case BoundKind.MeReference
                    Return CreateBoundMeReferenceOperation(DirectCast(boundNode, BoundMeReference))
                Case BoundKind.MyBaseReference
                    Return CreateBoundMyBaseReferenceOperation(DirectCast(boundNode, BoundMyBaseReference))
                Case BoundKind.MyClassReference
                    Return CreateBoundMyClassReferenceOperation(DirectCast(boundNode, BoundMyClassReference))
                Case BoundKind.Literal
                    Return CreateBoundLiteralOperation(DirectCast(boundNode, BoundLiteral))
                Case BoundKind.AwaitOperator
                    Return CreateBoundAwaitOperatorOperation(DirectCast(boundNode, BoundAwaitOperator))
                Case BoundKind.NameOfOperator
                    Return CreateBoundNameOfOperatorOperation(DirectCast(boundNode, BoundNameOfOperator))
                Case BoundKind.Lambda
                    Return CreateBoundLambdaOperation(DirectCast(boundNode, BoundLambda))
                Case BoundKind.Call
                    Return CreateBoundCallOperation(DirectCast(boundNode, BoundCall))
                Case BoundKind.OmittedArgument
                    Return CreateBoundOmittedArgumentOperation(DirectCast(boundNode, BoundOmittedArgument))
                Case BoundKind.Parenthesized
                    Return CreateBoundParenthesizedOperation(DirectCast(boundNode, BoundParenthesized))
                Case BoundKind.ArrayAccess
                    Return CreateBoundArrayAccessOperation(DirectCast(boundNode, BoundArrayAccess))
                Case BoundKind.UnaryOperator
                    Return CreateBoundUnaryOperatorOperation(DirectCast(boundNode, BoundUnaryOperator))
                Case BoundKind.UserDefinedUnaryOperator
                    Return CreateBoundUserDefinedUnaryOperatorOperation(DirectCast(boundNode, BoundUserDefinedUnaryOperator))
                Case BoundKind.BinaryOperator
                    Return CreateBoundBinaryOperatorOperation(DirectCast(boundNode, BoundBinaryOperator))
                Case BoundKind.UserDefinedBinaryOperator
                    Return CreateBoundUserDefinedBinaryOperatorOperation(DirectCast(boundNode, BoundUserDefinedBinaryOperator))
                Case BoundKind.BinaryConditionalExpression
                    Return CreateBoundBinaryConditionalExpressionOperation(DirectCast(boundNode, BoundBinaryConditionalExpression))
                Case BoundKind.UserDefinedShortCircuitingOperator
                    Return CreateBoundUserDefinedShortCircuitingOperatorOperation(DirectCast(boundNode, BoundUserDefinedShortCircuitingOperator))
                Case BoundKind.BadExpression
                    Return CreateBoundBadExpressionOperation(DirectCast(boundNode, BoundBadExpression))
                Case BoundKind.TryCast
                    Return CreateBoundTryCastOperation(DirectCast(boundNode, BoundTryCast))
                Case BoundKind.DirectCast
                    Return CreateBoundDirectCastOperation(DirectCast(boundNode, BoundDirectCast))
                Case BoundKind.Conversion
                    Return CreateBoundConversionOperation(DirectCast(boundNode, BoundConversion))
                Case BoundKind.DelegateCreationExpression
                    Return CreateBoundDelegateCreationExpressionOperation(DirectCast(boundNode, BoundDelegateCreationExpression))
                Case BoundKind.TernaryConditionalExpression
                    Return CreateBoundTernaryConditionalExpressionOperation(DirectCast(boundNode, BoundTernaryConditionalExpression))
                Case BoundKind.TypeOf
                    Return CreateBoundTypeOfOperation(DirectCast(boundNode, BoundTypeOf))
                Case BoundKind.GetType
                    Return CreateBoundGetTypeOperation(DirectCast(boundNode, BoundGetType))
                Case BoundKind.ObjectCreationExpression
                    Return CreateBoundObjectCreationExpressionOperation(DirectCast(boundNode, BoundObjectCreationExpression))
                Case BoundKind.ObjectInitializerExpression
                    Return CreateBoundObjectInitializerExpressionOperation(DirectCast(boundNode, BoundObjectInitializerExpression))
                Case BoundKind.CollectionInitializerExpression
                    Return CreateBoundCollectionInitializerExpressionOperation(DirectCast(boundNode, BoundCollectionInitializerExpression))
                Case BoundKind.NewT
                    Return CreateBoundNewTOperation(DirectCast(boundNode, BoundNewT))
                Case BoundKind.NoPiaObjectCreationExpression
                    Return CreateNoPiaObjectCreationExpressionOperation(DirectCast(boundNode, BoundNoPiaObjectCreationExpression))
                Case BoundKind.ArrayCreation
                    Return CreateBoundArrayCreationOperation(DirectCast(boundNode, BoundArrayCreation))
                Case BoundKind.ArrayInitialization
                    Return CreateBoundArrayInitializationOperation(DirectCast(boundNode, BoundArrayInitialization))
                Case BoundKind.PropertyAccess
                    Return CreateBoundPropertyAccessOperation(DirectCast(boundNode, BoundPropertyAccess))
                Case BoundKind.EventAccess
                    Return CreateBoundEventAccessOperation(DirectCast(boundNode, BoundEventAccess))
                Case BoundKind.FieldAccess
                    Return CreateBoundFieldAccessOperation(DirectCast(boundNode, BoundFieldAccess))
                Case BoundKind.ConditionalAccess
                    Return CreateBoundConditionalAccessOperation(DirectCast(boundNode, BoundConditionalAccess))
                Case BoundKind.ConditionalAccessReceiverPlaceholder
                    Return CreateBoundConditionalAccessReceiverPlaceholderOperation(DirectCast(boundNode, BoundConditionalAccessReceiverPlaceholder))
                Case BoundKind.Parameter
                    Return CreateBoundParameterOperation(DirectCast(boundNode, BoundParameter))
                Case BoundKind.Local
                    Return CreateBoundLocalOperation(DirectCast(boundNode, BoundLocal))
                Case BoundKind.LocalDeclaration
                    Return CreateBoundLocalDeclarationOperation(DirectCast(boundNode, BoundLocalDeclaration))
                Case BoundKind.LateInvocation
                    Return CreateBoundLateInvocationOperation(DirectCast(boundNode, BoundLateInvocation))
                Case BoundKind.LateMemberAccess
                    Return CreateBoundLateMemberAccessOperation(DirectCast(boundNode, BoundLateMemberAccess))
                Case BoundKind.FieldInitializer
                    Return CreateBoundFieldInitializerOperation(DirectCast(boundNode, BoundFieldInitializer))
                Case BoundKind.PropertyInitializer
                    Return CreateBoundPropertyInitializerOperation(DirectCast(boundNode, BoundPropertyInitializer))
                Case BoundKind.ParameterEqualsValue
                    Return CreateBoundParameterEqualsValueOperation(DirectCast(boundNode, BoundParameterEqualsValue))
                Case BoundKind.RValuePlaceholder
                    Return CreateBoundRValuePlaceholderOperation(DirectCast(boundNode, BoundRValuePlaceholder))
                Case BoundKind.IfStatement
                    Return CreateBoundIfStatementOperation(DirectCast(boundNode, BoundIfStatement))
                Case BoundKind.SelectStatement
                    Return CreateBoundSelectStatementOperation(DirectCast(boundNode, BoundSelectStatement))
                Case BoundKind.CaseBlock
                    Return CreateBoundCaseBlockOperation(DirectCast(boundNode, BoundCaseBlock))
                Case BoundKind.SimpleCaseClause
                    Return CreateBoundSimpleCaseClauseOperation(DirectCast(boundNode, BoundSimpleCaseClause))
                Case BoundKind.RangeCaseClause
                    Return CreateBoundRangeCaseClauseOperation(DirectCast(boundNode, BoundRangeCaseClause))
                Case BoundKind.RelationalCaseClause
                    Return CreateBoundRelationalCaseClauseOperation(DirectCast(boundNode, BoundRelationalCaseClause))
                Case BoundKind.DoLoopStatement
                    Return CreateBoundDoLoopStatementOperation(DirectCast(boundNode, BoundDoLoopStatement))
                Case BoundKind.ForToStatement
                    Return CreateBoundForToStatementOperation(DirectCast(boundNode, BoundForToStatement))
                Case BoundKind.ForEachStatement
                    Return CreateBoundForEachStatementOperation(DirectCast(boundNode, BoundForEachStatement))
                Case BoundKind.TryStatement
                    Return CreateBoundTryStatementOperation(DirectCast(boundNode, BoundTryStatement))
                Case BoundKind.CatchBlock
                    Return CreateBoundCatchBlockOperation(DirectCast(boundNode, BoundCatchBlock))
                Case BoundKind.Block
                    Return CreateBoundBlockOperation(DirectCast(boundNode, BoundBlock))
                Case BoundKind.BadStatement
                    Return CreateBoundBadStatementOperation(DirectCast(boundNode, BoundBadStatement))
                Case BoundKind.ReturnStatement
                    Return CreateBoundReturnStatementOperation(DirectCast(boundNode, BoundReturnStatement))
                Case BoundKind.ThrowStatement
                    Return CreateBoundThrowStatementOperation(DirectCast(boundNode, BoundThrowStatement))
                Case BoundKind.WhileStatement
                    Return CreateBoundWhileStatementOperation(DirectCast(boundNode, BoundWhileStatement))
                Case BoundKind.DimStatement
                    Return CreateBoundDimStatementOperation(DirectCast(boundNode, BoundDimStatement))
                Case BoundKind.YieldStatement
                    Return CreateBoundYieldStatementOperation(DirectCast(boundNode, BoundYieldStatement))
                Case BoundKind.LabelStatement
                    Return CreateBoundLabelStatementOperation(DirectCast(boundNode, BoundLabelStatement))
                Case BoundKind.GotoStatement
                    Return CreateBoundGotoStatementOperation(DirectCast(boundNode, BoundGotoStatement))
                Case BoundKind.ContinueStatement
                    Return CreateBoundContinueStatementOperation(DirectCast(boundNode, BoundContinueStatement))
                Case BoundKind.ExitStatement
                    Return CreateBoundExitStatementOperation(DirectCast(boundNode, BoundExitStatement))
                Case BoundKind.SyncLockStatement
                    Return CreateBoundSyncLockStatementOperation(DirectCast(boundNode, BoundSyncLockStatement))
                Case BoundKind.NoOpStatement
                    Return CreateBoundNoOpStatementOperation(DirectCast(boundNode, BoundNoOpStatement))
                Case BoundKind.StopStatement
                    Return CreateBoundStopStatementOperation(DirectCast(boundNode, BoundStopStatement))
                Case BoundKind.EndStatement
                    Return CreateBoundEndStatementOperation(DirectCast(boundNode, BoundEndStatement))
                Case BoundKind.WithStatement
                    Return CreateBoundWithStatementOperation(DirectCast(boundNode, BoundWithStatement))
                Case BoundKind.UsingStatement
                    Return CreateBoundUsingStatementOperation(DirectCast(boundNode, BoundUsingStatement))
                Case BoundKind.ExpressionStatement
                    Return CreateBoundExpressionStatementOperation(DirectCast(boundNode, BoundExpressionStatement))
                Case BoundKind.RaiseEventStatement
                    Return CreateBoundRaiseEventStatementOperation(DirectCast(boundNode, BoundRaiseEventStatement))
                Case BoundKind.AddHandlerStatement
                    Return CreateBoundAddHandlerStatementOperation(DirectCast(boundNode, BoundAddHandlerStatement))
                Case BoundKind.RemoveHandlerStatement
                    Return CreateBoundRemoveHandlerStatementOperation(DirectCast(boundNode, BoundRemoveHandlerStatement))
                Case BoundKind.TupleLiteral
                    Return CreateBoundTupleLiteralOperation(DirectCast(boundNode, BoundTupleLiteral))
                Case BoundKind.ConvertedTupleLiteral
                    Return CreateBoundConvertedTupleLiteralOperation(DirectCast(boundNode, BoundConvertedTupleLiteral))
                Case BoundKind.InterpolatedStringExpression
                    Return CreateBoundInterpolatedStringExpressionOperation(DirectCast(boundNode, BoundInterpolatedStringExpression))
                Case BoundKind.Interpolation
                    Return CreateBoundInterpolationOperation(DirectCast(boundNode, BoundInterpolation))
                Case BoundKind.AnonymousTypeCreationExpression
                    Return CreateBoundAnonymousTypeCreationExpressionOperation(DirectCast(boundNode, BoundAnonymousTypeCreationExpression))
                Case BoundKind.AnonymousTypeFieldInitializer
                    Return Create(DirectCast(boundNode, BoundAnonymousTypeFieldInitializer).Value)
                Case BoundKind.AnonymousTypePropertyAccess
                    Return CreateBoundAnonymousTypePropertyAccessOperation(DirectCast(boundNode, BoundAnonymousTypePropertyAccess))
                Case BoundKind.WithLValueExpressionPlaceholder
                    Return CreateBoundWithLValueExpressionPlaceholder(DirectCast(boundNode, BoundWithLValueExpressionPlaceholder))
                Case BoundKind.WithRValueExpressionPlaceholder
                    Return CreateBoundWithRValueExpressionPlaceholder(DirectCast(boundNode, BoundWithRValueExpressionPlaceholder))
                Case BoundKind.QueryExpression
                    Return CreateBoundQueryExpressionOperation(DirectCast(boundNode, BoundQueryExpression))
                Case BoundKind.LValueToRValueWrapper
                    Return CreateBoundLValueToRValueWrapper(DirectCast(boundNode, BoundLValueToRValueWrapper))
                Case BoundKind.QueryClause
                    ' Query clause has no special representation in the IOperation tree
                    Return Create(DirectCast(boundNode, BoundQueryClause).UnderlyingExpression)
                Case BoundKind.QueryableSource
                    ' Queryable source has no special representation in the IOperation tree
                    Return Create(DirectCast(boundNode, BoundQueryableSource).Source)
                Case BoundKind.AggregateClause
                    Return CreateBoundAggregateClauseOperation(DirectCast(boundNode, BoundAggregateClause))
                Case BoundKind.Ordering
                    ' Ordering clause has no special representation in the IOperation tree
                    Return Create(DirectCast(boundNode, BoundOrdering).UnderlyingExpression)
                Case BoundKind.GroupAggregation
                    ' Group aggregation has no special representation in the IOperation tree
                    Return Create(DirectCast(boundNode, BoundGroupAggregation).Group)
                Case BoundKind.QuerySource
                    ' Query source has no special representation in the IOperation tree
                    Return Create(DirectCast(boundNode, BoundQuerySource).Expression)
                Case BoundKind.ToQueryableCollectionConversion
                    ' Queryable collection conversion has no special representation in the IOperation tree
                    Return Create(DirectCast(boundNode, BoundToQueryableCollectionConversion).ConversionCall)
                Case BoundKind.QueryLambda
                    ' Query lambda must be lowered to the regular lambda form for the operation tree.
                    Dim rewrittenLambda As BoundNode = RewriteQueryLambda(DirectCast(boundNode, BoundQueryLambda))
                    Return Create(rewrittenLambda)
                Case BoundKind.RangeVariableAssignment
                    ' Range variable assignment has no special representation in the IOperation tree
                    Return Create(DirectCast(boundNode, BoundRangeVariableAssignment).Value)
                Case BoundKind.BadVariable
                    Return Create(DirectCast(boundNode, BoundBadVariable).Expression)
                Case BoundKind.NullableIsTrueOperator
                    Return CreateBoundNullableIsTrueOperator(DirectCast(boundNode, BoundNullableIsTrueOperator))
                Case BoundKind.RedimStatement
                    Return CreateBoundReDimOperation(DirectCast(boundNode, BoundRedimStatement))
                Case BoundKind.RedimClause
                    Return CreateBoundReDimClauseOperation(DirectCast(boundNode, BoundRedimClause))
                Case BoundKind.TypeArguments
                    Return CreateBoundTypeArgumentsOperation(DirectCast(boundNode, BoundTypeArguments))
                Case BoundKind.Attribute
                    Return CreateBoundAttributeOperation(DirectCast(boundNode, BoundAttribute))
 
                Case BoundKind.AddressOfOperator,
                     BoundKind.ArrayLiteral,
                     BoundKind.ByRefArgumentWithCopyBack,
                     BoundKind.CompoundAssignmentTargetPlaceholder,
                     BoundKind.EraseStatement,
                     BoundKind.Label,
                     BoundKind.LateAddressOfOperator,
                     BoundKind.MethodGroup,
                     BoundKind.MidResult,
                     BoundKind.NamespaceExpression,
                     BoundKind.OnErrorStatement,
                     BoundKind.PropertyGroup,
                     BoundKind.RangeVariable,
                     BoundKind.ResumeStatement,
                     BoundKind.TypeAsValueExpression,
                     BoundKind.TypeExpression,
                     BoundKind.TypeOrValueExpression,
                     BoundKind.XmlCData,
                     BoundKind.XmlComment,
                     BoundKind.XmlDocument,
                     BoundKind.XmlElement,
                     BoundKind.XmlEmbeddedExpression,
                     BoundKind.XmlMemberAccess,
                     BoundKind.XmlNamespace,
                     BoundKind.XmlProcessingInstruction,
                     BoundKind.UnboundLambda,
                     BoundKind.UnstructuredExceptionHandlingStatement
 
                    Dim constantValue As ConstantValue = Nothing
                    Dim type As TypeSymbol = Nothing
                    Dim expression = TryCast(boundNode, BoundExpression)
                    If expression IsNot Nothing Then
                        constantValue = expression.ConstantValueOpt
                        type = expression.Type
                    End If
                    Dim isImplicit As Boolean = boundNode.WasCompilerGenerated
                    Dim children As ImmutableArray(Of IOperation) = GetIOperationChildren(boundNode)
                    Return New NoneOperation(children, _semanticModel, boundNode.Syntax, type, constantValue, isImplicit)
 
                Case Else
                    ' If you're hitting this because the IOperation test hook has failed, see
                    ' <roslyn-root>/docs/Compilers/IOperation Test Hook.md for instructions on how to fix.
                    Throw ExceptionUtilities.UnexpectedValue(boundNode.Kind)
            End Select
        End Function
 
        Public Function CreateFromArray(Of TBoundNode As BoundNode, TOperation As {Class, IOperation})(nodeArray As ImmutableArray(Of TBoundNode)) As ImmutableArray(Of TOperation)
            Dim builder = ArrayBuilder(Of TOperation).GetInstance(nodeArray.Length)
            For Each node In nodeArray
                builder.AddIfNotNull(DirectCast(Create(node), TOperation))
            Next
 
            Return builder.ToImmutableAndFree()
        End Function
 
        Friend Function GetIOperationChildren(boundNode As BoundNode) As ImmutableArray(Of IOperation)
            Dim boundNodeWithChildren = DirectCast(boundNode, IBoundNodeWithIOperationChildren)
            If boundNodeWithChildren.Children.IsDefaultOrEmpty Then
                Return ImmutableArray(Of IOperation).Empty
            End If
 
            Dim builder = ArrayBuilder(Of IOperation).GetInstance(boundNodeWithChildren.Children.Length)
            For Each childNode In boundNodeWithChildren.Children
                Dim operation = Create(childNode)
                If operation Is Nothing Then
                    Continue For
                End If
 
                builder.Add(operation)
            Next
 
            Return builder.ToImmutableAndFree()
        End Function
 
        Private Function CreateBoundAssignmentOperatorOperation(boundAssignmentOperator As BoundAssignmentOperator) As IOperation
            If IsMidStatement(boundAssignmentOperator.Right) Then
                ' We don't support mid statements currently. Return a none operation for them
                ' https://github.com/dotnet/roslyn/issues/23109
                Dim constantValue As ConstantValue = boundAssignmentOperator.ConstantValueOpt
                Dim isImplicit As Boolean = boundAssignmentOperator.WasCompilerGenerated
                Dim children As ImmutableArray(Of IOperation) = GetIOperationChildren(boundAssignmentOperator)
                Return New NoneOperation(children, _semanticModel, boundAssignmentOperator.Syntax, type:=Nothing, constantValue, isImplicit)
            ElseIf boundAssignmentOperator.LeftOnTheRightOpt IsNot Nothing Then
                Return CreateCompoundAssignment(boundAssignmentOperator)
            Else
                Dim target As IOperation = Create(boundAssignmentOperator.Left)
                Dim value As IOperation = Create(boundAssignmentOperator.Right)
                Dim isImplicit As Boolean = boundAssignmentOperator.WasCompilerGenerated
                Dim isRef As Boolean = False
                Dim syntax As SyntaxNode = boundAssignmentOperator.Syntax
                Dim type As ITypeSymbol = boundAssignmentOperator.Type
                Dim constantValue As ConstantValue = boundAssignmentOperator.ConstantValueOpt
                Return New SimpleAssignmentOperation(isRef, target, value, _semanticModel, syntax, type, constantValue, isImplicit)
            End If
        End Function
 
        Private Function CreateBoundMeReferenceOperation(boundMeReference As BoundMeReference) As IInstanceReferenceOperation
            Dim referenceKind As InstanceReferenceKind = InstanceReferenceKind.ContainingTypeInstance
            Dim syntax As SyntaxNode = boundMeReference.Syntax
            Dim type As ITypeSymbol = boundMeReference.Type
            Dim isImplicit As Boolean = boundMeReference.WasCompilerGenerated
            Return New InstanceReferenceOperation(referenceKind, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundMyBaseReferenceOperation(boundMyBaseReference As BoundMyBaseReference) As IInstanceReferenceOperation
            Dim referenceKind As InstanceReferenceKind = InstanceReferenceKind.ContainingTypeInstance
            Dim syntax As SyntaxNode = boundMyBaseReference.Syntax
            Dim type As ITypeSymbol = boundMyBaseReference.Type
            Dim isImplicit As Boolean = boundMyBaseReference.WasCompilerGenerated
            Return New InstanceReferenceOperation(referenceKind, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundMyClassReferenceOperation(boundMyClassReference As BoundMyClassReference) As IInstanceReferenceOperation
            Dim referenceKind As InstanceReferenceKind = InstanceReferenceKind.ContainingTypeInstance
            Dim syntax As SyntaxNode = boundMyClassReference.Syntax
            Dim type As ITypeSymbol = boundMyClassReference.Type
            Dim isImplicit As Boolean = boundMyClassReference.WasCompilerGenerated
            Return New InstanceReferenceOperation(referenceKind, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Friend Function CreateBoundLiteralOperation(boundLiteral As BoundLiteral, Optional implicit As Boolean = False) As ILiteralOperation
            Dim syntax As SyntaxNode = boundLiteral.Syntax
            Dim type As ITypeSymbol = boundLiteral.Type
            Dim constantValue As ConstantValue = boundLiteral.ConstantValueOpt
            Dim isImplicit As Boolean = boundLiteral.WasCompilerGenerated OrElse implicit
            Return New LiteralOperation(_semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundAwaitOperatorOperation(boundAwaitOperator As BoundAwaitOperator) As IAwaitOperation
            Dim awaitedValue As IOperation = Create(boundAwaitOperator.Operand)
            Dim syntax As SyntaxNode = boundAwaitOperator.Syntax
            Dim type As ITypeSymbol = boundAwaitOperator.Type
            Dim isImplicit As Boolean = boundAwaitOperator.WasCompilerGenerated
            Return New AwaitOperation(awaitedValue, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundNameOfOperatorOperation(boundNameOfOperator As BoundNameOfOperator) As INameOfOperation
            Dim argument As IOperation = Create(boundNameOfOperator.Argument)
            Dim syntax As SyntaxNode = boundNameOfOperator.Syntax
            Dim type As ITypeSymbol = boundNameOfOperator.Type
            Dim constantValue As ConstantValue = boundNameOfOperator.ConstantValueOpt
            Dim isImplicit As Boolean = boundNameOfOperator.WasCompilerGenerated
            Return New NameOfOperation(argument, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundLambdaOperation(boundLambda As BoundLambda) As IAnonymousFunctionOperation
            Dim symbol As IMethodSymbol = boundLambda.LambdaSymbol
            Dim body As IBlockOperation = DirectCast(Create(boundLambda.Body), IBlockOperation)
            Dim syntax As SyntaxNode = boundLambda.Syntax
            Dim isImplicit As Boolean = boundLambda.WasCompilerGenerated
            Return New AnonymousFunctionOperation(symbol, body, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundCallOperation(boundCall As BoundCall) As IInvocationOperation
            Dim targetMethod As IMethodSymbol = boundCall.Method
 
            Dim isVirtual As Boolean =
                   targetMethod IsNot Nothing AndAlso
                   (targetMethod.IsVirtual OrElse targetMethod.IsAbstract OrElse targetMethod.IsOverride) AndAlso
                   If(boundCall.ReceiverOpt?.Kind <> BoundKind.MyBaseReference, False) AndAlso
                   If(boundCall.ReceiverOpt?.Kind <> BoundKind.MyClassReference, False)
 
            Dim boundReceiver As BoundExpression = If(boundCall.ReceiverOpt, boundCall.MethodGroupOpt?.ReceiverOpt)
            Dim receiver as IOperation = CreateReceiverOperation(boundReceiver, targetMethod)
            Dim arguments As ImmutableArray(Of IArgumentOperation) = DeriveArguments(boundCall)
 
            Dim syntax As SyntaxNode = boundCall.Syntax
            Dim type As ITypeSymbol = boundCall.Type
            Dim isImplicit As Boolean = boundCall.WasCompilerGenerated
            Return New InvocationOperation(targetMethod, constrainedToType:=Nothing, receiver, isVirtual, arguments, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundOmittedArgumentOperation(boundOmittedArgument As BoundOmittedArgument) As IOmittedArgumentOperation
            Dim syntax As SyntaxNode = boundOmittedArgument.Syntax
            Dim type As ITypeSymbol = boundOmittedArgument.Type
            Dim isImplicit As Boolean = boundOmittedArgument.WasCompilerGenerated
            Return New OmittedArgumentOperation(_semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundParenthesizedOperation(boundParenthesized As BoundParenthesized) As IParenthesizedOperation
            Dim operand As IOperation = Create(boundParenthesized.Expression)
            Dim syntax As SyntaxNode = boundParenthesized.Syntax
            Dim type As ITypeSymbol = boundParenthesized.Type
            Dim constantValue As ConstantValue = boundParenthesized.ConstantValueOpt
            Dim isImplicit As Boolean = boundParenthesized.WasCompilerGenerated
            Return New ParenthesizedOperation(operand, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundArrayAccessOperation(boundArrayAccess As BoundArrayAccess) As IArrayElementReferenceOperation
            Dim arrayReference as IOperation = Create(boundArrayAccess.Expression)
            Dim indices = CreateFromArray(Of BoundExpression, IOperation)(boundArrayAccess.Indices)
            Dim syntax As SyntaxNode = boundArrayAccess.Syntax
            Dim type As ITypeSymbol = boundArrayAccess.Type
            Dim isImplicit As Boolean = boundArrayAccess.WasCompilerGenerated
            Return New ArrayElementReferenceOperation(arrayReference, indices, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Friend Function CreateBoundUnaryOperatorChild(boundOperator As BoundExpression) As IOperation
            Select Case boundOperator.Kind
                Case BoundKind.UnaryOperator
                    Return Create(DirectCast(boundOperator, BoundUnaryOperator).Operand)
                Case BoundKind.UserDefinedUnaryOperator
                    Dim userDefined = DirectCast(boundOperator, BoundUserDefinedUnaryOperator)
                    If userDefined.UnderlyingExpression.Kind = BoundKind.Call Then
                        Return Create(userDefined.Operand)
                    Else
                        Return GetChildOfBadExpression(userDefined.UnderlyingExpression, 0)
                    End If
                Case Else
                    Throw ExceptionUtilities.UnexpectedValue(boundOperator.Kind)
            End Select
        End Function
 
        Private Function CreateBoundUnaryOperatorOperation(boundUnaryOperator As BoundUnaryOperator) As IUnaryOperation
            Dim operand As IOperation = CreateBoundUnaryOperatorChild(boundUnaryOperator)
            Dim operatorKind As UnaryOperatorKind = Helper.DeriveUnaryOperatorKind(boundUnaryOperator.OperatorKind)
            Dim operatorMethod As IMethodSymbol = Nothing
            Dim syntax As SyntaxNode = boundUnaryOperator.Syntax
            Dim type As ITypeSymbol = boundUnaryOperator.Type
            Dim constantValue As ConstantValue = boundUnaryOperator.ConstantValueOpt
            Dim isLifted As Boolean = (boundUnaryOperator.OperatorKind And VisualBasic.UnaryOperatorKind.Lifted) <> 0
            Dim isChecked As Boolean = boundUnaryOperator.Checked
            Dim isImplicit As Boolean = boundUnaryOperator.WasCompilerGenerated
            Return New UnaryOperation(operatorKind, operand, isLifted, isChecked, operatorMethod, constrainedToType:=Nothing, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundUserDefinedUnaryOperatorOperation(boundUserDefinedUnaryOperator As BoundUserDefinedUnaryOperator) As IUnaryOperation
            Dim operand As IOperation = CreateBoundUnaryOperatorChild(boundUserDefinedUnaryOperator)
            Dim operatorKind As UnaryOperatorKind = Helper.DeriveUnaryOperatorKind(boundUserDefinedUnaryOperator.OperatorKind)
            Dim operatorMethod As IMethodSymbol = TryGetOperatorMethod(boundUserDefinedUnaryOperator)
            Dim syntax As SyntaxNode = boundUserDefinedUnaryOperator.Syntax
            Dim type As ITypeSymbol = boundUserDefinedUnaryOperator.Type
            Dim constantValue As ConstantValue = boundUserDefinedUnaryOperator.ConstantValueOpt
            Dim isLifted As Boolean = (boundUserDefinedUnaryOperator.OperatorKind And VisualBasic.UnaryOperatorKind.Lifted) <> 0
            Dim isChecked As Boolean = False
            Dim isImplicit As Boolean = boundUserDefinedUnaryOperator.WasCompilerGenerated
            Return New UnaryOperation(operatorKind, operand, isLifted, isChecked, operatorMethod, constrainedToType:=Nothing, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Shared Function TryGetOperatorMethod(boundUserDefinedUnaryOperator As BoundUserDefinedUnaryOperator) As MethodSymbol
            Return If(boundUserDefinedUnaryOperator.UnderlyingExpression.Kind = BoundKind.Call, boundUserDefinedUnaryOperator.Call.Method, Nothing)
        End Function
 
        Friend Function CreateBoundBinaryOperatorChild(binaryOperator As BoundExpression, isLeft As Boolean) As IOperation
            Select Case binaryOperator.Kind
                Case BoundKind.UserDefinedBinaryOperator
                    Dim boundUserDefined = DirectCast(binaryOperator, BoundUserDefinedBinaryOperator)
                    Dim binaryOperatorInfo As BinaryOperatorInfo = GetUserDefinedBinaryOperatorInfo(boundUserDefined)
                    Return GetUserDefinedBinaryOperatorChild(boundUserDefined, If(isLeft, binaryOperatorInfo.LeftOperand, binaryOperatorInfo.RightOperand))
                Case BoundKind.UserDefinedShortCircuitingOperator
                    Dim boundShortCircuiting = DirectCast(binaryOperator, BoundUserDefinedShortCircuitingOperator)
                    Dim binaryOperatorInfo As BinaryOperatorInfo = GetUserDefinedBinaryOperatorInfo(boundShortCircuiting.BitwiseOperator)
                    If isLeft Then
                        Return If(boundShortCircuiting.LeftOperand IsNot Nothing,
                                  Create(boundShortCircuiting.LeftOperand), ' Possibly dropping conversions https://github.com/dotnet/roslyn/issues/23236
                                  GetUserDefinedBinaryOperatorChild(boundShortCircuiting.BitwiseOperator, binaryOperatorInfo.LeftOperand))
                    Else
                        Return GetUserDefinedBinaryOperatorChild(boundShortCircuiting.BitwiseOperator, binaryOperatorInfo.RightOperand)
                    End If
                Case Else
                    Throw ExceptionUtilities.UnexpectedValue(binaryOperator.Kind)
            End Select
        End Function
 
        Private Function CreateBoundBinaryOperatorOperation(boundBinaryOperator As BoundBinaryOperator) As IOperation
            ' Binary operators can be nested _many_ levels deep, and cause a stack overflow if we manually recurse.
            ' To solve this, we use a manual stack for the left side.
            Dim stack As ArrayBuilder(Of BoundBinaryOperator) = ArrayBuilder(Of BoundBinaryOperator).GetInstance()
            Dim currentBinary As BoundBinaryOperator = boundBinaryOperator
 
            Do
                stack.Push(currentBinary)
                currentBinary = TryCast(currentBinary.Left, BoundBinaryOperator)
            Loop While currentBinary IsNot Nothing
 
            Debug.Assert(stack.Count > 0)
            Dim left As IOperation = Nothing
 
            While stack.TryPop(currentBinary)
                left = If(left, Create(currentBinary.Left))
                Dim right As IOperation = Create(currentBinary.Right)
 
                Dim binaryOperatorInfo = GetBinaryOperatorInfo(currentBinary)
                Dim syntax As SyntaxNode = currentBinary.Syntax
                Dim type As ITypeSymbol = currentBinary.Type
                Dim constantValue As ConstantValue = currentBinary.ConstantValueOpt
                Dim isImplicit As Boolean = currentBinary.WasCompilerGenerated
 
                left = New BinaryOperation(binaryOperatorInfo.OperatorKind, left, right, binaryOperatorInfo.IsLifted,
                                           binaryOperatorInfo.IsChecked, binaryOperatorInfo.IsCompareText, binaryOperatorInfo.OperatorMethod, constrainedToType:=Nothing,
                                           unaryOperatorMethod:=Nothing, _semanticModel, syntax, type, constantValue, isImplicit)
            End While
 
            Debug.Assert(left IsNot Nothing AndAlso stack.Count = 0)
            stack.Free()
            Return left
        End Function
 
        Private Function CreateBoundUserDefinedBinaryOperatorOperation(boundUserDefinedBinaryOperator As BoundUserDefinedBinaryOperator) As IBinaryOperation
            Dim left As IOperation = CreateBoundBinaryOperatorChild(boundUserDefinedBinaryOperator, isLeft:=True)
            Dim right As IOperation = CreateBoundBinaryOperatorChild(boundUserDefinedBinaryOperator, isLeft:=False)
            Dim binaryOperatorInfo = GetUserDefinedBinaryOperatorInfo(boundUserDefinedBinaryOperator)
            Dim syntax As SyntaxNode = boundUserDefinedBinaryOperator.Syntax
            Dim type As ITypeSymbol = boundUserDefinedBinaryOperator.Type
            Dim constantValue As ConstantValue = boundUserDefinedBinaryOperator.ConstantValueOpt
            Dim isImplicit As Boolean = boundUserDefinedBinaryOperator.WasCompilerGenerated
            Return New BinaryOperation(binaryOperatorInfo.OperatorKind, left, right, binaryOperatorInfo.IsLifted,
                                       binaryOperatorInfo.IsChecked, binaryOperatorInfo.IsCompareText, binaryOperatorInfo.OperatorMethod, constrainedToType:=Nothing,
                                       unaryOperatorMethod:=Nothing, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundBinaryConditionalExpressionOperation(boundBinaryConditionalExpression As BoundBinaryConditionalExpression) As ICoalesceOperation
            Dim value As IOperation = Create(boundBinaryConditionalExpression.TestExpression)
            Dim whenFalse As IOperation = Create(boundBinaryConditionalExpression.ElseExpression)
            Dim syntax As SyntaxNode = boundBinaryConditionalExpression.Syntax
            Dim type As ITypeSymbol = boundBinaryConditionalExpression.Type
            Dim constantValue As ConstantValue = boundBinaryConditionalExpression.ConstantValueOpt
            Dim isImplicit As Boolean = boundBinaryConditionalExpression.WasCompilerGenerated
 
            Dim valueConversion = New Conversion(Conversions.Identity)
 
            If Not TypeSymbol.Equals(boundBinaryConditionalExpression.Type, boundBinaryConditionalExpression.TestExpression.Type, TypeCompareKind.ConsiderEverything) Then
                Dim convertedTestExpression As BoundExpression = boundBinaryConditionalExpression.ConvertedTestExpression
                If convertedTestExpression IsNot Nothing Then
                    If convertedTestExpression.Kind = BoundKind.Conversion Then
                        valueConversion = CreateConversion(convertedTestExpression)
                    Else
                        Debug.Assert(convertedTestExpression.Kind = BoundKind.BadExpression)
                        valueConversion = New Conversion()
                    End If
                End If
            End If
 
            Return New CoalesceOperation(value, whenFalse, valueConversion, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundUserDefinedShortCircuitingOperatorOperation(boundUserDefinedShortCircuitingOperator As BoundUserDefinedShortCircuitingOperator) As IBinaryOperation
            Dim left As IOperation = CreateBoundBinaryOperatorChild(boundUserDefinedShortCircuitingOperator, isLeft:=True)
            Dim right As IOperation = CreateBoundBinaryOperatorChild(boundUserDefinedShortCircuitingOperator, isLeft:=False)
            Dim bitwiseOperator As BoundUserDefinedBinaryOperator = boundUserDefinedShortCircuitingOperator.BitwiseOperator
            Dim binaryOperatorInfo As BinaryOperatorInfo = GetUserDefinedBinaryOperatorInfo(bitwiseOperator)
            Dim operatorKind As BinaryOperatorKind = If(binaryOperatorInfo.OperatorKind = BinaryOperatorKind.And, BinaryOperatorKind.ConditionalAnd, BinaryOperatorKind.ConditionalOr)
 
            Dim syntax As SyntaxNode = boundUserDefinedShortCircuitingOperator.Syntax
            Dim type As ITypeSymbol = boundUserDefinedShortCircuitingOperator.Type
            Dim constantValue As ConstantValue = boundUserDefinedShortCircuitingOperator.ConstantValueOpt
            Dim isChecked As Boolean = False
            Dim isCompareText As Boolean = False
            Dim isImplicit As Boolean = boundUserDefinedShortCircuitingOperator.WasCompilerGenerated
 
            Dim unaryOperatorMethod As IMethodSymbol = Nothing
            Dim leftTest As BoundExpression = boundUserDefinedShortCircuitingOperator.LeftTest
            If leftTest IsNot Nothing Then
                unaryOperatorMethod = TryGetOperatorMethod(DirectCast(If(leftTest.Kind = BoundKind.UserDefinedUnaryOperator,
                                                                         leftTest,
                                                                         DirectCast(leftTest, BoundNullableIsTrueOperator).Operand),
                                                                      BoundUserDefinedUnaryOperator))
            End If
 
            Return New BinaryOperation(operatorKind, left, right, binaryOperatorInfo.IsLifted, isChecked, isCompareText,
                                       binaryOperatorInfo.OperatorMethod, constrainedToType:=Nothing, unaryOperatorMethod, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundBadExpressionOperation(boundBadExpression As BoundBadExpression) As IInvalidOperation
            Dim syntax As SyntaxNode = boundBadExpression.Syntax
            ' We match semantic model here: If the Then expression IsMissing, we have a null type, rather than the ErrorType Of the bound node.
            Dim type As ITypeSymbol = If(syntax.IsMissing, Nothing, boundBadExpression.Type)
            Dim constantValue As ConstantValue = boundBadExpression.ConstantValueOpt
 
            ' if child has syntax node point to same syntax node as bad expression, then this invalid expression Is implicit
            Dim isImplicit = boundBadExpression.WasCompilerGenerated OrElse boundBadExpression.ChildBoundNodes.Any(Function(e) e?.Syntax Is boundBadExpression.Syntax)
            Dim children = CreateFromArray(Of BoundExpression, IOperation)(boundBadExpression.ChildBoundNodes)
            Return New InvalidOperation(children, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundTypeArgumentsOperation(boundTypeArguments As BoundTypeArguments) As IInvalidOperation
            ' This can occur in scenarios involving latebound member accesses in Strict mode, such as
            ' element.UnresolvedMember(Of String)
            ' The BadExpression has 2 children in this case: the receiver, and the type arguments.
            ' Just create an invalid operation to represent the node, as it won't ever be surfaced in good code.
 
            Dim syntax As SyntaxNode = boundTypeArguments.Syntax
            ' Match GetTypeInfo behavior for the syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As ConstantValue = boundTypeArguments.ConstantValueOpt
            Dim isImplicit As Boolean = boundTypeArguments.WasCompilerGenerated
            Dim children As ImmutableArray(Of IOperation) = ImmutableArray(Of IOperation).Empty
 
            Return New InvalidOperation(children, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundAttributeOperation(boundAttribute As BoundAttribute) As IAttributeOperation
            Dim isAttributeImplicit = boundAttribute.WasCompilerGenerated
            If boundAttribute.Constructor Is Nothing OrElse boundAttribute.ConstructorArguments.Length <> boundAttribute.Constructor.ParameterCount Then
                Dim invalidOperation = OperationFactory.CreateInvalidOperation(_semanticModel, boundAttribute.Syntax, GetIOperationChildren(boundAttribute), isImplicit:=True)
                Return New AttributeOperation(invalidOperation, _semanticModel, boundAttribute.Syntax, isAttributeImplicit)
            End If
 
            Dim initializer As ObjectOrCollectionInitializerOperation = Nothing
            If Not boundAttribute.NamedArguments.IsEmpty Then
                Dim namedArguments = CreateFromArray(Of BoundExpression, IOperation)(boundAttribute.NamedArguments)
                initializer = New ObjectOrCollectionInitializerOperation(namedArguments, _semanticModel, boundAttribute.Syntax, boundAttribute.Type, isImplicit:=True)
            End If
 
            Dim objectCreationOperation = New ObjectCreationOperation(boundAttribute.Constructor, initializer, DeriveArguments(boundAttribute), _semanticModel, boundAttribute.Syntax, boundAttribute.Type, boundAttribute.ConstantValueOpt, isImplicit:=True)
            Return New AttributeOperation(objectCreationOperation, _semanticModel, boundAttribute.Syntax, isAttributeImplicit)
        End Function
 
        Private Function CreateBoundTryCastOperation(boundTryCast As BoundTryCast) As IOperation
            Return CreateBoundConversionOrCastOperation(boundTryCast, isTryCast:=True)
        End Function
 
        Private Function CreateBoundDirectCastOperation(boundDirectCast As BoundDirectCast) As IOperation
            Return CreateBoundConversionOrCastOperation(boundDirectCast, isTryCast:=False)
        End Function
 
        Private Function CreateBoundConversionOperation(boundConversion As BoundConversion) As IOperation
            Dim syntax As SyntaxNode = boundConversion.Syntax
 
            If syntax.IsMissing AndAlso boundConversion.Operand.Kind = BoundKind.BadExpression Then
                ' If the underlying syntax IsMissing, then that means we're in case where the compiler generated a piece of syntax to fill in for
                ' an error, such as this case:
                '
                '  Dim i =
                '
                ' Semantic model has a special case here that we match: if the underlying syntax is missing, don't create a conversion expression,
                ' and instead directly return the operand, which will be a BoundBadExpression. When we generate a node for the BoundBadExpression,
                ' the resulting IOperation will also have a null Type.
                Return Create(boundConversion.Operand)
            End If
 
            Return CreateBoundConversionOrCastOperation(boundConversion, isTryCast:=False)
        End Function
 
        Private Function CreateBoundConversionOrCastOperation(boundConversionOrCast As BoundConversionOrCast, isTryCast As Boolean) As IOperation
            Dim isChecked As Boolean = False
            Dim type As ITypeSymbol = boundConversionOrCast.Type
            Dim constantValue As ConstantValue = boundConversionOrCast.ConstantValueOpt
            Dim syntax As SyntaxNode = boundConversionOrCast.Syntax
            Dim isImplicit As Boolean = boundConversionOrCast.WasCompilerGenerated OrElse Not boundConversionOrCast.ExplicitCastInCode
 
            Dim boundOperand = GetConversionOperand(boundConversionOrCast)
            If boundOperand.Syntax Is boundConversionOrCast.Syntax Then
                If boundOperand.Kind = BoundKind.ConvertedTupleLiteral AndAlso TypeSymbol.Equals(boundOperand.Type, boundConversionOrCast.Type, TypeCompareKind.ConsiderEverything) Then
                    ' Erase this conversion, this is an artificial conversion added on top of BoundConvertedTupleLiteral
                    ' in Binder.ReclassifyTupleLiteral
                    Return Create(boundOperand)
                Else
                    ' Make this conversion implicit
                    isImplicit = True
                End If
            End If
 
            Dim conversionInfo = GetConversionInfo(boundConversionOrCast)
            Dim conversion As Conversion = conversionInfo.Conversion
 
            If conversionInfo.IsDelegateCreation Then
                Return New DelegateCreationOperation(conversionInfo.Operation, _semanticModel, syntax, type, isImplicit)
            Else
                Return New ConversionOperation(conversionInfo.Operation, conversion, isTryCast, isChecked, _semanticModel, syntax, type, constantValue, isImplicit)
            End If
        End Function
 
        Private Function CreateBoundDelegateCreationExpressionOperation(boundDelegateCreationExpression As BoundDelegateCreationExpression) As IDelegateCreationOperation
            Dim target As IOperation = CreateBoundDelegateCreationExpressionChildOperation(boundDelegateCreationExpression)
            Dim syntax As SyntaxNode = boundDelegateCreationExpression.Syntax
            Dim type As ITypeSymbol = boundDelegateCreationExpression.Type
 
            ' The operand for this is going to be using the same syntax node as this, and since that node can be Explicit, this node cannot be.
            Dim isImplicit As Boolean = True
 
            Return New DelegateCreationOperation(target, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Friend Function CreateBoundDelegateCreationExpressionChildOperation(boundDelegateCreationExpression As BoundDelegateCreationExpression) As IMethodReferenceOperation
            Dim method As IMethodSymbol = boundDelegateCreationExpression.Method
            Dim isVirtual As Boolean = method IsNot Nothing AndAlso
                                               (method.IsAbstract OrElse method.IsOverride OrElse method.IsVirtual) AndAlso
                                               Not boundDelegateCreationExpression.SuppressVirtualCalls
 
            Dim receiverOpt As IOperation = CreateReceiverOperation(
                If(boundDelegateCreationExpression.ReceiverOpt, boundDelegateCreationExpression.MethodGroupOpt?.ReceiverOpt),
                method)
 
            ' The compiler creates a BoundDelegateCreationExpression node for the AddressOf expression, and that's the node we want to use for the operand
            ' of the IDelegateCreationExpression parent
            Dim syntax As SyntaxNode = boundDelegateCreationExpression.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim isImplicit As Boolean = boundDelegateCreationExpression.WasCompilerGenerated
            Return New MethodReferenceOperation(method, constrainedToType:=Nothing, isVirtual, receiverOpt, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundTernaryConditionalExpressionOperation(boundTernaryConditionalExpression As BoundTernaryConditionalExpression) As IConditionalOperation
            Dim condition As IOperation = Create(boundTernaryConditionalExpression.Condition)
            Dim whenTrue As IOperation = Create(boundTernaryConditionalExpression.WhenTrue)
            Dim whenFalse As IOperation = Create(boundTernaryConditionalExpression.WhenFalse)
            Dim syntax As SyntaxNode = boundTernaryConditionalExpression.Syntax
            Dim type As ITypeSymbol = boundTernaryConditionalExpression.Type
            Dim constantValue As ConstantValue = boundTernaryConditionalExpression.ConstantValueOpt
            Dim isImplicit As Boolean = boundTernaryConditionalExpression.WasCompilerGenerated
            Dim isRef As Boolean = False
            Return New ConditionalOperation(condition, whenTrue, whenFalse, isRef, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundTypeOfOperation(boundTypeOf As BoundTypeOf) As IIsTypeOperation
            Dim valueOperand = Create(boundTypeOf.Operand)
            Dim typeOperand As ITypeSymbol = boundTypeOf.TargetType
            Dim isNegated As Boolean = boundTypeOf.IsTypeOfIsNotExpression
            Dim syntax As SyntaxNode = boundTypeOf.Syntax
            Dim type As ITypeSymbol = boundTypeOf.Type
            Dim isImplicit As Boolean = boundTypeOf.WasCompilerGenerated
            Return New IsTypeOperation(valueOperand, typeOperand, isNegated, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundGetTypeOperation(boundGetType As BoundGetType) As ITypeOfOperation
            Dim typeOperand As ITypeSymbol = boundGetType.SourceType.Type
            Dim syntax As SyntaxNode = boundGetType.Syntax
            Dim type As ITypeSymbol = boundGetType.Type
            Dim isImplicit As Boolean = boundGetType.WasCompilerGenerated
            Return New TypeOfOperation(typeOperand, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundLateInvocationOperation(boundLateInvocation As BoundLateInvocation) As IOperation
            Dim operation As IOperation = Create(boundLateInvocation.Member)
            Dim arguments As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundLateInvocation.ArgumentsOpt)
            Dim argumentNames As ImmutableArray(Of String) = boundLateInvocation.ArgumentNamesOpt
            Dim argumentRefKinds As ImmutableArray(Of RefKind) = Nothing
            Dim syntax As SyntaxNode = boundLateInvocation.Syntax
            Dim type As ITypeSymbol = boundLateInvocation.Type
            Dim isImplicit As Boolean = boundLateInvocation.WasCompilerGenerated
            Return New DynamicInvocationOperation(operation, arguments, argumentNames, argumentRefKinds, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundObjectCreationExpressionOperation(boundObjectCreationExpression As BoundObjectCreationExpression) As IObjectCreationOperation
            Debug.Assert(boundObjectCreationExpression.ConstructorOpt IsNot Nothing OrElse boundObjectCreationExpression.Arguments.IsEmpty())
            Dim constructor As IMethodSymbol = boundObjectCreationExpression.ConstructorOpt
            Dim initializer As IObjectOrCollectionInitializerOperation = DirectCast(Create(boundObjectCreationExpression.InitializerOpt), IObjectOrCollectionInitializerOperation)
            Dim arguments as ImmutableArray(Of IArgumentOperation) = DeriveArguments(boundObjectCreationExpression)
 
            Dim syntax As SyntaxNode = boundObjectCreationExpression.Syntax
            Dim type As ITypeSymbol = boundObjectCreationExpression.Type
            Dim constantValue As ConstantValue = boundObjectCreationExpression.ConstantValueOpt
            Dim isImplicit As Boolean = boundObjectCreationExpression.WasCompilerGenerated
            Return New ObjectCreationOperation(constructor, initializer, arguments, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundObjectInitializerExpressionOperation(boundObjectInitializerExpression As BoundObjectInitializerExpression) As IObjectOrCollectionInitializerOperation
            Dim initializers As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundObjectInitializerExpression.Initializers)
            Dim syntax As SyntaxNode = boundObjectInitializerExpression.Syntax
            Dim type As ITypeSymbol = boundObjectInitializerExpression.Type
            Dim isImplicit As Boolean = boundObjectInitializerExpression.WasCompilerGenerated
            Return New ObjectOrCollectionInitializerOperation(initializers, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundCollectionInitializerExpressionOperation(boundCollectionInitializerExpression As BoundCollectionInitializerExpression) As IObjectOrCollectionInitializerOperation
            Dim initializers As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundCollectionInitializerExpression.Initializers)
            Dim syntax As SyntaxNode = boundCollectionInitializerExpression.Syntax
            Dim type As ITypeSymbol = boundCollectionInitializerExpression.Type
            Dim isImplicit As Boolean = boundCollectionInitializerExpression.WasCompilerGenerated
            Return New ObjectOrCollectionInitializerOperation(initializers, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundNewTOperation(boundNewT As BoundNewT) As ITypeParameterObjectCreationOperation
            Dim initializer As IObjectOrCollectionInitializerOperation = DirectCast(Create(boundNewT.InitializerOpt), IObjectOrCollectionInitializerOperation)
            Dim syntax As SyntaxNode = boundNewT.Syntax
            Dim type As ITypeSymbol = boundNewT.Type
            Dim isImplicit As Boolean = boundNewT.WasCompilerGenerated
            Return New TypeParameterObjectCreationOperation(initializer, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateNoPiaObjectCreationExpressionOperation(creation As BoundNoPiaObjectCreationExpression) As INoPiaObjectCreationOperation
            Dim initializer As IObjectOrCollectionInitializerOperation = DirectCast(Create(creation.InitializerOpt), IObjectOrCollectionInitializerOperation)
            Dim syntax As SyntaxNode = creation.Syntax
            Dim type As ITypeSymbol = creation.Type
            Dim isImplicit As Boolean = creation.WasCompilerGenerated
            Return New NoPiaObjectCreationOperation(initializer, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundArrayCreationOperation(boundArrayCreation As BoundArrayCreation) As IArrayCreationOperation
            Dim dimensionSizes As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundArrayCreation.Bounds)
            Dim initializer As IArrayInitializerOperation = DirectCast(Create(boundArrayCreation.InitializerOpt), IArrayInitializerOperation)
            Dim syntax As SyntaxNode = boundArrayCreation.Syntax
            Dim type As ITypeSymbol = boundArrayCreation.Type
            Dim isImplicit As Boolean = boundArrayCreation.WasCompilerGenerated
            Return New ArrayCreationOperation(dimensionSizes, initializer, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundArrayInitializationOperation(boundArrayInitialization As BoundArrayInitialization) As IArrayInitializerOperation
            Dim elementValues As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundArrayInitialization.Initializers)
            Dim syntax As SyntaxNode = boundArrayInitialization.Syntax
            Dim isImplicit As Boolean = boundArrayInitialization.WasCompilerGenerated
            Return New ArrayInitializerOperation(elementValues, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundPropertyAccessOperation(boundPropertyAccess As BoundPropertyAccess) As IPropertyReferenceOperation
            Dim [property] As IPropertySymbol = boundPropertyAccess.PropertySymbol
            Dim instance As IOperation = CreateReceiverOperation(
                If(boundPropertyAccess.ReceiverOpt, boundPropertyAccess.PropertyGroupOpt?.ReceiverOpt),
                [property])
            Dim arguments as ImmutableArray(Of IArgumentOperation) = DeriveArguments(boundPropertyAccess)
 
            Dim syntax As SyntaxNode = boundPropertyAccess.Syntax
            Dim type As ITypeSymbol = boundPropertyAccess.Type
            Dim isImplicit As Boolean = boundPropertyAccess.WasCompilerGenerated
            Return New PropertyReferenceOperation([property], constrainedToType:=Nothing, arguments, instance, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundWithLValueExpressionPlaceholder(boundWithLValueExpressionPlaceholder As BoundWithLValueExpressionPlaceholder) As IInstanceReferenceOperation
            Dim referenceKind As InstanceReferenceKind = InstanceReferenceKind.ImplicitReceiver
            Dim syntax As SyntaxNode = boundWithLValueExpressionPlaceholder.Syntax
            Dim type As ITypeSymbol = boundWithLValueExpressionPlaceholder.Type
            Dim isImplicit As Boolean = boundWithLValueExpressionPlaceholder.WasCompilerGenerated
            Return New InstanceReferenceOperation(referenceKind, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundWithRValueExpressionPlaceholder(boundWithRValueExpressionPlaceholder As BoundWithRValueExpressionPlaceholder) As IInstanceReferenceOperation
            Dim referenceKind As InstanceReferenceKind = InstanceReferenceKind.ImplicitReceiver
            Dim syntax As SyntaxNode = boundWithRValueExpressionPlaceholder.Syntax
            Dim type As ITypeSymbol = boundWithRValueExpressionPlaceholder.Type
            Dim isImplicit As Boolean = boundWithRValueExpressionPlaceholder.WasCompilerGenerated
            Return New InstanceReferenceOperation(referenceKind, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundEventAccessOperation(boundEventAccess As BoundEventAccess) As IEventReferenceOperation
            Dim [event] As IEventSymbol = boundEventAccess.EventSymbol
            Dim instance As IOperation = CreateReceiverOperation(boundEventAccess.ReceiverOpt, [event])
 
            Dim syntax As SyntaxNode = boundEventAccess.Syntax
            Dim type As ITypeSymbol = boundEventAccess.Type
            Dim isImplicit As Boolean = boundEventAccess.WasCompilerGenerated
            Return New EventReferenceOperation([event], constrainedToType:=Nothing, instance, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundFieldAccessOperation(boundFieldAccess As BoundFieldAccess) As IFieldReferenceOperation
            Dim field As IFieldSymbol = boundFieldAccess.FieldSymbol
            Dim isDeclaration As Boolean = False
            Dim instance As IOperation = CreateReceiverOperation(boundFieldAccess.ReceiverOpt, field)
 
            Dim syntax As SyntaxNode = boundFieldAccess.Syntax
            Dim type As ITypeSymbol = boundFieldAccess.Type
            Dim constantValue As ConstantValue = boundFieldAccess.ConstantValueOpt
            Dim isImplicit As Boolean = boundFieldAccess.WasCompilerGenerated
            Return New FieldReferenceOperation(field, isDeclaration, instance, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundConditionalAccessOperation(boundConditionalAccess As BoundConditionalAccess) As IConditionalAccessOperation
            RecordParent(boundConditionalAccess.Placeholder, boundConditionalAccess)
            Dim operation As IOperation = Create(boundConditionalAccess.Receiver)
            Dim whenNotNull As IOperation = Create(boundConditionalAccess.AccessExpression)
            Dim syntax As SyntaxNode = boundConditionalAccess.Syntax
            Dim type As ITypeSymbol = boundConditionalAccess.Type
            Dim isImplicit As Boolean = boundConditionalAccess.WasCompilerGenerated
            Return New ConditionalAccessOperation(operation, whenNotNull, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundConditionalAccessReceiverPlaceholderOperation(boundConditionalAccessReceiverPlaceholder As BoundConditionalAccessReceiverPlaceholder) As IConditionalAccessInstanceOperation
            Dim syntax As SyntaxNode = boundConditionalAccessReceiverPlaceholder.Syntax
            Dim type As ITypeSymbol = boundConditionalAccessReceiverPlaceholder.Type
            Dim isImplicit As Boolean = boundConditionalAccessReceiverPlaceholder.WasCompilerGenerated
            Return New ConditionalAccessInstanceOperation(_semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundParameterOperation(boundParameter As BoundParameter) As IParameterReferenceOperation
            Dim parameter As IParameterSymbol = boundParameter.ParameterSymbol
            Dim syntax As SyntaxNode = boundParameter.Syntax
            Dim type As ITypeSymbol = boundParameter.Type
            Dim isImplicit As Boolean = boundParameter.WasCompilerGenerated
            Return New ParameterReferenceOperation(parameter, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundLocalOperation(boundLocal As BoundLocal) As IOperation
            Dim local As ILocalSymbol = boundLocal.LocalSymbol
            Dim isDeclaration As Boolean = False
            Dim syntax As SyntaxNode = boundLocal.Syntax
            Dim type As ITypeSymbol = boundLocal.Type
            Dim constantValue As ConstantValue = boundLocal.ConstantValueOpt
            Dim isImplicit As Boolean = boundLocal.WasCompilerGenerated
            Return New LocalReferenceOperation(local, isDeclaration, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundLateMemberAccessOperation(boundLateMemberAccess As BoundLateMemberAccess) As IDynamicMemberReferenceOperation
            Debug.Assert(boundLateMemberAccess.ReceiverOpt Is Nothing OrElse boundLateMemberAccess.ReceiverOpt.Kind <> BoundKind.TypeExpression)
 
            Dim instance As IOperation = Create(boundLateMemberAccess.ReceiverOpt)
            Dim memberName As String = boundLateMemberAccess.NameOpt
            Dim typeArguments As ImmutableArray(Of ITypeSymbol) = ImmutableArray(Of ITypeSymbol).Empty
            If boundLateMemberAccess.TypeArgumentsOpt IsNot Nothing Then
                typeArguments = ImmutableArray(Of ITypeSymbol).CastUp(boundLateMemberAccess.TypeArgumentsOpt.Arguments)
            End If
            Dim containingType As ITypeSymbol = Nothing
            ' If there's nothing being late-bound against, something is very wrong
            Debug.Assert(boundLateMemberAccess.ReceiverOpt IsNot Nothing OrElse boundLateMemberAccess.ContainerTypeOpt IsNot Nothing)
            ' Only set containing type if the container is set to something, and either there is no receiver, or the receiver's type
            ' does not match the type of the containing type.
            If (boundLateMemberAccess.ContainerTypeOpt IsNot Nothing AndAlso
                (boundLateMemberAccess.ReceiverOpt Is Nothing OrElse
                 Not TypeSymbol.Equals(boundLateMemberAccess.ContainerTypeOpt, boundLateMemberAccess.ReceiverOpt.Type, TypeCompareKind.ConsiderEverything))) Then
                containingType = boundLateMemberAccess.ContainerTypeOpt
            End If
            Dim syntax As SyntaxNode = boundLateMemberAccess.Syntax
            Dim type As ITypeSymbol = boundLateMemberAccess.Type
            Dim isImplicit As Boolean = boundLateMemberAccess.WasCompilerGenerated
            Return New DynamicMemberReferenceOperation(instance, memberName, typeArguments, containingType, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundFieldInitializerOperation(boundFieldInitializer As BoundFieldInitializer) As IFieldInitializerOperation
            Dim initializedFields As ImmutableArray(Of IFieldSymbol) = boundFieldInitializer.InitializedFields.As(Of IFieldSymbol)
            Dim value As IOperation = Create(boundFieldInitializer.InitialValue)
            Dim syntax As SyntaxNode = boundFieldInitializer.Syntax
            Dim isImplicit As Boolean = boundFieldInitializer.WasCompilerGenerated
            Return New FieldInitializerOperation(initializedFields, ImmutableArray(Of ILocalSymbol).Empty, value, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundPropertyInitializerOperation(boundPropertyInitializer As BoundPropertyInitializer) As IPropertyInitializerOperation
            Dim initializedProperties As ImmutableArray(Of IPropertySymbol) = boundPropertyInitializer.InitializedProperties.As(Of IPropertySymbol)
            Dim value As IOperation = Create(boundPropertyInitializer.InitialValue)
            Dim syntax As SyntaxNode = boundPropertyInitializer.Syntax
            Dim isImplicit As Boolean = boundPropertyInitializer.WasCompilerGenerated
            Return New PropertyInitializerOperation(initializedProperties, ImmutableArray(Of ILocalSymbol).Empty, value, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundParameterEqualsValueOperation(boundParameterEqualsValue As BoundParameterEqualsValue) As IParameterInitializerOperation
            Dim parameter As IParameterSymbol = boundParameterEqualsValue.Parameter
            Dim value As IOperation = Create(boundParameterEqualsValue.Value)
            Dim syntax As SyntaxNode = boundParameterEqualsValue.Syntax
            Dim isImplicit As Boolean = boundParameterEqualsValue.WasCompilerGenerated
            Return New ParameterInitializerOperation(parameter, ImmutableArray(Of ILocalSymbol).Empty, value, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundLValueToRValueWrapper(boundNode As BoundLValueToRValueWrapper) As IOperation
            ' This is created in cases like collection initializers, where the implicit receiver is wrapped
            ' by this node. The node itself doesn't have anything interesting we want to expose, so we
            ' just pass through.
            Return Create(boundNode.UnderlyingLValue)
        End Function
 
        Private Function CreateBoundRValuePlaceholderOperation(boundRValuePlaceholder As BoundRValuePlaceholder) As IOperation
            Dim syntax As SyntaxNode = boundRValuePlaceholder.Syntax
            Dim type As ITypeSymbol = boundRValuePlaceholder.Type
            Dim isImplicit As Boolean = boundRValuePlaceholder.WasCompilerGenerated
 
            Dim knownParent As BoundNode = TryGetParent(boundRValuePlaceholder)
            Dim placeholderKind As PlaceholderKind = PlaceholderKind.Unspecified
 
            If knownParent IsNot Nothing Then
                Select Case knownParent.Kind
                    Case BoundKind.ConditionalAccess
                        ' BoundConditionalAccessReceiver isn't actually used until local rewriting, until then that node will be a
                        ' BoundRValuePlaceholder with a syntax node of the entire conditional access. So we dig through the syntax
                        ' to get the expression being conditionally accessed, and return an IConditionalAccessInstanceOperation
                        ' instead of a PlaceholderOperation
                        syntax = If(TryCast(syntax, ConditionalAccessExpressionSyntax)?.Expression, syntax)
                        Return New ConditionalAccessInstanceOperation(_semanticModel, syntax, type, isImplicit)
 
                    Case BoundKind.SelectStatement
                        placeholderKind = PlaceholderKind.SwitchOperationExpression
 
                    Case BoundKind.ForToStatement
                        Dim operators As BoundForToUserDefinedOperators = DirectCast(knownParent, BoundForToStatement).OperatorsOpt
                        If boundRValuePlaceholder Is operators.LeftOperandPlaceholder Then
                            placeholderKind = PlaceholderKind.ForToLoopBinaryOperatorLeftOperand
                        Else
                            Debug.Assert(boundRValuePlaceholder Is operators.RightOperandPlaceholder)
                            placeholderKind = PlaceholderKind.ForToLoopBinaryOperatorRightOperand
                        End If
 
                    Case BoundKind.AggregateClause
                        placeholderKind = PlaceholderKind.AggregationGroup
 
                End Select
            End If
 
            Return New PlaceholderOperation(placeholderKind, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundIfStatementOperation(boundIfStatement As BoundIfStatement) As IConditionalOperation
            Dim condition as IOperation = Create(boundIfStatement.Condition)
            Dim whenTrue as IOperation = Create(boundIfStatement.Consequence)
            Dim whenFalse as IOperation = Create(boundIfStatement.AlternativeOpt)
            Dim syntax As SyntaxNode = boundIfStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As ConstantValue = Nothing
            Dim isImplicit As Boolean = boundIfStatement.WasCompilerGenerated
            Dim isRef As Boolean = False
            Return New ConditionalOperation(condition, whenTrue, whenFalse, isRef, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Private Function CreateBoundSelectStatementOperation(boundSelectStatement As BoundSelectStatement) As ISwitchOperation
            RecordParent(boundSelectStatement.ExprPlaceholderOpt, boundSelectStatement)
            Dim value As IOperation = Create(boundSelectStatement.ExpressionStatement.Expression)
            Dim cases As ImmutableArray(Of ISwitchCaseOperation) = CreateFromArray(Of BoundCaseBlock, ISwitchCaseOperation)(boundSelectStatement.CaseBlocks)
            Dim exitLabel As ILabelSymbol = boundSelectStatement.ExitLabel
            Dim syntax As SyntaxNode = boundSelectStatement.Syntax
            Dim isImplicit As Boolean = boundSelectStatement.WasCompilerGenerated
            Return New SwitchOperation(ImmutableArray(Of ILocalSymbol).Empty, value, cases, exitLabel, _semanticModel, syntax, isImplicit)
        End Function
 
        Friend Function CreateBoundCaseBlockClauses(boundCaseBlock As BoundCaseBlock) As ImmutableArray(Of ICaseClauseOperation)
            ' `CaseElseClauseSyntax` is bound to `BoundCaseStatement` with an empty list of case clauses,
            ' so we explicitly create an IOperation node for Case-Else clause to differentiate it from Case clause.
            Dim caseStatement = boundCaseBlock.CaseStatement
            If caseStatement.CaseClauses.IsEmpty AndAlso caseStatement.Syntax.Kind() = SyntaxKind.CaseElseStatement Then
                Return ImmutableArray.Create(Of ICaseClauseOperation)(
                            New DefaultCaseClauseOperation(
                                label:=Nothing,
                                _semanticModel,
                                caseStatement.Syntax,
                                isImplicit:=boundCaseBlock.WasCompilerGenerated))
            Else
                Return caseStatement.CaseClauses.SelectAsArray(Function(n) DirectCast(Create(n), ICaseClauseOperation))
            End If
        End Function
 
        Friend Function CreateBoundCaseBlockBody(boundCaseBlock As BoundCaseBlock) As ImmutableArray(Of IOperation)
            Return ImmutableArray.Create(Create(boundCaseBlock.Body))
        End Function
 
        Friend Function CreateBoundCaseBlockCondition(boundCaseBlock As BoundCaseBlock) As IOperation
            Return Create(boundCaseBlock.CaseStatement.ConditionOpt)
        End Function
 
        Private Function CreateBoundCaseBlockOperation(boundCaseBlock As BoundCaseBlock) As ISwitchCaseOperation
            Dim clauses As ImmutableArray(Of ICaseClauseOperation) = CreateBoundCaseBlockClauses(boundCaseBlock)
            Dim body As ImmutableArray(Of IOperation) = ImmutableArray.Create(Create(boundCaseBlock.Body))
            Dim condition As IOperation = CreateBoundCaseBlockCondition(boundCaseBlock)
            Dim syntax As SyntaxNode = boundCaseBlock.Syntax
            Dim isImplicit As Boolean = boundCaseBlock.WasCompilerGenerated
 
            Return New SwitchCaseOperation(clauses, body, ImmutableArray(Of ILocalSymbol).Empty, condition, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundSimpleCaseClauseOperation(boundSimpleCaseClause As BoundSimpleCaseClause) As ISingleValueCaseClauseOperation
            Dim clauseValue As IOperation = Create(GetSingleValueCaseClauseValue(boundSimpleCaseClause))
            Dim syntax As SyntaxNode = boundSimpleCaseClause.Syntax
            Dim isImplicit As Boolean = boundSimpleCaseClause.WasCompilerGenerated
            Return New SingleValueCaseClauseOperation(clauseValue, label:=Nothing, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundRangeCaseClauseOperation(boundRangeCaseClause As BoundRangeCaseClause) As IRangeCaseClauseOperation
            Dim minimumValue As IOperation = Create(GetCaseClauseValue(boundRangeCaseClause.LowerBoundOpt, boundRangeCaseClause.LowerBoundConditionOpt))
            Dim maximumValue As IOperation = Create(GetCaseClauseValue(boundRangeCaseClause.UpperBoundOpt, boundRangeCaseClause.UpperBoundConditionOpt))
            Debug.Assert(minimumValue IsNot Nothing AndAlso maximumValue IsNot Nothing)
            Dim syntax As SyntaxNode = boundRangeCaseClause.Syntax
            Dim isImplicit As Boolean = boundRangeCaseClause.WasCompilerGenerated
            Return New RangeCaseClauseOperation(minimumValue, maximumValue, label:=Nothing, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundRelationalCaseClauseOperation(boundRelationalCaseClause As BoundRelationalCaseClause) As IRelationalCaseClauseOperation
            Dim valueExpression As IOperation = Create(GetSingleValueCaseClauseValue(boundRelationalCaseClause))
            Dim relation As BinaryOperatorKind = If(valueExpression IsNot Nothing, Helper.DeriveBinaryOperatorKind(boundRelationalCaseClause.OperatorKind, leftOpt:=Nothing), BinaryOperatorKind.None)
            Dim syntax As SyntaxNode = boundRelationalCaseClause.Syntax
            Dim isImplicit As Boolean = boundRelationalCaseClause.WasCompilerGenerated
            Return New RelationalCaseClauseOperation(valueExpression, relation, label:=Nothing, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundDoLoopStatementOperation(boundDoLoopStatement As BoundDoLoopStatement) As IWhileLoopOperation
            Dim condition As IOperation = Create(boundDoLoopStatement.ConditionOpt)
            Dim body As IOperation = Create(boundDoLoopStatement.Body)
            Dim ignoredCondition As IOperation = If(boundDoLoopStatement.TopConditionOpt IsNot Nothing AndAlso boundDoLoopStatement.BottomConditionOpt IsNot Nothing,
                Create(boundDoLoopStatement.BottomConditionOpt), Nothing)
            Dim locals As ImmutableArray(Of ILocalSymbol) = ImmutableArray(Of ILocalSymbol).Empty
            Dim continueLabel As ILabelSymbol = boundDoLoopStatement.ContinueLabel
            Dim exitLabel As ILabelSymbol = boundDoLoopStatement.ExitLabel
            Dim conditionIsTop As Boolean = boundDoLoopStatement.ConditionIsTop
            Dim conditionIsUntil As Boolean = boundDoLoopStatement.ConditionIsUntil
            Dim syntax As SyntaxNode = boundDoLoopStatement.Syntax
            Dim isImplicit As Boolean = boundDoLoopStatement.WasCompilerGenerated
            Return New WhileLoopOperation(condition, conditionIsTop, conditionIsUntil, ignoredCondition, body, locals, continueLabel, exitLabel, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundForToStatementOperation(boundForToStatement As BoundForToStatement) As IForToLoopOperation
            Dim loopControlVariable As IOperation = CreateBoundControlVariableOperation(boundForToStatement)
            Dim initialValue As IOperation = Create(boundForToStatement.InitialValue)
            Dim limitValue As IOperation = Create(boundForToStatement.LimitValue)
            Dim stepValue As IOperation = Create(boundForToStatement.StepValue)
            Dim body As IOperation = Create(boundForToStatement.Body)
            Dim nextVariables As ImmutableArray(Of IOperation) = If(boundForToStatement.NextVariablesOpt.IsDefault,
                ImmutableArray(Of IOperation).Empty,
                CreateFromArray(Of BoundExpression, IOperation)(boundForToStatement.NextVariablesOpt))
            Dim locals As ImmutableArray(Of ILocalSymbol) = If(boundForToStatement.DeclaredOrInferredLocalOpt IsNot Nothing,
                ImmutableArray.Create(Of ILocalSymbol)(boundForToStatement.DeclaredOrInferredLocalOpt),
                ImmutableArray(Of ILocalSymbol).Empty)
            Dim continueLabel As ILabelSymbol = boundForToStatement.ContinueLabel
            Dim exitLabel As ILabelSymbol = boundForToStatement.ExitLabel
            Dim syntax As SyntaxNode = boundForToStatement.Syntax
            Dim isImplicit As Boolean = boundForToStatement.WasCompilerGenerated
            Dim loopObj = If(boundForToStatement.ControlVariable.Type.IsObjectType,
                             New SynthesizedLocal(DirectCast(_semanticModel.GetEnclosingSymbol(boundForToStatement.Syntax.SpanStart), Symbol), boundForToStatement.ControlVariable.Type,
                                                  SynthesizedLocalKind.ForInitialValue, boundForToStatement.Syntax),
                             Nothing)
 
            Dim userDefinedInfo As ForToLoopOperationUserDefinedInfo = Nothing
            Dim operatorsOpt As BoundForToUserDefinedOperators = boundForToStatement.OperatorsOpt
            If operatorsOpt IsNot Nothing Then
                RecordParent(operatorsOpt.LeftOperandPlaceholder, boundForToStatement)
                RecordParent(operatorsOpt.RightOperandPlaceholder, boundForToStatement)
                userDefinedInfo = New ForToLoopOperationUserDefinedInfo(DirectCast(Operation.SetParentOperation(Create(operatorsOpt.Addition), Nothing), IBinaryOperation),
                                                                        DirectCast(Operation.SetParentOperation(Create(operatorsOpt.Subtraction), Nothing), IBinaryOperation),
                                                                        Operation.SetParentOperation(Create(operatorsOpt.LessThanOrEqual), Nothing),
                                                                        Operation.SetParentOperation(Create(operatorsOpt.GreaterThanOrEqual), Nothing))
            End If
 
            Return New ForToLoopOperation(loopControlVariable, initialValue, limitValue, stepValue, boundForToStatement.Checked, nextVariables, (loopObj, userDefinedInfo),
                                          body, locals, continueLabel, exitLabel, _semanticModel, syntax, isImplicit)
        End Function
 
        Friend Function GetForEachLoopOperationInfo(boundForEachStatement As BoundForEachStatement) As ForEachLoopOperationInfo
            Dim getEnumeratorArguments As ImmutableArray(Of BoundExpression) = Nothing
            Dim getEnumeratorDefaultArguments As BitVector = BitVector.Null
            Dim moveNextArguments As ImmutableArray(Of BoundExpression) = Nothing
            Dim moveNextDefaultArguments As BitVector = BitVector.Null
            Dim currentArguments As ImmutableArray(Of BoundExpression) = Nothing
            Dim currentDefaultArguments As BitVector = BitVector.Null
            Dim statementInfo As ForEachStatementInfo = MemberSemanticModel.GetForEachStatementInfo(boundForEachStatement,
                                                                                                    DirectCast(_semanticModel.Compilation, VisualBasicCompilation),
                                                                                                    getEnumeratorArguments, getEnumeratorDefaultArguments,
                                                                                                    moveNextArguments, moveNextDefaultArguments,
                                                                                                    currentArguments, currentDefaultArguments)
 
            Return New ForEachLoopOperationInfo(statementInfo.ElementType,
                                                     statementInfo.GetEnumeratorMethod,
                                                     statementInfo.CurrentProperty,
                                                     statementInfo.MoveNextMethod,
                                                     isAsynchronous:=False,
                                                     inlineArrayConversion:=Nothing,
                                                     collectionIsInlineArrayValue:=False,
                                                     boundForEachStatement.EnumeratorInfo.NeedToDispose,
                                                     knownToImplementIDisposable:=boundForEachStatement.EnumeratorInfo.NeedToDispose AndAlso
                                                                                  boundForEachStatement.EnumeratorInfo.IsOrInheritsFromOrImplementsIDisposable,
                                                     patternDisposeMethod:=Nothing,
                                                     statementInfo.CurrentConversion,
                                                     statementInfo.ElementConversion,
                                                     If(getEnumeratorArguments.IsDefaultOrEmpty, Nothing,
                                                        Operation.SetParentOperation(
                                                                           DeriveArguments(getEnumeratorArguments,
                                                                                           DirectCast(statementInfo.GetEnumeratorMethod, MethodSymbol).Parameters,
                                                                                           getEnumeratorDefaultArguments),
                                                                           Nothing)),
                                                     If(moveNextArguments.IsDefaultOrEmpty, Nothing,
                                                        Operation.SetParentOperation(
                                                                           DeriveArguments(moveNextArguments,
                                                                                           DirectCast(statementInfo.MoveNextMethod, MethodSymbol).Parameters,
                                                                                           moveNextDefaultArguments),
                                                                           Nothing)),
                                                     If(currentArguments.IsDefaultOrEmpty, Nothing,
                                                        Operation.SetParentOperation(
                                                                           DeriveArguments(currentArguments,
                                                                                           DirectCast(statementInfo.CurrentProperty, PropertySymbol).Parameters,
                                                                                           currentDefaultArguments),
                                                                           Nothing)))
        End Function
 
        Private Function CreateBoundForEachStatementOperation(boundForEachStatement As BoundForEachStatement) As IForEachLoopOperation
            Dim info As ForEachLoopOperationInfo = GetForEachLoopOperationInfo(boundForEachStatement)
            Dim controlVariable As IOperation = CreateBoundControlVariableOperation(boundForEachStatement)
            Dim collection As IOperation = Create(boundForEachStatement.Collection)
            Dim nextVariables = If(boundForEachStatement.NextVariablesOpt.IsDefault,
                ImmutableArray(Of IOperation).Empty,
                CreateFromArray(Of BoundExpression, IOperation)(boundForEachStatement.NextVariablesOpt))
            Dim body As IOperation = Create(boundForEachStatement.Body)
            Dim locals As ImmutableArray(Of ILocalSymbol) = If(boundForEachStatement.DeclaredOrInferredLocalOpt IsNot Nothing,
                ImmutableArray.Create(Of ILocalSymbol)(boundForEachStatement.DeclaredOrInferredLocalOpt),
                ImmutableArray(Of ILocalSymbol).Empty)
            Dim continueLabel As ILabelSymbol = boundForEachStatement.ContinueLabel
            Dim exitLabel As ILabelSymbol = boundForEachStatement.ExitLabel
            Dim syntax As SyntaxNode = boundForEachStatement.Syntax
            Dim isImplicit As Boolean = boundForEachStatement.WasCompilerGenerated
            Return New ForEachLoopOperation(controlVariable, collection, nextVariables, info, isAsynchronous:=False, body, locals, continueLabel, exitLabel, _semanticModel, syntax, isImplicit)
        End Function
 
        Friend Function CreateBoundControlVariableOperation(boundForStatement As BoundForStatement) As IOperation
            Dim localOpt As LocalSymbol = boundForStatement.DeclaredOrInferredLocalOpt
            Dim controlVariable As BoundExpression = boundForStatement.ControlVariable
            Return If(localOpt IsNot Nothing,
                New VariableDeclaratorOperation(localOpt, initializer:=Nothing, ignoredArguments:=ImmutableArray(Of IOperation).Empty, semanticModel:=_semanticModel, syntax:=controlVariable.Syntax, isImplicit:=boundForStatement.WasCompilerGenerated),
                Create(controlVariable))
        End Function
 
        Private Function CreateBoundTryStatementOperation(boundTryStatement As BoundTryStatement) As ITryOperation
            Dim body As IBlockOperation = DirectCast(Create(boundTryStatement.TryBlock), IBlockOperation)
            Dim catches As ImmutableArray(Of ICatchClauseOperation) = CreateFromArray(Of BoundCatchBlock, ICatchClauseOperation)(boundTryStatement.CatchBlocks)
            Dim [finally] As IBlockOperation = DirectCast(Create(boundTryStatement.FinallyBlockOpt), IBlockOperation)
            Dim exitLabel As ILabelSymbol = boundTryStatement.ExitLabelOpt
            Dim syntax As SyntaxNode = boundTryStatement.Syntax
            Dim isImplicit As Boolean = boundTryStatement.WasCompilerGenerated
            Return New TryOperation(body, catches, [finally], exitLabel, _semanticModel, syntax, isImplicit)
        End Function
 
        Friend Function CreateBoundCatchBlockExceptionDeclarationOrExpression(boundCatchBlock As BoundCatchBlock) As IOperation
            If boundCatchBlock.LocalOpt IsNot Nothing AndAlso
                        If(boundCatchBlock.ExceptionSourceOpt?.Kind = BoundKind.Local, False) AndAlso
                        boundCatchBlock.LocalOpt Is DirectCast(boundCatchBlock.ExceptionSourceOpt, BoundLocal).LocalSymbol Then
                Return New VariableDeclaratorOperation(boundCatchBlock.LocalOpt, initializer:=Nothing, ignoredArguments:=ImmutableArray(Of IOperation).Empty, semanticModel:=_semanticModel, syntax:=boundCatchBlock.ExceptionSourceOpt.Syntax, isImplicit:=False)
            Else
                Return Create(boundCatchBlock.ExceptionSourceOpt)
            End If
        End Function
 
        Private Function CreateBoundCatchBlockOperation(boundCatchBlock As BoundCatchBlock) As ICatchClauseOperation
            Dim exceptionDeclarationOrExpression as IOperation = CreateBoundCatchBlockExceptionDeclarationOrExpression(boundCatchBlock)
            Dim filter As IOperation = Create(boundCatchBlock.ExceptionFilterOpt)
            Dim handler As IBlockOperation = DirectCast(Create(boundCatchBlock.Body), IBlockOperation)
            Dim exceptionType As ITypeSymbol = If(boundCatchBlock.ExceptionSourceOpt?.Type, DirectCast(_semanticModel.Compilation, VisualBasicCompilation).GetWellKnownType(WellKnownType.System_Exception))
            Dim locals As ImmutableArray(Of ILocalSymbol) = If(boundCatchBlock.LocalOpt IsNot Nothing,
                ImmutableArray.Create(Of ILocalSymbol)(boundCatchBlock.LocalOpt),
                ImmutableArray(Of ILocalSymbol).Empty)
            Dim syntax As SyntaxNode = boundCatchBlock.Syntax
            Dim isImplicit As Boolean = boundCatchBlock.WasCompilerGenerated
            Return New CatchClauseOperation(exceptionDeclarationOrExpression, exceptionType, locals, filter, handler, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundBlockOperation(boundBlock As BoundBlock) As IBlockOperation
            Dim operations As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundStatement, IOperation)(boundBlock.Statements)
            Dim locals As ImmutableArray(Of ILocalSymbol) = boundBlock.Locals.As(Of ILocalSymbol)()
            Dim syntax As SyntaxNode = boundBlock.Syntax
            Dim isImplicit As Boolean = boundBlock.WasCompilerGenerated
            Return New BlockOperation(operations, locals, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundBadStatementOperation(boundBadStatement As BoundBadStatement) As IInvalidOperation
            Dim syntax As SyntaxNode = boundBadStatement.Syntax
 
            ' if child has syntax node point to same syntax node as bad statement, then this invalid statement is implicit
            Dim isImplicit = boundBadStatement.WasCompilerGenerated
            If Not isImplicit Then
                For Each child In boundBadStatement.ChildBoundNodes
                    If child?.Syntax Is boundBadStatement.Syntax Then
                        isImplicit = True
                        Exit For
                    End If
                Next
            End If
 
            Dim children = CreateFromArray(Of BoundNode, IOperation)(boundBadStatement.ChildBoundNodes)
 
            Return New InvalidOperation(children, _semanticModel, syntax, type:=Nothing, constantValue:=Nothing, isImplicit)
        End Function
 
        Private Function CreateBoundReturnStatementOperation(boundReturnStatement As BoundReturnStatement) As IReturnOperation
            Dim returnedValue As IOperation = Create(boundReturnStatement.ExpressionOpt)
            Dim syntax As SyntaxNode = boundReturnStatement.Syntax
            Dim isImplicit As Boolean = boundReturnStatement.WasCompilerGenerated OrElse IsEndSubOrFunctionStatement(syntax)
            Return New ReturnOperation(returnedValue, OperationKind.Return, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Shared Function IsEndSubOrFunctionStatement(syntax As SyntaxNode) As Boolean
            Return TryCast(syntax.Parent, MethodBlockBaseSyntax)?.EndBlockStatement Is syntax OrElse
                   TryCast(syntax.Parent, MultiLineLambdaExpressionSyntax)?.EndSubOrFunctionStatement Is syntax
        End Function
 
        Private Function CreateBoundThrowStatementOperation(boundThrowStatement As BoundThrowStatement) As IThrowOperation
            Dim thrownObject As IOperation = Create(boundThrowStatement.ExpressionOpt)
            Dim syntax As SyntaxNode = boundThrowStatement.Syntax
            Dim expressionType As ITypeSymbol = Nothing
            Dim isImplicit As Boolean = boundThrowStatement.WasCompilerGenerated
            Return New ThrowOperation(thrownObject, _semanticModel, syntax, expressionType, isImplicit)
        End Function
 
        Private Function CreateBoundWhileStatementOperation(boundWhileStatement As BoundWhileStatement) As IWhileLoopOperation
            Dim condition As IOperation = Create(boundWhileStatement.Condition)
            Dim body As IOperation = Create(boundWhileStatement.Body)
            Dim ignoredCondition As IOperation = Nothing
            Dim locals As ImmutableArray(Of ILocalSymbol) = ImmutableArray(Of ILocalSymbol).Empty
            Dim continueLabel As ILabelSymbol = boundWhileStatement.ContinueLabel
            Dim exitLabel As ILabelSymbol = boundWhileStatement.ExitLabel
            Dim conditionIsTop As Boolean = True
            Dim conditionIsUntil As Boolean = False
            Dim syntax As SyntaxNode = boundWhileStatement.Syntax
            Dim isImplicit As Boolean = boundWhileStatement.WasCompilerGenerated
            Return New WhileLoopOperation(condition, conditionIsTop, conditionIsUntil, ignoredCondition, body, locals, continueLabel, exitLabel, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundDimStatementOperation(boundDimStatement As BoundDimStatement) As IVariableDeclarationGroupOperation
            Dim declarations As ImmutableArray(Of IVariableDeclarationOperation) = GetVariableDeclarationStatementVariables(boundDimStatement.LocalDeclarations)
            Dim syntax As SyntaxNode = boundDimStatement.Syntax
            Dim isImplicit As Boolean = boundDimStatement.WasCompilerGenerated
            Return New VariableDeclarationGroupOperation(declarations, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundLocalDeclarationOperation(boundLocalDeclaration As BoundLocalDeclaration) As IVariableDeclarationGroupOperation
            Dim declarations As ImmutableArray(Of IVariableDeclarationOperation) =
                GetVariableDeclarationStatementVariables(ImmutableArray.Create(Of BoundLocalDeclarationBase)(boundLocalDeclaration))
            Dim syntax As SyntaxNode = boundLocalDeclaration.Syntax
            Debug.Assert(boundLocalDeclaration.WasCompilerGenerated)
            Dim isImplicit As Boolean = True
            Return New VariableDeclarationGroupOperation(declarations, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundYieldStatementOperation(boundYieldStatement As BoundYieldStatement) As IReturnOperation
            Dim returnedValue As IOperation = Create(boundYieldStatement.Expression)
            Dim syntax As SyntaxNode = boundYieldStatement.Syntax
            Dim isImplicit As Boolean = boundYieldStatement.WasCompilerGenerated
            Return New ReturnOperation(returnedValue, OperationKind.YieldReturn, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundLabelStatementOperation(boundLabelStatement As BoundLabelStatement) As ILabeledOperation
            Dim label As ILabelSymbol = boundLabelStatement.Label
            Dim statement As IOperation = Nothing
            Dim syntax As SyntaxNode = boundLabelStatement.Syntax
            Dim isImplicit As Boolean = boundLabelStatement.WasCompilerGenerated OrElse IsEndSubOrFunctionStatement(syntax)
            Return New LabeledOperation(label, statement, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundGotoStatementOperation(boundGotoStatement As BoundGotoStatement) As IBranchOperation
            Dim target As ILabelSymbol = boundGotoStatement.Label
            Dim branchKind As BranchKind = BranchKind.GoTo
            Dim syntax As SyntaxNode = boundGotoStatement.Syntax
            Dim isImplicit As Boolean = boundGotoStatement.WasCompilerGenerated
            Return New BranchOperation(target, branchKind, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundContinueStatementOperation(boundContinueStatement As BoundContinueStatement) As IBranchOperation
            Dim target As ILabelSymbol = boundContinueStatement.Label
            Dim branchKind As BranchKind = BranchKind.Continue
            Dim syntax As SyntaxNode = boundContinueStatement.Syntax
            Dim isImplicit As Boolean = boundContinueStatement.WasCompilerGenerated
            Return New BranchOperation(target, branchKind, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundExitStatementOperation(boundExitStatement As BoundExitStatement) As IBranchOperation
            Dim target As ILabelSymbol = boundExitStatement.Label
            Dim branchKind As BranchKind = BranchKind.Break
            Dim syntax As SyntaxNode = boundExitStatement.Syntax
            Dim isImplicit As Boolean = boundExitStatement.WasCompilerGenerated
            Return New BranchOperation(target, branchKind, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundSyncLockStatementOperation(boundSyncLockStatement As BoundSyncLockStatement) As ILockOperation
            Dim legacyMode = _semanticModel.Compilation.CommonGetWellKnownTypeMember(WellKnownMember.System_Threading_Monitor__Enter2) Is Nothing
            Dim lockTakenSymbol As ILocalSymbol =
                If(legacyMode, Nothing,
                               New SynthesizedLocal(DirectCast(_semanticModel.GetEnclosingSymbol(boundSyncLockStatement.Syntax.SpanStart), Symbol),
                                                    DirectCast(_semanticModel.Compilation.GetSpecialType(SpecialType.System_Boolean), TypeSymbol),
                                                    SynthesizedLocalKind.LockTaken,
                                                    syntaxOpt:=boundSyncLockStatement.LockExpression.Syntax))
            Dim lockedValue as IOperation = Create(boundSyncLockStatement.LockExpression)
            Dim body as IOperation = Create(boundSyncLockStatement.Body)
            Dim syntax As SyntaxNode = boundSyncLockStatement.Syntax
            Dim isImplicit As Boolean = boundSyncLockStatement.WasCompilerGenerated
            Return New LockOperation(lockedValue, body, lockTakenSymbol, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundNoOpStatementOperation(boundNoOpStatement As BoundNoOpStatement) As IEmptyOperation
            Dim syntax As SyntaxNode = boundNoOpStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As ConstantValue = Nothing
            Dim isImplicit As Boolean = boundNoOpStatement.WasCompilerGenerated
            Return New EmptyOperation(_semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundStopStatementOperation(boundStopStatement As BoundStopStatement) As IStopOperation
            Dim syntax As SyntaxNode = boundStopStatement.Syntax
            Dim isImplicit As Boolean = boundStopStatement.WasCompilerGenerated
            Return New StopOperation(_semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundEndStatementOperation(boundEndStatement As BoundEndStatement) As IEndOperation
            Dim syntax As SyntaxNode = boundEndStatement.Syntax
            Dim isImplicit As Boolean = boundEndStatement.WasCompilerGenerated
            Return New EndOperation(_semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundWithStatementOperation(boundWithStatement As BoundWithStatement) As IWithStatementOperation
            Dim value As IOperation = Create(boundWithStatement.OriginalExpression)
            Dim body As IOperation = Create(boundWithStatement.Body)
            Dim syntax As SyntaxNode = boundWithStatement.Syntax
            Dim isImplicit As Boolean = boundWithStatement.WasCompilerGenerated
            Return New WithStatementOperation(body, value, _semanticModel, syntax, isImplicit)
        End Function
 
        Friend Function CreateBoundUsingStatementResources(boundUsingStatement As BoundUsingStatement) As IOperation
            If Not boundUsingStatement.ResourceList.IsDefault Then
                Return GetUsingStatementDeclaration(boundUsingStatement.ResourceList, DirectCast(boundUsingStatement.Syntax, UsingBlockSyntax).UsingStatement)
            Else
                Return Create(boundUsingStatement.ResourceExpressionOpt)
            End If
        End Function
 
        Private Function CreateBoundUsingStatementOperation(boundUsingStatement As BoundUsingStatement) As IUsingOperation
            Dim resources As IOperation = CreateBoundUsingStatementResources(boundUsingStatement)
            Dim body As IOperation = Create(boundUsingStatement.Body)
            Dim locals As ImmutableArray(Of ILocalSymbol) = ImmutableArray(Of ILocalSymbol).CastUp(boundUsingStatement.Locals)
            Dim syntax As SyntaxNode = boundUsingStatement.Syntax
            Dim isImplicit As Boolean = boundUsingStatement.WasCompilerGenerated
            Return New UsingOperation(resources, body, locals, isAsynchronous:=False, disposeInfo:=Nothing, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundExpressionStatementOperation(boundExpressionStatement As BoundExpressionStatement) As IExpressionStatementOperation
            Dim expression As IOperation = Create(boundExpressionStatement.Expression)
            Dim syntax As SyntaxNode = boundExpressionStatement.Syntax
            Dim isImplicit As Boolean = boundExpressionStatement.WasCompilerGenerated
            Return New ExpressionStatementOperation(expression, _semanticModel, syntax, isImplicit)
        End Function
 
        Friend Function CreateBoundRaiseEventStatementEventReference(boundRaiseEventStatement As BoundRaiseEventStatement) As IEventReferenceOperation
            Dim eventInvocation = DirectCast(boundRaiseEventStatement.EventInvocation, BoundCall)
            Dim receiverOpt = eventInvocation.ReceiverOpt
            Dim eventReferenceSyntax = If(receiverOpt?.Syntax,
                                          If(TryCast(boundRaiseEventStatement.Syntax, RaiseEventStatementSyntax)?.Name,
                                             boundRaiseEventStatement.Syntax))
            Dim eventReferenceType As ITypeSymbol = boundRaiseEventStatement.EventSymbol.Type
            ' EventReference in a raise event statement is never implicit. However, the way it is implemented, we don't get
            ' a "BoundEventAccess" for either field backed event or custom event, and the bound nodes we get are marked as
            ' generated by compiler. As a result, we have to explicitly set IsImplicit to false.
            Dim eventReferenceIsImplicit As Boolean = False
 
            If receiverOpt?.Kind = BoundKind.FieldAccess Then
                ' For raising a field backed event, we will only get a field access node in bound tree.
                Dim eventFieldAccess = DirectCast(receiverOpt, BoundFieldAccess)
                Debug.Assert(eventFieldAccess.FieldSymbol.AssociatedSymbol = boundRaiseEventStatement.EventSymbol)
 
                receiverOpt = eventFieldAccess.ReceiverOpt
            End If
 
            Dim instance = CreateReceiverOperation(receiverOpt, boundRaiseEventStatement.EventSymbol)
            Return New EventReferenceOperation(boundRaiseEventStatement.EventSymbol, constrainedToType:=Nothing,
                                               instance,
                                               _semanticModel,
                                               eventReferenceSyntax,
                                               eventReferenceType,
                                               eventReferenceIsImplicit)
        End Function
 
        Private Function CreateBoundRaiseEventStatementOperation(boundRaiseEventStatement As BoundRaiseEventStatement) As IOperation
            Dim syntax As SyntaxNode = boundRaiseEventStatement.Syntax
            Dim isImplicit As Boolean = boundRaiseEventStatement.WasCompilerGenerated
 
            Dim eventSymbol = boundRaiseEventStatement.EventSymbol
            Dim eventInvocation = TryCast(boundRaiseEventStatement.EventInvocation, BoundCall)
 
            ' Return an invalid statement for invalid raise event statement
            If eventInvocation Is Nothing OrElse (eventInvocation.ReceiverOpt Is Nothing AndAlso Not eventSymbol.IsShared) Then
                Debug.Assert(boundRaiseEventStatement.HasErrors)
                Dim children = CreateFromArray(Of BoundNode, IOperation)(DirectCast(boundRaiseEventStatement, IBoundInvalidNode).InvalidNodeChildren)
                Return New InvalidOperation(children, _semanticModel, syntax, type:=Nothing, constantValue:=Nothing, isImplicit)
            End If
 
            Dim eventReference = CreateBoundRaiseEventStatementEventReference(boundRaiseEventStatement)
            Dim arguments = DeriveArguments(boundRaiseEventStatement)
 
            Return New RaiseEventOperation(eventReference, arguments, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundAddHandlerStatementOperation(boundAddHandlerStatement As BoundAddHandlerStatement) As IExpressionStatementOperation
            Dim expression As IOperation = GetAddRemoveHandlerStatementExpression(boundAddHandlerStatement)
            Dim syntax As SyntaxNode = boundAddHandlerStatement.Syntax
            Dim isImplicit As Boolean = boundAddHandlerStatement.WasCompilerGenerated
            Return New ExpressionStatementOperation(expression, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundRemoveHandlerStatementOperation(boundRemoveHandlerStatement As BoundRemoveHandlerStatement) As IExpressionStatementOperation
            Dim expression As IOperation = GetAddRemoveHandlerStatementExpression(boundRemoveHandlerStatement)
            Dim syntax As SyntaxNode = boundRemoveHandlerStatement.Syntax
            Dim type As ITypeSymbol = Nothing
            Dim constantValue As ConstantValue = Nothing
            Dim isImplicit As Boolean = boundRemoveHandlerStatement.WasCompilerGenerated
            Return New ExpressionStatementOperation(expression, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundTupleLiteralOperation(boundTupleLiteral As BoundTupleLiteral) As ITupleOperation
            Return CreateTupleOperation(boundTupleLiteral, boundTupleLiteral.Type)
        End Function
 
        Private Function CreateBoundConvertedTupleLiteralOperation(boundConvertedTupleLiteral As BoundConvertedTupleLiteral) As ITupleOperation
            Return CreateTupleOperation(boundConvertedTupleLiteral, boundConvertedTupleLiteral.NaturalTypeOpt)
        End Function
 
        Private Function CreateTupleOperation(boundTupleExpression As BoundTupleExpression, naturalType As ITypeSymbol) As ITupleOperation
            Dim elements As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundTupleExpression.Arguments)
            Dim syntax As SyntaxNode = boundTupleExpression.Syntax
            Dim type As ITypeSymbol = boundTupleExpression.Type
            Dim isImplicit As Boolean = boundTupleExpression.WasCompilerGenerated
            Return New TupleOperation(elements, naturalType, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundInterpolatedStringExpressionOperation(boundInterpolatedString As BoundInterpolatedStringExpression) As IInterpolatedStringOperation
            Dim parts As ImmutableArray(Of IInterpolatedStringContentOperation) = CreateBoundInterpolatedStringContentOperation(boundInterpolatedString.Contents)
            Dim syntax As SyntaxNode = boundInterpolatedString.Syntax
            Dim type As ITypeSymbol = boundInterpolatedString.Type
            Dim constantValue As ConstantValue = boundInterpolatedString.ConstantValueOpt
            Dim isImplicit As Boolean = boundInterpolatedString.WasCompilerGenerated
            Return New InterpolatedStringOperation(parts, _semanticModel, syntax, type, constantValue, isImplicit)
        End Function
 
        Friend Function CreateBoundInterpolatedStringContentOperation(parts As ImmutableArray(Of BoundNode)) As ImmutableArray(Of IInterpolatedStringContentOperation)
            Dim builder = ArrayBuilder(Of IInterpolatedStringContentOperation).GetInstance(parts.Length)
            For Each part In parts
                If part.Kind = BoundKind.Interpolation Then
                    builder.Add(DirectCast(Create(part), IInterpolatedStringContentOperation))
                Else
                    builder.Add(CreateBoundInterpolatedStringTextOperation(DirectCast(part, BoundLiteral)))
                End If
            Next
            Return builder.ToImmutableAndFree()
        End Function
 
        Private Function CreateBoundInterpolationOperation(boundInterpolation As BoundInterpolation) As IInterpolationOperation
            Dim expression As IOperation = Create(boundInterpolation.Expression)
            Dim alignment As IOperation = Create(boundInterpolation.AlignmentOpt)
            Dim formatString As IOperation = Create(boundInterpolation.FormatStringOpt)
            Dim syntax As SyntaxNode = boundInterpolation.Syntax
            Dim isImplicit As Boolean = boundInterpolation.WasCompilerGenerated
            Return New InterpolationOperation(expression, alignment, formatString, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundInterpolatedStringTextOperation(boundLiteral As BoundLiteral) As IInterpolatedStringTextOperation
            Dim text As IOperation = CreateBoundLiteralOperation(boundLiteral, implicit:=True)
            Dim syntax As SyntaxNode = boundLiteral.Syntax
            Dim isImplicit As Boolean = boundLiteral.WasCompilerGenerated
            Return New InterpolatedStringTextOperation(text, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundAnonymousTypeCreationExpressionOperation(boundAnonymousTypeCreationExpression As BoundAnonymousTypeCreationExpression) As IAnonymousObjectCreationOperation
            Dim initializers As ImmutableArray(Of IOperation) = GetAnonymousTypeCreationInitializers(boundAnonymousTypeCreationExpression)
            Dim syntax As SyntaxNode = boundAnonymousTypeCreationExpression.Syntax
            Dim type As ITypeSymbol = boundAnonymousTypeCreationExpression.Type
            Dim isImplicit As Boolean = boundAnonymousTypeCreationExpression.WasCompilerGenerated
            Return New AnonymousObjectCreationOperation(initializers, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundAnonymousTypePropertyAccessOperation(boundAnonymousTypePropertyAccess As BoundAnonymousTypePropertyAccess) As IPropertyReferenceOperation
            Dim [property] As IPropertySymbol = DirectCast(boundAnonymousTypePropertyAccess.ExpressionSymbol, IPropertySymbol)
            Return CreateBoundAnonymousTypePropertyAccessOperation(boundAnonymousTypePropertyAccess, [property])
        End Function
 
        Private Function CreateBoundAnonymousTypePropertyAccessOperation(boundAnonymousTypePropertyAccess As BoundAnonymousTypePropertyAccess, [property] As IPropertySymbol) As IPropertyReferenceOperation
            Dim instance As IOperation = CreateAnonymousTypePropertyAccessImplicitReceiverOperation([property], boundAnonymousTypePropertyAccess.Syntax.FirstAncestorOrSelf(Of AnonymousObjectCreationExpressionSyntax))
            Dim arguments = ImmutableArray(Of IArgumentOperation).Empty
            Dim syntax As SyntaxNode = boundAnonymousTypePropertyAccess.Syntax
            Dim type As ITypeSymbol = boundAnonymousTypePropertyAccess.Type
            Dim isImplicit As Boolean = boundAnonymousTypePropertyAccess.WasCompilerGenerated
            Return New PropertyReferenceOperation([property], constrainedToType:=Nothing, arguments, instance, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateAnonymousTypePropertyAccessImplicitReceiverOperation(propertySym As IPropertySymbol, syntax As SyntaxNode) As InstanceReferenceOperation
            Debug.Assert(propertySym IsNot Nothing)
            Debug.Assert(syntax IsNot Nothing)
            Return New InstanceReferenceOperation(
                InstanceReferenceKind.ImplicitReceiver,
                _semanticModel,
                syntax,
                propertySym.ContainingType,
                isImplicit:=True)
        End Function
 
        Private Function CreateBoundQueryExpressionOperation(boundQueryExpression As BoundQueryExpression) As IOperation
            Dim operation As IOperation = Create(boundQueryExpression.LastOperator)
            Dim syntax As SyntaxNode = boundQueryExpression.Syntax
            Dim type As ITypeSymbol = boundQueryExpression.Type
            Dim isImplicit As Boolean = boundQueryExpression.WasCompilerGenerated
            Return New TranslatedQueryOperation(operation, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundAggregateClauseOperation(boundAggregateClause As BoundAggregateClause) As IOperation
            If boundAggregateClause.CapturedGroupOpt Is Nothing Then
                ' This Aggregate clause has no special representation in the IOperation tree
                Return Create(boundAggregateClause.UnderlyingExpression)
            End If
 
            Debug.Assert(boundAggregateClause.GroupPlaceholderOpt IsNot Nothing)
            RecordParent(boundAggregateClause.GroupPlaceholderOpt, boundAggregateClause)
 
            Dim group As IOperation = Create(boundAggregateClause.CapturedGroupOpt)
            Dim aggregation As IOperation = Create(boundAggregateClause.UnderlyingExpression)
            Dim syntax As SyntaxNode = boundAggregateClause.Syntax
            Dim type As ITypeSymbol = boundAggregateClause.Type
            Dim isImplicit As Boolean = boundAggregateClause.WasCompilerGenerated
            Return New AggregateQueryOperation(group, aggregation, _semanticModel, syntax, type, isImplicit)
        End Function
 
        Private Function CreateBoundNullableIsTrueOperator(boundNullableIsTrueOperator As BoundNullableIsTrueOperator) As IOperation
            Dim syntax As SyntaxNode = boundNullableIsTrueOperator.Syntax
            Dim type As ITypeSymbol = boundNullableIsTrueOperator.Type
            Dim constantValue As ConstantValue = boundNullableIsTrueOperator.ConstantValueOpt
            Dim isImplicit As Boolean = boundNullableIsTrueOperator.WasCompilerGenerated
 
            Debug.Assert(boundNullableIsTrueOperator.Operand.Type.IsNullableOfBoolean() AndAlso boundNullableIsTrueOperator.Type.IsBooleanType())
 
            Dim method = DirectCast(DirectCast(_semanticModel.Compilation, VisualBasicCompilation).
                                        GetSpecialTypeMember(SpecialMember.System_Nullable_T_GetValueOrDefault), MethodSymbol)
 
            If method IsNot Nothing Then
                Dim receiver as IOperation = CreateReceiverOperation(boundNullableIsTrueOperator.Operand, method)
                Return New InvocationOperation(method.AsMember(DirectCast(boundNullableIsTrueOperator.Operand.Type, NamedTypeSymbol)), constrainedToType:=Nothing,
                                                              receiver,
                                                              isVirtual:=False,
                                                              arguments:=ImmutableArray(Of IArgumentOperation).Empty,
                                                              _semanticModel,
                                                              syntax,
                                                              boundNullableIsTrueOperator.Type,
                                                              isImplicit)
            Else
                Dim children = CreateFromArray(Of BoundNode, IOperation)(DirectCast(boundNullableIsTrueOperator, IBoundInvalidNode).InvalidNodeChildren)
                Return New InvalidOperation(children, _semanticModel, syntax, type, constantValue, isImplicit)
            End If
        End Function
 
        Private Function CreateBoundReDimOperation(boundRedimStatement As BoundRedimStatement) As IReDimOperation
            Dim clauses As ImmutableArray(Of IReDimClauseOperation) = CreateFromArray(Of BoundRedimClause, IReDimClauseOperation)(boundRedimStatement.Clauses)
            Dim preserve As Boolean = boundRedimStatement.Syntax.Kind = SyntaxKind.ReDimPreserveStatement
#If DEBUG Then
            For Each clause In boundRedimStatement.Clauses
                Debug.Assert(preserve = clause.Preserve)
            Next
#End If
            Dim syntax As SyntaxNode = boundRedimStatement.Syntax
            Dim isImplicit As Boolean = boundRedimStatement.WasCompilerGenerated
            Return New ReDimOperation(clauses, preserve, _semanticModel, syntax, isImplicit)
        End Function
 
        Private Function CreateBoundReDimClauseOperation(boundRedimClause As BoundRedimClause) As IReDimClauseOperation
            Dim operand As IOperation = Create(boundRedimClause.Operand)
            Dim dimensionSizes As ImmutableArray(Of IOperation) = CreateFromArray(Of BoundExpression, IOperation)(boundRedimClause.Indices)
            Dim syntax As SyntaxNode = boundRedimClause.Syntax
            Dim isImplicit As Boolean = boundRedimClause.WasCompilerGenerated
            Return New ReDimClauseOperation(operand, dimensionSizes, _semanticModel, syntax, isImplicit)
        End Function
    End Class
End Namespace