Expression support for anonymous classes; work in progress.
diff --git a/.idea/dictionaries/jhyde.xml b/.idea/dictionaries/jhyde.xml
index 4445648..3fc3d71 100644
--- a/.idea/dictionaries/jhyde.xml
+++ b/.idea/dictionaries/jhyde.xml
@@ -5,7 +5,10 @@
       <w>deptno</w>
       <w>depts</w>
       <w>emps</w>
+      <w>lprec</w>
+      <w>multi</w>
       <w>nullable</w>
+      <w>rprec</w>
     </words>
   </dictionary>
-</component>
\ No newline at end of file
+</component>
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/DeclarationExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/DeclarationExpression.java
new file mode 100644
index 0000000..6689538
--- /dev/null
+++ b/src/main/java/net/hydromatic/linq4j/expressions/DeclarationExpression.java
@@ -0,0 +1,42 @@
+/*
+// 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 java.lang.reflect.Type;
+
+/**
+ * Expression that declares and optionally initializes a variable.
+ *
+ * @author jhyde
+ */
+public class DeclarationExpression extends Expression {
+    public final int modifiers;
+    public final ParameterExpression parameter;
+    public final Expression initializer;
+
+    public DeclarationExpression(
+        int modifiers, ParameterExpression parameter, Expression initializer)
+    {
+        super(ExpressionType.Declaration, Void.TYPE);
+        this.modifiers = modifiers;
+        this.parameter = parameter;
+        this.initializer = initializer;
+    }
+}
+
+// End DeclarationExpression.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/ExpressionType.java b/src/main/java/net/hydromatic/linq4j/expressions/ExpressionType.java
index 5b37433..1c64f3c 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/ExpressionType.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/ExpressionType.java
@@ -405,7 +405,10 @@
     IsTrue,
 
     /** A false condition value. */
-    IsFalse;
+    IsFalse,
+
+    /** Declaration of a variable. */
+    Declaration;
 
     final String op;
     final boolean postfix;
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/Expressions.java b/src/main/java/net/hydromatic/linq4j/expressions/Expressions.java
index 9bf078b..2b238eb 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/Expressions.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/Expressions.java
@@ -1742,6 +1742,18 @@
         return memberInit(newExpression, Arrays.asList(bindings));
     }
 
+    /** Declares a method. */
+    public static MethodDeclaration methodDecl(
+        int modifier,
+        Type resultType,
+        String name,
+        Iterable<ParameterExpression> parameters,
+        Expression body)
+    {
+        return new MethodDeclaration(
+            modifier, name, resultType, toList(parameters), body);
+    }
+
     /** Creates a BinaryExpression that represents an arithmetic
      * remainder operation. */
     public static BinaryExpression modulo(
@@ -1977,15 +1989,15 @@
 
     /** Creates a NewExpression that represents calling the
      * parameterless constructor of the specified type. */
-    public static NewExpression new_(Class type) {
-        throw Extensions.todo();
+    public static NewExpression new_(Type type) {
+        return new_(type, Collections.<Expression>emptyList());
     }
 
     /** Creates a NewExpression that represents calling the constructor of the
      * specified type whose parameters are assignable from the specified
      * arguments. */
     public static NewExpression new_(
-        Class type, Iterable<Expression> arguments)
+        Type type, Iterable<Expression> arguments)
     {
         final Constructor constructor =
             Types.lookupConstructor(
@@ -1993,18 +2005,35 @@
         return new_(constructor, arguments);
     }
 
-    /** Creates a NewExpression that represents calling the specified
-     * constructor with the specified arguments. */
+    /** Creates a NewExpression that represents calling the constructor of the
+     * specified type whose parameters are assignable from the specified
+     * arguments. */
     public static NewExpression new_(
-        Constructor constructor, Iterable<Expression> expressions)
+        Type type,
+        Iterable<Expression> arguments,
+        Iterable<Member> members,
+        Iterable<MemberDeclaration> memberDeclarations)
     {
-        return new NewExpression(constructor, toList(expressions));
+        final Constructor constructor =
+            Types.lookupConstructor(
+                type, Types.toClassArray(arguments));
+        return new_(constructor, arguments, members, memberDeclarations);
     }
 
     /** Creates a NewExpression that represents calling the specified
      * constructor with the specified arguments. */
     public static NewExpression new_(
-        Constructor constructor, Expression[] expressions)
+        Constructor constructor, Iterable<Expression> expressions)
+    {
+        return new_(
+            constructor, expressions, Collections.<Member>emptyList(),
+            Collections.<MemberDeclaration>emptyList());
+    }
+
+    /** Creates a NewExpression that represents calling the specified
+     * constructor with the specified arguments. */
+    public static NewExpression new_(
+        Constructor constructor, Expression... expressions)
     {
         return new_(constructor, Arrays.asList(expressions));
     }
