Release 0.1.8.

Rename BlockExpression to BlockStatement (because it is a Statement, not an Expression); similarly DeclarationStatement, GotoStatement, LabelStatement, SwitchStatement, TryStatement.

Rename LoopExpression to ForStatement, and implement for old-style "for(;;)".

Add a few convenience methods to BlockBuilder.
diff --git a/pom.xml b/pom.xml
index fa63c75..3197205 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,8 +8,8 @@
   <packaging>jar</packaging>
 
   <!-- Version number. The version number committed to github should be
-       TRUNK-SNAPSHOT except, briefly, when making a release. Next up: 0.1.8. -->
-  <version>TRUNK-SNAPSHOT</version>
+       TRUNK-SNAPSHOT except, briefly, when making a release. Next: 0.1.9. -->
+  <version>0.1.8</version>
 
   <!-- More project information. -->
   <name>linq4j</name>
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/BlockBuilder.java b/src/main/java/net/hydromatic/linq4j/expressions/BlockBuilder.java
index 919dbf8..9491620 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/BlockBuilder.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/BlockBuilder.java
@@ -21,7 +21,7 @@
 import java.util.*;
 
 /**
- * Builder for {@link BlockExpression}.
+ * Builder for {@link BlockStatement}.
  *
  * <p>Has methods that help ensure that variable names are unique.</p>
  */
@@ -59,7 +59,7 @@
    * (possibly a variable) that represents the result of the newly added
    * block.
    */
