Upgrade to optiq-0.4.7, linq4j-0.1.8, junit-4.8, sqlline-1.1.4.
diff --git a/pom.xml b/pom.xml
index a87debe..b4e5e2d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -76,18 +76,18 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>3.8.1</version>
+      <version>[4.8,)</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>net.hydromatic</groupId>
       <artifactId>optiq</artifactId>
-      <version>0.4.1</version>
+      <version>0.4.7</version>
     </dependency>
     <dependency>
       <groupId>net.hydromatic</groupId>
       <artifactId>linq4j</artifactId>
-      <version>0.1.3</version>
+      <version>0.1.8</version>
     </dependency>
     <dependency>
       <groupId>net.sf.opencsv</groupId>
@@ -97,7 +97,7 @@
     <dependency>
       <groupId>sqlline</groupId>
       <artifactId>sqlline</artifactId>
-      <version>1.1.0</version>
+      <version>1.1.4</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
diff --git a/src/main/java/net/hydromatic/optiq/impl/csv/CsvEnumerator.java b/src/main/java/net/hydromatic/optiq/impl/csv/CsvEnumerator.java
index 2e49235..399d505 100644
--- a/src/main/java/net/hydromatic/optiq/impl/csv/CsvEnumerator.java
+++ b/src/main/java/net/hydromatic/optiq/impl/csv/CsvEnumerator.java
@@ -123,6 +123,14 @@
     throw new UnsupportedOperationException();
   }
 
+  public void close() {
+    try {
+      reader.close();
+    } catch (IOException e) {
+      throw new RuntimeException("Error closing CSV reader", e);
+    }
+  }
+
   /** Returns an array of integers {0, ..., n - 1}. */
   static int[] identityList(int n) {
     int[] integers = new int[n];
diff --git a/src/main/java/net/hydromatic/optiq/impl/csv/CsvPushProjectOntoTableRule.java b/src/main/java/net/hydromatic/optiq/impl/csv/CsvPushProjectOntoTableRule.java
index fd559ac..2da3c8a 100644
--- a/src/main/java/net/hydromatic/optiq/impl/csv/CsvPushProjectOntoTableRule.java
+++ b/src/main/java/net/hydromatic/optiq/impl/csv/CsvPushProjectOntoTableRule.java
@@ -20,10 +20,11 @@
 import org.eigenbase.rel.ProjectRel;
 import org.eigenbase.relopt.RelOptRule;
 import org.eigenbase.relopt.RelOptRuleCall;
-import org.eigenbase.relopt.RelOptRuleOperand;
 import org.eigenbase.rex.RexInputRef;
 import org.eigenbase.rex.RexNode;
 
+import java.util.List;
+
 /**
  * Planner rule that projects from a {@link CsvTableScan} scan just the columns
  * needed to satisfy a projection. If the projection's expressions are trivial,
@@ -35,18 +36,16 @@
 
   private CsvPushProjectOntoTableRule() {
     super(
-        new RelOptRuleOperand(
-            ProjectRel.class,
-            new RelOptRuleOperand(
-                CsvTableScan.class)),
+        some(ProjectRel.class,
+            leaf(CsvTableScan.class)),
         "CsvPushProjectOntoTableRule");
   }
 
   @Override
   public void onMatch(RelOptRuleCall call) {
-    final ProjectRel project = (ProjectRel) call.getRels()[0];
-    final CsvTableScan scan = (CsvTableScan) call.getRels()[1];
-    int[] fields = getProjectFields(project.getProjectExps());
+    final ProjectRel project = call.rel(0);
+    final CsvTableScan scan = call.rel(1);
+    int[] fields = getProjectFields(project.getProjects());
     if (fields == null) {
       // Project contains expressions more complex than just field references.
       return;
@@ -59,10 +58,10 @@
             fields));
   }
 
-  private int[] getProjectFields(RexNode[] exps) {
-    final int[] fields = new int[exps.length];
-    for (int i = 0; i < exps.length; i++) {
-      final RexNode exp = exps[i];
+  private int[] getProjectFields(List<RexNode> exps) {
+    final int[] fields = new int[exps.size()];
+    for (int i = 0; i < exps.size(); i++) {
+      final RexNode exp = exps.get(i);
       if (exp instanceof RexInputRef) {
         fields[i] = ((RexInputRef) exp).getIndex();
       } else {
diff --git a/src/main/java/net/hydromatic/optiq/impl/csv/CsvTable.java b/src/main/java/net/hydromatic/optiq/impl/csv/CsvTable.java
index f225b78..395be95 100644
--- a/src/main/java/net/hydromatic/optiq/impl/csv/CsvTable.java
+++ b/src/main/java/net/hydromatic/optiq/impl/csv/CsvTable.java
@@ -118,7 +118,7 @@
       RelOptTable relOptTable) {
     return new JavaRules.EnumerableTableAccessRel(
         context.getCluster(),
-        context.getCluster().traitSetOf(EnumerableConvention.ARRAY),
+        context.getCluster().traitSetOf(EnumerableConvention.INSTANCE),
         relOptTable,
         getExpression(),
         getElementType());
diff --git a/src/main/java/net/hydromatic/optiq/impl/csv/CsvTableScan.java b/src/main/java/net/hydromatic/optiq/impl/csv/CsvTableScan.java
index 94e1073..41e8bbc 100644
--- a/src/main/java/net/hydromatic/optiq/impl/csv/CsvTableScan.java
+++ b/src/main/java/net/hydromatic/optiq/impl/csv/CsvTableScan.java
@@ -17,10 +17,10 @@
 */
 package net.hydromatic.optiq.impl.csv;
 
-import net.hydromatic.linq4j.expressions.*;
-import net.hydromatic.optiq.impl.java.JavaTypeFactory;
 import net.hydromatic.optiq.rules.java.*;
 
+import net.hydromatic.linq4j.expressions.*;
+
 import org.eigenbase.rel.RelNode;
 import org.eigenbase.rel.TableAccessRelBase;
 import org.eigenbase.relopt.*;
@@ -37,26 +37,16 @@
 public class CsvTableScan extends TableAccessRelBase implements EnumerableRel {
   final CsvTable csvTable;
   final int[] fields;
-  final PhysType physType;
 
   protected CsvTableScan(RelOptCluster cluster, RelOptTable table,
       CsvTable csvTable, int[] fields) {
-    super(cluster, cluster.traitSetOf(EnumerableConvention.ARRAY), table);
+    super(cluster, cluster.traitSetOf(EnumerableConvention.INSTANCE), table);
     this.csvTable = csvTable;
     this.fields = fields;
-    this.physType =
-        PhysTypeImpl.of(
-            (JavaTypeFactory) cluster.getTypeFactory(),
-            getRowType(),
-            (EnumerableConvention) getConvention());
 
     assert csvTable != null;
   }
 
-  public PhysType getPhysType() {
-    return physType;
-  }
-
   @Override
   public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) {
     assert inputs.isEmpty();
@@ -84,10 +74,18 @@
     planner.addRule(CsvPushProjectOntoTableRule.INSTANCE);
   }
 
-  public BlockExpression implement(EnumerableRelImplementor implementor) {
-    return Blocks.toBlock(
-        Expressions.call(csvTable.getExpression(), "project",
-            Expressions.constant(fields)));
+  public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
+    PhysType physType =
+        PhysTypeImpl.of(
+            implementor.getTypeFactory(),
+            getRowType(),
+            pref.preferArray());
+
+    return implementor.result(
+        physType,
+        Blocks.toBlock(
+            Expressions.call(csvTable.getExpression(), "project",
+                Expressions.constant(fields))));
   }
 }
 
