private ExpressionSyntax AddTypeConversion(VBSyntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded, ITypeSymbol vbType, ITypeSymbol vbConvertedType)
    {
        switch (conversionKind)
        {
        case TypeConversionKind.FractionalNumberRoundThenCast:
            csNode = vbType.IsNullable() && vbConvertedType.IsNullable()
                    ? _vbNullableExpressionsConverter.InvokeConversionWhenNotNull(csNode, GetMathRoundMemberAccess(), GetTypeSyntax(vbConvertedType))
                    : AddRoundInvocation(vbType.IsNullable() ? csNode.NullableGetValueExpression() : csNode);

            return(AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, vbConvertedType));

        case TypeConversionKind.EnumConversionThenCast:
            vbConvertedType.IsNullable(out var convertedNullableType);
            var underlyingEnumType = ((INamedTypeSymbol)(convertedNullableType ?? vbConvertedType)).EnumUnderlyingType;
            csNode = vbType.IsNullable() && convertedNullableType != null
                    ? _vbNullableExpressionsConverter.InvokeConversionWhenNotNull(csNode, GetConversionsMemberAccess(underlyingEnumType), GetTypeSyntax(vbConvertedType))
                    : AddTypeConversion(vbNode, csNode, TypeConversionKind.Conversion, addParenthesisIfNeeded, vbType, underlyingEnumType);

            return(AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, vbConvertedType));

        case TypeConversionKind.EnumCastThenConversion:
            var enumUnderlyingType = ((INamedTypeSymbol)vbType).EnumUnderlyingType;
            csNode = AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, enumUnderlyingType);
            return(AddTypeConversion(vbNode, csNode, TypeConversionKind.Conversion, addParenthesisIfNeeded, enumUnderlyingType, vbConvertedType));

        case TypeConversionKind.Unknown:
        case TypeConversionKind.Identity:
            return(addParenthesisIfNeeded ? vbNode.ParenthesizeIfPrecedenceCouldChange(csNode) : csNode);

        case TypeConversionKind.DestructiveCast:
        case TypeConversionKind.NonDestructiveCast:
            return(CreateCast(csNode, vbConvertedType));

        case TypeConversionKind.Conversion:
            return(AddExplicitConvertTo(vbNode, csNode, vbType, vbConvertedType));

        case TypeConversionKind.NullableBool:
            return(SyntaxFactory.BinaryExpression(SyntaxKind.EqualsExpression, csNode,
                                                  LiteralConversions.GetLiteralExpression(true)));

        case TypeConversionKind.StringToCharArray:
            var memberAccessExpressionSyntax = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, csNode, SyntaxFactory.IdentifierName(nameof(string.ToCharArray)));
            return(SyntaxFactory.InvocationExpression(memberAccessExpressionSyntax,
                                                      SyntaxFactory.ArgumentList()));

        case TypeConversionKind.DelegateConstructor:
            return(SyntaxFactory.ObjectCreationExpression(GetCommonDelegateTypeOrNull(vbNode, vbConvertedType)).WithArgumentList(new[] { csNode }.CreateCsArgList()));

        default:
            throw new ArgumentOutOfRangeException(nameof(conversionKind), conversionKind, null);
        }
    }
    public ExpressionSyntax AddExplicitConversion(VBSyntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, bool addParenthesisIfNeeded = true, bool defaultToCast = false, bool isConst = false, ITypeSymbol forceSourceType = null, ITypeSymbol forceTargetType = null)
    {
        if (csNode == null)
        {
            return(null);
        }
        var conversionKind = AnalyzeConversion(vbNode, defaultToCast, isConst, forceSourceType, forceTargetType);

        csNode = addParenthesisIfNeeded && conversionKind is TypeConversionKind.DestructiveCast or TypeConversionKind.NonDestructiveCast
            ? vbNode.ParenthesizeIfPrecedenceCouldChange(csNode)
            : csNode;
        return(AddExplicitConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded, isConst, forceSourceType: forceSourceType, forceTargetType: forceTargetType).Expr);
    }