public override VB.SeparatedSyntaxList<VB.StatementSyntax> VisitForStatement(CS.ForStatementSyntax node)
 {
     // VB doesn't have a For statement that directly maps to C#'s.  However, some C# for
     // statements will map to a VB for statement.  Check for those common cases and
     // translate those.
     return IsSimpleForStatement(node)
         ? VisitSimpleForStatement(node)
         : VisitComplexForStatement(node);
 }
 private VB.ForStatementSyntax CreateForStatement(CS.ForStatementSyntax node)
 {
     var variableName = node.Declaration.Variables[0].Identifier.ValueText;
     var stepClause = CreateForStepClause(node);
     var toValue = CreateForToValue(node);
     return VB.Syntax.ForStatement(
         controlVariable: VB.Syntax.IdentifierName(variableName),
         fromValue: nodeVisitor.VisitExpression(node.Declaration.Variables[0].Initializer.Value),
         toValue: toValue,
         stepClause: stepClause);
 }
            private VB.SeparatedSyntaxList<VB.StatementSyntax> VisitSimpleForStatement(CS.ForStatementSyntax node)
            {
                var forStatement = CreateForStatement(node);
                var statements = VisitStatementEnumerable(node.Statement);

                var forBlock = VB.Syntax.ForBlock(
                    forStatement,
                    VB.Syntax.Token(VB.SyntaxKind.StatementTerminatorToken),
                    SeparatedNewLineList(statements),
                    VB.Syntax.NextStatement());

                return VB.Syntax.SeparatedList<VB.StatementSyntax>(forBlock);
            }
            private VB.ExpressionSyntax CreateForToValue(CS.ForStatementSyntax node)
            {
                var expression = nodeVisitor.VisitExpression(((CS.BinaryExpressionSyntax)node.Condition).Right);

                if (node.Condition.Kind != CS.SyntaxKind.LessThanOrEqualExpression &&
                    node.Condition.Kind != CS.SyntaxKind.GreaterThanOrEqualExpression)
                {
                    if (node.Condition.Kind == CS.SyntaxKind.LessThanExpression)
                    {
                        return VB.Syntax.SubtractExpression(
                            expression,
                            right: CreateOneExpression());
                    }

                    if (node.Condition.Kind == CS.SyntaxKind.GreaterThanExpression)
                    {
                        return VB.Syntax.AddExpression(
                            expression,
                            right: CreateOneExpression());
                    }
                }

                return expression;
            }
            private VB.ForStepClauseSyntax CreateForStepClause(CS.ForStatementSyntax node)
            {
                var incrementor = node.Incrementors[0];
                if (incrementor.Kind != CS.SyntaxKind.PreIncrementExpression &&
                    incrementor.Kind != CS.SyntaxKind.PostIncrementExpression)
                {
                    if (incrementor.Kind == CS.SyntaxKind.PreDecrementExpression ||
                        incrementor.Kind == CS.SyntaxKind.PostDecrementExpression)
                    {
                        return VB.Syntax.ForStepClause(
                            stepValue: VB.Syntax.NegateExpression(
                                operand: CreateOneExpression()));
                    }

                    if (incrementor.Kind == CS.SyntaxKind.AddAssignExpression)
                    {
                        return VB.Syntax.ForStepClause(
                            stepValue: nodeVisitor.VisitExpression(((CS.BinaryExpressionSyntax)incrementor).Right));
                    }

                    if (incrementor.Kind == CS.SyntaxKind.SubtractAssignExpression)
                    {
                        return VB.Syntax.ForStepClause(
                            stepValue: VB.Syntax.NegateExpression(
                                operand: nodeVisitor.VisitExpression(((CS.BinaryExpressionSyntax)incrementor).Right)));
                    }
                }

                return null;
            }
            private VB.SeparatedSyntaxList<VB.StatementSyntax> VisitComplexForStatement(CS.ForStatementSyntax node)
            {
                // VB doesn't have a for loop.  So convert:
                //   for (declarations; condition; incrementors) body into:
                //
                // declarations
                // while (condition) {
                //   body;
                //   incrementors;
                // }

                VB.WhileStatementSyntax begin;
                if (node.Condition == null)
                {
                    begin = VB.Syntax.WhileStatement(
                        condition: VB.Syntax.TrueLiteralExpression(VB.Syntax.Token(VB.SyntaxKind.TrueKeyword)));
                }
                else
                {
                    begin = VB.Syntax.WhileStatement(
                        condition: nodeVisitor.VisitExpression(node.Condition));
                }

                var initialBlock = Visit(node.Statement);

                var whileStatements = initialBlock.Concat(
                    node.Incrementors.Select(nodeVisitor.VisitStatement)).ToList();
                var whileBody = SeparatedNewLineList(whileStatements);

                var whileBlock = VB.Syntax.WhileBlock(
                    begin,
                    StatementTerminator(),
                    whileBody,
                    VB.Syntax.EndWhileStatement());

                var statements = new List<VB.StatementSyntax>();
                if (node.Declaration != null)
                {
                    statements.Add(nodeVisitor.Visit<VB.StatementSyntax>(node.Declaration));
                }

                statements.Add(whileBlock);

                return SeparatedNewLineList(statements);
            }
            private bool IsSimpleForIncrementor(CS.ForStatementSyntax node, string variableName)
            {
#if false
                name++;
                name--;
                ++name;
                --name;
                name += v3;
                name -= v3;
#endif
                if (node.Incrementors.Count == 1)
                {
                    var incrementor = node.Incrementors[0];
                    if (incrementor.Kind == CS.SyntaxKind.PostIncrementExpression ||
                        incrementor.Kind == CS.SyntaxKind.PostDecrementExpression)
                    {
                        var identifierName = ((CS.PostfixUnaryExpressionSyntax)incrementor).Operand as CS.IdentifierNameSyntax;
                        return identifierName != null && identifierName.Identifier.ValueText == variableName;
                    }

                    if (incrementor.Kind == CS.SyntaxKind.PreIncrementExpression ||
                        incrementor.Kind == CS.SyntaxKind.PreDecrementExpression)
                    {
                        var identifierName = ((CS.PrefixUnaryExpressionSyntax)incrementor).Operand as CS.IdentifierNameSyntax;
                        return identifierName != null && identifierName.Identifier.ValueText == variableName;
                    }

                    if (incrementor.Kind == CS.SyntaxKind.AddAssignExpression ||
                        incrementor.Kind == CS.SyntaxKind.SubtractAssignExpression)
                    {
                        var binaryExpression = (CS.BinaryExpressionSyntax)incrementor;
                        var identifierName = binaryExpression.Left as CS.IdentifierNameSyntax;
                        return identifierName != null && identifierName.Identifier.ValueText == variableName;
                    }
                }

                return false;
            }
            private bool IsSimpleForCondition(CS.ForStatementSyntax node, string variableName)
            {
#if false
                Condition must be one of:
                name < v2
                name <= v2
                name > v2
                name >= v2
#endif
                if (node.Condition != null)
                {
                    if (node.Condition.Kind == CS.SyntaxKind.LessThanExpression ||
                        node.Condition.Kind == CS.SyntaxKind.LessThanOrEqualExpression ||
                        node.Condition.Kind == CS.SyntaxKind.GreaterThanExpression ||
                        node.Condition.Kind == CS.SyntaxKind.GreaterThanOrEqualExpression)
                    {
                        var binaryExpression = (CS.BinaryExpressionSyntax)node.Condition;
                        var identifierName = binaryExpression.Left as CS.IdentifierNameSyntax;
                        return identifierName != null && identifierName.Identifier.ValueText == variableName;
                    }
                }

                return false;
            }
            private bool IsSimpleForDeclaration(CS.ForStatementSyntax node)
            {
#if false
                Declaration must be one of:
                var name = v1
                primitive_type name = v1
#endif

                if (node.Declaration != null &&
                    node.Declaration.Variables.Count == 1 &&
                    node.Declaration.Variables[0].Initializer != null)
                {
                    if (node.Declaration.Type.IsVar || node.Declaration.Type.Kind == CS.SyntaxKind.PredefinedType)
                    {
                        return true;
                    }
                }

                return false;
            }
            private bool IsSimpleForStatement(CS.ForStatementSyntax node)
            {
                // Has to look like one of the following:
#if false
                for (Declaration; Condition; Incrementor)

                Declaration must be one of:
                var name = v1
                primitive_type name = v1

                Condition must be one of:
                name < v2
                name <= v2
                name > v2
                name >= v2

                Incrementor must be one of:
                name++;
                name--;
                name += v3;
                name -= v3;
#endif
                if (node.Declaration == null ||
                    node.Declaration.Variables.Count != 1)
                {
                    return false;
                }

                var variableName = node.Declaration.Variables[0].Identifier.ValueText;

                return
                    IsSimpleForDeclaration(node) &&
                    IsSimpleForCondition(node, variableName) &&
                    IsSimpleForIncrementor(node, variableName);
            }