-  public Expression append(String name, BlockExpression block) {
+  public Expression append(String name, BlockStatement block) {
     return append(name, block, true);
   }
 
@@ -73,14 +73,14 @@
    * a variable. Do not do this if the expression has
    * side-effects or a time-dependent value.
    */
-  public Expression append(String name, BlockExpression block,
+  public Expression append(String name, BlockStatement block,
       boolean optimize) {
     if (statements.size() > 0) {
       Statement lastStatement = statements.get(statements.size() - 1);
-      if (lastStatement instanceof GotoExpression) {
+      if (lastStatement instanceof GotoStatement) {
         // convert "return expr;" into "expr;"
         statements.set(statements.size() - 1, Expressions.statement(
-            ((GotoExpression) lastStatement).expression));
+            ((GotoStatement) lastStatement).expression));
       }
     }
     Expression result = null;
@@ -93,8 +93,8 @@
         // Save effort, and only substitute variables if there are some.
         statement = statement.accept(visitor);
       }
-      if (statement instanceof DeclarationExpression) {
-        DeclarationExpression declaration = (DeclarationExpression) statement;
+      if (statement instanceof DeclarationStatement) {
+        DeclarationStatement declaration = (DeclarationStatement) statement;
         if (variables.contains(declaration.parameter.name)) {
           Expression x = append(
               newName(declaration.parameter.name, optimize),
@@ -109,18 +109,18 @@
         add(statement);
       }
       if (i == block.statements.size() - 1) {
-        if (statement instanceof DeclarationExpression) {
-          result = ((DeclarationExpression) statement).parameter;
-        } else if (statement instanceof GotoExpression) {
+        if (statement instanceof DeclarationStatement) {
+          result = ((DeclarationStatement) statement).parameter;
+        } else if (statement instanceof GotoStatement) {
           statements.remove(statements.size() - 1);
-          result = append_(name, ((GotoExpression) statement).expression,
+          result = append_(name, ((GotoStatement) statement).expression,
               optimize);
           if (result instanceof ParameterExpression
               || result instanceof ConstantExpression) {
             // already simple; no need to declare a variable or
             // even to evaluate the expression
           } else {
-            DeclarationExpression declare = Expressions.declare(Modifier.FINAL,
+            DeclarationStatement declare = Expressions.declare(Modifier.FINAL,
                 newName(name, optimize), result);
             add(declare);
             result = declare.parameter;
@@ -143,6 +143,16 @@
   }
 
   /**
+   * Appends an expression to a list of statements, if it is not null.
+   */
+  public Expression appendIfNotNull(String name, Expression expression) {
+    if (expression == null) {
+      return null;
+    }
+    return append(name, expression, true);
+  }
+
+  /**
    * Appends an expression to a list of statements, optionally optimizing if
    * the expression is used more than once.
    */
@@ -150,10 +160,10 @@
       boolean optimize) {
     if (statements.size() > 0) {
       Statement lastStatement = statements.get(statements.size() - 1);
-      if (lastStatement instanceof GotoExpression) {
+      if (lastStatement instanceof GotoStatement) {
         // convert "return expr;" into "expr;"
         statements.set(statements.size() - 1, Expressions.statement(
-            ((GotoExpression) lastStatement).expression));
+            ((GotoStatement) lastStatement).expression));
       }
     }
     return append_(name, expression, optimize);
@@ -172,8 +182,8 @@
     }
     if (optimizing) {
       for (Statement statement : statements) {
-        if (statement instanceof DeclarationExpression) {
-          DeclarationExpression decl = (DeclarationExpression) statement;
+        if (statement instanceof DeclarationStatement) {
+          DeclarationStatement decl = (DeclarationStatement) statement;
           if ((decl.modifiers & Modifier.FINAL) != 0
               && decl.initializer != null
               && decl.initializer.equals(expression)) {
@@ -182,7 +192,7 @@
         }
       }
     }
-    DeclarationExpression declare = Expressions.declare(Modifier.FINAL, newName(
+    DeclarationStatement declare = Expressions.declare(Modifier.FINAL, newName(
         name, optimize), expression);
     add(declare);
     return declare.parameter;
@@ -190,8 +200,8 @@
 
   public void add(Statement statement) {
     statements.add(statement);
-    if (statement instanceof DeclarationExpression) {
-      String name = ((DeclarationExpression) statement).parameter.name;
+    if (statement instanceof DeclarationStatement) {
+      String name = ((DeclarationStatement) statement).parameter.name;
       if (!variables.add(name)) {
         throw new AssertionError("duplicate variable " + name);
       }
@@ -205,7 +215,7 @@
   /**
    * Returns a block consisting of the current list of statements.
    */
-  public BlockExpression toBlock() {
+  public BlockStatement toBlock() {
     if (optimizing) {
       optimize();
     }
@@ -220,8 +230,8 @@
     List<Slot> slots = new ArrayList<Slot>();
     final UseCounter useCounter = new UseCounter();
     for (Statement statement : statements) {
-      if (statement instanceof DeclarationExpression) {
-        final Slot slot = new Slot((DeclarationExpression) statement);
+      if (statement instanceof DeclarationStatement) {
+        final Slot slot = new Slot((DeclarationStatement) statement);
         useCounter.map.put(slot.parameter, slot);
         slots.add(slot);
       }
@@ -237,8 +247,8 @@
         statements);
     statements.clear();
     for (Statement oldStatement : oldStatements) {
-      if (oldStatement instanceof DeclarationExpression) {
-        DeclarationExpression statement = (DeclarationExpression) oldStatement;
+      if (oldStatement instanceof DeclarationStatement) {
+        DeclarationStatement statement = (DeclarationStatement) oldStatement;
         final Slot slot = useCounter.map.get(statement.parameter);
         int count = slot.count;
         if (Expressions.isConstantNull(slot.expression)) {
@@ -288,13 +298,21 @@
   }
 
   /**
-   * Creates a name for a new variable, unique within this block.
+   * Creates a name for a new variable, unique within this block, controlling
+   * whether the variable can be inlined later.
    */
   private String newName(String suggestion, boolean optimize) {
     if (!optimize && !suggestion.startsWith("_")) {
       // "_" prefix reminds us not to consider the variable for inlining
       suggestion = '_' + suggestion;
     }
+    return newName(suggestion);
+  }
+
+  /**
+   * Creates a name for a new variable, unique within this block.
+   */
+  public String newName(String suggestion) {
     int i = 0;
     String candidate = suggestion;
     for (;;) {
@@ -364,9 +382,9 @@
     private final Expression expression;
     private int count;
 
-    public Slot(DeclarationExpression declarationExpression) {
-      this.parameter = declarationExpression.parameter;
-      this.expression = declarationExpression.initializer;
+    public Slot(DeclarationStatement declarationStatement) {
+      this.parameter = declarationStatement.parameter;
+      this.expression = declarationStatement.initializer;
     }
   }
 }
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/BlockExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/BlockStatement.java
similarity index 86%
rename from src/main/java/net/hydromatic/linq4j/expressions/BlockExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/BlockStatement.java
index 23c295f..b18802e 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/BlockExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/BlockStatement.java
@@ -26,10 +26,10 @@
  * Represents a block that contains a sequence of expressions where variables
  * can be defined.
  */
-public class BlockExpression extends Statement {
+public class BlockStatement extends Statement {
   public final List<Statement> statements;
 
-  BlockExpression(List<Statement> statements, Type type) {
+  BlockStatement(List<Statement> statements, Type type) {
     super(ExpressionType.Block, type);
     this.statements = statements;
     assert distinctVariables(true);
@@ -38,8 +38,8 @@
   private boolean distinctVariables(boolean fail) {
     Set<String> names = new HashSet<String>();
     for (Statement statement : statements) {
-      if (statement instanceof DeclarationExpression) {
-        String name = ((DeclarationExpression) statement).parameter.name;
+      if (statement instanceof DeclarationStatement) {
+        String name = ((DeclarationStatement) statement).parameter.name;
         if (!names.add(name)) {
           assert !fail : "duplicate variable " + name;
           return false;
@@ -50,7 +50,7 @@
   }
 
   @Override
-  public BlockExpression accept(Visitor visitor) {
+  public BlockStatement accept(Visitor visitor) {
     List<Statement> newStatements = Expressions.acceptStatements(statements,
         visitor);
     return visitor.visit(this, newStatements);
@@ -79,4 +79,4 @@
   }
 }
 
-// End BlockExpression.java
+// End BlockStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/Blocks.java b/src/main/java/net/hydromatic/linq4j/expressions/Blocks.java
index 12792c2..6f56803 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/Blocks.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/Blocks.java
@@ -18,9 +18,8 @@
 package net.hydromatic.linq4j.expressions;
 
 /**
- * <p>Helper methods concerning {@link BlockExpression}s.</p>
+ * <p>Helper methods concerning {@link BlockStatement}s.</p>
  *
- * @author jhyde
  * @see BlockBuilder
  */
 public final class Blocks {
@@ -28,9 +27,9 @@
     throw new AssertionError("no blocks for you!");
   }
 
-  private static BlockExpression toFunctionBlock(Node body, boolean function) {
-    if (body instanceof BlockExpression) {
-      return (BlockExpression) body;
+  private static BlockStatement toFunctionBlock(Node body, boolean function) {
+    if (body instanceof BlockStatement) {
+      return (BlockStatement) body;
     }
     Statement statement;
     if (body instanceof Statement) {
@@ -50,19 +49,19 @@
     return Expressions.block(statement);
   }
 
-  public static BlockExpression toFunctionBlock(Node body) {
+  public static BlockStatement toFunctionBlock(Node body) {
     return toFunctionBlock(body, true);
   }
 
-  public static BlockExpression toBlock(Node body) {
+  public static BlockStatement toBlock(Node body) {
     return toFunctionBlock(body, false);
   }
 
   /**
    * Prepends a statement to a block.
    */
-  public static BlockExpression create(Statement statement,
-      BlockExpression block) {
+  public static BlockStatement create(Statement statement,
+      BlockStatement block) {
     return Expressions.block(Expressions.list(statement).appendAll(
         block.statements));
   }
@@ -71,11 +70,11 @@
    * Converts a simple "{ return expr; }" block into "expr"; otherwise
    * throws.
    */
-  public static Expression simple(BlockExpression block) {
+  public static Expression simple(BlockStatement block) {
     if (block.statements.size() == 1) {
       Statement statement = block.statements.get(0);
-      if (statement instanceof GotoExpression) {
-        return ((GotoExpression) statement).expression;
+      if (statement instanceof GotoStatement) {
+        return ((GotoStatement) statement).expression;
       }
     }
     throw new AssertionError("not a simple block: " + block);
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/ConstructorDeclaration.java b/src/main/java/net/hydromatic/linq4j/expressions/ConstructorDeclaration.java
index 0d4d385..17231c6 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/ConstructorDeclaration.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/ConstructorDeclaration.java
@@ -29,10 +29,10 @@
   public final int modifier;
   public final Type resultType;
   public final List<ParameterExpression> parameters;
-  public final BlockExpression body;
+  public final BlockStatement body;
 
   public ConstructorDeclaration(int modifier, Type declaredAgainst,
-      List<ParameterExpression> parameters, BlockExpression body) {
+      List<ParameterExpression> parameters, BlockStatement body) {
     this.modifier = modifier;
     this.resultType = declaredAgainst;
     this.parameters = parameters;
@@ -42,7 +42,7 @@
   @Override
   public MemberDeclaration accept(Visitor visitor) {
     // do not visit parameters
-    final BlockExpression body = this.body.accept(visitor);
+    final BlockStatement body = this.body.accept(visitor);
     return visitor.visit(this, parameters, body);
   }
 
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/DeclarationExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/DeclarationStatement.java
similarity index 73%
rename from src/main/java/net/hydromatic/linq4j/expressions/DeclarationExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/DeclarationStatement.java
index 3f27441..1b91086 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/DeclarationExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/DeclarationStatement.java
@@ -21,15 +21,13 @@
 
 /**
  * Expression that declares and optionally initializes a variable.
- *
- * @author jhyde
  */
-public class DeclarationExpression extends Statement {
+public class DeclarationStatement extends Statement {
   public final int modifiers;
   public final ParameterExpression parameter;
   public final Expression initializer;
 
-  public DeclarationExpression(int modifiers, ParameterExpression parameter,
+  public DeclarationStatement(int modifiers, ParameterExpression parameter,
       Expression initializer) {
     super(ExpressionType.Declaration, Void.TYPE);
     this.modifiers = modifiers;
@@ -38,7 +36,7 @@
   }
 
   @Override
-  public Statement accept(Visitor visitor) {
+  public DeclarationStatement accept(Visitor visitor) {
     // do not visit parameter - visit may not return a ParameterExpression
     Expression initializer = this.initializer != null
         ? this.initializer.accept(visitor)
@@ -59,6 +57,22 @@
     writer.append(';');
     writer.newlineAndIndent();
   }
+
+  public void accept2(ExpressionWriter writer, boolean withType) {
+    if (withType) {
+      final String modifiers = Modifier.toString(this.modifiers);
+      if (!modifiers.isEmpty()) {
+        writer.append(modifiers).append(' ');
+      }
+      writer.append(parameter.type).append(' ');
+    } else {
+      writer.append(", ");
+    }
+    writer.append(parameter.name);
+    if (initializer != null) {
+      writer.append(" = ").append(initializer);
+    }
+  }
 }
 
-// End DeclarationExpression.java
+// End DeclarationStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/ExpressionType.java b/src/main/java/net/hydromatic/linq4j/expressions/ExpressionType.java
index a4707d8..81e25eb 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/ExpressionType.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/ExpressionType.java
@@ -582,6 +582,8 @@
    */
   Declaration,
 
+  For,
+
   While;
 
   final String op;
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/Expressions.java b/src/main/java/net/hydromatic/linq4j/expressions/Expressions.java
index 8c61461..ca2bcdc 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/Expressions.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/Expressions.java
@@ -209,8 +209,8 @@
    */
   public static IndexExpression arrayIndex(Expression array,
       Expression indexExpression) {
-    return new IndexExpression(array, Collections.singletonList(
-        indexExpression));
+    return new IndexExpression(array,
+        Collections.singletonList(indexExpression));
   }
 
   /**
@@ -248,23 +248,24 @@
   /**
    * Creates a BlockExpression that contains the given statements.
    */
-  public static BlockExpression block(Statement... statements) {
-    return block(toList(statements));
+  public static BlockStatement block(
+      Iterable<? extends Statement> statements) {
+    return block((Type) null, statements);
   }
 
   /**
-   * Creates a BlockExpression that contains the given statements.
+   * Creates a BlockExpression that contains the given statements,
+   * using varargs.
    */
-  public static BlockExpression block(
-      Iterable<? extends Statement> statements) {
-    return block((Type) null, statements);
+  public static BlockStatement block(Statement... statements) {
+    return block(toList(statements));
   }
 
   /**
    * Creates a BlockExpression that contains the given expressions,
    * has no variables and has specific result type.
    */
-  public static BlockExpression block(Type type,
+  public static BlockStatement block(Type type,
       Iterable<? extends Statement> expressions) {
     List<Statement> list = toList(expressions);
     if (type == null) {
@@ -274,38 +275,38 @@
         type = Void.TYPE;
       }
     }
-    return new BlockExpression(list, type);
+    return new BlockStatement(list, type);
   }
 
   /**
    * Creates a BlockExpression that contains the given statements
-   * and has a specific result type.
+   * and has a specific result type, using varargs.
    */
-  public static BlockExpression block(Type type, Statement... statements) {
+  public static BlockStatement block(Type type, Statement... statements) {
     return block(type, toList(statements));
   }
 
   /**
    * Creates a GotoExpression representing a break statement.
    */
-  public static GotoExpression break_(LabelTarget labelTarget) {
-    throw Extensions.todo();
+  public static GotoStatement break_(LabelTarget labelTarget) {
+    return new GotoStatement(GotoExpressionKind.Break, null, null);
   }
 
   /**
    * Creates a GotoExpression representing a break statement. The
    * value passed to the label upon jumping can be specified.
    */
-  public static GotoExpression break_(LabelTarget labelTarget,
+  public static GotoStatement break_(LabelTarget labelTarget,
       Expression expression) {
-    throw Extensions.todo();
+    return new GotoStatement(GotoExpressionKind.Break, null, expression);
   }
 
   /**
    * Creates a GotoExpression representing a break statement with
    * the specified type.
    */
-  public static GotoExpression break_(LabelTarget labelTarget, Type type) {
+  public static GotoStatement break_(LabelTarget labelTarget, Type type) {
     throw Extensions.todo();
   }
 
@@ -314,23 +315,23 @@
    * the specified type. The value passed to the label upon jumping
    * can be specified.
    */
-  public static GotoExpression break_(LabelTarget labelTarget,
+  public static GotoStatement break_(LabelTarget labelTarget,
       Expression expression, Type type) {
     throw Extensions.todo();
   }
 
   /**
    * Creates a MethodCallExpression that represents a call to a
-   * static method.
+   * static method that has arguments.
    */
   public static MethodCallExpression call(Method method,
-      Iterable<Expression> expressions) {
-    return new MethodCallExpression(method, null, toList(expressions));
+      Iterable<? extends Expression> arguments) {
+    return new MethodCallExpression(method, null, toList(arguments));
   }
 
   /**
    * Creates a MethodCallExpression that represents a call to a
-   * static method that has arguments.
+   * static method that has arguments, using varargs.
    */
   public static MethodCallExpression call(Method method,
       Expression... arguments) {
@@ -342,7 +343,16 @@
    * method that takes arguments.
    */
   public static MethodCallExpression call(Expression expression, Method method,
-      Iterable<Expression> arguments) {
+      Iterable<? extends Expression> arguments) {
+    return new MethodCallExpression(method, expression, toList(arguments));
+  }
+
+  /**
+   * Creates a MethodCallExpression that represents a call to a
+   * method that takes arguments, using varargs.
+   */
+  public static MethodCallExpression call(Expression expression, Method method,
+      Expression... arguments) {
     return new MethodCallExpression(method, expression, toList(arguments));
   }
 
@@ -357,37 +367,27 @@
    * is static.</p>
    */
   public static MethodCallExpression call(Type returnType,
-      Expression expression, Method method, Iterable<Expression> arguments) {
-    return new MethodCallExpression(returnType, method, expression, toList(
-        arguments));
+      Expression expression, Method method,
+      Iterable<? extends Expression> arguments) {
+    return new MethodCallExpression(returnType, method, expression,
+        toList(arguments));
   }
 
   /**
    * Creates a MethodCallExpression that represents a call to a
-   * method that takes arguments.
+   * method that takes arguments, with an explicit return type, with varargs.
+   *
+   * <p>The return type must be consistent with the return type of the method,
+   * but may contain extra information, such as type parameters.</p>
+   *
+   * <p>The {@code expression} argument may be null if and only if the method
+   * is static.</p>
    */
-  public static MethodCallExpression call(Expression expression, Method method,
+  public static MethodCallExpression call(Type returnType,
+      Expression expression, Method method,
       Expression... arguments) {
-    return new MethodCallExpression(method, expression, toList(arguments));
-  }
-
-  /**
-   * Creates a MethodCallExpression that represents a call to an
-   * instance method by calling the appropriate factory method.
-   */
-  public static MethodCallExpression call(Expression expression,
-      String methodName, Iterable<Expression> arguments) {
-    Method method;
-    try {
-      method = Types.toClass(expression.getType()).getMethod(methodName,
-          Types.toClassArray(arguments));
-    } catch (NoSuchMethodException e) {
-      throw new RuntimeException("while resolving method '"
-                                 + methodName
-                                 + "' in class "
-                                 + expression.getType(), e);
-    }
-    return call(expression, method, arguments);
+    return new MethodCallExpression(returnType, method, expression,
+        toList(arguments));
   }
 
   /**
@@ -395,8 +395,26 @@
    * instance method by calling the appropriate factory method.
    */
   public static MethodCallExpression call(Expression target, String methodName,
+      Iterable<? extends Expression> arguments) {
+    Method method;
+    try {
+      //noinspection unchecked
+      method = Types.toClass(target.getType())
+          .getMethod(methodName, Types.toClassArray(arguments));
+    } catch (NoSuchMethodException e) {
+      throw new RuntimeException("while resolving method '" + methodName
+          + "' in class " + target.getType(), e);
+    }
+    return call(target, method, arguments);
+  }
+
+  /**
+   * Creates a MethodCallExpression that represents a call to an
+   * instance method by calling the appropriate factory method, using varargs.
+   */
+  public static MethodCallExpression call(Expression target, String methodName,
       Expression... arguments) {
-    return call(target, methodName, Arrays.<Expression>asList(arguments));
+    return call(target, methodName, toList(arguments));
   }
 
   /**
@@ -405,7 +423,7 @@
    * appropriate factory method.
    */
   public static MethodCallExpression call(Type type, String methodName,
-      Iterable<Expression> arguments) {
+      Iterable<? extends Expression> arguments) {
     Method method = Types.lookupMethod(Types.toClass(type), methodName,
         Types.toClassArray(arguments));
     return new MethodCallExpression(method, null, toList(arguments));
@@ -414,11 +432,11 @@
   /**
    * Creates a MethodCallExpression that represents a call to a
    * static method by calling the
-   * appropriate factory method.
+   * appropriate factory method, using varargs.
    */
   public static MethodCallExpression call(Type type, String methodName,
       Expression... arguments) {
-    return call(type, methodName, Arrays.<Expression>asList(arguments));
+    return call(type, methodName, toList(arguments));
   }
 
   /**
@@ -556,7 +574,7 @@
     if (value != null && type instanceof Class) {
       // Fix up value so that it matches type.
       Class clazz = (Class) type;
-      Primitive primitive = Primitive.of(clazz);
+      Primitive primitive = Primitive.ofBoxOr(clazz);
       if (primitive != null) {
         clazz = primitive.boxClass;
       }
@@ -579,7 +597,7 @@
   /**
    * Creates a GotoExpression representing a continue statement.
    */
-  public static GotoExpression continue_(LabelTarget labelTarget) {
+  public static GotoStatement continue_(LabelTarget labelTarget) {
     throw Extensions.todo();
   }
 
@@ -587,7 +605,7 @@
    * Creates a GotoExpression representing a continue statement
    * with the specified type.
    */
-  public static GotoExpression continue_(LabelTarget labelTarget, Type type) {
+  public static GotoStatement continue_(LabelTarget labelTarget, Type type) {
     throw Extensions.todo();
   }
 
@@ -712,22 +730,13 @@
    * operation bound by the provided CallSiteBinder.
    */
   public static DynamicExpression dynamic(CallSiteBinder binder, Type type,
-      Iterable<Expression> expressions) {
+      Iterable<? extends Expression> expressions) {
     throw Extensions.todo();
   }
 
   /**
    * Creates a DynamicExpression that represents a dynamic
-   * operation bound by the provided CallSiteBinder.
-   */
-  public static DynamicExpression dynamic(CallSiteBinder binder, Type type,
-      Expression expression) {
-    throw Extensions.todo();
-  }
-
-  /**
-   * Creates a DynamicExpression that represents a dynamic
-   * operation bound by the provided CallSiteBinder.
+   * operation bound by the provided CallSiteBinder, using varargs.
    */
   public static DynamicExpression dynamic(CallSiteBinder binder, Type type,
       Expression... expression) {
@@ -739,13 +748,13 @@
    * argument.
    */
   public static ElementInit elementInit(Method method,
-      Iterable<Expression> expressions) {
+      Iterable<? extends Expression> expressions) {
     throw Extensions.todo();
   }
 
   /**
    * Creates an ElementInit, given an array of values as the second
-   * argument.
+   * argument, using varargs.
    */
   public static ElementInit elementInit(Method method,
       Expression... expressions) {
@@ -888,7 +897,7 @@
   /**
    * Creates a GotoExpression representing a "go to" statement.
    */
-  public static GotoExpression goto_(LabelTarget labelTarget) {
+  public static GotoStatement goto_(LabelTarget labelTarget) {
     throw Extensions.todo();
   }
 
@@ -896,7 +905,7 @@
    * Creates a GotoExpression representing a "go to" statement. The
    * value passed to the label upon jumping can be specified.
    */
-  public static GotoExpression goto_(LabelTarget labelTarget,
+  public static GotoStatement goto_(LabelTarget labelTarget,
       Expression expression) {
     throw Extensions.todo();
   }
@@ -905,7 +914,7 @@
    * Creates a GotoExpression representing a "go to" statement with
    * the specified type.
    */
-  public static GotoExpression goto_(LabelTarget labelTarget, Type type) {
+  public static GotoStatement goto_(LabelTarget labelTarget, Type type) {
     throw Extensions.todo();
   }
 
@@ -914,7 +923,7 @@
    * the specified type. The value passed to the label upon jumping
    * can be specified.
    */
-  public static GotoExpression goto_(LabelTarget labelTarget,
+  public static GotoStatement goto_(LabelTarget labelTarget,
       Expression expression, Type type) {
     throw Extensions.todo();
   }
@@ -995,13 +1004,13 @@
    * lambda expression to a list of argument expressions.
    */
   public static InvocationExpression invoke(Expression expression,
-      Iterable<Expression> arguments) {
+      Iterable<? extends Expression> arguments) {
     throw Extensions.todo();
   }
 
   /**
    * Creates an InvocationExpression that applies a delegate or
-   * lambda expression to a list of argument expressions.
+   * lambda expression to a list of argument expressions, using varargs.
    */
   public static InvocationExpression invoke(Expression expression,
       Expression... arguments) {
@@ -1048,7 +1057,7 @@
    * Creates a LabelExpression representing a label without a
    * default value.
    */
-  public static LabelExpression label(LabelTarget labelTarget) {
+  public static LabelStatement label(LabelTarget labelTarget) {
     throw Extensions.todo();
   }
 
@@ -1072,7 +1081,7 @@
    * Creates a LabelExpression representing a label with the given
    * default value.
    */
-  public static LabelExpression label(LabelTarget labelTarget,
+  public static LabelStatement label(LabelTarget labelTarget,
       Expression expression) {
     throw Extensions.todo();
   }
@@ -1102,90 +1111,86 @@
    * type.
    */
   public static <F extends Function<?>> FunctionExpression<F> lambda(
-      BlockExpression body, Iterable<ParameterExpression> parameters) {
+      BlockStatement body,
+      Iterable<? extends ParameterExpression> parameters) {
     final List<ParameterExpression> parameterList = toList(parameters);
+    @SuppressWarnings("unchecked")
     Class<F> type = deduceType(parameterList, body.getType());
     return new FunctionExpression<F>(type, body, parameterList);
   }
 
   /**
    * Creates a LambdaExpression by first constructing a delegate
-   * type.
+   * type, using varargs.
    */
   public static <F extends Function<?>> FunctionExpression<F> lambda(
-      Expression body, Iterable<ParameterExpression> parameters) {
-    return lambda(Blocks.toFunctionBlock(body), parameters);
-  }
-
-  /**
-   * Creates an Expression<TDelegate> where the delegate type is
-   * known at compile time.
-   */
-  public static <TDelegate extends Function<?>> FunctionExpression<TDelegate>
-  lambda(BlockExpression body, ParameterExpression... parameters) {
+      BlockStatement body, ParameterExpression... parameters) {
     return lambda(body, toList(parameters));
   }
 
   /**
-   * Creates an Expression<TDelegate> where the delegate type is
+   * Creates an Expression where the delegate type {@code F} is
    * known at compile time.
    */
-  public static <TDelegate extends Function<?>> FunctionExpression<TDelegate>
-  lambda(Expression body, ParameterExpression... parameters) {
+  public static <F extends Function<?>> FunctionExpression<F> lambda(
+      Expression body, Iterable<? extends ParameterExpression> parameters) {
+    return lambda(Blocks.toFunctionBlock(body), parameters);
+  }
+
+  /**
+   * Creates an Expression where the delegate type {@code F} is
+   * known at compile time, using varargs.
+   */
+  public static <F extends Function<?>> FunctionExpression<F> lambda(
+      Expression body, ParameterExpression... parameters) {
     return lambda(Blocks.toFunctionBlock(body), toList(parameters));
   }
 
   /**
    * Creates a LambdaExpression by first constructing a delegate
-   * type. It can be used when the delegate type is not known at
-   * compile time.
+   * type.
+   *
+   * <p>It can be used when the delegate type is not known at compile time.
    */
   public static <T, F extends Function<? extends T>> FunctionExpression<F>
-  lambda(Class<F> type, BlockExpression body,
-      Iterable<ParameterExpression> parameters) {
+  lambda(Class<F> type, BlockStatement body,
+      Iterable<? extends ParameterExpression> parameters) {
     return new FunctionExpression<F>(type, body, toList(parameters));
   }
 
   /**
    * Creates a LambdaExpression by first constructing a delegate
-   * type. It can be used when the delegate type is not known at
-   * compile time.
+   * type, using varargs.
+   *
+   * <p>It can be used when the delegate type is not known at compile time.
    */
   public static <T, F extends Function<? extends T>> FunctionExpression<F>
-  lambda(Class<F> type, Expression body,
-      Iterable<ParameterExpression> parameters) {
-    return lambda(type, Blocks.toFunctionBlock(body), toList(parameters));
-  }
-
-  /**
-   * Creates a LambdaExpression by first constructing a delegate
-   * type. It can be used when the delegate type is not known at
-   * compile time.
-   */
-  public static <T, F extends Function<? extends T>> FunctionExpression<F>
-  lambda(Class<F> type, BlockExpression body,
+  lambda(Class<F> type, BlockStatement body,
       ParameterExpression... parameters) {
     return lambda(type, body, toList(parameters));
   }
 
   /**
    * Creates a LambdaExpression by first constructing a delegate
-   * type. It can be used when the delegate type is not known at
-   * compile time.
+   * type.
+   *
+   * <p>It can be used when the delegate type is not known at compile time.
    */
   public static <T, F extends Function<? extends T>> FunctionExpression<F>
-  lambda(Class<F> type, Expression body, ParameterExpression... parameters) {
-    return lambda(type, body, toList(parameters));
+  lambda(Class<F> type, Expression body,
+      Iterable<? extends ParameterExpression> parameters) {
+    return lambda(type, Blocks.toFunctionBlock(body), toList(parameters));
   }
 
   /**
    * Creates a LambdaExpression by first constructing a delegate
-   * type.
+   * type, using varargs.
+   *
+   * <p>It can be used when the delegate type is not known at compile time.
    */
   public static <T, F extends Function<? extends T>> FunctionExpression<F>
-  lambda(Type type, BlockExpression body, String name,
-      Iterable<ParameterExpression> parameters) {
-    throw Extensions.todo();
+  lambda(Class<F> type, Expression body, ParameterExpression... parameters) {
+    return lambda(type, Blocks.toFunctionBlock(body), toList(parameters));
   }
 
   /**
@@ -1272,13 +1277,13 @@
    * property.
    */
   public static MemberListBinding listBind(Member member,
-      Iterable<ElementInit> elementInits) {
+      Iterable<? extends ElementInit> elementInits) {
     throw Extensions.todo();
   }
 
   /**
    * Creates a MemberListBinding where the member is a field or
-   * property.
+   * property, using varargs.
    */
   public static MemberListBinding listBind(Member member,
       ElementInit... elementInits) {
@@ -1290,13 +1295,13 @@
    * accessor method.
    */
   public static MemberListBinding listBind(Method method,
-      Iterable<ElementInit> elementInits) {
+      Iterable<? extends ElementInit> elementInits) {
     throw Extensions.todo();
   }
 
   /**
    * Creates a MemberListBinding object based on a specified
-   * property accessor method.
+   * property accessor method, using varargs.
    */
   public static MemberListBinding listBind(Method method,
       ElementInit... elementInits) {
@@ -1308,22 +1313,13 @@
    * objects to initialize a collection.
    */
   public static ListInitExpression listInit(NewExpression newExpression,
-      Iterable<ElementInit> elementInits) {
-    throw Extensions.todo();
-  }
-
-  /**
-   * Creates a ListInitExpression that uses a method named "Add" to
-   * add elements to a collection.
-   */
-  public static ListInitExpression listInitE(NewExpression newExpression,
-      Iterable<Expression> arguments) {
+      Iterable<? extends ElementInit> elementInits) {
     throw Extensions.todo();
   }
 
   /**
    * Creates a ListInitExpression that uses specified ElementInit
-   * objects to initialize a collection.
+   * objects to initialize a collection, using varargs.
    */
   public static ListInitExpression listInit(NewExpression newExpression,
       ElementInit... elementInits) {
@@ -1334,6 +1330,15 @@
    * Creates a ListInitExpression that uses a method named "Add" to
    * add elements to a collection.
    */
+  public static ListInitExpression listInitE(NewExpression newExpression,
+      Iterable<? extends Expression> arguments) {
+    throw Extensions.todo();
+  }
+
+  /**
+   * Creates a ListInitExpression that uses a method named "Add" to
+   * add elements to a collection, using varargs.
+   */
   public static ListInitExpression listInit(NewExpression newExpression,
       Expression... arguments) {
     throw Extensions.todo();
@@ -1344,13 +1349,13 @@
    * add elements to a collection.
    */
   public static ListInitExpression listInit(NewExpression newExpression,
-      Method method, Iterable<Expression> arguments) {
+      Method method, Iterable<? extends Expression> arguments) {
     throw Extensions.todo();
   }
 
   /**
    * Creates a ListInitExpression that uses a specified method to
-   * add elements to a collection.
+   * add elements to a collection, using varargs.
    */
   public static ListInitExpression listInit(NewExpression newExpression,
       Method method, Expression... arguments) {
@@ -1360,24 +1365,20 @@
   /**
    * Creates a LoopExpression with the given body.
    */
-  public static LoopExpression loop(Expression body) {
-    throw Extensions.todo();
-  }
-
-  /**
-   * Creates a LoopExpression with the given body and break
-   * target.
-   */
-  public static LoopExpression loop(Expression body, LabelTarget breakTarget) {
-    throw Extensions.todo();
+  public static ForStatement for_(
+      Iterable<? extends DeclarationStatement> declarations,
+      Expression condition, Expression post, Statement body) {
+    return new ForStatement(toList(declarations), condition, post, body);
   }
 
   /**
    * Creates a LoopExpression with the given body.
    */
-  public static LoopExpression loop(Expression body, LabelTarget breakTarget,
-      LabelTarget continueTarget) {
-    throw Extensions.todo();
+  public static ForStatement for_(
+      DeclarationStatement declaration,
+      Expression condition, Expression post, Statement body) {
+    return new ForStatement(Collections.singletonList(declaration), condition,
+        post, body);
   }
 
   /**
@@ -1525,23 +1526,13 @@
    * operation bound by the provided CallSiteBinder.
    */
   public static DynamicExpression makeDynamic(Type type, CallSiteBinder binder,
-      Iterable<Expression> arguments) {
+      Iterable<? extends Expression> arguments) {
     throw Extensions.todo();
   }
 
   /**
    * Creates a DynamicExpression that represents a dynamic
-   * operation bound by the provided CallSiteBinder and one
-   * argument.
-   */
-  public static DynamicExpression makeDynamic(Type type, CallSiteBinder binder,
-      Expression argument) {
-    throw Extensions.todo();
-  }
-
-  /**
-   * Creates a DynamicExpression that represents a dynamic
-   * operation bound by the provided CallSiteBinder.
+   * operation bound by the provided CallSiteBinder, using varargs.
    */
   public static DynamicExpression makeDynamic(Type type, CallSiteBinder binder,
       Expression... arguments) {
@@ -1553,21 +1544,12 @@
    * GotoExpressionKind. The value passed to the label upon jumping
    * can also be specified.
    */
-  public static GotoExpression makeGoto(GotoExpressionKind kind,
+  public static GotoStatement makeGoto(GotoExpressionKind kind,
       LabelTarget target, Expression value, Type type) {
     throw Extensions.todo();
   }
 
   /**
-   * Creates an IndexExpression that represents accessing an
-   * indexed property in an object.
-   */
-  public static IndexExpression makeIndex(Expression instance,
-      PropertyInfo indexer, Iterable<Expression> arguments) {
-    throw Extensions.todo();
-  }
-
-  /**
    * Creates a MemberExpression that represents accessing a field.
    */
   public static MemberExpression makeMemberAccess(Expression expression,
@@ -1579,8 +1561,19 @@
    * Creates a TryExpression representing a try block with the
    * specified elements.
    */
-  public static TryExpression makeTry(Type type, Expression body,
-      Expression finally_, Expression fault, Iterable<CatchBlock> handlers) {
+  public static TryStatement makeTry(Type type, Expression body,
+      Expression finally_, Expression fault,
+      Iterable<? extends CatchBlock> handlers) {
+    throw Extensions.todo();
+  }
+
+  /**
+   * Creates a TryExpression representing a try block with the
+   * specified elements, using varargs.
+   */
+  public static TryStatement makeTry(Type type, Expression body,
+      Expression finally_, Expression fault,
+      CatchBlock... handlers) {
     throw Extensions.todo();
   }
 
@@ -1609,13 +1602,13 @@
    * initialization of members of a field or property.
    */
   public static MemberMemberBinding memberBind(Member member,
-      Iterable<MemberBinding> bindings) {
+      Iterable<? extends MemberBinding> bindings) {
     throw Extensions.todo();
   }
 
   /**
    * Creates a MemberMemberBinding that represents the recursive
-   * initialization of members of a field or property.
+   * initialization of members of a field or property, using varargs.
    */
   public static MemberMemberBinding memberBind(Member member,
       MemberBinding... bindings) {
@@ -1628,14 +1621,14 @@
    * a property accessor method.
    */
   public static MemberMemberBinding memberBind(Method method,
-      Iterable<MemberBinding> bindings) {
+      Iterable<? extends MemberBinding> bindings) {
     throw Extensions.todo();
   }
 
   /**
    * Creates a MemberMemberBinding that represents the recursive
    * initialization of members of a member that is accessed by using
-   * a property accessor method.
+   * a property accessor method, using varargs.
    */
   public static MemberMemberBinding memberBind(Method method,
       MemberBinding... bindings) {
@@ -1647,12 +1640,13 @@
    * initializes a property of the object.
    */
   public static MemberInitExpression memberInit(NewExpression newExpression,
-      Iterable<MemberBinding> bindings) {
+      Iterable<? extends MemberBinding> bindings) {
     throw Extensions.todo();
   }
 
   /**
-   * Creates a MemberInitExpression.
+   * Represents an expression that creates a new object and
+   * initializes a property of the object, using varargs.
    */
   public static MemberInitExpression memberInit(NewExpression newExpression,
       MemberBinding... bindings) {
@@ -1663,8 +1657,8 @@
    * Declares a method.
    */
   public static MethodDeclaration methodDecl(int modifier, Type resultType,
-      String name, Iterable<ParameterExpression> parameters,
-      BlockExpression body) {
+      String name, Iterable<? extends ParameterExpression> parameters,
+      BlockStatement body) {
     return new MethodDeclaration(modifier, name, resultType, toList(parameters),
         body);
   }
@@ -1673,8 +1667,8 @@
    * Declares a constructor.
    */
   public static ConstructorDeclaration constructorDecl(int modifier,
-      Type declaredAgainst, Iterable<ParameterExpression> parameters,
-      BlockExpression body) {
+      Type declaredAgainst, Iterable<? extends ParameterExpression> parameters,
+      BlockStatement body) {
     return new ConstructorDeclaration(modifier, declaredAgainst, toList(
         parameters), body);
   }
@@ -1879,8 +1873,8 @@
    * constructor that takes no arguments.
    */
   public static NewExpression new_(Constructor constructor) {
-    return new_(constructor.getDeclaringClass(),
-        Collections.<Expression>emptyList());
+    return new_(
+        constructor.getDeclaringClass(), Collections.<Expression>emptyList());
   }
 
   /**
@@ -1896,10 +1890,22 @@
    * specified type whose parameters are assignable from the specified
    * arguments.
    */
-  public static NewExpression new_(Type type, Iterable<Expression> arguments) {
+  public static NewExpression new_(Type type,
+      Iterable<? extends Expression> arguments) {
     // Note that the last argument is not an empty list. That would cause
     // an anonymous inner-class with no members to be generated.
-    return new_(type, arguments, null);
+    return new NewExpression(type, toList(arguments), null);
+  }
+
+  /**
+   * Creates a NewExpression that represents calling the constructor of the
+   * specified type whose parameters are assignable from the specified
+   * arguments, using varargs.
+   */
+  public static NewExpression new_(Type type, Expression... arguments) {
+    // Note that the last argument is not an empty list. That would cause
+    // an anonymous inner-class with no members to be generated.
+    return new NewExpression(type, toList(arguments), null);
   }
 
   /**
@@ -1907,10 +1913,23 @@
    * specified type whose parameters are assignable from the specified
    * arguments.
    */
-  public static NewExpression new_(Type type, Iterable<Expression> arguments,
-      Iterable<MemberDeclaration> memberDeclarations) {
-    return new NewExpression(type, toList(arguments), toList(
-        memberDeclarations));
+  public static NewExpression new_(Type type,
+      Iterable<? extends Expression> arguments,
+      Iterable<? extends MemberDeclaration> memberDeclarations) {
+    return new NewExpression(type, toList(arguments),
+        toList(memberDeclarations));
+  }
+
+  /**
+   * Creates a NewExpression that represents calling the constructor of the
+   * specified type whose parameters are assignable from the specified
+   * arguments, using varargs.
+   */
+  public static NewExpression new_(Type type,
+      Iterable<? extends Expression> arguments,
+      MemberDeclaration... memberDeclarations) {
+    return new NewExpression(type, toList(arguments),
+        toList(memberDeclarations));
   }
 
   /**
@@ -1918,31 +1937,49 @@
    * constructor with the specified arguments.
    */
   public static NewExpression new_(Constructor constructor,
-      Iterable<Expression> expressions) {
+      Iterable<? extends Expression> expressions) {
     // Note that the last argument is not an empty list. That would cause
     // an anonymous inner-class with no members to be generated.
-    return new_(constructor.getDeclaringClass(), expressions, null);
+    return new NewExpression(constructor.getDeclaringClass(),
+        toList(expressions), null);
   }
 
   /**
    * Creates a NewExpression that represents calling the specified
-   * constructor with the specified arguments.
+   * constructor with the specified arguments, using varargs.
    */
   public static NewExpression new_(Constructor constructor,
       Expression... expressions) {
-    return new_(constructor, toList(expressions));
+    return new NewExpression(constructor.getDeclaringClass(),
+        toList(expressions), null);
   }
 
   /**
    * Creates a NewExpression that represents calling the specified
-   * constructor with the specified arguments. The members that
-   * access the constructor initialized fields are specified.
+   * constructor with the specified arguments.
+   *
+   * <p>The members that access the constructor initialized fields are
+   * specified.
    */
   public static NewExpression new_(Constructor constructor,
-      Iterable<Expression> expressions,
-      Iterable<MemberDeclaration> memberDeclarations) {
-    return new_(constructor.getDeclaringClass(), toList(expressions), toList(
-        memberDeclarations));
+      Iterable<? extends Expression> expressions,
+      Iterable<? extends MemberDeclaration> memberDeclarations) {
+    return new_(constructor.getDeclaringClass(), toList(expressions),
+        toList(memberDeclarations));
+  }
+
+  /**
+   * Creates a NewExpression that represents calling the specified
+   * constructor with the specified arguments, using varargs.
+   *
+   * <p>The members that access the constructor initialized fields are
+   * specified.
+   */
+  public static NewExpression new_(Constructor constructor,
+      Iterable<? extends Expression> expressions,
+      MemberDeclaration... memberDeclarations) {
+    return new_(constructor.getDeclaringClass(), toList(expressions),
+        toList(memberDeclarations));
   }
 
   /**
@@ -1950,13 +1987,13 @@
    * that has a specified rank.
    */
   public static NewArrayExpression newArrayBounds(Type type,
-      Iterable<Expression> expressions) {
+      Iterable<? extends Expression> expressions) {
     throw Extensions.todo();
   }
 
   /**
    * Creates a NewArrayExpression that represents creating an array
-   * that has a specified rank.
+   * that has a specified rank, using varargs.
    */
   public static NewArrayExpression newArrayBounds(Type type,
       Expression... expressions) {
@@ -1971,14 +2008,16 @@
    * @param type Element type of the array.
    */
   public static NewArrayExpression newArrayInit(Type type,
-      Iterable<Expression> expressions) {
+      Iterable<? extends Expression> expressions) {
     return new NewArrayExpression(type, toList(expressions));
   }
 
   /**
    * Creates a NewArrayExpression that represents creating a
    * one-dimensional array and initializing it from a list of
-   * elements.
+   * elements, using varargs.
+   *
+   * @param type Element type of the array.
    */
   public static NewArrayExpression newArrayInit(Type type,
       Expression... expressions) {
@@ -2283,13 +2322,13 @@
    */
   // REVIEW: No equivalent to properties in Java.
   public static IndexExpression property(Expression expression,
-      PropertyInfo property, Iterable<Expression> arguments) {
+      PropertyInfo property, Iterable<? extends Expression> arguments) {
     throw Extensions.todo();
   }
 
   /**
    * Creates an IndexExpression representing the access to an
-   * indexed property.
+   * indexed property, using varargs.
    */
   // REVIEW: No equivalent to properties in Java.
   public static IndexExpression property(Expression expression,
@@ -2396,7 +2435,7 @@
   /**
    * Creates a GotoExpression representing a return statement.
    */
-  public static GotoExpression return_(LabelTarget labelTarget) {
+  public static GotoStatement return_(LabelTarget labelTarget) {
     return return_(labelTarget, (Expression) null);
   }
 
@@ -2404,21 +2443,21 @@
    * Creates a GotoExpression representing a return statement. The
    * value passed to the label upon jumping can be specified.
    */
-  public static GotoExpression return_(LabelTarget labelTarget,
+  public static GotoStatement return_(LabelTarget labelTarget,
       Expression expression) {
     return makeGoto(GotoExpressionKind.Return, labelTarget, expression);
   }
 
-  public static GotoExpression makeGoto(GotoExpressionKind kind,
+  public static GotoStatement makeGoto(GotoExpressionKind kind,
       LabelTarget labelTarget, Expression expression) {
-    return new GotoExpression(kind, labelTarget, expression);
+    return new GotoStatement(kind, labelTarget, expression);
   }
 
   /**
    * Creates a GotoExpression representing a return statement with
    * the specified type.
    */
-  public static GotoExpression return_(LabelTarget labelTarget, Type type) {
+  public static GotoStatement return_(LabelTarget labelTarget, Type type) {
     throw Extensions.todo();
   }
 
@@ -2427,7 +2466,7 @@
    * the specified type. The value passed to the label upon jumping
    * can be specified.
    */
-  public static GotoExpression return_(LabelTarget labelTarget,
+  public static GotoStatement return_(LabelTarget labelTarget,
       Expression expression, Type type) {
     throw Extensions.todo();
   }
@@ -2482,12 +2521,12 @@
    * Creates an instance of RuntimeVariablesExpression.
    */
   public static RuntimeVariablesExpression runtimeVariables(
-      Iterable<ParameterExpression> expressions) {
+      Iterable<? extends ParameterExpression> expressions) {
     throw Extensions.todo();
   }
 
   /**
-   * Creates an instance of RuntimeVariablesExpression.
+   * Creates an instance of RuntimeVariablesExpression, using varargs.
    */
   public static RuntimeVariablesExpression runtimeVariables(
       ParameterExpression... arguments) {
@@ -2593,7 +2632,7 @@
    * Creates a SwitchExpression that represents a switch statement
    * without a default case.
    */
-  public static SwitchExpression switch_(Expression switchValue,
+  public static SwitchStatement switch_(Expression switchValue,
       SwitchCase... cases) {
     return switch_(switchValue, null, null, toList(cases));
   }
@@ -2602,7 +2641,7 @@
    * Creates a SwitchExpression that represents a switch statement
    * that has a default case.
    */
-  public static SwitchExpression switch_(Expression switchValue,
+  public static SwitchStatement switch_(Expression switchValue,
       Expression defaultBody, SwitchCase... cases) {
     return switch_(switchValue, defaultBody, null, toList(cases));
   }
@@ -2611,16 +2650,17 @@
    * Creates a SwitchExpression that represents a switch statement
    * that has a default case.
    */
-  public static SwitchExpression switch_(Expression switchValue,
-      Expression defaultBody, Method method, Iterable<SwitchCase> cases) {
+  public static SwitchStatement switch_(Expression switchValue,
+      Expression defaultBody, Method method,
+      Iterable<? extends SwitchCase> cases) {
     throw Extensions.todo();
   }
 
   /**
    * Creates a SwitchExpression that represents a switch statement
-   * that has a default case.
+   * that has a default case, using varargs.
    */
-  public static SwitchExpression switch_(Expression switchValue,
+  public static SwitchStatement switch_(Expression switchValue,
       Expression defaultBody, Method method, SwitchCase... cases) {
     return switch_(switchValue, defaultBody, method, toList(cases));
   }
@@ -2629,31 +2669,31 @@
    * Creates a SwitchExpression that represents a switch statement
    * that has a default case.
    */
-  public static SwitchExpression switch_(Type type, Expression switchValue,
-      Expression defaultBody, Method method, Iterable<SwitchCase> cases) {
+  public static SwitchStatement switch_(Type type, Expression switchValue,
+      Expression defaultBody, Method method,
+      Iterable<? extends SwitchCase> cases) {
     throw Extensions.todo();
   }
 
   /**
    * Creates a SwitchExpression that represents a switch statement
-   * that has a default case..
+   * that has a default case, using varargs.
    */
-  public static SwitchExpression switch_(Type type, Expression switchValue,
+  public static SwitchStatement switch_(Type type, Expression switchValue,
       Expression defaultBody, Method method, SwitchCase... cases) {
     return switch_(type, switchValue, defaultBody, method, toList(cases));
   }
 
   /**
-   * Creates a SwitchCase object to be used in a SwitchExpression
-   * object.
+   * Creates a SwitchCase for use in a SwitchExpression.
    */
   public static SwitchCase switchCase(Expression expression,
-      Iterable<Expression> body) {
+      Iterable<? extends Expression> body) {
     throw Extensions.todo();
   }
 
   /**
-   * Creates a SwitchCase for use in a SwitchExpression.
+   * Creates a SwitchCase for use in a SwitchExpression, with varargs.
    */
   public static SwitchCase switchCase(Expression expression,
       Expression... body) {
@@ -2712,7 +2752,7 @@
    * number of catch statements and neither a fault nor finally
    * block.
    */
-  public static TryExpression tryCatch(Expression body,
+  public static TryStatement tryCatch(Expression body,
       CatchBlock... handlers) {
     throw Extensions.todo();
   }
@@ -2721,7 +2761,7 @@
    * Creates a TryExpression representing a try block with any
    * number of catch statements and a finally block.
    */
-  public static TryExpression tryCatchFinally(Expression body,
+  public static TryStatement tryCatchFinally(Expression body,
       CatchBlock... handlers) {
     throw Extensions.todo();
   }
@@ -2730,7 +2770,7 @@
    * Creates a TryExpression representing a try block with a fault
    * block and no catch statements.
    */
-  public static TryExpression tryFault(Expression body, Expression fault) {
+  public static TryStatement tryFault(Expression body, Expression fault) {
     throw Extensions.todo();
   }
 
@@ -2738,7 +2778,7 @@
    * Creates a TryExpression representing a try block with a
    * finally block and no catch statements.
    */
-  public static TryExpression tryFinally(Expression body, Expression fault) {
+  public static TryStatement tryFinally(Expression body, Expression fault) {
     throw Extensions.todo();
   }
 
@@ -2839,25 +2879,25 @@
   /**
    * Creates a WhileExpression representing a while loop.
    */
-  public static WhileExpression while_(Expression condition, Statement body) {
-    return new WhileExpression(condition, body);
+  public static WhileStatement while_(Expression condition, Statement body) {
+    return new WhileStatement(condition, body);
   }
 
   /**
    * Creates a statement that declares a variable.
    */
-  public static DeclarationExpression declare(int modifiers,
+  public static DeclarationStatement declare(int modifiers,
       ParameterExpression parameter, Expression initializer) {
-    return new DeclarationExpression(modifiers, parameter, initializer);
+    return new DeclarationStatement(modifiers, parameter, initializer);
   }
 
   /**
    * Creates an expression that declares and initializes a variable. No
    * type is required; it is assumed that the variable is the same type as
    * the initializer. You can retrieve the {@link ParameterExpression} from
-   * the {@link DeclarationExpression#parameter} field of the result.
+   * the {@link DeclarationStatement#parameter} field of the result.
    */
-  public static DeclarationExpression declare(int modifiers, String name,
+  public static DeclarationStatement declare(int modifiers, String name,
       Expression initializer) {
     return declare(modifiers, parameter(initializer.getType(), name),
         initializer);
@@ -2867,7 +2907,7 @@
    * Creates a statement that executes an expression.
    */
   public static Statement statement(Expression expression) {
-    return new GotoExpression(GotoExpressionKind.Sequence, null, expression);
+    return new GotoStatement(GotoExpressionKind.Sequence, null, expression);
   }
 
   /** Combines a list of expressions using AND. Returns TRUE if the list is
@@ -2933,7 +2973,7 @@
   }
 
   /**
-   * Creates a fluent list with given elements.
+   * Creates a fluent list with elements from the given collection.
    */
   public static <T> FluentList<T> list(Iterable<T> ts) {
     return new FluentArrayList<T>(toList(ts));
@@ -3043,6 +3083,19 @@
     return parameterExpressions1;
   }
 
+  static List<DeclarationStatement> acceptDeclarations(
+      List<DeclarationStatement> declarations, Visitor visitor) {
+    if (declarations == null || declarations.isEmpty()) {
+      return declarations; // short cut
+    }
+    final List<DeclarationStatement> declarations1 =
+        new ArrayList<DeclarationStatement>();
+    for (DeclarationStatement declaration : declarations) {
+      declarations1.add(declaration.accept(visitor));
+    }
+    return declarations1;
+  }
+
   static List<MemberDeclaration> acceptMemberDeclarations(
       List<MemberDeclaration> memberDeclarations, Visitor visitor) {
     if (memberDeclarations == null || memberDeclarations.isEmpty()) {
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/ForStatement.java b/src/main/java/net/hydromatic/linq4j/expressions/ForStatement.java
new file mode 100644
index 0000000..0b9560b
--- /dev/null
+++ b/src/main/java/net/hydromatic/linq4j/expressions/ForStatement.java
@@ -0,0 +1,73 @@
+/*
+// Licensed to Julian Hyde under one or more contributor license
+// agreements. See the NOTICE file distributed with this work for
+// additional information regarding copyright ownership.
+//
+// Julian Hyde licenses this file to you under the Apache License,
+// Version 2.0 (the "License"); you may not use this file except in
+// compliance with the License. You may obtain a copy of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+package net.hydromatic.linq4j.expressions;
+
+import net.hydromatic.linq4j.Ord;
+
+import java.util.List;
+
+/**
+ * Represents an infinite loop. It can be exited with "break".
+ */
+public class ForStatement extends Statement {
+  public final List<DeclarationStatement> declarations;
+  public final Expression condition;
+  public final Expression post;
+  public final Statement body;
+
+  public ForStatement(List<DeclarationStatement> declarations,
+      Expression condition, Expression post, Statement body) {
+    super(ExpressionType.For, Void.TYPE);
+    assert declarations != null;
+    assert body != null;
+    this.declarations = declarations; // may be empty, not null
+    this.condition = condition; // may be null
+    this.post = post; // may be null
+    this.body = body; // may be empty block, not null
+  }
+
+  @Override
+  public ForStatement accept(Visitor visitor) {
+    List<DeclarationStatement> decls1 =
+        Expressions.acceptDeclarations(declarations, visitor);
+    final Expression condition1 =
+        condition == null ? null : condition.accept(visitor);
+    final Expression post1 = post == null ? null : post.accept(visitor);
+    final Statement body1 = body.accept(visitor);
+    return visitor.visit(this, decls1, condition1, post1, body1);
+  }
+
+  @Override
+  void accept0(ExpressionWriter writer) {
+    writer.append("for (");
+    for (Ord<DeclarationStatement> declaration : Ord.zip(declarations)) {
+      declaration.e.accept2(writer, declaration.i == 0);
+    }
+    writer.append("; ");
+    if (condition != null) {
+      writer.append(condition);
+    }
+    writer.append("; ");
+    if (post != null) {
+      writer.append(post);
+    }
+    writer.append(") ").append(Blocks.toBlock(body));
+  }
+}
+
+// End ForStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/FunctionExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/FunctionExpression.java
index b7d7d61..bb1fe3f 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/FunctionExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/FunctionExpression.java
@@ -29,11 +29,11 @@
 public final class FunctionExpression<F extends Function<?>>
     extends LambdaExpression {
   public final F function;
-  public final BlockExpression body;
+  public final BlockStatement body;
   public final List<ParameterExpression> parameterList;
   private F dynamicFunction;
 
-  private FunctionExpression(Class<F> type, F function, BlockExpression body,
+  private FunctionExpression(Class<F> type, F function, BlockStatement body,
       List<ParameterExpression> parameterList) {
     super(ExpressionType.Lambda, type);
     assert type != null;
@@ -48,14 +48,14 @@
         Collections.<ParameterExpression>emptyList());
   }
 
-  public FunctionExpression(Class<F> type, BlockExpression body,
+  public FunctionExpression(Class<F> type, BlockStatement body,
       List<ParameterExpression> parameters) {
     this(type, null, body, parameters);
   }
 
   @Override
   public Expression accept(Visitor visitor) {
-    BlockExpression body = this.body.accept(visitor);
+    BlockStatement body = this.body.accept(visitor);
     return visitor.visit(this, body, parameterList);
   }
 
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/GotoExpressionKind.java b/src/main/java/net/hydromatic/linq4j/expressions/GotoExpressionKind.java
index 61b25ad..bf84070 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/GotoExpressionKind.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/GotoExpressionKind.java
@@ -18,7 +18,7 @@
 package net.hydromatic.linq4j.expressions;
 
 /**
- * Specifies what kind of jump a {@link GotoExpression} represents.
+ * Specifies what kind of jump a {@link GotoStatement} represents.
  */
 public enum GotoExpressionKind {
   /**
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/GotoExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/GotoStatement.java
similarity index 90%
rename from src/main/java/net/hydromatic/linq4j/expressions/GotoExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/GotoStatement.java
index 494985a..932b253 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/GotoExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/GotoStatement.java
@@ -21,12 +21,12 @@
  * Represents an unconditional jump. This includes return statements, break and
  * continue statements, and other jumps.
  */
-public class GotoExpression extends Statement {
+public class GotoStatement extends Statement {
   public final GotoExpressionKind kind;
   public final LabelTarget labelTarget;
   public final Expression expression;
 
-  GotoExpression(GotoExpressionKind kind, LabelTarget labelTarget,
+  GotoStatement(GotoExpressionKind kind, LabelTarget labelTarget,
       Expression expression) {
     super(ExpressionType.Goto,
         expression == null ? Void.TYPE : expression.getType());
@@ -54,8 +54,9 @@
 
   @Override
   public Statement accept(Visitor visitor) {
-    Expression expression = this.expression.accept(visitor);
-    return visitor.visit(this, expression);
+    Expression expression1 =
+        expression == null ? null : expression.accept(visitor);
+    return visitor.visit(this, expression1);
   }
 
   @Override
@@ -96,4 +97,4 @@
   }
 }
 
-// End GotoExpression.java
+// End GotoStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/LabelExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/LabelStatement.java
similarity index 81%
rename from src/main/java/net/hydromatic/linq4j/expressions/LabelExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/LabelStatement.java
index 1f35b5d..cf25219 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/LabelExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/LabelStatement.java
@@ -20,22 +20,22 @@
 /**
  * Represents a label, which can be put in any {@link Expression} context. If it
  * is jumped to, it will get the value provided by the corresponding
- * {@link GotoExpression}. Otherwise, it receives the value in
+ * {@link GotoStatement}. Otherwise, it receives the value in
  * {@link #defaultValue}. If the Type equals {@link Void}, no value should be
  * provided.
  */
-public class LabelExpression extends Statement {
+public class LabelStatement extends Statement {
   public final Expression defaultValue;
 
-  public LabelExpression(Expression defaultValue, ExpressionType nodeType) {
+  public LabelStatement(Expression defaultValue, ExpressionType nodeType) {
     super(nodeType, Void.TYPE);
     this.defaultValue = defaultValue;
   }
 
   @Override
-  public LabelExpression accept(Visitor visitor) {
+  public LabelStatement accept(Visitor visitor) {
     return visitor.visit(this);
   }
 }
 
-// End LabelExpression.java
+// End LabelStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/LabelTarget.java b/src/main/java/net/hydromatic/linq4j/expressions/LabelTarget.java
index 974c413..2ad7381 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/LabelTarget.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/LabelTarget.java
@@ -18,7 +18,7 @@
 package net.hydromatic.linq4j.expressions;
 
 /**
- * Used to represent the target of a {@link GotoExpression}.
+ * Used to represent the target of a {@link GotoStatement}.
  */
 public class LabelTarget {
   public final String name;
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/LoopExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/LoopExpression.java
deleted file mode 100644
index aa84419..0000000
--- a/src/main/java/net/hydromatic/linq4j/expressions/LoopExpression.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-// Licensed to Julian Hyde under one or more contributor license
-// agreements. See the NOTICE file distributed with this work for
-// additional information regarding copyright ownership.
-//
-// Julian Hyde licenses this file to you under the Apache License,
-// Version 2.0 (the "License"); you may not use this file except in
-// compliance with the License. You may obtain a copy of the License at:
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-*/
-package net.hydromatic.linq4j.expressions;
-
-/**
- * Represents an infinite loop. It can be exited with "break".
- */
-public class LoopExpression extends Statement {
-  public LoopExpression(ExpressionType nodeType) {
-    super(nodeType, Void.TYPE);
-  }
-
-  @Override
-  public LoopExpression accept(Visitor visitor) {
-    return visitor.visit(this);
-  }
-}
-
-// End LoopExpression.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/MethodDeclaration.java b/src/main/java/net/hydromatic/linq4j/expressions/MethodDeclaration.java
index d31eabc..306d46e 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/MethodDeclaration.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/MethodDeclaration.java
@@ -30,10 +30,10 @@
   public final String name;
   public final Type resultType;
   public final List<ParameterExpression> parameters;
-  public final BlockExpression body;
+  public final BlockStatement body;
 
   public MethodDeclaration(int modifier, String name, Type resultType,
-      List<ParameterExpression> parameters, BlockExpression body) {
+      List<ParameterExpression> parameters, BlockStatement body) {
     this.modifier = modifier;
     this.name = name;
     this.resultType = resultType;
@@ -44,7 +44,7 @@
   @Override
   public MemberDeclaration accept(Visitor visitor) {
     // do not visit parameters
-    final BlockExpression body = this.body.accept(visitor);
+    final BlockStatement body = this.body.accept(visitor);
     return visitor.visit(this, parameters, body);
   }
 
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/SwitchCase.java b/src/main/java/net/hydromatic/linq4j/expressions/SwitchCase.java
index a724750..27dd250 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/SwitchCase.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/SwitchCase.java
@@ -18,7 +18,7 @@
 package net.hydromatic.linq4j.expressions;
 
 /**
- * Represents one case of a {@link SwitchExpression}.
+ * Represents one case of a {@link SwitchStatement}.
  */
 public class SwitchCase {
 }
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/SwitchExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/SwitchStatement.java
similarity index 88%
rename from src/main/java/net/hydromatic/linq4j/expressions/SwitchExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/SwitchStatement.java
index 54f9a4c..8ecfd2e 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/SwitchExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/SwitchStatement.java
@@ -21,8 +21,8 @@
  * Represents a control expression that handles multiple selections by passing
  * control to {@link SwitchCase}.
  */
-public class SwitchExpression extends Statement {
-  public SwitchExpression(ExpressionType nodeType) {
+public class SwitchStatement extends Statement {
+  public SwitchStatement(ExpressionType nodeType) {
     super(nodeType, Void.TYPE);
   }
 
@@ -32,4 +32,4 @@
   }
 }
 
-// End SwitchExpression.java
+// End SwitchStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/TryExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/TryStatement.java
similarity index 88%
rename from src/main/java/net/hydromatic/linq4j/expressions/TryExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/TryStatement.java
index 0647431..35dac9f 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/TryExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/TryStatement.java
@@ -20,8 +20,8 @@
 /**
  * Represents a try/catch/finally/fault block.
  */
-public class TryExpression extends Statement {
-  public TryExpression(ExpressionType nodeType) {
+public class TryStatement extends Statement {
+  public TryStatement(ExpressionType nodeType) {
     super(nodeType, Void.TYPE);
   }
 
@@ -31,4 +31,4 @@
   }
 }
 
-// End TryExpression.java
+// End TryStatement.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/Types.java b/src/main/java/net/hydromatic/linq4j/expressions/Types.java
index ed01dbe..925878b 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/Types.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/Types.java
@@ -98,6 +98,8 @@
   static PseudoField getField(String fieldName, Type type) {
     if (type instanceof RecordType) {
       return getRecordField(fieldName, (RecordType) type);
+    } else if (type instanceof Class && ((Class) type).isArray()) {
+      return getSystemField(fieldName, (Class) type);
     } else {
       return field(getField(fieldName, toClass(type)));
     }
@@ -113,6 +115,36 @@
         "Unknown field '" + fieldName + "' in type " + type);
   }
 
+  private static RecordField getSystemField(final String fieldName,
+      final Class clazz) {
+    // The "length" field of an array does not appear in Class.getFields().
+    return new RecordField() {
+      public boolean nullable() {
+        return false;
+      }
+
+      public String getName() {
+        return fieldName;
+      }
+
+      public Type getType() {
+        return int.class;
+      }
+
+      public int getModifiers() {
+        return 0;
+      }
+
+      public Object get(Object o) throws IllegalAccessException {
+        return Array.getLength(o);
+      }
+
+      public Type getDeclaringClass() {
+        return clazz;
+      }
+    };
+  }
+
   public static Class toClass(Type type) {
     if (type instanceof Class) {
       return (Class) type;
@@ -135,7 +167,7 @@
     return classes.toArray(new Class[classes.size()]);
   }
 
-  static Class[] toClassArray(Iterable<Expression> arguments) {
+  static Class[] toClassArray(Iterable<? extends Expression> arguments) {
     List<Class> classes = new ArrayList<Class>();
     for (Expression argument : arguments) {
       classes.add(toClass(argument.getType()));
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/Visitor.java b/src/main/java/net/hydromatic/linq4j/expressions/Visitor.java
index 7f73d56..8e05276 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/Visitor.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/Visitor.java
@@ -23,46 +23,48 @@
 
 /**
  * Node visitor.
- *
- * @author jhyde
  */
 public class Visitor {
-  public Statement visit(WhileExpression whileExpression, Expression condition,
+  public Statement visit(WhileStatement whileStatement, Expression condition,
       Statement body) {
-    return condition == whileExpression.condition
-           && body == whileExpression.body
-        ? whileExpression
+    return condition == whileStatement.condition
+           && body == whileStatement.body
+        ? whileStatement
         : Expressions.while_(condition, body);
   }
 
-  public BlockExpression visit(BlockExpression blockExpression,
+  public BlockStatement visit(BlockStatement blockStatement,
       List<Statement> statements) {
-    return statements.equals(blockExpression.statements)
-        ? blockExpression
+    return statements.equals(blockStatement.statements)
+        ? blockStatement
         : Expressions.block(statements);
   }
 
-  public Statement visit(GotoExpression gotoExpression, Expression expression) {
-    return expression == gotoExpression.expression
-        ? gotoExpression
-        : Expressions.makeGoto(gotoExpression.kind, gotoExpression.labelTarget,
+  public Statement visit(GotoStatement gotoStatement, Expression expression) {
+    return expression == gotoStatement.expression
+        ? gotoStatement
+        : Expressions.makeGoto(
+            gotoStatement.kind, gotoStatement.labelTarget,
             expression);
   }
 
-  public LabelExpression visit(LabelExpression labelExpression) {
-    return labelExpression;
+  public LabelStatement visit(LabelStatement labelStatement) {
+    return labelStatement;
   }
 
-  public LoopExpression visit(LoopExpression loopExpression) {
-    return loopExpression;
+  public ForStatement visit(ForStatement forStatement,
+      List<DeclarationStatement> declarations, Expression condition,
+      Expression post, Statement body) {
+    return forStatement;
   }
 
-  public Statement visit(DeclarationExpression declarationExpression,
+  public DeclarationStatement visit(DeclarationStatement declarationStatement,
       ParameterExpression parameter, Expression initializer) {
-    return declarationExpression.parameter == parameter
-           && declarationExpression.initializer == initializer
-        ? declarationExpression
-        : Expressions.declare(declarationExpression.modifiers, parameter,
+    return declarationStatement.parameter == parameter
+           && declarationStatement.initializer == initializer
+        ? declarationStatement
+        : Expressions.declare(
+            declarationStatement.modifiers, parameter,
             initializer);
   }
 
@@ -71,7 +73,7 @@
   }
 
   public Expression visit(FunctionExpression functionExpression,
-      BlockExpression body, List<ParameterExpression> parameterList) {
+      BlockStatement body, List<ParameterExpression> parameterList) {
     return functionExpression.body.equals(body)
            && functionExpression.parameterList.equals(parameterList)
         ? functionExpression
@@ -161,12 +163,12 @@
         : Expressions.new_(newExpression.type, arguments, memberDeclarations);
   }
 
-  public Statement visit(SwitchExpression switchExpression) {
-    return switchExpression;
+  public Statement visit(SwitchStatement switchStatement) {
+    return switchStatement;
   }
 
-  public Statement visit(TryExpression tryExpression) {
-    return tryExpression;
+  public Statement visit(TryStatement tryStatement) {
+    return tryStatement;
   }
 
   public Expression visit(MemberInitExpression memberInitExpression) {
@@ -179,7 +181,7 @@
   }
 
   public MemberDeclaration visit(MethodDeclaration methodDeclaration,
-      List<ParameterExpression> parameters, BlockExpression body) {
+      List<ParameterExpression> parameters, BlockStatement body) {
     return parameters.equals(methodDeclaration.parameters)
         && body.equals(methodDeclaration.body)
         ? methodDeclaration
@@ -211,7 +213,7 @@
   }
 
   public MemberDeclaration visit(ConstructorDeclaration constructorDeclaration,
-      List<ParameterExpression> parameters, BlockExpression body) {
+      List<ParameterExpression> parameters, BlockStatement body) {
     return constructorDeclaration;
   }
 }
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/WhileExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/WhileStatement.java
similarity index 90%
rename from src/main/java/net/hydromatic/linq4j/expressions/WhileExpression.java
rename to src/main/java/net/hydromatic/linq4j/expressions/WhileStatement.java
index 8ca2528..6b680f2 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/WhileExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/WhileStatement.java
@@ -20,11 +20,11 @@
 /**
  * Represents a "while" statement.
  */
-public class WhileExpression extends Statement {
+public class WhileStatement extends Statement {
   public final Expression condition;
   public final Statement body;
 
-  public WhileExpression(Expression condition, Statement body) {
+  public WhileStatement(Expression condition, Statement body) {
     super(ExpressionType.While, Void.TYPE);
     this.condition = condition;
     this.body = body;
@@ -44,4 +44,4 @@
   }
 }
 
-// End WhileExpression.java
+// End WhileStatement.java
diff --git a/src/test/java/net/hydromatic/linq4j/test/ExpressionTest.java b/src/test/java/net/hydromatic/linq4j/test/ExpressionTest.java
index 08747b4..30dbfe8 100644
--- a/src/test/java/net/hydromatic/linq4j/test/ExpressionTest.java
+++ b/src/test/java/net/hydromatic/linq4j/test/ExpressionTest.java
@@ -293,6 +293,13 @@
                 "empno")));
 
     assertEquals(
+        "a.length",
+        Expressions.toString(
+            Expressions.field(
+                Expressions.parameter(Object[].class, "a"),
+                "length")));
+
+    assertEquals(
         "java.util.Collections.EMPTY_LIST",
         Expressions.toString(
             Expressions.field(
@@ -541,7 +548,7 @@
         Expressions.parameter(
             Integer.TYPE,
             "index");
-    BlockExpression e =
+    BlockStatement e =
         Expressions.block(
             Expressions.declare(
                 Modifier.FINAL,
@@ -609,7 +616,7 @@
   }
 
   @Test public void testWriteWhile() {
-    DeclarationExpression xDecl, yDecl;
+    DeclarationStatement xDecl, yDecl;
     Node node =
         Expressions.block(
             xDecl = Expressions.declare(
@@ -948,6 +955,61 @@
         Expressions.toString(builder.toBlock()));
   }
 
+  @Test public void testFor() throws NoSuchFieldException {
+    final BlockBuilder builder = new BlockBuilder();
+    final ParameterExpression i_ = Expressions.parameter(int.class, "i");
+    builder.add(
+        Expressions.for_(
+            Expressions.declare(
+                0, i_, Expressions.constant(0)),
+            Expressions.lessThan(i_, Expressions.constant(10)),
+            Expressions.postIncrementAssign(i_),
+            Expressions.block(
+                Expressions.statement(
+                    Expressions.call(
+                        Expressions.field(
+                            null, System.class.getField("out")),
+                        "println",
+                        i_)))));
+    assertEquals(
+        "{\n"
+        + "  for (int i = 0; i < 10; i++) {\n"
+        + "    System.out.println(i);\n"
+        + "  }\n"
+        + "}\n",
+        Expressions.toString(builder.toBlock()));
+  }
+
+  @Test public void testFor2() throws NoSuchFieldException {
+    final BlockBuilder builder = new BlockBuilder();
+    final ParameterExpression i_ = Expressions.parameter(int.class, "i");
+    final ParameterExpression j_ = Expressions.parameter(int.class, "j");
+    builder.add(
+        Expressions.for_(
+            Arrays.asList(
+                Expressions.declare(
+                    0, i_, Expressions.constant(0)),
+                Expressions.declare(
+                    0, j_, Expressions.constant(10))),
+            null,
+            null,
+            Expressions.block(
+                Expressions.ifThen(
+                    Expressions.lessThan(
+                        Expressions.preIncrementAssign(i_),
+                        Expressions.preDecrementAssign(j_)),
+                    Expressions.break_(null)))));
+    assertEquals(
+        "{\n"
+        + "  for (int i = 0, j = 10; ; ) {\n"
+        + "    if (++i < --j) {\n"
+        + "      break;\n"
+        + "    }\n"
+        + "  }\n"
+        + "}\n",
+        Expressions.toString(builder.toBlock()));
+  }
+
   enum MyEnum {
     X,
     Y {