Add tests for constant expressions.
diff --git a/src/test/java/net/hydromatic/linq4j/test/DeterministicTest.java b/src/test/java/net/hydromatic/linq4j/test/DeterministicTest.java
index bda6599..ab4b3f9 100644
--- a/src/test/java/net/hydromatic/linq4j/test/DeterministicTest.java
+++ b/src/test/java/net/hydromatic/linq4j/test/DeterministicTest.java
@@ -24,6 +24,7 @@
 
 import org.junit.Test;
 
+import java.lang.reflect.Method;
 import java.math.BigInteger;
 import java.util.Collections;
 import java.util.concurrent.Callable;
@@ -66,6 +67,58 @@
     }
   }
 
+  private boolean isAtomic(Expression e) {
+    /** Subclass to make a protected method public. */
+    class MyDeterministicCodeOptimizer extends DeterministicCodeOptimizer {
+      public MyDeterministicCodeOptimizer() {
+        super(ClassDeclarationFinder.create());
+      }
+
+      @Override public boolean isConstant(Expression expression) {
+        return super.isConstant(expression);
+      }
+    }
+    return new MyDeterministicCodeOptimizer().isConstant(e);
+  }
+
+  private static Method getMethod(Class<?> thisClass, String methodName,
+      Class<?>... paramClasses) {
+    try {
+      return thisClass.getMethod(methodName, paramClasses);
+    } catch (NoSuchMethodException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  private boolean isConstant(Expression e) {
+    Expression e2 =
+        e.accept(
+            new DeterministicCodeOptimizer(ClassDeclarationFinder.create()));
+    return !e.equals(e2);
+  }
+
+  @Test public void testConstantIsConstant() {
+    // Small expressions are atomic.
+    assertThat(isAtomic(Expressions.constant(0)), is(true));
+    assertThat(isAtomic(Expressions.constant("xxx")), is(true));
+    assertThat(isAtomic(Expressions.constant(null)), is(true));
+
+    Expression e =
+        Expressions.call(getMethod(Integer.class, "valueOf", int.class),
+            Expressions.constant(-100));
+    assertThat(isAtomic(e), is(false));
+    assertThat(isConstant(e), is(true));
+
+    e = Expressions.call(
+        Integer.class, "valueOf", Expressions.constant(0));
+    assertThat(isAtomic(e), is(false));
+    assertThat(isConstant(e), is(true));
+
+    e = Expressions.call(Expressions.constant("xxx"), "length");
+    assertThat(isAtomic(e), is(false));
+    assertThat(isConstant(e), is(true));
+  }
+
   @Test public void testFactorOutBinaryAdd() {
     assertThat(
         optimize(
@@ -90,7 +143,7 @@
             + "}\n"));
   }
 
-  @Test public void testFactorOutBinaryAddSurviesMultipleOptimizations() {
+  @Test public void testFactorOutBinaryAddSurvivesMultipleOptimizations() {
     assertThat(
         optimize(optimizeExpression(
             Expressions.new_(
@@ -290,6 +343,29 @@
             + "}\n"));
   }
 
+  @Test public void testIntegerValueOfZeroComplexTest() {
+    // Integer.valueOf(0) is optimized in complex expressions
+    assertThat(
+        optimize(
+            Expressions.new_(Runnable.class,
+                Collections.<Expression>emptyList(),
+                Expressions.methodDecl(0, int.class, "test",
+                    Collections.<ParameterExpression>emptyList(),
+                    Blocks.toFunctionBlock(
+                        Expressions.call(
+                            getMethod(Integer.class, "valueOf", int.class),
+                            Expressions.constant(0)))))),
+        equalTo("{\n"
+            + "  return new Runnable(){\n"
+            + "      int test() {\n"
+            + "        return $L4J$C$Integer_valueOf_0_;\n"
+            + "      }\n"
+            + "\n"
+            + "      static final Integer $L4J$C$Integer_valueOf_0_ = Integer.valueOf(0);\n"
+            + "    };\n"
+            + "}\n"));
+  }
+
   @Test public void testStaticField() {
     // instanceof is optimized in complex expressions
     assertThat(