diff --git a/src/test/java/net/hydromatic/optiq/test/CsvTest.java b/src/test/java/net/hydromatic/optiq/test/CsvTest.java
index 637bd8b..1a20963 100644
--- a/src/test/java/net/hydromatic/optiq/test/CsvTest.java
+++ b/src/test/java/net/hydromatic/optiq/test/CsvTest.java
@@ -19,7 +19,9 @@
 
 import net.hydromatic.linq4j.function.Function1;
 
-import junit.framework.TestCase;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
 
 import java.io.PrintStream;
 import java.sql.*;
@@ -28,7 +30,7 @@
 /**
  * Unit test of the Optiq adapter for CSV.
  */
-public class CsvTest extends TestCase {
+public class CsvTest {
   private void close(Connection connection, Statement statement) {
     if (statement != null) {
       try {
@@ -49,7 +51,8 @@
   /**
    * Tests the vanity driver.
    */
-  public void _testVanityDriver() throws SQLException {
+  @Ignore
+  @Test public void testVanityDriver() throws SQLException {
     Properties info = new Properties();
     Connection connection =
         DriverManager.getConnection("jdbc:csv:", info);
@@ -59,7 +62,8 @@
   /**
    * Tests the vanity driver with properties in the URL.
    */
-  public void _testVanityDriverArgsInUrl() throws SQLException {
+  @Ignore
+  @Test public void testVanityDriverArgsInUrl() throws SQLException {
     Connection connection =
         DriverManager.getConnection(
             "jdbc:csv:"
@@ -70,29 +74,28 @@
   /**
    * Reads from a table.
    */
-  public void testSelect() throws SQLException {
+  @Test public void testSelect() throws SQLException {
     checkSql("model", "select * from EMPS");
   }
 
-  public void testCustomTable() throws SQLException {
+  @Test public void testCustomTable() throws SQLException {
     checkSql("model-with-custom-table", "select * from CUSTOM_TABLE.EMPS");
   }
 
-  public void testPushDownProjectDumb() throws SQLException {
+  @Test public void testPushDownProjectDumb() throws SQLException {
     // rule does not fire, because we're using 'dumb' tables in simple model
     checkSql("model", "explain plan for select * from EMPS",
-        "PLAN=EnumerableCalcRel(expr#0..9=[{inputs}], proj#0..9=[{exprs}])\n"
-        + "  EnumerableTableAccessRel(table=[[SALES, EMPS]])\n"
+        "PLAN=EnumerableTableAccessRel(table=[[SALES, EMPS]])\n"
         + "\n");
   }
 
-  public void testPushDownProject() throws SQLException {
+  @Test public void testPushDownProject() throws SQLException {
     checkSql("smart", "explain plan for select * from EMPS",
         "PLAN=CsvTableScan(table=[[SALES, EMPS]], fields=[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])\n"
         + "\n");
   }
 
-  public void testPushDownProject2() throws SQLException {
+  @Test public void testPushDownProject2() throws SQLException {
     checkSql("smart", "explain plan for select name, empno from EMPS",
         "PLAN=CsvTableScan(table=[[SALES, EMPS]], fields=[[1, 0]])\n"
         + "\n");
@@ -124,7 +127,7 @@
       public Void apply(ResultSet resultSet) {
         try {
           String actual = CsvTest.toString(resultSet);
-          assertEquals(expected, actual);
+          Assert.assertEquals(expected, actual);
         } catch (SQLException e) {
           throw new RuntimeException(e);
         }