@@ -2015,9 +2044,12 @@
     public static NewExpression new_(
         Constructor constructor,
         Iterable<Expression> expressions,
-        Iterable<Member> members)
+        Iterable<Member> members,
+        Iterable<MemberDeclaration> memberDeclarations)
     {
-        throw Extensions.todo();
+        return new NewExpression(
+            constructor, toList(expressions), toList(members),
+            toList(memberDeclarations));
     }
 
     /** Creates a NewExpression that represents calling the specified
@@ -2029,7 +2061,9 @@
         Iterable<Expression> expressions,
         Member[] members)
     {
-        return new_(constructor, expressions, Arrays.asList(members));
+        return new_(
+            constructor, expressions, Arrays.asList(members),
+            Collections.<MemberDeclaration>emptyList());
     }
 
     /** Creates a NewArrayExpression that represents creating an array
@@ -2196,13 +2230,13 @@
 
     /** Creates a ParameterExpression node that can be used to
      * identify a parameter or a variable in an expression tree. */
-    public static ParameterExpression parameter(Class type) {
+    public static ParameterExpression parameter(Type type) {
         return new ParameterExpression(type);
     }
 
     /** Creates a ParameterExpression node that can be used to
      * identify a parameter or a variable in an expression tree. */
-    public static ParameterExpression parameter(Class type, String name) {
+    public static ParameterExpression parameter(Type type, String name) {
         return new ParameterExpression(type, name);
     }
 
@@ -2934,6 +2968,13 @@
         throw Extensions.todo();
     }
 
+    /** Creates an expression that declares a variable. */
+    public static DeclarationExpression declare(
+        int modifiers, ParameterExpression parameter, Expression initializer)
+    {
+        return new DeclarationExpression(modifiers, parameter, initializer);
+    }
+
     // Some interfaces we'd rather not implement yet. They don't seem relevant
     // in the Java world.
 
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/MemberDeclaration.java b/src/main/java/net/hydromatic/linq4j/expressions/MemberDeclaration.java
new file mode 100644
index 0000000..972b32f
--- /dev/null
+++ b/src/main/java/net/hydromatic/linq4j/expressions/MemberDeclaration.java
@@ -0,0 +1,26 @@
+/*
+// 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;
+
+/**
+ * Declaration of a member of a class.
+ */
+public abstract class MemberDeclaration {
+}
+
+// End MemberDeclaration.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/MethodDeclaration.java b/src/main/java/net/hydromatic/linq4j/expressions/MethodDeclaration.java
new file mode 100644
index 0000000..8d85888
--- /dev/null
+++ b/src/main/java/net/hydromatic/linq4j/expressions/MethodDeclaration.java
@@ -0,0 +1,48 @@
+/*
+// 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 java.lang.reflect.Type;
+import java.util.List;
+
+/**
+ * Declaration of a method.
+ */
+public class MethodDeclaration extends MemberDeclaration {
+    public final int modifier;
+    public final String name;
+    public final Type resultType;
+    public final List<ParameterExpression> parameters;
+    public final Expression body;
+
+    public MethodDeclaration(
+        int modifier,
+        String name,
+        Type resultType,
+        List<ParameterExpression> parameters,
+        Expression body)
+    {
+        this.modifier = modifier;
+        this.name = name;
+        this.resultType = resultType;
+        this.parameters = parameters;
+        this.body = body;
+    }
+}
+
+// End MethodDeclaration.java
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/NewExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/NewExpression.java
index de13910..f76e1ae 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/NewExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/NewExpression.java
@@ -18,22 +18,30 @@
 package net.hydromatic.linq4j.expressions;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
 import java.util.List;
 
 /**
  * Represents a constructor call.
+ *
+ * <p>If {@link #memberDeclarations} is not null (even if empty) represents
+ * an anonymous class.</p>
  */
 public class NewExpression extends Expression {
     public final Constructor constructor;
     public final List<Expression> arguments;
+    public final List<MemberDeclaration> memberDeclarations;
 
     public NewExpression(
         Constructor constructor,
-        List<Expression> arguments)
+        List<Expression> arguments,
+        List<Member> members, // not used
+        List<MemberDeclaration> memberDeclarations)
     {
         super(ExpressionType.New, constructor.getDeclaringClass());
         this.constructor = constructor;
         this.arguments = arguments;
+        this.memberDeclarations = memberDeclarations;
     }
 }
 
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/ParameterExpression.java b/src/main/java/net/hydromatic/linq4j/expressions/ParameterExpression.java
index 6ec72da..18f0eaf 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/ParameterExpression.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/ParameterExpression.java
@@ -17,6 +17,8 @@
 */
 package net.hydromatic.linq4j.expressions;
 
+import java.lang.reflect.Type;
+
 /**
  * Represents a named parameter expression.
  */
@@ -25,11 +27,11 @@
 
     final String name;
 
-    public ParameterExpression(Class type) {
+    public ParameterExpression(Type type) {
         this(type, "p" + seq++);
     }
 
-    public ParameterExpression(Class type, String name) {
+    public ParameterExpression(Type type, String name) {
         super(ExpressionType.Parameter, type);
         this.name = name;
     }
diff --git a/src/main/java/net/hydromatic/linq4j/expressions/Types.java b/src/main/java/net/hydromatic/linq4j/expressions/Types.java
index d49a95d..976ab1a 100644
--- a/src/main/java/net/hydromatic/linq4j/expressions/Types.java
+++ b/src/main/java/net/hydromatic/linq4j/expressions/Types.java
@@ -173,13 +173,23 @@
     }
 
     static boolean allAssignable(
-        Class[] parameterTypes, Class[] argumentTypes)
+        boolean varArgs, Class[] parameterTypes, Class[] argumentTypes)
     {
-        if (parameterTypes.length != argumentTypes.length) {
-            return false;
+        if (varArgs) {
+            if (argumentTypes.length < parameterTypes.length - 1) {
+                return false;
+            }
+        } else {
+            if (parameterTypes.length != argumentTypes.length) {
+                return false;
+            }
         }
-        for (int i = 0; i < parameterTypes.length; i++) {
-            if (!parameterTypes[i].isAssignableFrom(argumentTypes[i])) {
+        for (int i = 0; i < argumentTypes.length; i++) {
+            Class parameterType =
+                !varArgs || i < parameterTypes.length - 1
+                    ? parameterTypes[i]
+                    : Object.class;
+            if (!parameterType.isAssignableFrom(argumentTypes[i])) {
                 return false;
             }
         }
@@ -207,6 +217,7 @@
             for (Method method : clazz.getMethods()) {
                 if (method.getName().equals(methodName)
                     && allAssignable(
+                        method.isVarArgs(),
                         method.getParameterTypes(),
                         argumentTypes))
                 {
@@ -224,25 +235,28 @@
      * Finds a constructor of a given class that accepts a given set of
      * arguments. Includes in its search methods with wider argument types.
      *
-     *
-     * @param clazz Class against which method is invoked
+     * @param type Class against which method is invoked
      * @param argumentTypes Types of arguments
      * @return A method with the given name that matches the arguments given
      *
      * @throws RuntimeException if method not found
      */
     public static Constructor lookupConstructor(
-        Class clazz, Class... argumentTypes)
+        Type type, Class... argumentTypes)
     {
+        final Class clazz = toClass(type);
         for (Constructor constructor : clazz.getConstructors()) {
             if (allAssignable(
-                    constructor.getParameterTypes(), argumentTypes))
+                constructor.isVarArgs(),
+                constructor.getParameterTypes(),
+                argumentTypes))
             {
                 return constructor;
             }
         }
         throw new RuntimeException(
-            "while resolving static constructor in class " + clazz);
+            "while resolving constructor in class " + type + " with types "
+            + Arrays.toString(argumentTypes));
     }
 
     static class ParameterizedTypeImpl implements ParameterizedType {
@@ -259,6 +273,22 @@
             this.ownerType = ownerType;
         }
 
+        @Override
+        public String toString() {
+            final StringBuilder buf = new StringBuilder();
+            buf.append(className(rawType));
+            buf.append("<");
+            int i = 0;
+            for (Type typeArgument : typeArguments) {
+                if (i++ > 0) {
+                    buf.append(", ");
+                }
+                buf.append(className(typeArgument));
+            }
+            buf.append(">");
+            return buf.toString();
+        }
+
         public Type[] getActualTypeArguments() {
             return typeArguments.toArray(new Type[typeArguments.size()]);
         }
diff --git a/src/test/java/net/hydromatic/linq4j/test/ExpressionTest.java b/src/test/java/net/hydromatic/linq4j/test/ExpressionTest.java
index c1b1c97..e7a1cc0 100644
--- a/src/test/java/net/hydromatic/linq4j/test/ExpressionTest.java
+++ b/src/test/java/net/hydromatic/linq4j/test/ExpressionTest.java
@@ -22,6 +22,8 @@
 
 import junit.framework.TestCase;
 
+import java.lang.reflect.Member;
+import java.lang.reflect.Modifier;
 import java.util.*;
 
 /**
@@ -266,6 +268,70 @@
                 Expressions.constant(Linq4jTest.emps)));
     }
 
+    public void testWriteAnonymousClass() {
+        // final List<String> baz = Arrays.asList("foo", "bar");
+        // new AbstractList<String>() {
+        //     public int size() {
+        //         return baz.size();
+        //     }
+        //     public String get(int index) {
+        //         return ((String) baz.get(index)).toUpperCase();
+        //     }
+        // }
+        final ParameterExpression bazParameter =
+            Expressions.parameter(
+                Types.of(List.class, String.class),
+                "baz");
+        final ParameterExpression indexParameter =
+            Expressions.parameter(
+                Integer.TYPE,
+                "index");
+        Expression e =
+            Expressions.block(
+                Arrays.<Expression>asList(
+                    Expressions.declare(
+                        Modifier.FINAL, bazParameter,
+                        Expressions.call(
+                            Arrays.class,
+                            "asList",
+                            Arrays.<Expression>asList(
+                                Expressions.constant("foo"),
+                                Expressions.constant("bar")))),
+                    Expressions.new_(
+                        Types.of(AbstractList.class, String.class),
+                        Collections.<Expression>emptyList(),
+                        Collections.<Member>emptyList(),
+                        Arrays.<MemberDeclaration>asList(
+                            Expressions.methodDecl(
+                                Modifier.PUBLIC,
+                                Integer.TYPE,
+                                "size",
+                                Collections.<ParameterExpression>emptyList(),
+                                Expressions.call(
+                                    bazParameter,
+                                    "size",
+                                    Collections.<Expression>emptyList())),
+                            Expressions.methodDecl(
+                                Modifier.PUBLIC,
+                                String.class,
+                                "get",
+                                Arrays.asList(
+                                    indexParameter),
+                                Expressions.call(
+                                    Expressions.convert_(
+                                        Expressions.call(
+                                            bazParameter,
+                                            "get",
+                                            Arrays.<Expression>asList(
+                                                indexParameter)),
+                                        String.class),
+                                    "toUpperCase",
+                                    Collections.<Expression>emptyList()))))));
+        assertEquals(
+            "xxx",
+            Expressions.toString(e));
+    }
+
     public void testCompile() throws NoSuchMethodException {
         // Creating a parameter for the expression tree.
         ParameterExpression param = Expressions.parameter(String.class);