changeset 10551:99dd9e50f37e

Merge
author henryjen
date Mon, 11 Nov 2013 23:17:30 -0800
parents f82b730c798b (current diff) ed09558136be (diff)
children 2b0c2fc213d6
files .hgtags .jcheck/conf makefiles/CreateJars.gmk makefiles/CreateSecurityJars.gmk src/macosx/native/sun/osxapp/NSApplicationAWT.m src/share/classes/java/awt/EventDispatchThread.java src/share/classes/java/beans/EventHandler.java src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java src/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java src/share/classes/java/util/Arrays.java src/share/classes/java/util/PriorityQueue.java src/share/classes/java/util/concurrent/ArrayBlockingQueue.java src/share/classes/java/util/concurrent/ConcurrentSkipListMap.java src/share/classes/java/util/regex/Pattern.java src/share/classes/java/util/stream/DistinctOps.java src/share/classes/java/util/stream/StreamSpliterators.java src/share/classes/sun/awt/datatransfer/DataTransferer.java src/share/javavm/export/jvm.h src/solaris/classes/sun/nio/fs/UnixPath.java src/windows/classes/sun/nio/fs/WindowsPath.java test/ProblemList.txt test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java
diffstat 136 files changed, 19157 insertions(+), 79 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Thu Oct 31 16:44:18 2013 -0700
+++ b/.hgignore	Mon Nov 11 23:17:30 2013 -0800
@@ -5,3 +5,19 @@
 ^make/netbeans/.*/dist/
 ^.hgtip
 .DS_Store
+^test-ng/gen-separate/
+^test-ng/lib/
+^.idea/
+^combo-tests/gen/
+^combo-tests/build/
+^out/
+.*\.rej$
+.*\.orig$
+.*\.iml$
+.*~$
+^webrev/
+webrev.zip$
+^.classpath
+^.project
+JTreport
+JTwork
--- a/.hgtags	Thu Oct 31 16:44:18 2013 -0700
+++ b/.hgtags	Mon Nov 11 23:17:30 2013 -0800
@@ -167,16 +167,20 @@
 b3246687c3695dff6f461bb407f9db88f7d072e7 jdk8-b43
 db471a7af03168e4441c245b1d9976f720a7cb77 jdk8-b44
 b92353a01aa049bc508fc56f0347d5934b7c4390 jdk8-b45
+077225955d5722f0fbd780650178c5931693c07e lambda-b45
 8d2ed9d58453c8049715a72a6d26b6b66b37a94c jdk8-b46
 00b22b23269a57d0bb46c57753be2fe9a9d2c1a3 jdk8-b47
 3e4ab821f46166fcf63e8fe5c8046216003c941f jdk8-b48
+b3b65a3d441e7f39cb68140d2db547704ea0a670 lambda-b48
 51707c3b75c0f521794d9ab425f4e5b2351c70c1 jdk8-b49
 e4bae5c53fca8fcb9393d47fd36a34b9e2e8d4ec jdk8-b50
+958eaa191b79bf79be82979240903199791ed9f7 lambda-b50
 e865efbc71059a414b3b2dd2e0adfcb3d2ab6ff9 jdk8-b51
 e8569a473cee7f4955bd9e76a9bdf6c6a07ced27 jdk8-b52
 2c6933c5106b81a8578b70996fe5b735fb3adb60 jdk8-b53
 70ad0ed1d6cef0e7712690d1bab21e4769708aad jdk8-b54
 1f3f4b333341873f00da3dee85e4879f0e89c9bb jdk8-b55
+2e6170973d921fe4b8d2dfd6032f5aaf4150a542 lambda-b56
 2e9eeef2909b33c9224a024afddb61ccb0b77f14 jdk8-b56
 51594d095a4bcffac4a314bf6e148214501399e0 jdk8-b57
 d94613ac03d8de375ef60493e2bb76dbd30d875d jdk8-b58
--- a/.jcheck/conf	Thu Oct 31 16:44:18 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-project=jdk8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/build.xml	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="jdk" default="test">
+
+    <property name="build.dir" value="../../build/combo-tests" />
+    <property name="gen.dir" value="${build.dir}/gen" />
+    <property name="test.classes.dir" value="${build.dir}/test-classes"/>
+    <property name="test.reports.dir" value="${build.dir}/test-reports"/>
+    <property name="test.src.dir" value="tests"/>
+    <property name="lib.dir" location="lib" />
+    <property name="test.pattern" value="*Test" />
+    <property name="lambda.metafactory" value="" />
+    <property name="combo.debug" value="" />
+    <property name="heap.size" value="4G" />
+
+    <property name="lib.testng.jar" value="${lib.dir}/testng-6.7.jar"/>
+    <property name="lib.tools.jar" value="${java.home}/../lib/tools.jar"/>
+
+    <path id="test.class.path">
+        <pathelement path="${sun.boot.class.path}" />
+        <pathelement location="${test.classes.dir}" />
+        <pathelement location="${lib.testng.jar}"/>
+        <pathelement location="${lib.tools.jar}"/>
+    </path>
+
+    <taskdef name="testng" classpathref="test.class.path" classname="org.testng.TestNGAntTask" />
+
+    <target name="prepare">
+        <mkdir dir="${build.dir}"/>
+        <mkdir dir="${lib.dir}"/>
+        <mkdir dir="${test.classes.dir}"/>
+        <mkdir dir="${test.reports.dir}"/>
+    </target>
+
+    <target name="test-compile" depends="prepare">
+        <javac destdir="${test.classes.dir}" debug="on" srcdir="${test.src.dir}" fork="true"
+               classpathref="test.class.path">
+            <compilerarg value="-XDlambdaToMethod"/>
+        </javac>
+    </target>
+
+    <target name="test" depends="test-compile" >
+        <delete dir="${gen.dir}" />
+        <testng outputdir="${test.reports.dir}" usedefaultlisteners="false"
+                listeners="org.testng.reporters.FailedReporter,org.testng.reporters.XMLReporter">
+            <classpath refid="test.class.path" />
+            <classfileset dir="${test.classes.dir}" includes="**/${test.pattern}.class"/>
+            <jvmarg value="-Xms1G" />
+            <jvmarg value="-Xmx${heap.size}" />
+            <jvmarg value="-XX:+UseNUMA" />
+            <jvmarg value="-XX:+UseG1GC" />
+            <jvmarg value="-ea" />
+            <jvmarg value="-esa" />
+            <jvmarg value="-Xverify:all" />
+            <sysproperty key="lambda.metafactory" value="${lambda.metafactory}" />
+            <sysproperty key="combo.debug" value="${combo.debug}" />
+        </testng>
+    </target>
+   
+    <!-- New target added that uses a different set of listeners to show results in Aurora --> 
+    <target name="aurora-test" depends="test-compile" >
+        <testng outputdir="${test.reports.dir}" usedefaultlisteners="false"
+                listeners="org.testng.reporters.JUnitXMLReporter,org.testng.reporters.JUnitReportReporter,
+                           org.testng.reporters.XMLReporter">
+            <classpath refid="test.class.path" />
+            <classfileset dir="${test.classes.dir}" includes="**/${test.pattern}.class"/>
+            <jvmarg value="-Xms1G" />
+            <jvmarg value="-Xmx2G" />
+            <jvmarg value="-XX:+UseNUMA" />
+            <jvmarg value="-XX:+UseG1GC" />
+            <jvmarg value="-ea" />
+            <jvmarg value="-esa" />
+            <jvmarg value="-Xverify:all" />
+            <sysproperty key="lambda.metafactory" value="${lambda.metafactory}" />
+            <sysproperty key="combo.debug" value="${combo.debug}" />
+        </testng>
+    </target>
+
+    <target name="clean">
+        <delete dir="${build.dir}" />
+        <delete dir="${gen.dir}" />
+    </target>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/BridgeMethodTestCase.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringJoiner;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.fail;
+
+/**
+ * BridgeMethodTestCase -- used for asserting linkage to bridges under separate compilation.
+ *
+ * Example test case:
+ *     public void test1() throws IOException, ReflectiveOperationException {
+ *         compileSpec("C(Bc1(A))");
+ *         assertLinkage("C", LINKAGE_ERROR, "B1");
+ *         recompileSpec("C(Bc1(Ac0))", "A");
+ *          assertLinkage("C", "A0", "B1");
+ *     }
+ *
+ * This compiles A, B, and C, asserts that C.m()Object does not exist, asserts
+ * that C.m()Number eventually invokes B.m()Number, recompiles B, and then asserts
+ * that the result of calling C.m()Object now arrives at A.
+ *
+ * @author Brian Goetz
+ */
+
+@Test
+public abstract class BridgeMethodTestCase extends JavacTemplateTestBase {
+
+    private static final String TYPE_LETTERS = "ABCDIJK";
+
+    private static final String BASE_INDEX_CLASS = "class C0 {\n" +
+                                                   "    int val;\n" +
+                                                   "    C0(int val) { this.val = val; }\n" +
+                                                   "    public int getVal() { return val; }\n" +
+                                                   "}\n";
+    
+    private static final String INDEX_CLASS_TEMPLATE = "class C#ID extends C#PREV {\n" +
+                                                       "    C#ID(int val) { super(val); }\n" +
+                                                       "}\n";
+
+
+
+    protected static String LINKAGE_ERROR = "-1";
+
+    private List<File> compileDirs = new ArrayList<>();
+
+    /**
+     * Compile all the classes in a class spec, and put them on the classpath.
+     *
+     * The spec is the specification for a nest of classes, using the following notation
+     * A, B represent abstract classes
+     * C represents a concrete class
+     * I, J, K represent interfaces
+     * Lowercase 'c' following a class means that the method m() is concrete
+     * Lowercase 'a' following a class or interface means that the method m() is abstract
+     * Lowercase 'd' following an interface means that the method m() is default
+     * A number 0, 1, or 2 following the lowercase letter indicates the return type of that method
+     * 0 = Object, 1 = Number, 2 = Integer (these form an inheritance chain so bridges are generated)
+     * A classes supertypes follow its method spec, in parentheses
+     * Examples:
+     *   C(Ia0, Jd0) -- C extends I and J, I has abstract m()Object, J has default m()Object
+     *   Cc1(Ia0) -- C has concrete m()Number, extends I with abstract m()Object
+     * If a type must appear multiple times, its full spec must be in the first occurrence
+     * Example:
+     *   C(I(Kd0), J(K))
+     */
+    protected void compileSpec(String spec) throws IOException {
+        compileSpec(spec, false);
+    }
+
+    /**
+     * Compile all the classes in a class spec, and assert that there were compilation errors.
+     */
+    protected void compileSpec(String spec, String... errorKeys) throws IOException {
+        compileSpec(spec, false, errorKeys);
+    }
+
+    protected void compileSpec(String spec, boolean debug, String... errorKeys) throws IOException {
+        ClassModel cm = new Parser(spec).parseClassModel();
+        for (int i = 0; i <= cm.maxIndex() ; i++) {
+            if (debug) System.out.println(indexClass(i));
+            addSourceFile(String.format("C%d.java", i), new StringTemplate(indexClass(i)));
+        }  
+        for (Map.Entry<String, ClassModel> e : classes(cm).entrySet()) {
+            if (debug) System.out.println(e.getValue().toSource());
+            addSourceFile(e.getKey() + ".java", new StringTemplate(e.getValue().toSource()));
+        }
+        compileDirs.add(compile(true));
+        resetSourceFiles();
+        if (errorKeys.length == 0)
+            assertCompileSucceeded();
+        else
+            assertCompileErrors(errorKeys);
+    }
+
+    /**
+     * Recompile only a subset of classes in the class spec, as named by names,
+     * and put them on the classpath such that they shadow earlier versions of that class.
+     */
+    protected void recompileSpec(String spec, String... names) throws IOException {
+        List<String> nameList = Arrays.asList(names);
+        ClassModel cm = new Parser(spec).parseClassModel();
+        for (int i = 0; i <= cm.maxIndex() ; i++) {
+            addSourceFile(String.format("C%d.java", i), new StringTemplate(indexClass(i)));
+        }
+        for (Map.Entry<String, ClassModel> e : classes(cm).entrySet())
+            if (nameList.contains(e.getKey()))
+                addSourceFile(e.getKey() + ".java", new StringTemplate(e.getValue().toSource()));
+        compileDirs.add(compile(Arrays.asList(classPaths()), true));
+        resetSourceFiles();
+        assertCompileSucceeded();
+    }
+
+    protected void assertLinkage(String name, String... expected) throws ReflectiveOperationException {
+        for (int i=0; i<expected.length; i++) {
+            String e = expected[i];
+            if (e.equals(LINKAGE_ERROR)) {
+                try {
+                    int actual = invoke(name, i);
+                    fail("Expected linkage error, got" + fromNum(actual));
+                }
+                catch (LinkageError x) {
+                    // success
+                }
+            }
+            else {
+                if (e.length() == 1)
+                    e += "0";
+                int expectedInt = toNum(e);
+                int actual = invoke(name, i);
+                if (expectedInt != actual)
+                    fail(String.format("Expected %s but found %s for %s.m()%d", fromNum(expectedInt), fromNum(actual), name, i));
+            }
+        }
+    }
+
+    private Map<String, ClassModel> classes(ClassModel cm) {
+        HashMap<String, ClassModel> m = new HashMap<>();
+        classesHelper(cm, m);
+        return m;
+    }
+
+    private String indexClass(int index) {
+        if (index == 0) {
+            return BASE_INDEX_CLASS;
+        } else {
+            return INDEX_CLASS_TEMPLATE
+                    .replace("#ID", String.valueOf(index))
+                    .replace("#PREV", String.valueOf(index - 1));
+        }
+    }
+
+    private static String overrideName(int index) {
+        return "C" + index;
+    }
+
+    private void classesHelper(ClassModel cm, Map<String, ClassModel> m) {
+        if (!m.containsKey(cm.name))
+            m.put(cm.name, cm);
+        for (ClassModel s : cm.supertypes)
+            classesHelper(s, m);
+    }
+
+    private static String fromNum(int num) {
+        return String.format("%c%d", TYPE_LETTERS.charAt(num / 10), num % 10);
+    }
+
+    private static int toNum(String name, int index) {
+        return 10*(TYPE_LETTERS.indexOf(name.charAt(0))) + index;
+    }
+
+    private static int toNum(String string) {
+        return 10*(TYPE_LETTERS.indexOf(string.charAt(0))) + Integer.parseInt(string.substring(1, 2));
+    }
+
+    private int invoke(String name, int index) throws ReflectiveOperationException {
+        File[] files = classPaths();
+        Class clazz = loadClass(name, files);
+        Method[] ms = clazz.getMethods();
+        for (Method m : ms) {
+            if (m.getName().equals("m") && m.getReturnType().getName().equals(overrideName(index))) {
+                m.setAccessible(true);
+                Object instance = clazz.newInstance();
+                Object c0 = m.invoke(instance);
+                Method getVal = c0.getClass().getMethod("getVal");
+                getVal.setAccessible(true);
+                return (int)getVal.invoke(c0);
+            }
+        }
+        throw new NoSuchMethodError("cannot find method m()" + index + " in class " + name);
+    }
+
+    private File[] classPaths() {
+        File[] files = new File[compileDirs.size()];
+        for (int i=0; i<files.length; i++)
+            files[files.length - i - 1] = compileDirs.get(i);
+        return files;
+    }
+
+    @BeforeMethod
+    @Override
+    public void reset() {
+        compileDirs.clear();
+        super.reset();
+    }
+
+    private static class ClassModel {
+
+        enum MethodType {
+            ABSTRACT('a'), CONCRETE('c'), DEFAULT('d');
+
+            public final char designator;
+
+            MethodType(char designator) {
+                this.designator = designator;
+            }
+
+            public static MethodType find(char c) {
+                for (MethodType m : values())
+                    if (m.designator == c)
+                        return m;
+                throw new IllegalArgumentException();
+            }
+        }
+
+        private final String name;
+        private final boolean isInterface;
+        private final List<ClassModel> supertypes;
+        private final MethodType methodType;
+        private final int methodIndex;
+
+        private ClassModel(String name,
+                           boolean anInterface,
+                           List<ClassModel> supertypes,
+                           MethodType methodType,
+                           int methodIndex) {
+            this.name = name;
+            isInterface = anInterface;
+            this.supertypes = supertypes;
+            this.methodType = methodType;
+            this.methodIndex = methodIndex;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(name);
+            if (methodType != null) {
+                sb.append(methodType.designator);
+                sb.append(methodIndex);
+            }
+            if (!supertypes.isEmpty()) {
+                sb.append("(");
+                for (int i=0; i<supertypes.size(); i++) {
+                    if (i > 0)
+                        sb.append(",");
+                    sb.append(supertypes.get(i).toString());
+                }
+                sb.append(")");
+            }
+            return sb.toString();
+        }
+
+        int maxIndex() {
+            int maxSoFar = methodIndex;
+            for (ClassModel cm : supertypes) {
+                maxSoFar = Math.max(cm.maxIndex(), maxSoFar);
+            }
+            return maxSoFar;
+        }
+
+        public String toSource() {
+            String extendsClause = "";
+            String implementsClause = "";
+            String methodBody = "";
+            boolean isAbstract = "AB".contains(name);
+
+            for (ClassModel s : supertypes) {
+                if (!s.isInterface) {
+                    extendsClause = String.format("extends %s", s.name);
+                    break;
+                }
+            }
+
+            StringJoiner sj = new StringJoiner(", ");
+            for (ClassModel s : supertypes)
+                if (s.isInterface)
+                    sj.add(s.name);
+            if (sj.length() > 0) {
+                if (isInterface)
+                    implementsClause = "extends " + sj.toString();
+                else
+                implementsClause = "implements " + sj.toString();
+            }
+            if (methodType != null) {
+                switch (methodType) {
+                    case ABSTRACT:
+                        methodBody = String.format("public abstract %s m();", overrideName(methodIndex));
+                        break;
+                    case CONCRETE:
+                        methodBody = String.format("public %s m() { return new %s(%d); };",
+                                overrideName(methodIndex), overrideName(methodIndex), toNum(name, methodIndex));
+                        break;
+                    case DEFAULT:
+                        methodBody = String.format("public default %s m() { return new %s(%d); };",
+                                overrideName(methodIndex), overrideName(methodIndex), toNum(name, methodIndex));
+                        break;
+
+                }
+            }
+
+            return String.format("public %s %s %s %s %s {  %s }", isAbstract ? "abstract" : "",
+                                 isInterface ? "interface" : "class",
+                                 name, extendsClause, implementsClause, methodBody);
+        }
+    }
+
+    private static class Parser {
+        private final String input;
+        private final char[] chars;
+        private int index;
+
+        private Parser(String s) {
+            input = s;
+            chars = s.toCharArray();
+        }
+
+        private char peek() {
+            return index < chars.length ? chars[index] : 0;
+        }
+
+        private boolean peek(String validChars) {
+            return validChars.indexOf(peek()) >= 0;
+        }
+
+        private char advanceIf(String validChars) {
+            if (peek(validChars))
+                return chars[index++];
+            else
+                return 0;
+        }
+
+        private char advanceIfDigit() {
+            return advanceIf("0123456789");
+        }
+
+        private int index() {
+            StringBuilder buf = new StringBuilder();
+            char c = advanceIfDigit();
+            while (c != 0) {
+                buf.append(c);
+                c = advanceIfDigit();
+            }
+            return Integer.valueOf(buf.toString());
+        }
+
+        private char advance() {
+            return chars[index++];
+        }
+
+        private char expect(String validChars) {
+            char c = advanceIf(validChars);
+            if (c == 0)
+                throw new IllegalArgumentException(String.format("Expecting %s at position %d of %s", validChars, index, input));
+            return c;
+        }
+
+        public ClassModel parseClassModel() {
+            List<ClassModel> supers = new ArrayList<>();
+            char name = expect(TYPE_LETTERS);
+            boolean isInterface = "IJK".indexOf(name) >= 0;
+            ClassModel.MethodType methodType = peek(isInterface ? "ad" : "ac") ? ClassModel.MethodType.find(advance()) : null;
+            int methodIndex = 0;
+            if (methodType != null) {
+                methodIndex = index();
+            }
+            if (peek() == '(') {
+                advance();
+                supers.add(parseClassModel());
+                while (peek() == ',') {
+                    advance();
+                    supers.add(parseClassModel());
+                }
+                expect(")");
+            }
+            return new ClassModel(new String(new char[]{ name }), isInterface, supers, methodType, methodIndex);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/BridgeMethodsLinearTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,1083 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import java.io.IOException;
+
+import org.testng.annotations.Test;
+
+/**
+ * BridgeMethodsLinearTest
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class BridgeMethodsLinearTest extends BridgeMethodTestCase {
+
+    /*
+     * Cc1(A) -> Cc1(Ac0)
+     *
+     * 0*: Inherited from A
+     * 1: Declared in C
+     */
+    public void test1() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc1(A)");
+        assertLinkage("C", LINKAGE_ERROR, "C1");
+        recompileSpec("Cc1(Ac0)", "A");
+        assertLinkage("C", "A0", "C1");
+    }
+
+    /*
+     * Cc1(I) -> Cc1(Id0)
+     *
+     * 0*: Inherited default from I
+     * 1: Declared in C
+     */
+    public void test2() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc1(I)");
+        assertLinkage("C", LINKAGE_ERROR, "C1");
+        recompileSpec("Cc1(Id0)", "I");
+        assertLinkage("C", "I0", "C1");
+    }
+
+    /*
+     * C(Bc1(A)) -> C(Bc1(Ac0))
+     *
+     * 0*: Inherited from A
+     * 1: Inherited from B
+     */
+    public void test3() throws IOException, ReflectiveOperationException {
+        compileSpec("C(Bc1(A))");
+        assertLinkage("C", LINKAGE_ERROR, "B1");
+        recompileSpec("C(Bc1(Ac0))", "A");
+        assertLinkage("C", "A0", "B1");
+    }
+
+    /*
+     * C(B(Ac0)) -> C(Bc1(Ac0))
+     *
+     * 0: Inherited from B (through bridge)
+     * 1: Inherited from B
+     */
+    public void test4() throws IOException, ReflectiveOperationException {
+        compileSpec("C(B(Ac0))");
+        assertLinkage("C", "A0", LINKAGE_ERROR);
+        recompileSpec("C(Bc1(Ac0))", "B");
+        assertLinkage("C", "B1", "B1");
+    }
+
+    /*
+     * C(B(A)) -> C(Bc1(Ac0))
+     *
+     * 0: Inherited from B (through bridge)
+     * 1: Inherited from B
+     */
+    public void test5() throws IOException, ReflectiveOperationException {
+        compileSpec("C(B(A))");
+        assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR);
+        recompileSpec("C(Bc1(Ac0))", "A", "B");
+        assertLinkage("C", "B1", "B1");
+    }
+
+    /*
+     * C(Ac1(I)) -> C(Ac1(Id0))
+     *
+     * 0*: Inherited default from I
+     * 1: Inherited from A
+     */
+    public void test6() throws IOException, ReflectiveOperationException {
+        compileSpec("C(Ac1(I))");
+        assertLinkage("C", LINKAGE_ERROR, "A1");
+        recompileSpec("C(Ac1(Id0))", "I");
+        assertLinkage("C", "I0", "A1");
+    }
+
+    /*
+     * C(A(Id0)) -> C(Ac1(Id0))
+     *
+     * 0: Inherited from A (through bridge)
+     * 1: Inherited from A
+     */
+    public void test7() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A(Id0))");
+        assertLinkage("C", "I0", LINKAGE_ERROR);
+        recompileSpec("C(Ac1(Id0))", "A");
+        assertLinkage("C", "A1", "A1");
+    }
+
+    /*
+     * C(A(I)) -> C(Ac1(Id0))
+     *
+     * 0*: Inherited from A (through bridge)
+     * 1*: Inherited from A
+     */
+    public void test8() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A(I))");
+        assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR);
+        recompileSpec("C(Ac1(Id0))", "A", "I");
+        assertLinkage("C", "A1", "A1");
+    }
+
+    /*
+     * C(Id1(J)) -> C(Id1(Jd0))
+     *
+     * 0*: Inherited default from J
+     * 1: Inherited default from I
+     */
+    public void test9() throws IOException, ReflectiveOperationException {
+        compileSpec("C(Id1(J))");
+        assertLinkage("C", LINKAGE_ERROR, "I1");
+        recompileSpec("C(Id1(Jd0))", "J");
+        assertLinkage("C", "J0", "I1");
+    }
+
+    /*
+     * C(I(Jd0)) -> C(Id1(Jd0))
+     *
+     * 0: Inherited default from I (through bridge)
+     * 1: Inherited default from I
+     */
+    public void test10() throws IOException, ReflectiveOperationException {
+        compileSpec("C(I(Jd0))");
+        assertLinkage("C", "J0", LINKAGE_ERROR);
+        recompileSpec("C(Id1(Jd0))", "I");
+        assertLinkage("C", "I1", "I1");
+    }
+
+    /*
+     * C(I(J)) -> C(Id1(Jd0))
+     *
+     * 0: Inherited default from I (through bridge)
+     * 1: Inherited default from I
+     */
+    public void test11() throws IOException, ReflectiveOperationException {
+        compileSpec("C(I(J))");
+        assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR);
+        recompileSpec("C(Id1(Jd0))", "I", "J");
+        assertLinkage("C", "I1", "I1");
+    }
+
+    /*
+     * Cc2(B(Ac0)) -> Cc2(Bc1(Ac0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited from B
+     * 2: Declared in C
+     */
+    public void test12() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(B(Ac0))");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Bc1(Ac0))", "B");
+        assertLinkage("C", "C2", "B1", "C2");
+    }
+
+    /*
+     * Cc2(B(Aa0)) -> Cc2(Bc1(Aa0))
+     *
+     * 0: Bridge in C (through bridge)
+     * 1*: Inherited from B
+     * 2: Declared in C
+     */
+    public void test13() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(B(Aa0))");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Bc1(Aa0))", "B");
+        assertLinkage("C", "C2", "B1", "C2");
+    }
+
+    /*
+     * Cc2(Bc1(A)) -> Cc2(Bc1(Ac0))
+     *
+     * 0*: Inherited from A
+     * 1: Declared in C (through bridge)
+     * 2: Declared in C
+     */
+    public void test14() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(Bc1(A))");
+        assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+        recompileSpec("Cc2(Bc1(Ac0))", "A");
+        assertLinkage("C", "A0", "C2", "C2");
+    }
+
+    /*
+     * Cc2(Ba1(A)) -> Cc2(Ba1(Ac0))
+     *
+     * 0*: Inherited from A
+     * 1: Declared in C (through bridge)
+     * 2: Declared in C
+     */
+    public void test15() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(Ba1(A))");
+        assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+        recompileSpec("Cc2(Ba1(Ac0))", "A");
+        assertLinkage("C", "A0", "C2", "C2");
+    }
+
+    /*
+     * Cc2(B(A)) -> Cc2(Bc1(Ac0))
+     *
+     * 0*: Inherited from B (through bridge)
+     * 1*: Inherited from B
+     * 2: Declared in C
+     */
+    public void test16() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(B(A))");
+        assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Bc1(Ac0))", "B", "A");
+        assertLinkage("C", "B1", "B1", "C2");
+    }
+
+    /*
+     * Cc2(A(Id0)) -> Cc2(Ac1(Id0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited from A
+     * 2: Declared in C
+     */
+    public void test17() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(A(Id0))");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Ac1(Id0))", "A");
+        assertLinkage("C", "C2", "A1", "C2");
+    }
+
+    /*
+     * Cc2(A(Ia0)) -> Cc2(Ac1(Ia0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited from A
+     * 2: Declared in C
+     */
+    public void test18() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(A(Ia0))");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Ac1(Ia0))", "A");
+        assertLinkage("C", "C2", "A1", "C2");
+    }
+
+    /*
+     * Cc2(Ac1(I)) -> Cc2(Ac1(Id0))
+     *
+     * 0*: Inherited from I
+     * 1: Declared in C (through bridge)
+     * 2: Declared in C
+     */
+    public void test19() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(Ac1(I))");
+        assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+        recompileSpec("Cc2(Ac1(Id0))", "I");
+        assertLinkage("C", "I0", "C2", "C2");
+    }
+
+    /*
+     * Cc2(Aa1(I)) -> Cc2(Aa1(Id0))
+     *
+     * 0*: Inherited from I
+     * 1: Declared in C (through bridge)
+     * 2: Declared in C
+     */
+    public void test20() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(Aa1(I))");
+        assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+        recompileSpec("Cc2(Aa1(Id0))", "I");
+        assertLinkage("C", "I0", "C2", "C2");
+    }
+
+    /*
+     * Cc2(A(I)) -> Cc2(Ac1(Id0))
+     *
+     * 0*: Inherited from A (through bridge)
+     * 1*: Inherited from A
+     * 2: Declared in C
+     */
+    public void test21() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(A(I))");
+        assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Ac1(Id0))", "A", "I");
+        assertLinkage("C", "A1", "A1", "C2");
+    }
+
+    /*
+     * Cc2(J(Id0)) -> Cc2(Jd1(Id0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited default from J
+     * 2: Declared in C
+     */
+    public void test22() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(J(Id0))");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Jd1(Id0))", "J");
+        assertLinkage("C", "C2", "J1", "C2");
+    }
+
+    /*
+     * Cc2(J(Ia0)) -> Cc2(Jd1(Ia0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited default from J
+     * 2: Declared in C
+     */
+    public void test23() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(J(Ia0))");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Jd1(Ia0))", "J");
+        assertLinkage("C", "C2", "J1", "C2");
+    }
+
+    /*
+     * Cc2(Jd1(I)) -> Cc2(Jd1(Id0))
+     *
+     * 0*: Inherited default from I
+     * 1: Declared in C (through bridge)
+     * 2: Declared in C
+     */
+    public void test24() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(Jd1(I))");
+        assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+        recompileSpec("Cc2(Jd1(Id0))", "I");
+        assertLinkage("C", "I0", "C2", "C2");
+    }
+
+    /*
+     * Cc2(Ja1(I)) -> Cc2(Ja1(Id0))
+     *
+     * 0*: Inherited default from I
+     * 1: Declared in C (through bridge)
+     * 2: Declared in C
+     */
+    public void test25() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(Ja1(I))");
+        assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+        recompileSpec("Cc2(Ja1(Id0))", "I");
+        assertLinkage("C", "I0", "C2", "C2");
+    }
+
+    /*
+     * Cc2(J(I)) -> Cc2(Jd1(Id0))
+     *
+     * 0*: Inherited default from J (through bridge)
+     * 1*: Inherited default from J
+     * 2: Declared in C
+     */
+    public void test26() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(J(I))");
+        assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Jd1(Id0))", "J", "I");
+        assertLinkage("C", "J1", "J1", "C2");
+    }
+
+    /*
+     * C(Ac1, I) -> C(Ac1, Id0)
+     *
+     * 0*: Inherited default from I
+     * 1: Inherited from A
+     */
+    public void test27() throws IOException, ReflectiveOperationException {
+        compileSpec("C(Ac1,I)");
+        assertLinkage("C", LINKAGE_ERROR, "A1");
+        recompileSpec("C(Ac1,Id0)", "I");
+        assertLinkage("C", "I0", "A1");
+    }
+
+    /*
+     * C(A, Id0) -> C(Ac1, Id0)
+     *
+     * 0*: Inherited default from I
+     * 1: Inherited from A
+     */
+    public void test28() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A,Id0)");
+        assertLinkage("C", "I0", LINKAGE_ERROR);
+        recompileSpec("C(Ac1,Id0)", "A");
+        assertLinkage("C", "I0", "A1");
+    }
+
+    /*
+     * C(A, I) -> C(Ac1, Id0)
+     *
+     * 0*: Inherited default from I
+     * 1: Inherited from A
+     */
+    public void test29() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A,I)");
+        assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR);
+        recompileSpec("C(Ac1,Id0)", "A", "I");
+        assertLinkage("C", "I0", "A1");
+    }
+
+    /*
+     * Cc2(Ac1, I) -> Cc2(Ac1, Id0)
+     *
+     * 0*: Inherited default from I
+     * 1: Declared in C (through bridge)
+     * 2: Declared in C
+     */
+    public void test30() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(Ac1,I)");
+        assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+        recompileSpec("Cc2(Ac1,Id0)", "I");
+        assertLinkage("C", "I0", "C2", "C2");
+    }
+
+    /*
+     * Cc2(Aa1, I) -> Cc2(Aa1, Id0)
+     *
+     * 0*: Inherited default from I
+     * 1: Declared in C (through bridge)
+     * 2: Declared in C
+     */
+    public void test31() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(Aa1,I)");
+        assertLinkage("C", LINKAGE_ERROR, "C2", "C2");
+        recompileSpec("Cc2(Aa1,Id0)", "I");
+        assertLinkage("C", "I0", "C2", "C2");
+    }
+
+    /*
+     * Cc2(A, Id0) -> Cc2(Ac1, Id0)
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited from A
+     * 2: Declared in C
+     */
+    public void test32() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(A,Id0)");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Ac1,Id0)", "A");
+        assertLinkage("C", "C2", "A1", "C2");
+    }
+
+    /*
+     * Cc2(A, Ia0) -> Cc2(Ac1, Ia0)
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited from A
+     * 2: Declared in C
+     */
+    public void test33() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(A,Ia0)");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Ac1,Ia0)", "A");
+        assertLinkage("C", "C2", "A1", "C2");
+    }
+
+    /*
+     * Cc2(A, I) -> Cc2(Ac1, Id0)
+     *
+     * 0*: Inherited from A
+     * 1*: Inherited default from I
+     * 2: Declared in C
+     */
+    public void test34() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(A,I)");
+        assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Ac1,Id0)", "A", "I");
+        assertLinkage("C", "I0", "A1", "C2");
+    }
+
+    /*
+     * Cc2(Id0, J) -> Cc2(Id0, Jd1)
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited default from J
+     * 2: Declared in C
+     */
+    public void test35() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(Id0,J)");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Id0,Jd1)", "J");
+        assertLinkage("C", "C2", "J1", "C2");
+    }
+
+    /*
+     * Cc2(Ia0, J) -> Cc2(Ia0, Jd1)
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited default from J
+     * 2: Declared in C
+     */
+    public void test36() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(Ia0,J)");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Ia0,Jd1)", "J");
+        assertLinkage("C", "C2", "J1", "C2");
+    }
+
+    /*
+     * Cc2(I, J) -> Cc2(Id0, Jd1)
+     *
+     * 0*: Inherited default from I
+     * 1*: Inherited default from J
+     * 2: Declared in C
+     */
+    public void test37() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(I,J)");
+        assertLinkage("C", LINKAGE_ERROR, LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Id0,Jd1)", "I", "J");
+        assertLinkage("C", "I0", "J1", "C2");
+    }
+
+    /*
+     * C(A(Id0), J(Id0)) -> C(Ac1(Id0), J(Id0))
+     *
+     * 0: Inherited default from I
+     * 0*: Inherited from A (through bridge)
+     * 1*: Inherited from A
+     */
+    public void test38() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A(Id0),J(Id0))");
+        assertLinkage("C", "I0", LINKAGE_ERROR);
+        recompileSpec("C(Ac1(Id0),J(Id0))", "A");
+        assertLinkage("C", "A1", "A1");
+    }
+
+    /*
+     * C(A(Id0), J(Id0)) -> C(A(Id0), Jd1(Id0))
+     *
+     * 0: Inherited default from I
+     * 0: Inherited default from J (through bridge)
+     * 1*: Inherited default from J
+     */
+    public void test39() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A(Id0),J(Id0))");
+        assertLinkage("C", "I0", LINKAGE_ERROR);
+        recompileSpec("C(A(Id0),Jd1(Id0))", "J");
+        assertLinkage("C", "J1", "J1");
+    }
+
+    /*
+     * C(A(Id0), J(Id0)) -> C(Ac2(Id0), Jd1(Id0))
+     *
+     * 0: Inherited default from I
+     * 0*: Inherited from A (new bridge in A beats new bridge in J)
+     * 1*: Inherited default from J
+     * 2: Inherited from A
+     */
+    public void test40() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A(Id0),J(Id0))");
+        assertLinkage("C", "I0", LINKAGE_ERROR);
+        recompileSpec("C(Ac2(Id0),Jd1(Id0))", "A", "J");
+        assertLinkage("C", "A2", "J1", "A2");
+    }
+
+    /*
+     * C(J(Id0), K(Id0)) -> C(Jd1(Id0), K(Id0))
+     *
+     * 0: Inherited from I
+     * 0*: Inherited default from J (through bridge)
+     * 1: Inherited default from J
+     */
+    public void test41() throws IOException, ReflectiveOperationException {
+        compileSpec("C(J(Id0),K(Id0))");
+        assertLinkage("C", "I0", LINKAGE_ERROR);
+        recompileSpec("C(Jd1(Id0),K(Id0))", "J");
+        assertLinkage("C", "J1", "J1");
+    }
+
+    /*
+     * C(Ac2(Id0), J(Id0)) -> C(Ac2(Id0), Jd1(Id0))
+     *
+     * 0: Inherited from A (bridge in A beats new bridge in J)
+     * 1*: Inherited default from J
+     * 2: Inherited from A
+     */
+    public void test42() throws IOException, ReflectiveOperationException {
+        compileSpec("C(Ac2(Id0),J(Id0))");
+        assertLinkage("C", "A2", LINKAGE_ERROR, "A2");
+        recompileSpec("C(Ac2(Id0),Jd1(Id0))", "J");
+        assertLinkage("C", "A2", "J1", "A2");
+    }
+
+    /*
+     * C(Ac2(Ia0), J(Ia0)) -> C(Ac2(Ia0), Jd1(Ia0))
+     *
+     * 0: Inherited from A (bridge in A beats new bridge in J)
+     * 1*: Inherited default from J
+     * 2: Inherited from A
+     */
+    public void test43() throws IOException, ReflectiveOperationException {
+        compileSpec("C(Ac2(Ia0),J(Ia0))");
+        assertLinkage("C", "A2", LINKAGE_ERROR, "A2");
+        recompileSpec("C(Ac2(Ia0),Jd1(Ia0))", "J");
+        assertLinkage("C", "A2", "J1", "A2");
+    }
+
+    /*
+     * C(A(Id0), Jd1(Id0)) -> C(Ac2(Id0), Jd1(Id0))
+     *
+     * 0: Inherited from J
+     * 0*: Inherited from A (new bridge in A beats bridge in J)
+     * 1: Inherited default from J
+     * 2*: Inherited from A
+     */
+    public void test44() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A(Id0),Jd1(Id0))");
+        assertLinkage("C", "J1", "J1", LINKAGE_ERROR);
+        recompileSpec("C(Ac2(Id0),Jd1(Id0))", "A");
+        assertLinkage("C", "A2", "J1", "A2");
+    }
+
+    /*
+     * C(A(Ia0), Jd1(Ia0)) -> C(Ac2(Ia0), Jd1(Ia0))
+     *
+     * 0: Inherited from J
+     * 0*: Inherited from A (new bridge in A beats bridge in J)
+     * 1: Inherited default from J
+     * 2*: Inherited from A
+     */
+    public void test45() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A(Ia0),Jd1(Ia0))");
+        assertLinkage("C", "J1", "J1", LINKAGE_ERROR);
+        recompileSpec("C(Ac2(Ia0),Jd1(Ia0))", "A");
+        assertLinkage("C", "A2", "J1", "A2");
+    }
+
+    /*
+     * Cc2(A(Id0), J(Id0)) -> Cc2(Ac1(Id0), J(Id0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited from A
+     * 2: Declared in C
+     */
+    public void test46() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(A(Id0),J(Id0))");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Ac1(Id0),J(Id0))", "A");
+        assertLinkage("C", "C2", "A1", "C2");
+    }
+
+    /*
+     * Cc2(A(Ia0), J(Ia0)) -> Cc2(Ac1(Ia0), J(Ia0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited from A
+     * 2: Declared in C
+     */
+    public void test47() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(A(Ia0),J(Ia0))");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Ac1(Ia0),J(Ia0))", "A");
+        assertLinkage("C", "C2", "A1", "C2");
+    }
+
+    /*
+     * Cc2(A(Id0), J(Id0)) -> Cc2(A(Id0), Jd1(Id0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited default from J
+     * 2: Declared in C
+     */
+    public void test48() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(A(Id0),J(Id0))");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(A(Id0),Jd1(Id0))", "J");
+        assertLinkage("C", "C2", "J1", "C2");
+    }
+
+    /*
+     * Cc2(A(Ia0), J(Ia0)) -> Cc2(A(Ia0), Jd1(Ia0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited default from J
+     * 2: Declared in C
+     */
+    public void test49() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(A(Ia0),J(Ia0))");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(A(Ia0),Jd1(Ia0))", "J");
+        assertLinkage("C", "C2", "J1", "C2");
+    }
+
+
+    /*
+     * Cc3(A(Id0), J(Id0)) -> Cc3(Ac1(Id0), Jd2(Id0))
+     *
+     * 0: Bridge in C
+     * 1*: Inherited from A
+     * 2*: Inherited default from J
+     * 3: Declared in C
+     */
+    public void test50() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(A(Id0),J(Id0))");
+        assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3");
+        recompileSpec("Cc3(Ac1(Id0),Jd2(Id0))", "A", "J");
+        assertLinkage("C", "C3", "A1", "J2", "C3");
+    }
+
+    /*
+     * Cc3(A(Ia0), J(Ia0)) -> Cc3(Ac1(Ia0), Jd2(Ia0))
+     *
+     * 0: Bridge in C
+     * 1*: Inherited from A
+     * 2*: Inherited default from J
+     * 3: Declared in C
+     */
+    public void test51() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(A(Ia0),J(Ia0))");
+        assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3");
+        recompileSpec("Cc3(Ac1(Ia0),Jd2(Ia0))", "A", "J");
+        assertLinkage("C", "C3", "A1", "J2", "C3");
+    }
+
+    /*
+     * Cc2(J(Id0), K(Id0)) -> Cc2(Jd1(Id0), K(Id0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited default from J
+     * 2: Declared in C
+     */
+    public void test52() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(J(Id0),K(Id0))");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Jd1(Id0),K(Id0))", "J");
+        assertLinkage("C", "C2", "J1", "C2");
+    }
+
+    /*
+     * Cc2(J(Ia0), K(Ia0)) -> Cc2(Jd1(Ia0), K(Ia0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited default from J
+     * 2: Declared in C
+     */
+    public void test53() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc2(J(Ia0),K(Ia0))");
+        assertLinkage("C", "C2", LINKAGE_ERROR, "C2");
+        recompileSpec("Cc2(Jd1(Ia0),K(Ia0))", "J");
+        assertLinkage("C", "C2", "J1", "C2");
+    }
+
+    /*
+     * Cc3(J(Id0), K(Id0)) -> Cc3(Jd1(Id0), Kd2(Id0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited default from J
+     * 2*: Inherited default from K
+     * 3: Declared in C
+     */
+    public void test54() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(J(Id0),K(Id0))");
+        assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3");
+        recompileSpec("Cc3(Jd1(Id0),Kd2(Id0))", "J", "K");
+        assertLinkage("C", "C3", "J1", "K2", "C3");
+    }
+
+    /*
+     * Cc3(J(Ia0), K(Ia0)) -> Cc3(Jd1(Ia0), Kd2(Ia0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited default from J
+     * 2*: Inherited default from K
+     * 3: Declared in C
+     */
+    public void test55() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(J(Ia0),K(Ia0))");
+        assertLinkage("C", "C3", LINKAGE_ERROR, LINKAGE_ERROR, "C3");
+        recompileSpec("Cc3(Jd1(Ia0),Kd2(Ia0))", "J", "K");
+        assertLinkage("C", "C3", "J1", "K2", "C3");
+    }
+
+    /*
+     * Cc3(Ac1(Id0), J(Id0)) -> Cc3(Ac1(Id0), Jd2(Id0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1: Declared in C (through bridge)
+     * 2*: Inherited default from J
+     * 3: Declared in C
+     */
+    public void test56() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(Ac1(Id0),J(Id0))");
+        assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+        recompileSpec("Cc3(Ac1(Id0),Jd2(Id0))", "J");
+        assertLinkage("C", "C3", "C3", "J2", "C3");
+    }
+
+    /*
+     * Cc3(Ac1(Ia0), J(Ia0)) -> Cc3(Ac1(Ia0), Jd2(Ia0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1: Declared in C (through bridge)
+     * 2*: Inherited default from J
+     * 3: Declared in C
+     */
+    public void test57() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(Ac1(Ia0),J(Ia0))");
+        assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+        recompileSpec("Cc3(Ac1(Ia0),Jd2(Ia0))", "J");
+        assertLinkage("C", "C3", "C3", "J2", "C3");
+    }
+
+    /*
+     * Cc3(Aa1(Id0), J(Id0)) -> Cc3(Aa1(Id0), Jd2(Id0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1: Declared in C (through bridge)
+     * 2*: Inherited default from J
+     * 3: Declared in C
+     */
+    public void test58() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(Aa1(Id0),J(Id0))");
+        assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+        recompileSpec("Cc3(Aa1(Id0),Jd2(Id0))", "J");
+        assertLinkage("C", "C3", "C3", "J2", "C3");
+    }
+
+    /*
+     * Cc3(Aa1(Ia0), J(Ia0)) -> Cc3(Aa1(Ia0), Jd2(Ia0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1: Declared in C (through bridge)
+     * 2*: Inherited default from J
+     * 3: Declared in C
+     */
+    public void test59() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(Aa1(Ia0),J(Ia0))");
+        assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+        recompileSpec("Cc3(Aa1(Ia0),Jd2(Ia0))", "J");
+        assertLinkage("C", "C3", "C3", "J2", "C3");
+    }
+
+    /*
+     * Cc3(A(Id0), Jd2(Id0)) -> Cc3(Ac1(Id0), Jd2(Id0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited from A
+     * 2: Declared in C (through bridge)
+     * 3: Declared in C
+     */
+    public void test60() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(A(Id0),Jd2(Id0))");
+        assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3");
+        recompileSpec("Cc3(Ac1(Id0),Jd2(Id0))", "A");
+        assertLinkage("C", "C3", "A1", "C3", "C3");
+    }
+
+    /*
+     * Cc3(A(Im0), Jd2(Ia0)) -> Cc3(Ac1(Im0), Jd2(Ia0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited from A
+     * 2: Declared in C (through bridge)
+     * 3: Declared in C
+     */
+    public void test61() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(A(Ia0),Jd2(Ia0))");
+        assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3");
+        recompileSpec("Cc3(Ac1(Ia0),Jd2(Ia0))", "A");
+        assertLinkage("C", "C3", "A1", "C3", "C3");
+    }
+
+    /*
+     * Cc3(A(Im0), Ja2(Id0)) -> Cc3(Ac1(Id0), Ja2(Id0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited from A
+     * 2: Declared in C (through bridge)
+     * 3: Declared in C
+     */
+    public void test62() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(A(Id0),Ja2(Id0))");
+        assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3");
+        recompileSpec("Cc3(Ac1(Id0),Ja2(Id0))", "A");
+        assertLinkage("C", "C3", "A1", "C3", "C3");
+    }
+
+    /*
+     * Cc3(A(Im0), Ja2(Ia0)) -> Cc3(Ac1(Ia0), Ja2(Ia0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1*: Inherited from A
+     * 2: Declared in C (through bridge)
+     * 3: Declared in C
+     */
+    public void test63() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(A(Ia0),Ja2(Ia0))");
+        assertLinkage("C", "C3", LINKAGE_ERROR, "C3", "C3");
+        recompileSpec("Cc3(Ac1(Ia0),Ja2(Ia0))", "A");
+        assertLinkage("C", "C3", "A1", "C3", "C3");
+    }
+
+    /*
+     * Cc3(Jd1(Id0), K(Id0)) -> Cc3(Jd1(Id0), Kd2(Id0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1: Declared in C (through bridge)
+     * 2*: Inherited default from K
+     * 3: Declared in C
+     */
+    public void test64() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(Jd1(Id0),K(Id0))");
+        assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+        recompileSpec("Cc3(Jd1(Id0),Kd2(Id0))", "K");
+        assertLinkage("C", "C3", "C3", "K2", "C3");
+    }
+
+    /*
+     * Cc3(Jd1(Ia0), K(Ia0)) -> Cc3(Jd1(Ia0), Kd2(Ia0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1: Declared in C (through bridge)
+     * 2*: Inherited default from K
+     * 3: Declared in C
+     */
+    public void test65() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(Jd1(Ia0),K(Ia0))");
+        assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+        recompileSpec("Cc3(Jd1(Ia0),Kd2(Ia0))", "K");
+        assertLinkage("C", "C3", "C3", "K2", "C3");
+    }
+
+    /*
+     * Cc3(Ja1(Id0), K(Id0)) -> Cc3(Ja1(Id0), Kd2(Id0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1: Declared in C (through bridge)
+     * 2*: Inherited default from K
+     * 3: Declared in C
+     */
+    public void test66() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(Jd1(Id0),K(Id0))");
+        assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+        recompileSpec("Cc3(Jd1(Id0),Kd2(Id0))", "K");
+        assertLinkage("C", "C3", "C3", "K2", "C3");
+    }
+
+    /*
+     * Cc3(Ja1(Ia0), K(Ia0)) -> Cc3(Ja1(Ia0), Kd2(Ia0))
+     *
+     * 0: Declared in C (through bridge)
+     * 1: Declared in C (through bridge)
+     * 2*: Inherited default from K
+     * 3: Declared in C
+     */
+    public void test67() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc3(Jd1(Ia0),K(Ia0))");
+        assertLinkage("C", "C3", "C3", LINKAGE_ERROR, "C3");
+        recompileSpec("Cc3(Jd1(Ia0),Kd2(Ia0))", "K");
+        assertLinkage("C", "C3", "C3", "K2", "C3");
+    }
+
+    // Dan's set A
+    public void testA1() throws IOException, ReflectiveOperationException {
+        compileSpec("C(Id0)");
+        assertLinkage("C", "I0");
+    }
+
+    public void testA2() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A(Id0))");
+        assertLinkage("C", "I0");
+    }
+
+    public void testA3() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A(Id0),J)");
+        assertLinkage("C", "I0");
+    }
+
+    public void testA4() throws IOException, ReflectiveOperationException {
+        compileSpec("D(C(Id0),Jd0(Id0))");
+        assertLinkage("D", "J0");
+        assertLinkage("C", "I0");
+    }
+    /* Doesn't compile
+    public void testA5() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A(Id0),Jd0)");
+        assertLinkage("C", "J0");
+        assertLinkage("A", "I0");
+    }
+    */
+    /* Doesn't compile
+    public void testA6() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A(Id0,Jd0))");
+        assertLinkage("C", "J0");
+        assertLinkage("A", "I0");
+    }
+    */
+    /* Doesn't compile
+    public void testA7() throws IOException, ReflectiveOperationException {
+        compileSpec("C(A(I0,Jd0))");
+        assertLinkage("C", "J0");
+        assertLinkage("A", "I0");
+    }
+    */
+    public void testA8() throws IOException, ReflectiveOperationException {
+        compileSpec("C(Ac0(Id0))");
+        assertLinkage("C", "A0");
+    }
+
+    /* Doesn't compile
+    public void testA9() throws IOException, ReflectiveOperationException {
+        compileSpec("C(Ac0,Id0)");
+        assertLinkage("C", "A0");
+    }
+    */
+
+    // Dan's set B
+
+    /* B1 can't be done, needs a second concrete class D
+    public void testB1() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc1(Dc0)");
+        assertLinkage("C", "C1", "C1");
+        assertLinkage("D", "A0", LINKAGE_ERROR);
+    }
+    */
+
+    public void testB2() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc1(Ac0)");
+        assertLinkage("C", "C1", "C1");
+    }
+
+    //??? B3 seems to suggest that we should create an abstract class
+    //public void testB3() throws IOException, ReflectiveOperationException {
+    //    compileSpec("Ba1(Cc0)");
+    //    assertLinkage("B", "C0", "A1");
+    //}
+
+    // B4 needs too many classes
+
+    public void testB5() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc1(Aa1(Id0))");
+        assertLinkage("C", "C1", "C1");
+    }
+
+    public void testB6() throws IOException, ReflectiveOperationException {
+        compileSpec("C(Ac1(Id0))");
+        assertLinkage("C", "A1", "A1");
+    }
+
+    public void testB7() throws IOException, ReflectiveOperationException {
+        compileSpec("Cc1(Id0)");
+        assertLinkage("C", "C1", "C1");
+    }
+
+    public void testB8() throws IOException, ReflectiveOperationException {
+        compileSpec("C(Jd1(Id0))");
+        assertLinkage("C", "J1", "J1");
+    }
+
+    // B9 needs too many classes
+
+    // The rest of Dan's tests need generics
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/ComboTestBase.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import com.sun.tools.javac.util.Pair;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.Test;
+
+import java.io.*;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.*;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/**
+ * ComboTestBase
+ *
+ * @author Brian Goetz
+ */
+public abstract class ComboTestBase<T extends ComboTestBase<T>> extends JavacTemplateTestBase {
+    private final static Map<Class, ComboTestMetadata> metadataMap = new HashMap<>();
+    private final static boolean DEBUG_PROPERTY_SET = !System.getProperty("combo.debug", "").equals("");
+    private final static long timestamp = System.currentTimeMillis();
+    private final static Map</* filename */ String,
+                             Map</* combo vars */ Map<String, String>, /* data */ Map<String, String>>> debugInfo
+            = new HashMap<>();
+
+    protected final ComboTestMetadata<T> metadata;
+    protected final Object[] comboArgs;
+    private boolean debugOnly = false;
+
+    // This class cannot have a constructor; it interferes with testng's ability to find the factory method
+    //in subclasses.  Anything that would be done by a constructor should insteady be done by init blocks
+    //or the pseudoConstructor() method.
+
+    /* init */ {
+        metadata = getMetadata((Class<T>) getClass());
+        comboArgs = new Object[metadata.dimensions.length];
+    }
+
+    /**
+     * This method is meant to be called from an @Factory method in the subclass, passing its own class literal
+     * as the clazz argument.  It will introspect over the provided class, find the dimension variables, and
+     * generate the combinatorial explosion of test cases.  (It consults shouldSkip() to determine if a particular
+     * combination should be skipped.)
+     */
+    public static<T extends ComboTestBase> Object[] factory(Class<T> clazz) throws ReflectiveOperationException {
+        int index = 0;
+        try {
+            ComboTestMetadata<T> md = getMetadata(clazz);
+            List<T> list = new ArrayList<>();
+            for (Object[] args : md.makeLoop()) {
+                T instance = md.makeInstance(args);
+                if (!instance.shouldSkip()) {
+                    instance.pseudoConstructor(args);
+                    list.add(instance);
+                    instance.templates.put("__INDEX__", instance.new StringTemplate(Integer.toString(index++)));
+                    if (DEBUG_PROPERTY_SET)
+                        ((ComboTestBase) instance).debugOnly = true;
+                }
+            }
+
+            return list.toArray();
+        } catch (Throwable t) {
+            // This is a needed annoyance; TestNG swallows exception data from exceptions thrown from @Factory methods
+            t.printStackTrace(System.err);
+            t.printStackTrace(System.out);
+            throw t;
+        }
+    }
+
+    /** For debugging of test cases -- sets tests into debug-only mode, where we print out the instantiations of
+     * the dimension variables and the templates.
+     */
+    public static<T extends ComboTestBase> Object[] debugFactory(Class<T> clazz) throws ReflectiveOperationException {
+        Object[] results = factory(clazz);
+        for (Object o : results)
+            ((ComboTestBase) o).debugOnly = true;
+        return results;
+    }
+
+    private static<T extends ComboTestBase<T>> ComboTestMetadata<T> getMetadata(Class<T> clazz) {
+        try {
+            ComboTestMetadata<T> md = metadataMap.get(clazz);
+            if (md == null) {
+                md = new ComboTestMetadata<T>(clazz);
+                metadataMap.put(clazz, md);
+            }
+            return md;
+        } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // Should be private, but can't be
+    void pseudoConstructor(Object[] args) throws ReflectiveOperationException {
+        System.arraycopy(args, 0, comboArgs, 0, args.length);
+    }
+
+    private void addTemplates() throws ReflectiveOperationException {
+        for (int i=0; i<comboArgs.length; i++)
+            addTemplate(metadata.dimensions[i].name, asTemplate(comboArgs[i]));
+
+        for (ComboTestMetadata.TemplateMember<TemplateVar, Field> m : metadata.templateFields)
+            addTemplate(m.name, asTemplate(m.member.get(this)));
+
+        for (ComboTestMetadata.TemplateMember<TemplateVar, Method> m : metadata.templateMethods)
+            addTemplate(m.name, asTemplate(m.member.invoke(this)));
+    }
+
+    private void addAllSourceFiles() throws ReflectiveOperationException {
+        for (ComboTestMetadata.TemplateMember<SourceFile, Field> m : metadata.sourceFields)
+            addSourceFile(m.name, asTemplate(m.member.get(this)));
+
+        for (ComboTestMetadata.TemplateMember<SourceFile, Method> m : metadata.sourceMethods)
+            addSourceFile(m.name, asTemplate(m.member.invoke(this)));
+    }
+
+    private void addSourceFiles(String group) throws ReflectiveOperationException {
+        for (ComboTestMetadata.TemplateMember<SourceFile, Field> m : metadata.sourceFields)
+            if (group.equals(m.annotation.group()))
+                addSourceFile(m.name, asTemplate(m.member.get(this)));
+
+        for (ComboTestMetadata.TemplateMember<SourceFile, Method> m : metadata.sourceMethods)
+            if (group.equals(m.annotation.group()))
+                addSourceFile(m.name, asTemplate(m.member.invoke(this)));
+    }
+
+    /**
+     * Should the current combination of inputs be skipped?  Default implementation returns false for
+     * all combinations (indicating all combinations are valid.)
+     */
+    protected boolean shouldSkip() {
+        return false;
+    }
+
+    protected boolean shouldRun() {
+        return false;
+    }
+
+    /**
+     * Called after test() compiles, allowing subclass an opportunity to examine diagonstics and assert
+     * their properties.  Default implementation calls assertCompileSucceeded().
+     * @param group
+     */
+    protected void postCompile(String group) {
+        assertCompileSucceeded();
+    }
+
+    protected String[] getCompileOptions(String group) {
+        return new String[0];
+    }
+
+    /**
+     * Called before test() compiles, allowing subclass an opportunity to set compilation options.
+     */
+    protected void preCompile(String group) {
+    }
+
+    @Test
+    public void test() throws Exception {
+        if (debugOnly) {
+            addTemplates();
+            addAllSourceFiles();
+            System.out.println("Test case : " + getTestCaseDescription());
+            for (Pair<String, Template> e : sourceFiles)
+                System.out.println("Source file " + e.fst + ": " + e.snd);
+
+            String testFile = getClass().getName();
+            Map<Map<String, String>, Map<String, String>> testCaseMap = debugInfo.get(testFile);
+            if (testCaseMap == null) {
+                testCaseMap = new HashMap<>();
+                debugInfo.put(testFile, testCaseMap);
+            }
+
+            Map<String, String> comboKeys = new HashMap<>();
+            for (int i=0; i<metadata.dimensions.length; i++)
+                comboKeys.put(metadata.dimensions[i].name, comboArgs[i].toString());
+            String compileOptions = Arrays.asList(getCompileOptions("")).toString();
+            Map<String, String> data = new HashMap<>();
+            int count = 0;
+            for (Pair<String, Template> e : sourceFiles) {
+                count++;
+                data.put("File." + count + ".FileName", e.fst);
+                data.put("File." + count + ".Source", e.snd.toString());
+                data.put("File." + count + ".Group", "");
+                data.put("File." + count + ".CompileOptions", compileOptions);
+            }
+            Object prev = testCaseMap.put(comboKeys, data);
+            if (prev != null)
+                fail(String.format("Duplicate key for file %s, keys %s", testFile, comboKeys.toString()));
+        }
+        else {
+            boolean generate = shouldRun();
+            boolean errors = false;
+            List<File> files = new ArrayList<>();
+            List<String> groupsReversed = new ArrayList<>(metadata.groups);
+            Collections.reverse(groupsReversed);
+            for (String g : groupsReversed) {
+                addTemplates();
+                addSourceFiles(g);
+                preCompile(g);
+                addCompileOptions(getCompileOptions(g));
+                for (File f : files)
+                    addClassPath(f);
+                files.add(0, compile(generate));
+                errors |= diags.errorsFound();
+                postCompile(g);
+                reset();
+            }
+
+            if (generate && !errors) {
+                run(loadClass("Main", files.toArray(new File[files.size()])));
+            }
+        }
+    }
+
+    @AfterSuite
+    public void dumpDebug() throws IOException {
+        if (DEBUG_PROPERTY_SET) {
+            for (Map.Entry<String, Map<Map<String, String>, Map<String, String>>> f : debugInfo.entrySet()) {
+                File out = new File(String.format("ComboLog-%s-%d.ser", f.getKey(), timestamp));
+                try (ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(out))) {
+                    os.writeObject(f.getValue());
+                }
+            }
+        }
+    }
+
+    protected void run(Class<?> clazz) throws ReflectiveOperationException {
+        assertTrue(clazz != null);
+    }
+
+    protected String getTestCaseDescription() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("ComboTest[").append(getClass().getName()).append(": ");
+        for (int i=0; i<metadata.dimensions.length; i++)
+            sb.append(metadata.dimensions[i].name).append(" = ").append(comboArgs[i]).append(", ");
+        sb.append("]");
+        return sb.toString();
+    }
+
+    protected boolean skipConstrained(int arity, Enum... enums) {
+        for (int i=arity; i<enums.length; i++)
+            if (enums[i].ordinal() != 0)
+                return true;
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/ComboTestDebug.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * ComboTestDebug -- utility program for dumping or comparing combo test debug logs.  Debug logs can be
+ * used for debugging combo tests, as they contain all the generated source files and options (but are
+ * primarily used for testing for regressions in the combo test framework when changes are made to the
+ * framework.)
+ *
+ * @author Brian Goetz
+ */
+public class ComboTestDebug {
+    public static List<String> files = new ArrayList<>();
+    public static boolean compare;
+
+    private static void compareFiles(String s1, String s2) throws IOException, ClassNotFoundException {
+        Map</* combo vars */ Map<String, String>,
+                /* data */ Map<String, String>> f1, f2;
+        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(s1))) {
+            f1 = (Map<Map<String, String>, Map<String, String>>) ois.readObject();
+        }
+        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(s2))) {
+            f2 = (Map<Map<String, String>, Map<String, String>>) ois.readObject();
+        }
+
+        if (f1.size() != f2.size())
+            System.out.printf("Number of test cases differ: %d, %d%n", f1.size(), f2.size());
+
+        if (!f1.keySet().equals(f2.keySet())) {
+            System.out.printf("Test cases differ%n");
+            for (Map<String, String> k : f1.keySet()) {
+                if (!f2.containsKey(k))
+                    System.out.printf("Only in file 1: test case %s%n", k);
+            }
+            for (Map<String, String> k : f2.keySet()) {
+                if (!f1.containsKey(k))
+                    System.out.printf("Only in file 2: test case %s%n", k);
+            }
+        }
+
+        for (Map<String, String> k : f1.keySet()) {
+            if (!f2.keySet().contains(k))
+                continue;
+            Map<String, String> d1 = f1.get(k);
+            Map<String, String> d2 = f2.get(k);
+            if (!d1.equals(d2)) {
+                System.out.printf("Test case %s%n", k);
+                for (String s : d1.keySet())
+                    if (!d2.containsKey(s))
+                        System.out.printf("  Only in file 1: key %s%n", s);
+                    else {
+                        if (!d1.get(s).equals(d2.get(s))) {
+                            System.out.printf("  Key values differ for key %s: [%s] [%s]%n", s, d1.get(s), d2.get(s));
+                        }
+                    }
+                for (String s : d2.keySet())
+                    if (!d1.containsKey(s))
+                        System.out.printf("  Only in file 2: key %s%n", s);
+                System.out.println();
+            }
+        }
+    }
+
+    private static void dumpFile(String s) throws IOException, ClassNotFoundException {
+        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(s))) {
+            Map</* combo vars */ Map<String, String>,
+                /* data */ Map<String, String>> debugInfo;
+
+            debugInfo = (Map<Map<String, String>, Map<String, String>>) ois.readObject();
+            System.out.printf("%d test cases%n%n", debugInfo.size());
+            for (Map.Entry<Map<String, String>, Map<String, String>> e : debugInfo.entrySet()) {
+                System.out.println("Test case: " + e.getKey());
+                for (Map.Entry<String, String> de : new TreeMap<>(e.getValue()).entrySet())
+                    System.out.printf("  %s = %s%n", de.getKey(), de.getValue());
+                System.out.println();
+            }
+        }
+
+    }
+
+    public static void main(String[] args) throws IOException, ClassNotFoundException {
+        for (String a : args) {
+            if (a.equals("-c"))
+                compare = true;
+            else if (a.startsWith("-"))
+                usage();
+            else
+                files.add(a);
+        }
+
+        if (compare) {
+            if (files.size() != 2)
+                usage();
+            compareFiles(files.get(0), files.get(1));
+        }
+        else {
+            for (String f : files)
+                dumpFile(f);
+        }
+    }
+
+    public static void usage() {
+        System.out.println("Usage: ComboTestDebug [ -c ] files...");
+        System.exit(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/ComboTestMetadata.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * ComboTestMetadata
+ *
+ * @author Brian Goetz*/
+class ComboTestMetadata<T> {
+    public final Class<T> clazz;
+    public final Constructor<T> ctor;
+    public final List<TemplateMember<TemplateVar, Field>> templateFields = new ArrayList<>();
+    public final List<TemplateMember<TemplateVar, Method>> templateMethods = new ArrayList<>();
+    public final List<TemplateMember<SourceFile, Field>> sourceFields = new ArrayList<>();
+    public final List<TemplateMember<SourceFile, Method>> sourceMethods = new ArrayList<>();
+    public final Set<String> groups = new TreeSet<>();
+    public final Dimension[] dimensions;
+
+    public ComboTestMetadata(Class<T> clazz) throws ReflectiveOperationException {
+        this.clazz = clazz;
+        Constructor[] constructors = clazz.getConstructors();
+        ctor = (constructors.length == 1 && constructors[0].getParameterTypes().length > 0) ? constructors[0] : null;
+
+        Map<DimensionVar, Field> tmpDimFields = new LinkedHashMap<>();
+        for (Field f : clazz.getDeclaredFields()) {
+            TemplateVar template = f.getAnnotation(TemplateVar.class);
+            if (template != null) {
+                if (!Template.class.isAssignableFrom(f.getType()) && !String.class.isAssignableFrom(f.getType()))
+                    throw new AssertionError(String.format("Found @TemplateVar on field %s whose type is not Template or String", f));
+                f.setAccessible(true);
+                templateFields.add(new TemplateMember<>(template.value(), template, f));
+            }
+
+            SourceFile source = f.getAnnotation(SourceFile.class);
+            if (source != null) {
+                if (!Template.class.isAssignableFrom(f.getType()) && !String.class.isAssignableFrom(f.getType()))
+                    throw new AssertionError(String.format("Found @SourceFile on field %s whose type is not Template or String", f));
+                f.setAccessible(true);
+                sourceFields.add(new TemplateMember<>(source.value(), source, f));
+                groups.add(source.group());
+            }
+            
+            DimensionVar dim = f.getAnnotation(DimensionVar.class);
+            if (dim != null) 
+                tmpDimFields.put(dim, f);
+        }
+
+        for (Method m : clazz.getDeclaredMethods()) {
+            TemplateVar template = m.getAnnotation(TemplateVar.class);
+            if (template != null) {
+                if (!Template.class.isAssignableFrom(m.getReturnType()) && !String.class.isAssignableFrom(m.getReturnType()))
+                    throw new AssertionError(String.format("Found @TemplateVar on method %s whose return type is not Template or String", m));
+                m.setAccessible(true);
+                templateMethods.add(new TemplateMember<>(template.value(), template, m));
+            }
+
+            SourceFile source = m.getAnnotation(SourceFile.class);
+            if (source != null) {
+                if (!Template.class.isAssignableFrom(m.getReturnType()) && !String.class.isAssignableFrom(m.getReturnType()))
+                    throw new AssertionError(String.format("Found @SourceFile on method %s whose return type is not Template or String ", m));
+                sourceMethods.add(new TemplateMember<>(source.value(), source, m));
+                groups.add(source.group());
+            }
+        }
+
+        if (constructors.length > 1)
+            throw new AssertionError(String.format("Multiple constructors for class %s", clazz));
+        else if (ctor != null && !tmpDimFields.isEmpty())
+            throw new AssertionError(String.format("Class %s has both constructors and fields with @DimensionVar", clazz));
+        else if (constructors.length == 0 && tmpDimFields.isEmpty())
+            throw new AssertionError(String.format("Class %s has neither constructors nor fields with @DimensionVar", clazz));
+        else if (ctor != null) {
+            Class<?>[] argTypes = ctor.getParameterTypes();
+            Annotation[][] paramAnnotations = ctor.getParameterAnnotations();
+            dimensions = new Dimension[argTypes.length];
+            for (int i = 0, argTypesLength = argTypes.length; i < argTypesLength; i++) {
+                DimensionVar cd = null;
+                for (Annotation a : paramAnnotations[i])
+                    if (a instanceof DimensionVar) {
+                        cd = (DimensionVar) a;
+                        break;
+                    }
+                if (cd == null)
+                    throw new AssertionError(String.format("Parameter %d of constructor %s does not have @DimensionVar annotation", i, ctor));
+                dimensions[i] = new Dimension(cd, argTypes[i], String.format("Parameter %d of constructor %s", i, ctor));
+            }
+        }
+        else {
+            dimensions = new Dimension[tmpDimFields.size()];
+            int i = 0;
+            for (Map.Entry<DimensionVar, Field> e : tmpDimFields.entrySet())
+                dimensions[i++] = new Dimension(e.getKey(), e.getValue());
+        }
+    }
+
+    public T makeInstance(Object[] args) throws ReflectiveOperationException {
+        if (ctor != null)
+            return ctor.newInstance(args);
+        else {
+            T t = clazz.newInstance();
+            for (int i=0; i< dimensions.length; i++)
+                dimensions[i].field.set(t, args[i]);
+            return t;
+        }
+    }
+
+    public SyntheticLoop makeLoop() {
+        int n = dimensions.length;
+        Object[][] dimValues = new Object[n][];
+        for (int i=0; i<n; i++)
+            dimValues[i] = dimensions[i].values;
+        return new SyntheticLoop(dimValues);
+    }
+
+    static class Dimension {
+        public final Object[] values;
+        public final String name;
+        public final Field field;
+
+        public Dimension(DimensionVar dv, Field f) throws ReflectiveOperationException {
+            field = f;
+            field.setAccessible(true);
+            name = dv.value();
+            values = getValues(dv, f.getType(), String.format("Field %s", f.getName()));
+        }
+
+        public Dimension(DimensionVar dv, Class<?> paramType, String descr) throws ReflectiveOperationException {
+            field = null;
+            name = dv.value();
+            values = getValues(dv, paramType, descr);
+        }
+
+        private Object[] getValues(DimensionVar dv, Class<?> clazz, String descr) throws ReflectiveOperationException {
+            if (Enum.class.isAssignableFrom(clazz) && Template.class.isAssignableFrom(clazz)) {
+                Method m = clazz.getDeclaredMethod("values");
+                m.setAccessible(true);
+                return (Template[]) m.invoke(null);
+            }
+            else if (int.class.isAssignableFrom(clazz)) {
+                Object[] ts = new Object[dv.rangeUpper() - dv.rangeLower() + 1];
+                for (int i=dv.rangeLower(); i <= dv.rangeUpper(); i++)
+                    ts[i-dv.rangeLower()] = i;
+                return ts;
+            }
+            else
+                throw new AssertionError(String.format("Invalid type %s for %s", clazz.getName(), descr));
+        }
+    }
+
+    static class TemplateMember<A extends Annotation, M extends Member> {
+        public final String name;
+        public final A annotation;
+        public final M member;
+
+        TemplateMember(String name, A annotation, M member) {
+            this.name = name;
+            this.annotation = annotation;
+            this.member = member;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/Diagnostics.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.util.stream.Collectors.toList;
+
+/**
+* A container for compiler diagnostics, separated into errors and warnings,
+ * used by JavacTemplateTestBase.
+ *
+ * @author Brian Goetz
+*/
+public class Diagnostics implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+    protected List<Diagnostic<? extends JavaFileObject>> diags = new ArrayList<>();
+    protected boolean foundErrors = false;
+
+    public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+        diags.add(diagnostic);
+        foundErrors = foundErrors || diagnostic.getKind() == Diagnostic.Kind.ERROR;
+    }
+
+    /** Were there any errors found? */
+    public boolean errorsFound() {
+        return foundErrors;
+    }
+
+    /** Get all diagnostic keys */
+    public List<String> keys() {
+        return diags.stream()
+                    .map(Diagnostic::getCode)
+                    .collect(toList());
+    }
+
+    /** Do the diagnostics contain the specified error key? */
+    public boolean containsErrorKey(String key) {
+        return diags.stream()
+                    .filter(d -> d.getKind() == Diagnostic.Kind.ERROR)
+                    .anyMatch(d -> d.getCode().equals(key));
+    }
+
+    /** Get the error keys */
+    public List<String> errorKeys() {
+        return diags.stream()
+                    .filter(d -> d.getKind() == Diagnostic.Kind.ERROR)
+                    .map(Diagnostic::getCode)
+                    .collect(toList());
+    }
+
+    public String toString() { return keys().toString(); }
+
+    /** Clear all diagnostic state */
+    public void reset() {
+        diags.clear();
+        foundErrors = false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/DimensionVar.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+* DimensionVar
+*/
+@Retention(RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target({ElementType.PARAMETER, ElementType.FIELD})
+public @interface DimensionVar {
+    String value();
+    int rangeLower() default 0;
+    int rangeUpper() default 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/JavacTemplateTestBase.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.util.Pair;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.fail;
+
+/**
+ * Base class for template-driven TestNG javac tests that support on-the-fly
+ * source file generation, compilation, classloading, execution, and separate
+ * compilation.
+ *
+ * <p>Manages a set of templates (which have embedded tags of the form
+ * {@code #\{NAME\}}), source files (which are also templates), and compile
+ * options.  Test cases can register templates and source files, cause them to
+ * be compiled, validate whether the set of diagnostic messages output by the
+ * compiler is correct, and optionally load and run the compiled classes.
+ *
+ * @author Brian Goetz
+ */
+@Test
+public abstract class JavacTemplateTestBase {
+    private static final Set<String> suiteErrors = Collections.synchronizedSet(new HashSet<>());
+    private static final AtomicInteger counter = new AtomicInteger();
+    private static final File root = new File(System.getProperty("user.dir"), "gen");
+    private static final File nullDir = new File(System.getProperty("user.dir"), "empty");
+
+    protected final Map<String, Template> templates = new HashMap<>();
+    protected final Diagnostics diags = new Diagnostics();
+    protected final List<Pair<String, Template>> sourceFiles = new ArrayList<>();
+    protected final List<String> compileOptions = new ArrayList<>();
+    protected final List<File> classpaths = new ArrayList<>();
+    protected final Template.Resolver defaultResolver = new MapResolver(templates);
+
+    private Template.Resolver currentResolver = defaultResolver;
+
+    /** Add a template with a specified name */
+    protected void addTemplate(String name, Template t) {
+        templates.put(name, t);
+    }
+
+    /** Add a template with a specified name */
+    protected void addTemplate(String name, String s) {
+        templates.put(name, new StringTemplate(s));
+    }
+
+    /** Add a source file */
+    protected void addSourceFile(String name, Template t) {
+        sourceFiles.add(new Pair<>(name, t));
+    }
+
+    /** Add a File to the class path to be used when loading classes; File values
+     * will generally be the result of a previous call to {@link #compile()}.
+     * This enables testing of separate compilation scenarios if the class path
+     * is set up properly.
+     */
+    protected void addClassPath(File path) {
+        classpaths.add(path);
+    }
+
+    /**
+     * Add a set of compilation command-line options
+     */
+    protected void addCompileOptions(String... opts) {
+        Collections.addAll(compileOptions, opts);
+    }
+
+    /** Reset the compile options to the default (empty) value */
+    protected void resetCompileOptions() { compileOptions.clear(); }
+
+    /** Remove all templates */
+    protected void resetTemplates() { templates.clear(); }
+
+    /** Remove accumulated diagnostics */
+    protected void resetDiagnostics() { diags.reset(); }
+
+    /** Remove all source files */
+    protected void resetSourceFiles() { sourceFiles.clear(); }
+
+    /** Remove registered class paths */
+    protected void resetClassPaths() { classpaths.clear(); }
+
+    // Before each test method, reset everything
+    @BeforeMethod
+    public void reset() {
+        resetCompileOptions();
+        resetDiagnostics();
+        resetSourceFiles();
+        resetTemplates();
+        resetClassPaths();
+    }
+
+    // After each test method, if the test failed, capture source files and diagnostics and put them in the log
+    @AfterMethod
+    public void copyErrors(ITestResult result) {
+        if (!result.isSuccess()) {
+            suiteErrors.addAll(diags.errorKeys());
+
+            List<Object> list = new ArrayList<>();
+            Collections.addAll(list, result.getParameters());
+            list.add("Test case: " + getTestCaseDescription());
+            for (Pair<String, Template> e : sourceFiles)
+                list.add("Source file " + e.fst + ": " + e.snd);
+            if (diags.errorsFound())
+                list.add("Compile diagnostics: " + diags.toString());
+            result.setParameters(list.toArray(new Object[list.size()]));
+        }
+    }
+
+    @AfterSuite
+    // After the suite is done, dump any errors to output
+    public void dumpErrors() {
+        if (!suiteErrors.isEmpty())
+            System.err.println("Errors found in test suite: " + suiteErrors);
+    }
+
+    /**
+     * Get a description of this test case; since test cases may be combinatorially
+     * generated, this should include all information needed to describe the test case
+     */
+    protected String getTestCaseDescription() {
+        return this.toString();
+    }
+
+    /** Assert that all previous calls to compile() succeeded */
+    protected void assertCompileSucceeded() {
+        if (diags.errorsFound())
+            fail("Expected successful compilation");
+    }
+
+    /**
+     * If the provided boolean is true, assert all previous compiles succeeded,
+     * otherwise assert that a compile failed.
+     * */
+    protected void assertCompileSucceededIff(boolean b) {
+        if (b)
+            assertCompileSucceeded();
+        else
+            assertCompileFailed();
+    }
+
+    /** Assert that a previous call to compile() failed */
+    protected void assertCompileFailed() {
+        if (!diags.errorsFound())
+            fail("Expected failed compilation");
+    }
+
+    /** Assert that a previous call to compile() failed with a specific error key */
+    protected void assertCompileFailed(String message) {
+        if (!diags.errorsFound())
+            fail("Expected failed compilation: " + message);
+    }
+
+    /** Assert that a previous call to compile() failed with all of the specified error keys */
+    protected void assertCompileErrors(String... keys) {
+        if (!diags.errorsFound())
+            fail("Expected failed compilation");
+        for (String k : keys)
+            if (!diags.containsErrorKey(k))
+                fail("Expected compilation error " + k);
+    }
+
+    /** Convert an object, which may be a Template or a String, into a Template */
+    protected Template asTemplate(Object o) {
+        if (o instanceof Template)
+            return (Template) o;
+        else if (o instanceof String)
+            return new StringTemplate((String) o);
+        else
+            return new StringTemplate(o.toString());
+    }
+
+    /** Compile all registered source files */
+    protected void compile() throws IOException {
+        compile(false);
+    }
+
+    /** Compile all registered source files, optionally generating class files
+     * and returning a File describing the directory to which they were written */
+    protected File compile(boolean generate) throws IOException {
+        List<JavaFileObject> files = new ArrayList<>();
+        for (Pair<String, Template> e : sourceFiles)
+            files.add(new FileAdapter(e.fst, asTemplate(e.snd)));
+        return compile(classpaths, files, generate);
+    }
+
+    /** Compile all registered source files, using the provided list of class paths
+     * for finding required classfiles, optionally generating class files
+     * and returning a File describing the directory to which they were written */
+    protected File compile(List<File> classpaths, boolean generate) throws IOException {
+        List<JavaFileObject> files = new ArrayList<>();
+        for (Pair<String, Template> e : sourceFiles)
+            files.add(new FileAdapter(e.fst, asTemplate(e.snd)));
+        return compile(classpaths, files, generate);
+    }
+
+    private File compile(List<File> classpaths, List<JavaFileObject> files, boolean generate) throws IOException {
+        JavaCompiler systemJavaCompiler = ToolProvider.getSystemJavaCompiler();
+        StandardJavaFileManager fm = systemJavaCompiler.getStandardFileManager(null, null, null);
+        if (classpaths.size() > 0)
+            fm.setLocation(StandardLocation.CLASS_PATH, classpaths);
+        JavacTask ct = (JavacTask) systemJavaCompiler.getTask(null, fm, diags, compileOptions, null, files);
+        if (generate) {
+            File destDir = new File(root, Integer.toString(counter.incrementAndGet()));
+            // @@@ Assert that this directory didn't exist, or start counter at max+1
+            destDir.mkdirs();
+            fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir));
+            ct.generate();
+            return destDir;
+        }
+        else {
+            ct.analyze();
+            return nullDir;
+        }
+    }
+
+    /** Load the given class using the provided list of class paths */
+    protected Class<?> loadClass(String className, File... destDirs) {
+        try {
+            List<URL> list = new ArrayList<>();
+            for (File f : destDirs)
+                list.add(new URL("file:" + f.toString().replace("\\", "/") + "/"));
+            return Class.forName(className, true, new URLClassLoader(list.toArray(new URL[list.size()])));
+        } catch (ClassNotFoundException | MalformedURLException e) {
+            throw new RuntimeException("Error loading class " + className, e);
+        }
+    }
+
+    /** An implementation of Template which is backed by a String */
+    protected class StringTemplate implements Template {
+        protected final String template;
+
+        public StringTemplate(String template) {
+            this.template = template;
+        }
+
+        public String expand(String selector) {
+            return Behavior.expandTemplate(template, currentResolver);
+        }
+
+        public String toString() {
+            return expand("");
+        }
+
+        public StringTemplate with(final String key, final String value) {
+            return new StringTemplateWithResolver(template, new KeyResolver(key, value));
+        }
+
+    }
+
+    /** An implementation of Template which is backed by a String and which
+     * encapsulates a Resolver for resolving embedded tags. */
+    protected class StringTemplateWithResolver extends StringTemplate {
+        private final Resolver localResolver;
+
+        public StringTemplateWithResolver(String template, Resolver localResolver) {
+            super(template);
+            this.localResolver = localResolver;
+        }
+
+        @Override
+        public String expand(String selector) {
+            Resolver saved = currentResolver;
+            currentResolver = new ChainedResolver(currentResolver, localResolver);
+            try {
+                return super.expand(selector);
+            }
+            finally {
+                currentResolver = saved;
+            }
+        }
+
+        @Override
+        public StringTemplate with(String key, String value) {
+            return new StringTemplateWithResolver(template, new ChainedResolver(localResolver, new KeyResolver(key, value)));
+        }
+    }
+
+    /** A Resolver which uses a Map to resolve tags */
+    private class KeyResolver implements Template.Resolver {
+        private final String key;
+        private final String value;
+
+        public KeyResolver(String key, String value) {
+            this.key = key;
+            this.value = value;
+        }
+
+        @Override
+        public Template lookup(String k) {
+            return key.equals(k) ? new StringTemplate(value) : null;
+        }
+    }
+
+    private class FileAdapter extends SimpleJavaFileObject {
+        private final String filename;
+        private final Template template;
+
+        public FileAdapter(String filename, Template template) {
+            super(URI.create("myfo:/" + filename), Kind.SOURCE);
+            this.template = template;
+            this.filename = filename;
+        }
+
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return toString();
+        }
+
+        public String toString() {
+            return Template.Behavior.expandTemplate(template.expand(filename), defaultResolver);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/SeparateCompilationComboTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import org.testng.annotations.Factory;
+
+import java.lang.reflect.Method;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * SeparateCompilationComboTest
+ */
+public class SeparateCompilationComboTest extends ComboTestBase<SeparateCompilationComboTest> {
+    @Factory
+    public static Object[] testCombo() throws Exception {
+        return factory(SeparateCompilationComboTest.class);
+    }
+
+    @DimensionVar("FOO") Dummy dummy;
+
+    @SourceFile(value="Main.java", group="B") String a2 = "public class Main { public String main() { return Other.b(); } }";
+    @SourceFile(value="Other.java", group="B") String b2 = "public class Other { public static String b() { return \"1\"; } }";
+    @SourceFile(value="Other.java", group="A") String b1 = "public class Other { public static String b() { return \"2\"; } }";
+
+    @Override
+    protected boolean shouldRun() {
+        return true;
+    }
+
+    @Override
+    protected void run(Class<?> clazz) throws ReflectiveOperationException {
+        Object obj = clazz.newInstance();
+        Method m = clazz.getMethod("main");
+        String result = (String) m.invoke(obj);
+        assertEquals("2", result);
+    }
+
+    static enum Dummy implements Template {
+        A();
+
+        public String expand(String selector) { return toString(); }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/SeparateCompilationComboTest2.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import org.testng.annotations.Factory;
+
+import java.lang.reflect.Method;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * SeparateCompilationComboTest2
+ */
+public class SeparateCompilationComboTest2 extends ComboTestBase<SeparateCompilationComboTest2> {
+    @Factory
+    public static Object[] testCombo() throws Exception {
+        return factory(SeparateCompilationComboTest2.class);
+    }
+
+    @DimensionVar("FOO") Dummy dummy;
+
+    @SourceFile(value="Main.java", group="A" )
+    String main = "public class Main { public String main() { return new B().x(); } }";
+    @SourceFile(value="B.java", group="B" )
+    String b = "public class B extends C { public String x() { return \"2\"; } }";
+    @SourceFile(value="C.java", group="C" )
+    String c = "public class C { public String x() { return \"1\"; } }";
+
+    @Override
+    protected boolean shouldRun() {
+        return true;
+    }
+
+    @Override
+    protected void run(Class<?> clazz) throws ReflectiveOperationException {
+        Object obj = clazz.newInstance();
+        Method m = clazz.getMethod("main");
+        String result = (String) m.invoke(obj);
+        assertEquals("2", result);
+    }
+
+    static enum Dummy implements Template {
+        A();
+
+        public String expand(String selector) { return toString(); }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/SeparateCompilationTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * SeparateCompilationTest -- test of test framework to do separate compilation
+ */
+@Test
+public class SeparateCompilationTest extends JavacTemplateTestBase {
+
+    public void testCompletelySeparate() throws ReflectiveOperationException, IOException {
+        addSourceFile("A.java", new StringTemplate("public class A { public String a() throws Throwable { return Class.forName(\"B\").getName(); } }"));
+        File aFile = compile(true);
+        assertCompileSucceeded();
+        reset();
+
+        addSourceFile("B.java", new StringTemplate("public class B {  }"));
+        File bFile = compile(true);
+        assertCompileSucceeded();
+
+        Class clazz = loadClass("A", aFile, bFile);
+        Method m = clazz.getMethod("a");
+        Object instance = clazz.newInstance();
+        String x = (String) m.invoke(instance);
+        assertEquals("B", x);
+    }
+
+    public void testIdenticalRecompile() throws ReflectiveOperationException, IOException {
+        addSourceFile("A.java", new StringTemplate("public class A { public String a() { return B.b(); } }"));
+        addSourceFile("B.java", new StringTemplate("public class B { public static String b() { return \"1\"; } }"));
+        File aFile = compile(true);
+        assertCompileSucceeded();
+        // Deleting B.class is not generally needed for test cases that simply replace B, but here we're testing the framework's ability to find B elsewhere
+        File bClass = new File(aFile, "B.class");
+        assertTrue(bClass.exists());
+        boolean deleted = bClass.delete();
+        assertTrue(deleted);
+        reset();
+
+        addSourceFile("B.java", new StringTemplate("public class B { public static String b() { return \"1\"; } }"));
+        File bFile = compile(true);
+        assertCompileSucceeded();
+
+        Class clazz = loadClass("A", bFile, aFile);
+        Method m = clazz.getMethod("a");
+        Object instance = clazz.newInstance();
+        String x = (String) m.invoke(instance);
+        assertEquals("1", x);
+    }
+
+    public void testConsistentRecompile() throws ReflectiveOperationException, IOException {
+        addSourceFile("A.java", new StringTemplate("public class A { public String a() { return B.b(); } }"));
+        addSourceFile("B.java", new StringTemplate("public class B { public static String b() { return \"1\"; } }"));
+        File aFile = compile(true);
+        assertCompileSucceeded();
+        reset();
+
+        addSourceFile("B.java", new StringTemplate("public class B { public static String b() { return \"2\"; } }"));
+        File bFile = compile(true);
+        assertCompileSucceeded();
+
+        Class clazz = loadClass("A", bFile, aFile);
+        Method m = clazz.getMethod("a");
+        Object instance = clazz.newInstance();
+        String x = (String) m.invoke(instance);
+        assertEquals("2", x);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/SourceFile.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * SourceFile
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target({ElementType.METHOD, ElementType.FIELD})
+public @interface SourceFile {
+    String value();
+    String group() default "";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/StackProcessingUtils.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package tools.javac.combo;
+
+/**
+ * Utility class for defining stack processing-like operations
+ *
+ * @author Maurizio Cimadamore
+ */
+public class StackProcessingUtils {
+
+    /**
+     * interface representing a stack item - each item has an arity ---
+     * if arity is > 0 - then the item is an operator
+     */
+    public interface StackItem<T extends StackItem<T>> {
+        int arity();
+    }
+
+    /**
+     * A reducer takes an element of the stack and produces a result of a given
+     * type by applying the stack item to zero or more operands
+     */
+    public interface StackReducer<I extends StackItem<I>, T, O> {
+        T reduce(I item, T[] operands, O o);
+        Class<T> resultToken();
+        O reducerArg(I item, int i);
+    }
+
+    static class StackResult<T> {
+        T result;
+        int nextPos;
+
+        StackResult(T result, int nextPos) {
+            this.result = result;
+            this.nextPos = nextPos;
+        }
+    }
+
+    public static <I extends StackItem<I>, T, O> T process(I[] elems, StackReducer<I, T, O> reducer, O o) {
+        StackResult<T> result = processInternal(0, elems, reducer, o);
+        assert result.nextPos == elems.length;
+        return result.result;
+    }
+
+    private static <I extends StackItem<I>, T, O> StackResult<T> processInternal(int start, I[] elems, StackReducer<I, T, O> reducer, O o) {
+        @SuppressWarnings("unchecked")
+        I head = elems[start];
+        T[] operands = (T[])java.lang.reflect.Array.newInstance(reducer.resultToken(), head.arity());
+        int nextPos = start + 1;
+        for (int i = 0 ; i < head.arity() ; i++) {
+            StackResult<T> partialResult = processInternal(nextPos, elems, reducer, reducer.reducerArg(head, i));
+            nextPos = partialResult.nextPos;
+            operands[i] = partialResult.result;
+        }
+        return new StackResult<T>(reducer.reduce(head, operands, o), nextPos);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/StringTemplateTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * StringTemplateTest
+ */
+@Test
+public class StringTemplateTest extends JavacTemplateTestBase {
+    private void assertTemplate(String expected, Template template) {
+        String result = template.expand("");
+        assertEquals(result, expected, "for " + template);
+    }
+
+    public void testStringTemplate() {
+        assertTemplate("XYZ", new StringTemplate("XYZ"));
+        addTemplate("NONE", "SOME");
+        assertTemplate("SOME", new StringTemplate("#{NONE}"));
+
+        addTemplate("A", "#{B}");
+        addTemplate("B", "C");
+        assertTemplate("C", new StringTemplate("#{A}"));
+    }
+
+    public void testChainedTemplate() {
+        assertTemplate("A", new StringTemplate("#{A}").with("A", "A"));
+        assertTemplate("AB", new StringTemplate("#{A}#{B}").with("A", "A").with("B", "B"));
+        assertTemplate("TWO", new StringTemplate("#{A}").with("A", "ONE").with("A", "TWO"));
+        addTemplate("A", "BASE_A");
+        addTemplate("AA", "#{A}");
+        assertTemplate("FAKE_A", new StringTemplate("#{A}").with("A", "FAKE_A"));
+        assertTemplate("BASE_A", new StringTemplate("#{AA}"));
+        assertTemplate("FAKE_A", new StringTemplate("#{AA}").with("A", "FAKE_A"));
+
+        addTemplate("X", new StringTemplate("#{A}").with("A", "intercepted"));
+        assertTemplate("intercepted", new StringTemplate("#{B}").with("B", "#{X}"));
+        addTemplate("Y", new StringTemplate("#{A}"));
+        assertTemplate("again", new StringTemplate("#{B}").with("B", "#{Y}").with("A", "again"));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/SyntheticLoop.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import java.util.Iterator;
+
+/**
+ * SyntheticLoop -- exhaustively generate a set of combinations of variables
+ *
+ * @author Brian Goetz
+ */
+public class SyntheticLoop implements Iterable<Object[]> {
+    final int dimensions;
+    final int[] maxs;
+    final Object[][] values;
+
+    /** Simple version -- generate the cartesian product of the provided sets of axis values */
+    public SyntheticLoop(Object[][] dimValues) {
+        dimensions = dimValues.length;
+        maxs = new int[dimensions];
+        values = new Object[dimensions][];
+        for (int i=0; i<dimensions; i++) {
+            values[i] = dimValues[i];
+            maxs[i] = values[i].length;
+        }
+    }
+
+//    /** Complex version -- allow the contents of some dimensions to depend on previous dimensions, such
+//     * as generating tuples (a,b) where foo(b) <= foo(a).  Of the two arrays provided, for each index i,
+//     * exactly one of dimValues[i], dimGenerators[i] must be non-null.
+//     */
+//    public SyntheticLoop(Object[][] dimValues, DimensionFactory[] dimGenerators) {
+//        @@@NYI
+//    }
+
+    public Iterator<Object[]> iterator() {
+        return new Iterator<Object[]>() {
+            final int[] idxs = new int[dimensions];
+            boolean hasNext = (dimensions > 0);
+
+            public boolean hasNext() {
+                return hasNext;
+            }
+
+            public Object[] next() {
+                Object[] ret = new Object[dimensions];
+                for (int i=0; i<dimensions; i++)
+                    ret[i] = values[i][idxs[i]];
+                hasNext = !advance(dimensions-1);
+                return ret;
+            }
+
+            public void remove() { throw new UnsupportedOperationException(); }
+
+            private boolean advance(int i) {
+                if (i < 0)
+                    return true;
+                if (++idxs[i] == maxs[i]) {
+                    idxs[i] = 0;
+                    return advance(i - 1);
+                }
+                return false;
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/SyntheticLoopTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import org.testng.annotations.Test;
+
+import java.util.Iterator;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * SyntheticLoopTest
+ */
+@Test
+public class SyntheticLoopTest {
+    public void testEmpty() {
+        SyntheticLoop sl = new SyntheticLoop(new Object[0][]);
+        Iterator<Object[]> it = sl.iterator();
+        assertTrue(!it.hasNext());
+    }
+
+    private void assertSL(String expected, SyntheticLoop sl) {
+        StringBuilder sb = new StringBuilder();
+        for (Object[] row : sl) {
+            for (Object o : row) {
+                sb.append(o);
+            }
+            sb.append(" ");
+        }
+        assertEquals(sb.toString(), expected);
+    }
+
+    private void assertSL(int size, SyntheticLoop sl) {
+        int count = 0;
+        for (Object row : sl) {
+            ++count;
+        }
+        assertEquals(count, size);
+    }
+
+    public void testSimple() {
+        Object[] abc = {"A", "B", "C"};
+        assertSL("A B C ", new SyntheticLoop(new Object[][] {abc}));
+        assertSL("AA AB AC BA BB BC CA CB CC ", new SyntheticLoop(new Object[][] {abc, abc}));
+        assertSL(9, new SyntheticLoop(new Object[][] {abc, abc}));
+        assertSL(9, new SyntheticLoop(new Object[][] {abc, abc, new Object[] { "X" }}));
+        assertSL(27, new SyntheticLoop(new Object[][] {abc, abc, abc}));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/Template.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A template into which tags of the form {@code #\{KEY\}} or
+ * {@code #\{KEY.SUBKEY\}} can be expanded.
+ */
+public interface Template {
+    String expand(String selector);
+
+    interface Resolver {
+        public Template lookup(String key);
+    }
+
+    public static class Behavior {
+        /* Looks for expandable keys.  An expandable key can take the form:
+         *   #{MAJOR}
+         *   #{MAJOR.MINOR}
+         *   where MAJOR can be IDENTIFIER or IDENTIFIER[NUMERIC_INDEX]
+         *   and MINOR can be an identifier
+         */
+        private static final Pattern pattern = Pattern.compile("#\\{([A-Z_][A-Z0-9_]*(?:\\[\\d+\\])?)(?:\\.([A-Z0-9_]*))?\\}");
+
+        public static String expandTemplate(String template, final Map<String, Template> vars) {
+            return expandTemplate(template, new MapResolver(vars));
+        }
+
+        public static String expandTemplate(String template, Resolver res) {
+            CharSequence in = template;
+            StringBuffer out = new StringBuffer();
+            while (true) {
+                boolean more = false;
+                Matcher m = pattern.matcher(in);
+                while (m.find()) {
+                    String major = m.group(1);
+                    String minor = m.group(2);
+                    Template key = res.lookup(major);
+                    if (key == null)
+                        throw new IllegalStateException("Unknown major key " + major);
+
+                    String replacement = key.expand(minor == null ? "" : minor);
+                    more |= pattern.matcher(replacement).find();
+                    m.appendReplacement(out, replacement);
+                }
+                m.appendTail(out);
+                if (!more)
+                    return out.toString();
+                else {
+                    in = out;
+                    out = new StringBuffer();
+                }
+            }
+        }
+
+    }
+}
+
+class MapResolver implements Template.Resolver {
+    private final Map<String, Template> vars;
+
+    public MapResolver(Map<String, Template> vars) {this.vars = vars;}
+
+    public Template lookup(String key) {
+        return vars.get(key);
+    }
+}
+
+class ChainedResolver implements Template.Resolver {
+    private final Template.Resolver upstreamResolver, thisResolver;
+
+    public ChainedResolver(Template.Resolver upstreamResolver, Template.Resolver thisResolver) {
+        this.upstreamResolver = upstreamResolver;
+        this.thisResolver = thisResolver;
+    }
+
+    public Template.Resolver getUpstreamResolver() {
+        return upstreamResolver;
+    }
+
+    @Override
+    public Template lookup(String key) {
+        Template result = thisResolver.lookup(key);
+        if (result == null)
+            result = upstreamResolver.lookup(key);
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/TemplateTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * TemplateTest
+ */
+@Test
+public class TemplateTest {
+    Map<String, Template> vars = new HashMap<>();
+
+    @BeforeTest
+    void before() { vars.clear(); }
+
+    private void assertTemplate(String expected, String template) {
+        String result = Template.Behavior.expandTemplate(template, vars);
+        assertEquals(result, expected, "for " + template);
+    }
+
+    private String dotIf(String s) {
+        return s == null || s.isEmpty() ? "" : "." + s;
+    }
+
+    public void testTemplateExpansion() {
+        vars.put("A", s -> "a" + dotIf(s));
+        vars.put("B", s -> "b" + dotIf(s));
+        vars.put("C", s -> "#{A}#{B}");
+        vars.put("D", s -> "#{A" + dotIf(s) + "}#{B" + dotIf(s) + "}");
+        vars.put("_D", s -> "d");
+
+        assertTemplate("", "");
+        assertTemplate("foo", "foo");
+        assertTemplate("a", "#{A}");
+        assertTemplate("a", "#{A.}");
+        assertTemplate("a.FOO", "#{A.FOO}");
+        assertTemplate("aa", "#{A}#{A}");
+        assertTemplate("ab", "#{C}");
+        assertTemplate("ab", "#{C.FOO}");
+        assertTemplate("ab", "#{C.}");
+        assertTemplate("a.FOOb.FOO", "#{D.FOO}");
+        assertTemplate("ab", "#{D}");
+        assertTemplate("d", "#{_D}");
+        assertTemplate("#{A", "#{A");
+    }
+
+    public void testIndexedTemplate() {
+        vars.put("A[0]", s -> "a" );
+        vars.put("A[1]", s -> "b" );
+        vars.put("A[2]", s -> "c" );
+        vars.put("X", s -> "0");
+        assertTemplate("a", "#{A[0]}");
+        assertTemplate("b", "#{A[1]}");
+        assertTemplate("c", "#{A[2]}");
+    }
+
+    public void testAngleBrackets() {
+        vars.put("X", s -> "xyz");
+        assertTemplate("List<String> ls = xyz;", "List<String> ls = #{X};");
+    }
+
+    @Test(expectedExceptions = IllegalStateException.class )
+    public void testUnknownKey() {
+        assertTemplate("#{Q}", "#{Q}");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/combo/TemplateVar.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.combo;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * ComboTemplate
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@java.lang.annotation.Target({ElementType.METHOD, ElementType.FIELD})
+public @interface TemplateVar {
+    String value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/lambda/ConditionalExpressionTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.lambda;
+
+import org.testng.annotations.Factory;
+import tools.javac.combo.ComboTestBase;
+import tools.javac.combo.DimensionVar;
+import tools.javac.combo.SourceFile;
+import tools.javac.combo.Template;
+import tools.javac.combo.TemplateVar;
+
+/**
+ * ConditionalExpressionTest
+ */
+public class ConditionalExpressionTest extends ComboTestBase<ConditionalExpressionTest> {
+    @Factory
+    public static Object[] testConditionalExpression() throws Exception {
+        return factory(ConditionalExpressionTest.class);
+    }
+
+    @DimensionVar("TYPE1") Type type1;
+    @DimensionVar("TYPE2") Type type2;
+    @DimensionVar("TARGET") Type target;
+    @DimensionVar("STMT") Statement stmt;
+
+    @SourceFile("Main.java")
+    String clientFile = "public class Main {\n"
+            + " #{STMT_DECL};\n"
+            + " #{DECL.1};\n"
+            + " #{DECL.2};\n"  
+            + " void test(boolean cond) { \n"
+            + "   #{STMT};"
+            + " }\n"
+            +"}";
+
+    @Override
+    protected void postCompile(String grp) {
+        CondResult res = Type.condType(type1, type2);
+        if (!res.check(type1, type2, target)) {
+            assertCompileFailed();
+        } else {
+            assertCompileSucceeded();
+        }
+    }
+
+    @Override
+    protected boolean shouldSkip() {
+        return target == Type.INT_CONST;
+    }
+
+    interface CondResult {
+        boolean check(Type op1, Type op2, Type target);
+    }
+
+    static CondResult ERR = new CondResult() {
+        public boolean check(Type op1, Type op2, Type target) { return false; }
+    };
+
+    static CondResult TARGET = new CondResult() {
+        public boolean check(Type op1, Type op2, Type target) {
+           return op1.compatibleWith(target) && op2.compatibleWith(target);
+        }
+    };
+
+    enum TypeKind {
+        NUMERIC,
+        BOOLEAN,
+        OTHER;
+    }
+
+    enum Type implements Template, CondResult {
+        BYTE("byte", "0", TypeKind.NUMERIC),
+        SHORT("short", "0", TypeKind.NUMERIC),
+        INT("int", "0", TypeKind.NUMERIC),
+        INT_CONST("int", "0", TypeKind.NUMERIC),
+        LONG("long", "0", TypeKind.NUMERIC),
+        FLOAT("float", "0", TypeKind.NUMERIC),
+        DOUBLE("double", "0", TypeKind.NUMERIC),
+        CHAR("char", "'0'", TypeKind.NUMERIC),
+        BOOLEAN("boolean", "false", TypeKind.BOOLEAN),
+        J_L_BYTE("Byte", "null", TypeKind.NUMERIC),
+        J_L_SHORT("Short", "null", TypeKind.NUMERIC),
+        J_L_INT("Integer", "null", TypeKind.NUMERIC),
+        J_L_LONG("Long", "null", TypeKind.NUMERIC),
+        J_L_FLOAT("Float", "null", TypeKind.NUMERIC),
+        J_L_DOUBLE("Double", "null", TypeKind.NUMERIC),
+        J_L_CHAR("Character", "null", TypeKind.NUMERIC),
+        J_L_BOOLEAN("Boolean", "null", TypeKind.BOOLEAN),
+        NUMBER("Number", "null", TypeKind.OTHER),
+        SERIAL("java.io.Serializable", "null", TypeKind.OTHER);
+
+        public boolean check(Type op1, Type op2, Type target) {
+            return compatibleWith(target);
+        }
+
+        public boolean isErroneous() {
+            return false;
+        }
+
+        public String expand(String qualifier) {
+            return typeStr;
+        }
+
+        boolean compatibleWith(Type that) {
+            return that.anyOf(compatibleWith[this.ordinal()]);
+        }
+
+        boolean anyOf(Type... ts) {
+            for (Type t : ts) {
+                if (t == this) return true;
+            }
+            return false;
+        }
+
+        Type unbox() {
+            switch (this) {
+                case BYTE:
+                case J_L_BYTE: return BYTE;
+                case SHORT:
+                case J_L_SHORT: return SHORT;
+                case INT:
+                case INT_CONST:
+                case J_L_INT: return INT;
+                case LONG:
+                case J_L_LONG: return LONG;
+                case FLOAT:
+                case J_L_FLOAT: return FLOAT;
+                case DOUBLE:
+                case J_L_DOUBLE: return DOUBLE;
+                case BOOLEAN:
+                case J_L_BOOLEAN: return BOOLEAN;
+                case CHAR:
+                case J_L_CHAR: return CHAR;                
+                default:
+                    return null;
+            }
+        }
+
+        String typeStr;
+        String defaultVal;
+        TypeKind kind;
+
+        Type(String typeStr, String defaultVal, TypeKind kind) {
+            this.typeStr = typeStr;
+            this.defaultVal = defaultVal;
+            this.kind = kind;
+        }
+
+        static CondResult condType(Type type1, Type type2) {
+            if (type1.kind == TypeKind.BOOLEAN && type2.kind == TypeKind.BOOLEAN) {
+                //boolean conditional
+                return BOOLEAN;
+            } else if (type1.kind == TypeKind.NUMERIC && type2.kind == TypeKind.NUMERIC) {                    
+                //numeric conditional
+                Type unbox1 = type1.unbox();
+                Type unbox2 = type2.unbox();
+                if (type1 == INT_CONST &&     
+                        unbox2.anyOf(CHAR, BYTE, SHORT)) {
+                    return unbox2;
+                }
+                if (type2 == INT_CONST &&     
+                        unbox1.anyOf(CHAR, BYTE, SHORT)) {
+                    return unbox1;
+                }
+                if (unbox1 == unbox2) {
+                    return unbox1;
+                }
+                if (unbox1 == CHAR) {
+                    return condType(INT, unbox2);
+                }
+                if (unbox2 == CHAR) {
+                    return condType(unbox1, INT);
+                }
+                if (unbox1.compatibleWith(unbox2)) {
+                    return unbox2;
+                } else if (unbox2.compatibleWith(unbox1)) {
+                    return unbox1;
+                } else {
+                    return ERR;
+                }
+            } else {
+                //reference conditional
+                return TARGET;
+            }
+        }
+
+        static Type[][] compatibleWith = new Type[][] {
+        /* BYTE */        { BYTE, SHORT, INT, LONG, FLOAT, DOUBLE, J_L_BYTE, NUMBER, SERIAL },
+        /* SHORT */       { SHORT, INT, LONG, FLOAT, DOUBLE, J_L_SHORT, NUMBER, SERIAL },
+        /* INT */         { INT, LONG, FLOAT, DOUBLE, J_L_INT, NUMBER, SERIAL },
+        /* INT_CONST */   { INT, LONG, FLOAT, DOUBLE, J_L_INT, NUMBER, SERIAL },
+        /* LONG */        { LONG, FLOAT, DOUBLE, J_L_LONG, NUMBER, SERIAL },
+        /* FLOAT */       { FLOAT, DOUBLE, J_L_FLOAT, NUMBER, SERIAL },
+        /* DOUBLE */      { DOUBLE, J_L_DOUBLE, NUMBER, SERIAL },
+        /* CHAR */        { CHAR, INT, LONG, FLOAT, DOUBLE, J_L_CHAR, SERIAL },
+        /* BOOLEAN */     { BOOLEAN, J_L_BOOLEAN, SERIAL },
+        /* J_L_BYTE */    { J_L_BYTE, BYTE, SHORT, INT, LONG, FLOAT, DOUBLE, NUMBER, SERIAL },
+        /* J_L_SHORT */   { J_L_SHORT, SHORT, INT, LONG, FLOAT, DOUBLE, NUMBER, SERIAL },
+        /* J_L_INT */     { J_L_INT, INT, LONG, FLOAT, DOUBLE, NUMBER, SERIAL },
+        /* J_L_LONG */    { J_L_LONG, LONG, FLOAT, DOUBLE, NUMBER, SERIAL },
+        /* J_L_FLOAT */   { J_L_FLOAT, FLOAT, DOUBLE, NUMBER, SERIAL },
+        /* J_L_DOUBLE */  { J_L_DOUBLE, DOUBLE, NUMBER, SERIAL },
+        /* J_L_CHAR */    { J_L_CHAR, CHAR, INT, LONG, FLOAT, DOUBLE, SERIAL },
+        /* J_L_BOOLEAN */ { J_L_BOOLEAN, BOOLEAN, SERIAL },
+        /* NUMBER */      { NUMBER, SERIAL },
+        /* SERIAL */      { SERIAL } };
+    }
+
+    enum Statement implements Template {
+        ASSIGN("#{TARGET} t = cond ? #{EXPR.1} : #{EXPR.2}"),
+        METHOD("m(cond ? #{EXPR.1} : #{EXPR.2})");
+
+        String stmtStr;
+
+        Statement(String stmtStr) {
+            this.stmtStr = stmtStr;
+        }
+
+        public String expand(String qual) {
+            return stmtStr;
+        }
+    }
+
+    @TemplateVar("STMT_DECL")
+    Template stmt_decl = new Template() {
+        public String expand(String selector) {            
+            return stmt == Statement.ASSIGN ? "" : "void m(#{TARGET} arg) { }";
+        }
+    };
+
+    @TemplateVar("DECL")
+    Template decl = new Template() {
+        public String expand(String selector) {
+            int sel = Integer.valueOf(selector);
+            Type t = sel == 1 ? type1 : type2;
+            return t == Type.INT_CONST ? "" : String.format("#{TYPE%d} m%d() { return %s; }", sel, sel, t.defaultVal);
+        }
+    };
+
+    @TemplateVar("EXPR")
+    Template expr = new Template() {
+        public String expand(String selector) {
+            int sel = Integer.valueOf(selector);
+            Type t = sel == 1 ? type1 : type2;
+            return t == Type.INT_CONST ? t.defaultVal : String.format("m%d()", sel);
+        }
+    };
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/lambda/DefaultMethodAddTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.lambda;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.testng.annotations.Factory;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import tools.javac.combo.*;
+
+/**
+ * DefaultMethodAddTest: Test default method by running bytecode compiled at different times
+ *                       where conflicting default methods are added or declared
+ */
+public class DefaultMethodAddTest extends ComboTestBase<DefaultMethodAddTest> {
+    @Factory
+    public static Object[] testDefaultMethodAdd() throws Exception {
+        return factory(DefaultMethodAddTest.class);
+    }
+    
+    @DimensionVar("SHAPE") CShapes shapeType;
+    
+    /**
+     * The separate-compilation operation to be performed, such as adding a default method, 
+     * adding an abstract itnerface method, redeclaring an inherited default method as 
+     * abstract interface method, etc
+     */     
+    @DimensionVar("ADD") AddType addType;
+        
+    @SourceFile(value="B.java", group="A")
+    String interfaceBModified = "interface B #{SHAPE.B_DECL} { #{ADD} }";
+    
+    @SourceFile(value="B.java", group="B")
+    String interfaceB =         "interface B #{SHAPE.B_DECL} {}";
+    
+    @SourceFile(value="A.java", group="B")
+    String interfaceA =         "interface A { default String m() { return \"A\"; } }";
+    
+    @SourceFile(value="C.java", group="B")
+    String classC = "#{SHAPE.C}";
+    
+    @SourceFile(value="Main.java", group="B")
+    String classMain = "public class Main {\n" +
+                       "    public String main() {\n" +
+                       "        return new C().m();\n" +                       
+                       "    }\n" +
+                       "}";    
+
+    @Override
+    protected boolean shouldRun() { return true; }
+    
+    @Override
+    protected void run(Class<?> clazz) throws ReflectiveOperationException {
+        Method m = clazz.getMethod("main");
+        Object obj = clazz.newInstance();
+        String result = null, output = null;
+        try {
+            result = (String) m.invoke(obj);
+        } catch (InvocationTargetException ex) {
+            output = ex.getCause().toString();
+        }        
+        if(shapeType == CShapes.C_B_A) {
+            if(addType == AddType.ADD) {
+                assertEquals(output, null);
+                assertEquals(result, "B");
+            }
+            else //redeclare
+                assertEquals(output, "java.lang.AbstractMethodError: Method B.m()Ljava/lang/String; is abstract");
+        }
+        else if(shapeType == CShapes.C_I_AB2) {
+            assertEquals(output, null);
+            assertEquals(result, "A");
+        }
+        else if(shapeType == CShapes.C_CI) {
+            assertEquals(output, null);
+            assertEquals(result, "D");
+        }
+        else if(shapeType == CShapes.C_I_AB3) {
+            assertEquals(output, null);
+            assertEquals(result, "AB");
+        }
+        else            
+            assertTrue(output.matches("java.lang.AbstractMethodError: Conflicting default methods: .+[.]m .+[.]m"));        
+    }
+    
+    enum CShapes implements Template { //shapes of class hirarchy
+        //class C implements interface A, B
+        C_AB("",            
+           "class C implements A, B {}"), 
+        //class C implments interface B, B extends interface A
+        C_B_A("extends A", 
+           "class C implements B {}"),
+        //class C implments interface AB, AB extends interface A, B
+        C_I_AB("", 
+           "interface AB extends A, B {  }\n" + 
+           "class C implements AB {}"),
+        //class C implments interface AB, AB extends interface A, B and explicitly inherits the default method in A
+        C_I_AB2("", 
+        "interface AB extends A, B { default String m() { return A.super.m(); } }\n" + 
+        "class C implements AB {}"),
+        //class C implments interface AB, AB extends interface A, B and overrides the default method inherited
+        C_I_AB3("", 
+        "interface AB extends A, B { default String m() { return \"AB\"; } }\n" + 
+        "class C implements AB {}"),
+        //class C extends Class D implements Interface B
+        C_CI("", 
+            "class D { public String m() { return \"D\"; } }\n" + 
+            "class C extends D implements B {}");
+        
+        private final String sB_DECL;
+        private final String sC;
+        
+        CShapes(String sB_DECL, String sC) {
+            this.sB_DECL = sB_DECL;
+            this.sC = sC;
+        }
+        
+        public String expand(String selector) {
+            switch(selector) {
+                case "B_DECL": return sB_DECL;
+                case "C": return sC;
+                default: return toString();
+            }            
+        }        
+    }
+    
+    enum AddType implements Template { // add by adding default method or abstract interface method
+        ADD("default String m() { return \"B\"; }"),
+        REDECLARE("String m();");
+        
+        final String newCode;
+        
+        AddType(String str) {
+            newCode = str;
+        }
+        
+        public String expand(String selector) {
+            return newCode;        
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/lambda/DefaultMethodRemoveTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.lambda;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.testng.annotations.Factory;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import tools.javac.combo.*;
+
+/**
+ * DefaultMethodRemoveTest: Test default method by running bytecode compiled at different times
+ *                          where default methods are removed or redeclared
+ */
+public class DefaultMethodRemoveTest extends ComboTestBase<DefaultMethodRemoveTest> {
+    @Factory
+    public static Object[] testDefalutMethodRemove() throws Exception {
+        return factory(DefaultMethodRemoveTest.class);
+    }
+    
+    @DimensionVar("SHAPE") CShapes shapeType;
+    
+    /**
+     * The separate-compilation operation to be performed, such as removing a default method, 
+     * redeclaring as abstract interface method, etc
+     */  
+    @DimensionVar("REMOVE") RemoveType removeType;
+    
+    @SourceFile(value="B.java", group="A")
+    String interfaceBModified = "interface B #{SHAPE.B_DECL} { #{REMOVE} }";
+      
+    @SourceFile(value="A.java", group="B")
+    String interfaceA = "interface A { default String m() { return \"A\"; } }";
+    
+    @SourceFile(value="B.java", group="B")
+    String interfaceB = "interface B #{SHAPE.B_DECL} { default String m() { return \"B\"; } }";
+        
+    @SourceFile(value="C.java", group="B")
+    String classC = "#{SHAPE.C}";
+    
+    @SourceFile(value="Main.java", group="B")
+    String classMain = "public class Main {\n" +
+                       "    public String main() {\n" +
+                       "        return new C().m();\n" +                       
+                       "    }\n" +
+                       "}";    
+
+    @Override
+    protected boolean shouldRun() { return true; }
+    
+    @Override
+    protected void postCompile(String group) {
+        if( group.equals("A") && shapeType == CShapes.C_B_AD && removeType == RemoveType.REMOVE )
+            assertCompileErrors("compiler.err.types.incompatible.unrelated.defaults");
+    }
+
+    @Override
+    protected void run(Class<?> clazz) throws ReflectiveOperationException {
+        Method m = clazz.getMethod("main");
+        Object obj = clazz.newInstance();
+        String result = null, output = null;
+        try {
+            result = (String) m.invoke(obj);
+        } catch (InvocationTargetException ex) {
+            output = ex.getCause().toString();            
+        }
+        if(shapeType == CShapes.C_B_A) {
+            if(removeType == RemoveType.REMOVE)
+                assertEquals(result, "A");
+            else
+                assertEquals(output, "java.lang.AbstractMethodError: Method B.m()Ljava/lang/String; is abstract");
+        }
+        else if(shapeType == CShapes.C_CI)
+            assertEquals(result, "D");
+        else if(shapeType == CShapes.C_B_AD) {
+            if(removeType == RemoveType.REMOVE)
+                assertEquals(output, "java.lang.AbstractMethodError: C.m()Ljava/lang/String;");
+            else    
+                assertEquals(output, "java.lang.AbstractMethodError: Method B.m()Ljava/lang/String; is abstract");
+        }
+        else { //C_B
+            if( removeType == RemoveType.REMOVE)
+                assertEquals(output, "java.lang.NoSuchMethodError: C.m()Ljava/lang/String;");
+            else
+                assertEquals(output, "java.lang.AbstractMethodError: C.m()Ljava/lang/String;");
+        }
+    }
+    
+    enum CShapes implements Template { //shapes of class hirarchy
+        //class C implements interface B
+        C_B("", 
+            "class C implements B {}"), 
+        //class C implments interface B, B extends interface A
+        C_B_A("extends A", 
+              "class C implements B {}"),
+        //class C implments interface B, B extends interface A, D
+        C_B_AD("extends A, D", 
+               "interface D { default String m() { return \"D\"; } }\n" + 
+               "class C implements B {}"),
+        //class C extends Class D implements Interface B
+        C_CI("", 
+             "class D { public String m() { return \"D\"; } }\n" + 
+             "class C extends D implements B {}");
+        
+        private final String sB_DECL;
+        private final String sC;
+        
+        CShapes(String sB_DECL, String sC) {
+            this.sB_DECL = sB_DECL;
+            this.sC = sC;            
+        }
+        
+        public String expand(String selector) {
+            switch(selector) {
+                case "B_DECL": return sB_DECL;
+                case "C": return sC;                
+                default: return toString();
+            }
+        }        
+    }
+    
+    enum RemoveType implements Template { //remove by removing default method code or redeclaring the interface method
+        REMOVE(""),
+        REDECLARE("String m();");
+        
+        final String newCode;
+        
+        RemoveType(String str) {
+            newCode = str;
+        }
+        
+        public String expand(String selector) {
+            return newCode;        
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/lambda/LambdaArgAdaptationTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.lambda;
+
+import org.testng.annotations.Factory;
+import tools.javac.combo.ComboTestBase;
+import tools.javac.combo.DimensionVar;
+import tools.javac.combo.SourceFile;
+import tools.javac.combo.Template;
+
+import java.lang.reflect.Method;
+import java.util.EnumMap;
+import java.util.EnumSet;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * LambdaArgAdaptationTest
+ */
+public class LambdaArgAdaptationTest extends ComboTestBase<LambdaArgAdaptationTest> {
+    @Factory
+    public static Object[] testArgAdaptation() throws Exception {
+        return factory(LambdaArgAdaptationTest.class);
+    }
+
+    @DimensionVar("FROM") Types fromType;
+    @DimensionVar("TO") Types toType;
+
+    @SourceFile("Sam.java")
+    String samFile = "public interface Sam { String m(#{FROM} arg); }";
+
+    @SourceFile("Main.java")
+    String clientFile = "public class Main {\n"
+                        +"  static String m(#{TO} arg) { \n"
+                        +"    return String.valueOf(arg);\n"
+                        +"  }\n"
+                        +"  public String main() { \n"
+                        + "   Sam s = Main::m;\n"
+                        + "   return s.m(#{FROM.ARG});\n"
+                        + " }\n"
+                        +"}";
+
+
+    @Override
+    protected String[] getCompileOptions(String group) {
+        return new String[] { "-XDlambdaToMethod" };
+    }
+
+    @Override
+    protected void postCompile(String group) {
+        if (fromType == Types.VOID || toType == Types.VOID)
+            assertCompileFailed();
+        else if (fromType.pr == PR.REF && toType.pr == PR.REF)
+            assertCompileSucceededIff(toType.clazz.isAssignableFrom(fromType.clazz));
+        else if (fromType.pr == PR.PRIM && toType.pr == PR.REF)
+            assertCompileSucceededIff(toType.clazz.isAssignableFrom(Types.boxMap.get(fromType).clazz));
+        else if (fromType.pr == PR.REF && toType.pr == PR.PRIM)
+            assertCompileSucceededIff(fromType.unboxed != null && Types.widenMap.get(fromType.unboxed).contains(toType));
+        else if (fromType.pr == PR.PRIM && toType.pr == PR.PRIM)
+            assertCompileSucceededIff(Types.widenMap.get(fromType).contains(toType));
+        else
+            assertCompileSucceeded();
+    }
+
+    @Override
+    protected boolean shouldRun() { return true; }
+
+    @Override
+    protected void run(Class<?> clazz) throws ReflectiveOperationException {
+        Method m = clazz.getMethod("main");
+        Object obj = clazz.newInstance();
+        String result = (String) m.invoke(obj);
+        String formatted = fromType.asObject.toString();
+        if (fromType == Types.CHAR || fromType == Types.BOXED_CHAR) {
+            result = result.replace("A", "65");
+            formatted = formatted.replace("A", "65");
+        }
+        assertEquals(result.replace(".0", ""), formatted.replace(".0", ""));
+    }
+}
+
+enum PR {PRIM, REF}
+
+enum Types implements Template {
+    BYTE(PR.PRIM, "byte", byte.class, "(byte) 1", (byte) 1),
+    SHORT(PR.PRIM, "short", short.class, "(short) 2", (short) 2),
+    CHAR(PR.PRIM, "char", char.class, "'A'", 'A'),
+    INT(PR.PRIM, "int", int.class, "3", 3),
+    LONG(PR.PRIM, "long", long.class, "4L", 4L),
+    FLOAT(PR.PRIM, "float", float.class, "5.0f", 5.0f),
+    DOUBLE(PR.PRIM, "double", double.class, "6.0", 6.0),
+    BOOLEAN(PR.PRIM, "boolean", boolean.class, "true", true),
+    VOID(PR.PRIM, "void", void.class, "null", null),
+    BOXED_BYTE(PR.REF, "Byte", Byte.class, "Byte.valueOf((byte) 1)", (byte) 1, BYTE),
+    BOXED_SHORT(PR.REF, "Short", Short.class, "Short.valueOf((short) 2)", (short) 2, SHORT),
+    BOXED_CHAR(PR.REF, "Character", Character.class, "Character.valueOf('A')", 'A', CHAR),
+    BOXED_INT(PR.REF, "Integer", Integer.class, "Integer.valueOf(3)", 3, INT),
+    BOXED_LONG(PR.REF, "Long", Long.class, "Long.valueOf(4)", (long) 4, LONG),
+    BOXED_FLOAT(PR.REF, "Float", Float.class, "Float.valueOf(5.0f)", 5.0f, FLOAT),
+    BOXED_DOUBLE(PR.REF, "Double", Double.class, "Double.valueOf(6.0)", 6.0, DOUBLE),
+    BOXED_BOOLEAN(PR.REF, "Boolean", Boolean.class, "Boolean.valueOf(true)", true, BOOLEAN),
+    NUMBER(PR.REF, "Number", Number.class, "9", 9),
+    OBJECT(PR.REF, "Object", Object.class, "10", 10),
+    STRING(PR.REF, "String", String.class, "\"foo\"", "foo");
+
+    public static EnumMap<Types, Types> boxMap = new EnumMap<>(Types.class);
+    public static EnumMap<Types, Types> unboxMap = new EnumMap<>(Types.class);
+    public static EnumMap<Types, EnumSet<Types>> widenMap = new EnumMap<>(Types.class);
+
+    static {
+        for (Types t : values()) {
+            if (t.unboxed != null) {
+                boxMap.put(t.unboxed, t);
+                unboxMap.put(t, t.unboxed);
+            }
+        }
+
+        widenMap.put(BYTE, EnumSet.of(BYTE, SHORT, INT, LONG, FLOAT, DOUBLE));
+        widenMap.put(SHORT, EnumSet.of(SHORT, INT, LONG, FLOAT, DOUBLE));
+        widenMap.put(CHAR, EnumSet.of(CHAR, INT, LONG, FLOAT, DOUBLE));
+        widenMap.put(INT, EnumSet.of(INT, LONG, FLOAT, DOUBLE));
+        widenMap.put(LONG, EnumSet.of(LONG, FLOAT, DOUBLE));
+        widenMap.put(FLOAT, EnumSet.of(FLOAT, DOUBLE));
+        widenMap.put(DOUBLE, EnumSet.of(DOUBLE));
+        widenMap.put(BOOLEAN, EnumSet.of(BOOLEAN));
+    }
+
+    final PR pr;
+    final String name;
+    final Class<?> clazz;
+    final String valueString;
+    final Object asObject;
+    final Types unboxed;
+
+    Types(PR pr, String name, Class<?> clazz, String valueString, Object asObject) {
+        this (pr, name, clazz, valueString, asObject, null);
+    }
+
+    Types(PR pr, String name, Class<?> clazz, String valueString, Object asObject, Types unboxed) {
+        this.pr = pr;
+        this.name = name;
+        this.clazz = clazz;
+        this.valueString = valueString;
+        this.asObject = asObject;
+        this.unboxed = unboxed;
+    }
+
+    public String expand(String selector) {
+        switch (selector) {
+            case "ARG": return valueString;
+            default: return name;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/lambda/LambdaCaptureTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.lambda;
+
+import org.testng.annotations.Factory;
+import org.testng.annotations.Test;
+import tools.javac.combo.*;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * LambdaCaptureTest
+ *
+ * @author Brian Goetz
+ */
+public class LambdaCaptureTest extends ComboTestBase<LambdaCaptureTest> {
+    @Factory
+    public static Object[] testCombo() throws Exception {
+        return factory(LambdaCaptureTest.class);
+    }
+
+    final int arity;
+    final ArgType[] argTypes;
+    final int capArity;
+    final CapType[] capTypes;
+    final boolean shouldSkip;
+
+    public LambdaCaptureTest(@DimensionVar(value = "ARITY", rangeLower = 0, rangeUpper = 2) int arity,
+                             @DimensionVar("ARGTYPE1") ArgType argType1,
+                             @DimensionVar("ARGTYPE2") ArgType argType2,
+                             @DimensionVar(value = "CAP_ARITY", rangeLower = 0, rangeUpper = 2) int capArity,
+                             @DimensionVar("CAPTYPE1") CapType capType1,
+                             @DimensionVar("CAPTYPE2") CapType capType2) {
+        this.arity = arity;
+        this.capArity = capArity;
+        this.argTypes = new ArgType[] { argType1, argType2 };
+        this.capTypes = new CapType[] { capType1, capType2 };
+        shouldSkip = skipConstrained(arity, argTypes) || skipConstrained(capArity, capTypes);
+    }
+
+    @Override
+    protected String[] getCompileOptions(String group) {
+        return new String[] { "-XDlambdaToMethod" };
+    }
+
+    @SourceFile("Main.java") String test
+            = "public class Main {\n"
+            + "  #{CAPTYPE1} f0 = #{CAPV.1};\n"
+            + "  #{CAPTYPE2} f1 = #{CAPV.2};\n"
+            + "  interface Target { String m(#{SAM_FORMALS}); }\n"
+            + "  public String convert() { #{CAPTYPE1} loc0 = #{CAPV.1};\n"
+            + "                            #{CAPTYPE2} loc1 = #{CAPV.2};\n"
+            + "                            Target lambda = (#{LAMBDA_FORMALS}) -> String.format(\"#{FORMAT_STRING}\" #{FORMAT_ARGS});\n"
+            + "                            return lambda.m(#{INVOKE_ARGS}); }\n"
+            + "}";
+
+    @TemplateVar("LAMBDA_FORMALS") Template formalArgs = new Template() {
+        public String expand(String selector) {
+            List<String> list = new ArrayList<>();
+            for (int i=0; i<arity; i++)
+                list.add(argTypes[i].typeName + " a" + i);
+            return intersperse(list, ", ");
+        }
+    };
+
+    @TemplateVar("SAM_FORMALS") Template samArgs = new Template() {
+        public String expand(String selector) {
+            List<String> list = new ArrayList<>();
+            for (int i=0; i<arity; i++)
+                list.add(argTypes[i].typeName + " a" + i);
+            return intersperse(list, ", ");
+        }
+    };
+
+    @TemplateVar("FORMAT_STRING") Template formatString = new Template() {
+        public String expand(String selector) {
+            List<String> list = new ArrayList<>();
+            for (int i=0; i<capArity; i++)
+                list.add(capTypes[i].argType.format);
+            for (int i=0; i<arity; i++)
+                list.add(argTypes[i].format);
+            return intersperse(list, " ");
+        }
+    };
+
+    @TemplateVar("FORMAT_ARGS") Template formatArgs = new Template() {
+        public String expand(String selector) {
+            List<String> list = new ArrayList<>();
+            for (int i=0; i<capArity; i++)
+                list.add((capTypes[i].lf == LF.LOCAL ? "loc" : "f") + i);
+            for (int i=0; i<arity; i++)
+                list.add("a" + i);
+            return ((list.size()) > 0 ? ", " : "") + intersperse(list, ", ");
+        }
+    };
+
+    @TemplateVar("INVOKE_ARGS") Template invokeArgs = new Template() {
+        public String expand(String selector) {
+            List<String> list = new ArrayList<>();
+            for (int i=0; i<arity; i++)
+                list.add(argTypes[i].formatValue(i+capArity));
+            return intersperse(list, ", ");
+        }
+    };
+
+    @TemplateVar("CAPV") Template capv = new Template() {
+        public String expand(String selector) {
+            int i = Integer.parseInt(selector) - 1;
+            return capTypes[i].argType.formatValue(i);
+        }
+    };
+
+    private String intersperse(List<String> list, String delim) {
+        StringBuilder sb = new StringBuilder();
+        boolean first = true;
+        for (String s : list) {
+            if (!first)
+                sb.append(delim);
+            first = false;
+            sb.append(s);
+        }
+        return sb.toString();
+    }
+
+    @Override
+    protected boolean shouldSkip() {
+        return shouldSkip;
+    }
+
+    @Override
+    protected boolean shouldRun() {
+        return true;
+    }
+
+    @Override
+    protected void run(Class<?> clazz) throws ReflectiveOperationException {
+        Object obj = clazz.newInstance();
+        Method m = clazz.getMethod("convert");
+        Object o = m.invoke(obj);
+
+        List<String> list = new ArrayList<>();
+        for (int i=0; i<capArity; i++)
+            list.add(capTypes[i].argType.formatResult(i));
+        for (int i=0; i<arity; i++)
+            list.add(argTypes[i].formatResult(i+capArity));
+        String result = intersperse(list, " ");
+        assertEquals(result, o);
+    }
+
+    static enum ArgType implements Template {
+        LONG("long", "Long", "J%d", null) {
+            String formatValue(int x) { return String.format("(long) %d", x); }
+            String formatResult(int x) { return "J" + Integer.toString(x); }
+        },
+        BYTE("byte", "Byte", "B%d", LONG) {
+            String formatValue(int x) { return String.format("(byte) %d", x); }
+            String formatResult(int x) { return "B" + Integer.toString(x); }
+        },
+        SHORT("short", "Short", "S%d", LONG) {
+            String formatValue(int x) { return String.format("(short) %d", x); }
+            String formatResult(int x) { return "S" + Integer.toString(x); }
+        },
+        CHAR("char", "Character", "C%c", LONG) {
+            String formatValue(int x) { return String.format("(char) (((int) 'A') + %d)", x); }
+            String formatResult(int x) { return "C" + (char) (((int) 'A') + x); }
+        },
+        INT("int", "Integer", "I%d", LONG) {
+            String formatValue(int x) { return String.format("%d", x); }
+            String formatResult(int x) { return "I" + Integer.toString(x); }
+        },
+        BOOLEAN("boolean", "Boolean", "Z%b", null) {
+            String formatValue(int x) { return String.format("%d %% 2 != 0", x); }
+            String formatResult(int x) { return "Z" + (x % 2 != 0); }
+        },
+        DOUBLE("double", "Double", "D%f", null) {
+            String formatValue(int x) { return String.format("(double) %d", x); }
+            String formatResult(int x) { return "D" + String.format("%f", (double) x); }
+        },
+        FLOAT("float", "Float", "F%f", DOUBLE) {
+            String formatValue(int x) { return String.format("(float) %d", x); }
+            String formatResult(int x) { return "F" + String.format("%f", (float) x); }
+        },
+        OBJECT("Object", "Object", "O%s", null) {
+            String formatValue(int x) { return String.format("Integer.toString(%d)", x); }
+            String formatResult(int x) { return "O" + Integer.toString(x); }
+        },
+        STRING("String", "String", "S%s", null) {
+            String formatValue(int x) { return String.format("Integer.toString(%d)", x); }
+            String formatResult(int x) { return "S" + Integer.toString(x); }
+        };
+
+        final String typeName, boxed, format;
+        final ArgType widened;
+
+        ArgType(String typeName, String boxed, String format, ArgType widened) {
+            this.typeName = typeName;
+            this.boxed = boxed;
+            this.format = format;
+            this.widened = widened;
+        }
+
+        abstract String formatValue(int x);
+        abstract String formatResult(int x);
+
+        public String expand(String selector) {
+            return typeName;
+        }
+    }
+
+    private static enum LF { LOCAL, FIELD }
+
+    static enum CapType implements Template {
+        LOCAL_INT(ArgType.INT, LF.LOCAL),
+        LOCAL_LONG(ArgType.LONG, LF.LOCAL),
+        LOCAL_STRING(ArgType.STRING, LF.LOCAL),
+        FIELD_INT(ArgType.INT, LF.FIELD),
+        FIELD_LONG(ArgType.LONG, LF.FIELD),
+        FIELD_STRING(ArgType.STRING, LF.FIELD);
+
+        final ArgType argType;
+        final LF lf;
+
+        CapType(ArgType argType, LF lf) {
+            this.argType = argType;
+            this.lf = lf;
+        }
+
+        public String expand(String selector) {
+            return argType.typeName;
+        }
+    }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/lambda/LambdaConversionTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.lambda;
+
+import org.testng.annotations.Factory;
+import tools.javac.combo.*;
+
+/**
+ * LambdaConversionTestCase
+ *
+ * @author Maurizio Cimadamore
+ */
+public class LambdaConversionTest extends ComboTestBase<LambdaConversionTest> {
+
+    @Factory
+    public static Object[] testCombo() throws Exception {
+        return factory(LambdaConversionTest.class);
+    }
+
+    @DimensionVar("PACKAGE")  PackageKind  samPkg;
+    @DimensionVar("MODIFIER") ModifierKind modKind;
+    @DimensionVar("CLASS")    SamKind      samKind;
+    @DimensionVar("METH")     MethodKind   meth;
+    @DimensionVar("RET")      TypeKind     retType;
+    @DimensionVar("ARG")      TypeKind     argType;
+    @DimensionVar("THROWN")   TypeKind     thrownType;
+
+    @SourceFile("Sam.java")
+    String samSource = "#{PACKAGE.PACKAGE_DECL} \n #{CLASS}";
+
+    @SourceFile("PackageClass.java")
+    String packageSource = "#{PACKAGE.PACKAGE_DECL}\n #{MODIFIER} class PackageClass extends Exception { }";
+
+    @SourceFile("Client.java")
+    String clientSource = "#{PACKAGE.IMPORT_STATEMENT}\n class Client { Sam s = x -> null; }";
+
+    @Override
+    protected void postCompile(String group) {
+        if (samKind != SamKind.INTERFACE) {
+            assertCompileFailed("SAM type must be an interface");
+        } else if (meth != MethodKind.NON_GENERIC) {
+            assertCompileFailed("target method must be non-generic");
+        } else if (samPkg != PackageKind.NO_PKG &&
+                   modKind != ModifierKind.PUBLIC &&
+                   (retType == TypeKind.PKG_CLASS
+                           || argType == TypeKind.PKG_CLASS
+                           || thrownType == TypeKind.PKG_CLASS)) {
+            assertCompileFailed("target must not contain inaccessible types");
+        } else {
+            assertCompileSucceeded();
+        }
+    }
+
+    static enum PackageKind implements Template {
+        NO_PKG(""),
+        PKG_A("a");
+
+        String pkg;
+
+        PackageKind(String pkg) {
+            this.pkg = pkg;
+        }
+
+        public String expand(String selector) {
+            if (this == NO_PKG)
+                return "";
+            switch (selector) {
+                case "PACKAGE_DECL": return String.format("package %s;", pkg);
+                case "IMPORT_STATEMENT":  return String.format("import %s.*;", pkg);
+                default: throw new IllegalArgumentException(selector);
+            }
+        }
+    }
+
+    static enum SamKind implements Template {
+        CLASS("public class Sam {  }"),
+        ABSTRACT_CLASS("public abstract class Sam {  }"),
+        ANNOTATION("public @interface Sam {  }"),
+        ENUM("public enum Sam { }"),
+        INTERFACE("public interface Sam { \n #{METH}; \n }");
+
+        String template;
+
+        SamKind(String template) { this.template = template; }
+
+        public String expand(String selector) { return template; }
+    }
+
+    static enum ModifierKind implements Template {
+        PUBLIC("public"),
+        PACKAGE("");
+
+        String template;
+
+        ModifierKind(String template) { this.template = template; }
+
+        public String expand(String selector) { return template; }
+    }
+
+    static enum TypeKind implements Template {
+        EXCEPTION("Exception"),
+        PKG_CLASS("PackageClass");
+
+        String template;
+
+        private TypeKind(String template) { this.template = template; }
+
+        public String expand(String selector) { return template; }
+    }
+
+    static enum MethodKind implements Template {
+        NONE(""),
+        NON_GENERIC("public #{RET} m(#{ARG} s) throws #{THROWN};"),
+        GENERIC("public <X> #{RET} m(#{ARG} s) throws #{THROWN};");
+
+        String template;
+
+        private MethodKind(String template) { this.template = template; }
+
+        public String expand(String selector) { return template; }
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/lambda/LambdaExpressionTypeInferenceTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.lambda;
+
+import org.testng.annotations.Factory;
+import tools.javac.combo.ComboTestBase;
+import tools.javac.combo.DimensionVar;
+import tools.javac.combo.SourceFile;
+import tools.javac.combo.Template;
+
+import static tools.javac.combo.StackProcessingUtils.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * LambdaExpressionTypeInferenceTest
+ */
+public class LambdaExpressionTypeInferenceTest extends ComboTestBase<LambdaExpressionTypeInferenceTest> {
+    @Factory
+    public static Object[] testLambdaExpressionInference() throws Exception {
+        return factory(LambdaExpressionTypeInferenceTest.class);
+    }
+
+    @DimensionVar("FORMAL_SHAPE") FormalTypeShape formalShape;
+    @DimensionVar("TREE_SHAPE") TreeShape treeShape;
+    @DimensionVar("ARG_SHAPE_1") ArgTypeShape argShape1;
+    @DimensionVar("ARG_SHAPE_2") ArgTypeShape argShape2;
+    @DimensionVar("ARG_SHAPE_3") ArgTypeShape argShape3;
+
+    @SourceFile("SAM.java")
+    String samFile = "public interface SAM<X,Y> {\n"
+            +"  Y apply(X x);\n"
+            +"}";
+
+
+    @SourceFile("Main.java")
+    String clientFile = "import java.util.*;\n"
+            +"public class Main {\n"
+            +"  <A,R> void m(#{FORMAL_SHAPE} x) { }\n"
+            +"  void test() {\n"
+            +"     m(#{TREE_SHAPE});\n"
+            +"  }\n"
+            +"}";
+
+    @Override
+    protected void postCompile(String grp) {
+        if (treeShape.compute().typeCheck(formalShape.compute(), new Type[] { argShape1.compute(), argShape2.compute(), argShape3.compute() }).isErroneous()) {
+            assertCompileFailed();
+        } else {
+            assertCompileSucceeded();
+        }
+    }
+
+    @Override
+    protected boolean shouldSkip() {
+        return argShape2.ordinal() != 0 && treeShape.depth < 2 || argShape3.ordinal() != 0 && treeShape.depth < 3;
+    }
+
+    static class Tree {
+        TreeTag treeTag;
+        Tree[] subtrees;
+
+        Tree(TreeTag treeTag, Tree... subtrees) {
+            this.treeTag = treeTag;
+            this.subtrees = subtrees;
+        }
+
+        public String toString() {
+            Object[] substrings = new Object[subtrees.length];
+            for (int i = 0; i < subtrees.length; i++) {
+                substrings[i] = subtrees[i].toString();
+            }
+            return String.format(treeTag.treeStr, substrings);
+        }
+
+        Type typeCheck(Type target, Type[] argtypes) {
+            switch (treeTag) {
+                case INT:   
+                   Type type = new Type(TypeToken.INTEGER);
+                   return type.compatibleWith(target) ? type : errType;
+                case STRING:
+                   type = new Type(TypeToken.STRING);
+                   return type.compatibleWith(target) ? type : errType;
+                case EXPR_LAMBDA:
+                    Type restype = target.getReturnType();
+                    if (restype == null) {
+                        return errType;
+                    }
+                    Type argtype = target.getArgType();
+                    int idx = subtrees[0].treeTag.argIndex();
+                    if (idx >= 0 && !argtypes[idx].compatibleWith(argtype)) {
+                        //arg type mismatch
+                        return errType;
+                    }
+                    
+                    for (int i = 1; i < subtrees.length; i++) {
+                        if (subtrees[i].typeCheck(restype, argtypes).isErroneous()) {
+                            return errType;
+                        }
+                    }
+                    return target;
+                case COND:
+                    Type typeToCheck = target;
+                    if (subtrees[0].treeTag == TreeTag.INT && subtrees[1].treeTag == TreeTag.INT) {
+                        Type owntype = new Type(TypeToken.INTEGER);
+                        return owntype.compatibleWith(target) ? owntype : errType;
+                    } else {
+                        for (int i = 0; i < subtrees.length; i++) {
+                            if (subtrees[i].typeCheck(target, argtypes).isErroneous()) {
+                                return errType;
+                            }
+                        }
+                        return target;
+                    }
+                default:
+                    throw new AssertionError();
+            }
+        }
+    }
+
+    enum TreeTag implements StackItem<TreeTag> {
+        INT("1", 0),
+        STRING("\"\"", 0),
+        COND("true ? %s : %s", 2),
+        EXPR_LAMBDA("(%s)->%s", 2),
+        IMPLICIT_1("x1", 0),
+        IMPLICIT_2("x2", 0),
+        IMPLICIT_3("x3", 0),
+        EXPLICIT_1("#{ARG_SHAPE_1} x1", 0),
+        EXPLICIT_2("#{ARG_SHAPE_2} x2", 0),
+        EXPLICIT_3("#{ARG_SHAPE_3} x3", 0);
+
+        String treeStr;
+        int arity;
+
+        TreeTag(String treeStr, int arity) {
+            this.treeStr = treeStr;
+            this.arity = arity;
+        }
+
+        public int arity() {
+            return arity;
+        }
+
+        Tree apply(Tree... args) {
+            return new Tree(this, args);
+        }
+
+        int argIndex() {
+            switch (this) {
+                case EXPLICIT_1:
+                    return 0;
+                case EXPLICIT_2:
+                    return 1;
+                case EXPLICIT_3:
+                    return 2;
+                default:
+                    return -1;
+            }
+        }
+    }
+
+    enum TreeShape implements Template, StackReducer<TreeTag, Tree, Void> {
+        LAMBDA_INT(1, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.INT),
+        LAMBDA_STRING(1, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.STRING),
+        LAMBDA_COND_INT_INT(1, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.COND, TreeTag.INT, TreeTag.INT),
+        IMPL_LAMBDA_INT(1, TreeTag.EXPR_LAMBDA, TreeTag.IMPLICIT_1, TreeTag.INT),
+        IMPL_LAMBDA_STRING(1, TreeTag.EXPR_LAMBDA, TreeTag.IMPLICIT_1, TreeTag.STRING),
+        IMPL_LAMBDA_COND_INT_INT(1, TreeTag.EXPR_LAMBDA, TreeTag.IMPLICIT_1, TreeTag.COND, TreeTag.INT, TreeTag.INT),
+        LAMBDA_LAMBDA_INT(2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_2, TreeTag.INT),
+        LAMBDA_LAMBDA_STRING(2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_2, TreeTag.STRING),
+        LAMBDA_LAMBDA_COND_INT_INT(2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_2, TreeTag.COND, TreeTag.INT, TreeTag.INT),
+        LAMBDA_IMPL_LAMBDA_INT(2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.EXPR_LAMBDA, TreeTag.IMPLICIT_2, TreeTag.INT),
+        LAMBDA_IMPL_LAMBDA_STRING(2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.EXPR_LAMBDA, TreeTag.IMPLICIT_2, TreeTag.STRING),
+        LAMBDA_IMPL_LAMBDA_COND_INT_INT(2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.EXPR_LAMBDA, TreeTag.IMPLICIT_2, TreeTag.COND, TreeTag.INT, TreeTag.INT),
+        LAMBDA_COND_LAMBDA_INT_INT(2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.COND, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_2, TreeTag.INT, TreeTag.INT),
+        LAMBDA_COND_LAMBDA_STRING_INT(2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.COND, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_2, TreeTag.STRING, TreeTag.INT),
+        LAMBDA_COND_LAMBDA_COND_INT_INT_INT(2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.COND, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_2, TreeTag.COND, TreeTag.INT, TreeTag.INT, TreeTag.INT),
+        LAMBDA_COND_IMPL_LAMBDA_INT_INT(2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.COND, TreeTag.EXPR_LAMBDA, TreeTag.IMPLICIT_2, TreeTag.INT, TreeTag.INT),
+        LAMBDA_COND_IMPL_LAMBDA_STRING_INT(2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.COND, TreeTag.EXPR_LAMBDA, TreeTag.IMPLICIT_2, TreeTag.STRING, TreeTag.INT),
+        LAMBDA_COND_IMPL_LAMBDA_COND_INT_INT_INT(2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.COND, TreeTag.EXPR_LAMBDA, TreeTag.IMPLICIT_2, TreeTag.COND, TreeTag.INT, TreeTag.INT, TreeTag.INT),
+        LAMBDA_LAMBDA_LAMBDA_INT(3, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_3, TreeTag.INT),
+        LAMBDA_LAMBDA_LAMBDA_STRING(3, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_3, TreeTag.STRING),
+        LAMBDA_LAMBDA_LAMBDA_COND_INT_INT(3, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_2, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_3, TreeTag.COND, TreeTag.INT, TreeTag.INT),
+        LAMBDA_LAMBDA_IMPL_LAMBDA_INT(3, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_2, TreeTag.EXPR_LAMBDA, TreeTag.IMPLICIT_3, TreeTag.INT),
+        LAMBDA_LAMBDA_IMPL_LAMBDA_STRING(3, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_2, TreeTag.EXPR_LAMBDA, TreeTag.IMPLICIT_3, TreeTag.STRING),
+        LAMBDA_LAMBDA_IMPL_LAMBDA_COND_INT_INT(3, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_1, TreeTag.EXPR_LAMBDA, TreeTag.EXPLICIT_2, TreeTag.EXPR_LAMBDA, TreeTag.IMPLICIT_3, TreeTag.COND, TreeTag.INT, TreeTag.INT);
+
+        TreeTag[] treeTags;
+        int depth;
+
+        TreeShape(int depth, TreeTag... treeTags) {
+            this.depth = depth;
+            this.treeTags = treeTags;
+        }
+
+        Tree compute() {
+            return process(treeTags, this, null);
+        }
+
+        public String expand(String selector) {
+            return compute().toString();
+        }
+
+        public Tree reduce(TreeTag tag, Tree[] args, Void _unused) {
+            return new Tree(tag, args);
+        }
+
+        public Void reducerArg(TreeTag item, int i) { return null; }
+
+        public Class<Tree> resultToken() {
+            return Tree.class;
+        }
+    }
+
+    static class Type {
+        TypeToken typeToken;
+        Type[] typeargs;
+
+        Type(TypeToken typeToken, Type... typeargs) {
+            this.typeToken = typeToken;
+            this.typeargs = typeargs;
+        }
+
+        public String toString() {
+            Object[] typeargStrings = new Object[typeargs.length];
+            for (int i = 0; i < typeargs.length; i++) {
+                typeargStrings[i] = typeargs[i].toString();
+            }
+            return String.format(typeToken.tokenStr, typeargStrings);
+        }
+
+        boolean isErroneous() { return false; }
+
+        Type getReturnType() {
+            return typeToken == TypeToken.SAM ?
+                typeargs[1] : null;
+        }
+
+        Type getArgType() {
+            return typeToken == TypeToken.SAM ?
+                typeargs[0] : null;
+        }
+
+        boolean isFree() {
+            switch (typeToken) {
+                case A:
+                case R:
+                    return true;
+                default:
+                    for (Type t : typeargs) {
+                        if (t.isFree()) return true;
+                    }
+                    return false;    
+            }
+        }
+
+        boolean isFreeVar() {
+            switch (typeToken) {
+                case A:
+                case R:
+                    return true;
+                default:                    
+                    return false;    
+            }
+        }
+
+        boolean compatibleWith(Type that) {
+            if (that.isFreeVar()) {
+                return true;
+            } else {
+                if (typeToken != that.typeToken)
+                    return false;
+                if (typeargs.length != that.typeargs.length) {
+                    return false;
+                }
+                for (int i = 0; i < typeargs.length ; i++) {
+                    if (!typeargs[i].compatibleWith(that.typeargs[i]))
+                        return false;
+                }
+                return true;
+            }
+        }
+    }
+
+    static Type errType = new Type(null) {
+        boolean isErroneous() {
+            return true;
+        }
+    };
+
+    enum TypeToken implements StackItem<TypeToken> {
+        STRING("String", 0),
+        INTEGER("Integer", 0),
+        A("A", 0),
+        R("R", 0),
+        LIST("List<%s>", 1),
+        SAM("SAM<%s,%s>", 2);
+
+        int arity;
+        String tokenStr;
+
+        TypeToken(String tokenStr, int arity) {
+            this.tokenStr = tokenStr;
+            this.arity = arity;
+        }
+
+        public int arity() {
+            return arity;
+        }
+    }
+
+    enum ArgTypeShape implements Template, StackReducer<TypeToken, Type, Void> {
+        STRING(TypeToken.STRING),
+        INTEGER(TypeToken.INTEGER),
+        LIST_STRING(TypeToken.LIST, TypeToken.STRING),
+        LIST_INTEGER(TypeToken.LIST, TypeToken.INTEGER);
+
+        TypeToken[] tokens;
+
+        ArgTypeShape(TypeToken... tokens) {
+            this.tokens = tokens;
+        }
+
+        Type compute() {
+            return process(tokens, this, null);
+        }
+
+        public String expand(String selector) {
+            return compute().toString();
+        }
+
+        public Type reduce(TypeToken token, Type[] args, Void _unused) {
+            return new Type(token, args);
+        }
+
+        public Void reducerArg(TypeToken item, int i) { return null; }
+
+        public Class<Type> resultToken() {
+            return Type.class;
+        }
+    }
+
+    enum FormalTypeShape implements Template, StackReducer<TypeToken, Type, Void> {
+        SAM_String_String(TypeToken.SAM, TypeToken.STRING, TypeToken.STRING),
+        SAM_Integer_String(TypeToken.SAM, TypeToken.INTEGER, TypeToken.STRING),
+        SAM_List_String_String(TypeToken.SAM, TypeToken.LIST, TypeToken.STRING, TypeToken.STRING),
+        SAM_List_Integer_String(TypeToken.SAM, TypeToken.LIST, TypeToken.INTEGER, TypeToken.STRING),
+        SAM_A_String(TypeToken.SAM, TypeToken.A, TypeToken.STRING),
+        SAM_List_A_String(TypeToken.SAM, TypeToken.LIST, TypeToken.A, TypeToken.STRING),
+        SAM_String_R(TypeToken.SAM, TypeToken.STRING, TypeToken.R),
+        SAM_A_R(TypeToken.SAM, TypeToken.A, TypeToken.R),
+        SAM_List_A_R(TypeToken.SAM, TypeToken.LIST, TypeToken.A, TypeToken.R),
+        SAM_String_SAM_String_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.STRING),
+        SAM_String_SAM_Integer_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.INTEGER, TypeToken.STRING),
+        SAM_String_SAM_List_String_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.LIST, TypeToken.STRING, TypeToken.STRING),
+        SAM_String_SAM_List_Integer_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.LIST, TypeToken.INTEGER, TypeToken.STRING),
+        SAM_String_SAM_A_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.A, TypeToken.STRING),
+        SAM_String_SAM_List_A_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.LIST, TypeToken.A, TypeToken.STRING),
+        SAM_String_SAM_String_R(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.R),
+        SAM_String_SAM_A_R(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.A, TypeToken.R),
+        SAM_String_SAM_List_A_R(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.LIST, TypeToken.A, TypeToken.R),
+        SAM_A_SAM_String_String(TypeToken.SAM, TypeToken.A, TypeToken.SAM, TypeToken.STRING, TypeToken.STRING),
+        SAM_String_SAM_String_SAM_String_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.STRING),
+        SAM_String_SAM_String_SAM_Integer_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.INTEGER, TypeToken.STRING),
+        SAM_String_SAM_String_SAM_List_String_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.LIST, TypeToken.STRING, TypeToken.STRING),
+        SAM_String_SAM_String_SAM_List_Integer_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.LIST, TypeToken.INTEGER, TypeToken.STRING),
+        SAM_String_SAM_String_SAM_A_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.A, TypeToken.STRING),
+        SAM_String_SAM_String_SAM_List_A_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.LIST, TypeToken.A, TypeToken.STRING),
+        SAM_String_SAM_String_SAM_String_R(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.R),
+        SAM_String_SAM_String_SAM_A_R(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.A, TypeToken.R),
+        SAM_String_SAM_String_SAM_List_A_R(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.LIST, TypeToken.A, TypeToken.R),
+        SAM_String_SAM_A_SAM_String_String(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.A, TypeToken.SAM, TypeToken.STRING, TypeToken.STRING),
+        SAM_String_SAM_A_SAM_String_R(TypeToken.SAM, TypeToken.STRING, TypeToken.SAM, TypeToken.A, TypeToken.SAM, TypeToken.STRING, TypeToken.R);
+
+        TypeToken[] tokens;
+
+        FormalTypeShape(TypeToken... tokens) {
+            this.tokens = tokens;
+        }
+
+        Type compute() {
+            return process(tokens, this, null);
+        }
+
+        public String expand(String selector) {
+            return compute().toString();
+        }
+
+        public Type reduce(TypeToken token, Type[] args, Void _unused) {
+            return new Type(token, args);
+        }
+
+        public Void reducerArg(TypeToken item, int i) { return null; }
+
+        public Class<Type> resultToken() {
+            return Type.class;
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/lambda/LambdaReturnAdaptationTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.lambda;
+
+import org.testng.annotations.Factory;
+import tools.javac.combo.*;
+
+import java.lang.reflect.Method;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * LambaReturnAdaptationTest
+ */
+public class LambdaReturnAdaptationTest extends ComboTestBase<LambdaReturnAdaptationTest> {
+    @Factory
+    public static Object[] testReturnAdaptation() throws Exception {
+        return factory(LambdaReturnAdaptationTest.class);
+    }
+
+    @DimensionVar("FROM") Types fromType;
+    @DimensionVar("TO") Types toType;
+
+    @SourceFile("Sam.java")
+    String samFile = "public interface Sam { #{TO} m(int arg); }";
+
+    @SourceFile("Main.java")
+    String clientFile = "public class Main {\n"
+                        +"  static #{FROM} m(int arg) { \n"
+                        +"    #{RET};\n"
+                        +"  }\n"
+                        +"  public #{TO} main() { \n"
+                        + "   Sam s = Main::m;\n"
+                        + "   #{RET_MAIN};\n"
+                        + " }\n"
+                        +"}";
+
+    @TemplateVar("RET")
+    Template retTemplate = new Template() {
+        public String expand(String selector) {
+            if (fromType == Types.VOID)
+                return "";
+            else if (fromType == Types.STRING)
+                return "return \"66\"";
+            else if (fromType == Types.BOOLEAN || fromType == Types.BOXED_BOOLEAN)
+                return "return true";
+            else if (fromType.unboxed != null)
+                return "return (" + fromType.unboxed.name + ") arg";
+            else
+                return "return (" + fromType.name + ") arg";
+        }
+    };
+
+    @TemplateVar("RET_MAIN")
+    Template retMainTemplate = new Template() {
+        public String expand(String selector) {
+            return toType == Types.VOID ? "s.m(66)" : "return s.m(66)";
+        }
+    };
+
+    @Override
+    protected String[] getCompileOptions(String group) {
+        return new String[] { "-XDlambdaToMethod" };
+    }
+
+    @Override
+    protected void postCompile(String group) {
+        if (fromType != Types.VOID && toType == Types.VOID)
+            assertCompileSucceeded();
+        else if (fromType == Types.VOID && toType != Types.VOID)
+            assertCompileFailed();
+        else if (fromType == Types.VOID && toType == Types.VOID)
+            assertCompileSucceeded();
+        else if (fromType.pr == PR.REF && toType.pr == PR.REF)
+            assertCompileSucceededIff(toType.clazz.isAssignableFrom(fromType.clazz));
+        else if (fromType.pr == PR.PRIM && toType.pr == PR.REF)
+            assertCompileSucceededIff(toType.clazz.isAssignableFrom(Types.boxMap.get(fromType).clazz));
+        else if (fromType.pr == PR.REF && toType.pr == PR.PRIM)
+            assertCompileSucceededIff(fromType.unboxed != null && Types.widenMap.get(fromType.unboxed).contains(toType));
+        else if (fromType.pr == PR.PRIM && toType.pr == PR.PRIM)
+            assertCompileSucceededIff(Types.widenMap.get(fromType).contains(toType));
+        else
+            assertCompileSucceeded();
+    }
+
+    @Override
+    protected boolean shouldRun() { return true; }
+
+    @Override
+    protected void run(Class<?> clazz) throws ReflectiveOperationException {
+        Method m = clazz.getMethod("main");
+        Object obj = clazz.newInstance();
+        Object in = 66;
+        Object out = m.invoke(obj);
+        if (toType == Types.VOID)
+            assertTrue(out == null);
+        else if (fromType == Types.BOOLEAN || fromType == Types.BOXED_BOOLEAN)
+            assertEquals("true", out.toString());
+        else
+            assertEquals(in.toString(), out.toString().replace("B", "66").replace(".0", ""));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/lambda/MethodRefCaptureTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.lambda;
+
+import org.testng.annotations.Factory;
+import tools.javac.combo.*;
+
+/**
+ * MethodRefCaptureTest
+ *
+ * @author Brian Goetz
+ */
+public class MethodRefCaptureTest extends ComboTestBase<MethodRefCaptureTest> {
+    @Factory
+    public static Object[] testCombo() throws Exception {
+        return factory(MethodRefCaptureTest.class);
+    }
+
+    @DimensionVar("VAR") ContextKind context;
+    @DimensionVar("LOCATION") LocationKind location;
+    @DimensionVar("ACC") AccessibilityKind accessibility;
+    @DimensionVar("METHOD") RefKind ref;
+
+    @TemplateVar("PACKAGE")
+    String makePackage() {
+        return location == LocationKind.OTHER_PACKAGE ? "package a;" : "";
+    }
+
+    // @@@ not yet used
+    @TemplateVar("MAIN") String main = "public static void main(String[] args) { #{METHOD.SAMTYPE} x = #{VAR.REF}";
+
+    @SourceFile("Sam1.java") String sam1 = "#{PACKAGE} \npublic interface Sam1 { public String get(String s); }";
+    @SourceFile("Sam2.java") String sam2 = "#{PACKAGE} \npublic interface Sam2<T> { public String get(T target, String s); }";
+    @SourceFile("Sam3.java") String sam3 = "#{PACKAGE} \npublic interface Sam3<T> { public T get(String s); }";
+    @SourceFile("A.java") String mainFile = "#{LOCATION.CAPTURING_CLASS}";
+    @SourceFile("Target.java") String extFile = "#{LOCATION.EXT_CLASS}";
+
+    @Override
+    protected String[] getCompileOptions(String group) {
+        return new String[] { "-XDlambdaToMethod" };
+    }
+
+    @Override
+    protected void postCompile(String group) {
+        if (location == LocationKind.OTHER_FILE && accessibility == AccessibilityKind.PRIVATE)
+            assertCompileFailed();
+        else if (location == LocationKind.OTHER_PACKAGE && accessibility != AccessibilityKind.PUBLIC)
+            assertCompileFailed();
+        else
+            assertCompileSucceeded();
+    }
+
+
+    static enum ContextKind implements Template {
+        STATIC_FIELD_INIT("static #{METHOD.SAMTYPE} var = #{METHOD.MREF};"),
+        STATIC_FIELD_CLINIT("static #{METHOD.SAMTYPE} var; static { var = #{METHOD.MREF}; };"),
+        INSTANCE_FIELD_INIT("#{METHOD.SAMTYPE} var = #{METHOD.MREF};"),
+        LOCAL_VAR("void m() { #{METHOD.SAMTYPE} var = #{METHOD.MREF}; };"),
+        METHOD_CALL("static void m(#{METHOD.SAMTYPE} s) { }; static void m() { m(#{METHOD.MREF}); };"),
+        RETURN("#{METHOD.SAMTYPE} m() { return #{METHOD.MREF}; };"),
+        ARRAY_INITIALIZER("#{METHOD.SAMTYPE}[] var = (#{METHOD.SAMTYPE}[]) new #{METHOD.ERASED_SAMTYPE}[] { (#{METHOD.SAMTYPE}) #{METHOD.MREF} };"),
+        CONDITIONAL("#{METHOD.SAMTYPE} var = new Object().equals(new Object()) ? #{METHOD.MREF} : #{METHOD.MREF};"),
+        CAST("#{METHOD.SAMTYPE} var = (#{METHOD.SAMTYPE}) #{METHOD.MREF};");
+
+        private final String t1;
+
+        ContextKind(String t1) { this.t1 = t1; }
+
+        public String expand(String selector) {
+            switch (selector) {
+                case "DECL": return t1;
+                default:     throw new IllegalArgumentException(selector);
+            }
+        }
+    }
+
+    static enum LocationKind implements Template {
+        SAME_CLASS("class Target { \n#{VAR.DECL} \n#{METHOD.DECL} }"),
+        ENCLOSING_CLASS("class Target { \n#{METHOD.DECL} \nstatic class Capturing { #{VAR.DECL} } }"),
+        SIBLING_INNER_CLASS("class Outer { \nstatic class Capturing { #{VAR.DECL} }  \nstatic class Target { #{METHOD.DECL} } }"),
+        NESTED_CLASS("class Capturing { \n#{VAR.DECL} \nstatic class Target { #{METHOD.DECL} } }"),
+        OTHER_FILE("class Capturing { \n#{VAR.DECL} }", "class Target { \n#{METHOD.DECL} }"),
+        OTHER_PACKAGE("package a; \nimport b.*; \nclass Capturing { \n#{VAR.DECL} }",
+                      "package b; \npublic class Target { \n#{METHOD.DECL} }");
+
+        private final String t1, t2;
+
+        LocationKind(String t1, String t2) {
+            this.t1 = t1;
+            this.t2 = t2;
+        }
+        LocationKind(String t1) { this(t1, "class Unused {}"); }
+
+        public String expand(String selector) {
+            switch (selector) {
+                case "CAPTURING_CLASS": return t1;
+                case "EXT_CLASS":       return t2;
+                default:                throw new IllegalArgumentException(selector);
+            }
+        }
+    }
+
+    static enum AccessibilityKind implements Template {
+        PUBLIC("public"),
+        PROTECTED("protected"),
+        PACKAGE(""),
+        PRIVATE("private");
+
+        private final String template;
+
+        AccessibilityKind(String template) { this.template = template; }
+
+        public String expand(String selector) { return template; }
+    }
+
+    static enum RefKind implements Template {
+        STATIC(0, "Target::staticMethod", "static #{ACC} String staticMethod(String s) { return \"1\"; }"),
+        UNBOUND_INSTANCE(1, "Target::instanceMethod", "#{ACC} String instanceMethod(String s) { return \"2\"; }"),
+        BOUND_INSTANCE(0, "(new Target())::instanceMethod", "#{ACC} String instanceMethod(String s) { return \"3\"; }"),
+        CTOR(2, "Target::new", "#{ACC} Target(String s) { }"),
+//    UNBOUND_INNER_CTOR,
+//    BOUND_INNER_CTOR
+//    , SUPER
+        ;
+
+        private static final String[] sams = { "Sam1", "Sam2<Target>", "Sam3<Target>" };
+        private final int samNo;
+        private final String t1, t2;
+
+        RefKind(int samNo, String t1, String t2) { this.samNo = samNo; this.t1 = t1; this.t2 = t2; }
+
+        public String expand(String selector) {
+            switch (selector) {
+                case "MREF": return t1;
+                case "DECL": return t2;
+                case "SAMTYPE": return sams[samNo];
+                case "ERASED_SAMTYPE": return sams[samNo].replaceAll("<Target>", "<?>");
+                default:   throw new IllegalArgumentException(selector);
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/lambda/NestedGenericMethodCallTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.lambda;
+
+import org.testng.annotations.Factory;
+import org.testng.annotations.Test;
+import tools.javac.combo.ComboTestBase;
+import tools.javac.combo.DimensionVar;
+import tools.javac.combo.SourceFile;
+import tools.javac.combo.Template;
+
+import static tools.javac.combo.StackProcessingUtils.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * NestedGenericMethodCallTest
+ */
+public class NestedGenericMethodCallTest extends ComboTestBase<NestedGenericMethodCallTest> {
+    @Factory
+    public static Object[] testNestedGenericMethodCallType() throws Exception {
+        return factory(NestedGenericMethodCallTest.class);
+    }
+
+    @Test(enabled=false)
+    public void test() throws Exception {
+        //disabled as the test has never been updated to support graph inference
+        super.test();
+    }
+
+    @DimensionVar("ID_METHOD") IdMethod idMethod;
+    @DimensionVar("NIL_METHOD") NilMethod nilMethod;
+    @DimensionVar("CONS_METHOD") ConsMethod consMethod;
+    @DimensionVar("SHAPE") Shape shape;
+    @DimensionVar("TARGET") Type target;
+
+    @SourceFile("Main.java")
+    String clientFile = "import java.util.*;\n"
+            +"public class Main {\n"
+            +"  #{ID_METHOD}\n"
+            +"  #{NIL_METHOD}\n"
+            +"  #{CONS_METHOD}\n"
+            +"  void test() { \n"
+            + "   #{TARGET} t = #{SHAPE};\n"
+            + " }\n"
+            +"}";
+
+    @Override
+    protected void postCompile(String grp) {
+        Type res = shape.compile(idMethod, nilMethod, consMethod, target);
+        if (res.asSubtypeOf(target).isError()) {
+            assertCompileFailed("Bad result = " + res);
+        } else {
+            assertCompileSucceeded();
+        }
+    }
+
+    @Override
+    protected boolean shouldSkip() {
+        return target.free || target == Type.ERROR;
+    }
+
+    enum Type implements Template {
+        Z("Z", true),
+        OBJECT("Object", false),
+        STRING("String", false),
+        LIST_Z("List<Z>", true),
+        LIST_OBJECT("List<Object>", false),
+        LIST_STRING("List<String>", false),
+        ERROR("<any>", false);
+
+        String typeStr;
+        boolean free;
+
+        Type(String typeStr, boolean free) {
+            this.typeStr = typeStr;
+            this.free = free;
+        }
+
+        boolean isError() {
+            return this == ERROR;
+        }
+
+        Type asSubtypeOf(Type that) {
+            return asSubtypeMap[this.ordinal()][that.ordinal()];
+        }
+ 
+        boolean isSubtypeOf(Type that) {
+            return !asSubtypeOf(that).isError();
+        }
+
+        public String expand(String selector) {
+            return typeStr;
+        }
+
+        enum ConstraintKind {
+            Z_EXT_OBJ(false, OBJECT),
+            Z_EXT_STRING(false, STRING),
+            Z_EXT_LIST_OBJECT(false, LIST_OBJECT),
+            Z_EXT_LIST_STRING(false, STRING),
+            Z_SUP_OBJECT(true, OBJECT),
+            Z_SUP_STRING(true, STRING),
+            Z_SUP_LIST_OBJECT(true, LIST_OBJECT),
+            Z_SUP_LIST_STRING(true, LIST_STRING),
+            ERROR(false, Type.ERROR);
+
+            boolean isSuper;
+            Type type;
+
+            ConstraintKind(boolean isSuper, Type type) {
+                this.isSuper = isSuper;
+                this.type = type;
+            }
+        }
+
+        static Type[][] asSubtypeMap = new Type[][] {
+                //                   Z           OBJECT      STRING       LIST_Z      LIST_OBJECT      LIST_STRING        ERROR
+                { /* Z           */  OBJECT     ,OBJECT     ,STRING      ,ERROR      ,LIST_OBJECT     ,LIST_STRING       ,ERROR        },
+                { /* OBJECT      */  OBJECT     ,OBJECT     ,ERROR       ,ERROR      ,ERROR           ,ERROR             ,ERROR        },
+                { /* STRING      */  STRING     ,STRING     ,STRING      ,ERROR      ,ERROR           ,ERROR             ,ERROR        },
+                { /* LIST_Z      */  LIST_OBJECT,LIST_OBJECT,ERROR       ,LIST_OBJECT,LIST_OBJECT     ,LIST_STRING       ,ERROR        },
+                { /* LIST_OBJECT */  LIST_OBJECT,LIST_OBJECT,ERROR       ,LIST_OBJECT,LIST_OBJECT     ,ERROR             ,ERROR        },
+                { /* LIST_STRING */  LIST_STRING,LIST_STRING,ERROR       ,LIST_STRING,ERROR           ,LIST_STRING       ,ERROR        },
+                { /* ERROR       */  ERROR      ,ERROR      ,ERROR       ,ERROR      ,ERROR           ,ERROR             ,ERROR        }};
+
+        static boolean isSubtypes(Type[] ts1, Type[] ts2) {
+            assertEquals(ts1.length, ts2.length);
+            for (int i = 0; i < ts1.length ; i++) {
+                if (!ts1[i].isSubtypeOf(ts2[i])) return false;
+            }
+            return true;
+        }
+
+        static Type listOf(Type t) {
+            switch (t) {
+                case OBJECT: return LIST_OBJECT;
+                case STRING: return LIST_STRING;
+                case Z: return LIST_Z;              
+                default: return ERROR;
+            }
+        }
+
+        static Type elemtype(Type t) {
+            switch (t) {
+                case LIST_OBJECT: return OBJECT;
+                case LIST_STRING: return STRING;
+                case LIST_Z: return Z;
+                default: return ERROR;
+            }
+        }   
+
+        static Type lub(Type t1, Type t2) {
+            if (!t1.asSubtypeOf(t2).isError()) {
+                return t2;
+            } else if (!t2.asSubtypeOf(t1).isError()) {
+                return t1;
+            } else {
+                return Type.ERROR;
+            }
+        }
+    }
+
+    interface MethodSig {
+        Type apply(Type target, Type... argTypes);
+        Type[] getFormals();
+    }
+
+    enum IdMethod implements Template, MethodSig {
+        NON_GENERIC_1("String id(String s) { return null; };", Type.STRING),
+        NON_GENERIC_2("List<String> id(List<String> s) { return null; };", Type.LIST_STRING),
+        GENERIC_1("<Z> Z id(Z z) { return null; };", Type.Z),
+        GENERIC_2("<Z> List<Z> id(List<Z> z) { return null; };", Type.LIST_Z);
+
+        String sig;
+        Type formal;
+
+        IdMethod(String sig, Type formal) {
+            this.sig = sig;
+            this.formal = formal;
+        }
+
+        public String expand(String selector) {
+            return sig;
+        }
+
+        public Type apply(Type target, Type... argTypes) {
+            return argTypes[0].asSubtypeOf(formal);
+        }
+
+        public Type[] getFormals() {
+            return new Type[] { formal };
+        }
+    }
+
+    enum NilMethod implements Template, MethodSig {
+        NON_GENERIC("List<String> nil() { return null; }", Type.LIST_STRING),
+        GENERIC("<Z> List<Z> nil() { return null; }", Type.LIST_Z);
+
+        String sig;
+        Type returnType;
+
+        NilMethod(String sig, Type returnType) {
+            this.sig = sig;
+            this.returnType = returnType;
+        }
+
+        public String expand(String selector) {
+            return sig;
+        }
+
+        public Type apply(Type target, Type... argTypes) {            
+            return this == NON_GENERIC ?
+                Type.LIST_STRING :
+                returnType.asSubtypeOf(target);
+        }
+
+        public Type[] getFormals() {
+            return null;
+        }
+    }
+
+    enum ConsMethod implements Template, MethodSig {
+        NON_GENERIC("List<String> cons(String s, List<String> ls) { return null; }", Type.STRING, Type.LIST_STRING) {
+            Type getReturnType(Type target, Type... argTypes) { return Type.LIST_STRING; }
+        },
+        GENERIC_1("<Z> List<Z> cons(Z z, List<String> ls) { return null; }", Type.Z, Type.LIST_STRING) {
+            Type getReturnType(Type target, Type... argTypes) { 
+                 switch (target) {
+                     case LIST_OBJECT:
+                     case LIST_STRING:
+                        return Type.LIST_Z.asSubtypeOf(target);
+                     default:
+                        return Type.listOf(argTypes[0].asSubtypeOf(Type.Z));
+                 }
+            }
+        },
+        GENERIC_2("<Z> List<Z> cons(String s, List<Z> lz) { return null; }", Type.STRING, Type.LIST_Z) {
+            Type getReturnType(Type target, Type... argTypes) { return Type.listOf(Type.elemtype(argTypes[1].asSubtypeOf(Type.LIST_Z))); }
+        },
+        GENERIC_3("<Z> List<Z> cons(Z z, List<Z> lz) { return null; }", Type.Z, Type.LIST_Z) {
+            Type getReturnType(Type target, Type... argTypes) {
+                Type lub = Type.lub(argTypes[0], Type.elemtype(argTypes[1].asSubtypeOf(Type.LIST_Z)));
+                return lub.isError() ? lub : Type.listOf(lub);
+            }
+        },
+        GENERIC_4("<U, V> List<U> cons(U z, List<V> lz) { return null; }", Type.Z, Type.LIST_Z) {
+            Type getReturnType(Type target, Type... argTypes) { 
+                switch (target) {
+                    case LIST_OBJECT:
+                    case LIST_STRING:
+                        return Type.LIST_Z.asSubtypeOf(target);
+                    default:
+                        return Type.listOf(argTypes[0].asSubtypeOf(Type.Z));
+                }
+            }
+        };
+
+        String sig;
+        Type[] formals;
+
+        ConsMethod(String sig, Type... formals) {
+            this.sig = sig;
+            this.formals = formals;
+        }
+
+        public String expand(String selector) {
+            return sig;
+        }
+
+        public Type apply(Type target, Type... argTypes) {
+            return Type.isSubtypes(argTypes, formals) ?
+                    getReturnType(target, argTypes) : Type.ERROR;
+        }
+
+        abstract Type getReturnType(Type target, Type... argTypes);
+
+        public Type[] getFormals() {
+            return formals;
+        }
+    }
+
+    enum Token implements StackItem<Token> {
+        NIL(0, "nil"),
+        DIAMOND(0, "new ArrayList<>"),
+        STRING(0, "\"\""),
+        ID(1, "id"),
+        CONS(2, "cons");
+
+        int arity;
+        String tokenStr;
+
+        Token(int arity, String tokenStr) {
+            this.arity = arity;
+            this.tokenStr = tokenStr;
+        }
+
+        public int arity() { return arity; }
+    }
+
+    enum Shape implements Template {
+        NIL(Token.NIL),
+        ID_NIL(Token.ID, Token.NIL),
+        ID_ID_NIL(Token.ID, Token.ID, Token.NIL),
+        CONS_STRING_NIL(Token.CONS, Token.STRING, Token.NIL),
+        CONS_STRING_ID_NIL(Token.CONS, Token.STRING, Token.ID, Token.NIL),
+        CONS_ID_STRING_NIL(Token.CONS, Token.ID, Token.STRING, Token.NIL),
+        CONS_ID_STRING_ID_NIL(Token.CONS, Token.ID, Token.STRING, Token.ID, Token.NIL),
+        CONS_ID_STRING_CONS_STRING_NIL(Token.CONS, Token.ID, Token.STRING, Token.CONS, Token.STRING, Token.NIL),
+        CONS_ID_STRING_CONS_ID_STRING_NIL(Token.CONS, Token.ID, Token.STRING, Token.CONS, Token.ID, Token.STRING, Token.NIL),
+        CONS_ID_STRING_CONS_STRING_ID_NIL(Token.CONS, Token.ID, Token.STRING, Token.CONS, Token.STRING, Token.ID, Token.NIL),
+        CONS_ID_STRING_CONS_ID_STRING_ID_NIL(Token.CONS, Token.ID, Token.STRING, Token.CONS, Token.ID, Token.STRING, Token.ID, Token.NIL),
+        CONS_ID_STRING_ID_CONS_ID_STRING_ID_NIL(Token.CONS, Token.ID, Token.STRING, Token.ID, Token.CONS, Token.ID, Token.STRING, Token.ID, Token.NIL),
+        ID_CONS_ID_STRING_ID_CONS_ID_STRING_ID_NIL(Token.ID, Token.CONS, Token.ID, Token.STRING, Token.ID, Token.CONS, Token.ID, Token.STRING, Token.ID, Token.NIL),
+        DIAMOND(Token.DIAMOND),
+        ID_DIAMOND(Token.ID, Token.DIAMOND),
+        CONS_STRING_DIAMOND(Token.CONS, Token.STRING, Token.DIAMOND),
+        CONS_STRING_ID_DIAMOND(Token.CONS, Token.STRING, Token.ID, Token.DIAMOND),
+        CONS_ID_STRING_DIAMOND(Token.CONS, Token.ID, Token.STRING, Token.DIAMOND),
+        CONS_ID_STRING_ID_DIAMOND(Token.CONS, Token.ID, Token.STRING, Token.ID, Token.DIAMOND),
+        CONS_ID_STRING_CONS_STRING_DIAMOND(Token.CONS, Token.ID, Token.STRING, Token.CONS, Token.STRING, Token.DIAMOND),
+        CONS_ID_STRING_CONS_ID_STRING_DIAMOND(Token.CONS, Token.ID, Token.STRING, Token.CONS, Token.ID, Token.STRING, Token.DIAMOND),
+        CONS_ID_STRING_CONS_STRING_ID_DIAMOND(Token.CONS, Token.ID, Token.STRING, Token.CONS, Token.STRING, Token.ID, Token.DIAMOND),
+        CONS_ID_STRING_CONS_ID_STRING_ID_DIAMOND(Token.CONS, Token.ID, Token.STRING, Token.CONS, Token.ID, Token.STRING, Token.ID, Token.DIAMOND),
+        CONS_ID_STRING_ID_CONS_ID_STRING_ID_DIAMOND(Token.CONS, Token.ID, Token.STRING, Token.ID, Token.CONS, Token.ID, Token.STRING, Token.ID, Token.DIAMOND),
+        ID_CONS_ID_STRING_ID_CONS_ID_STRING_ID_DIAMOND(Token.ID, Token.CONS, Token.ID, Token.STRING, Token.ID, Token.CONS, Token.ID, Token.STRING, Token.ID, Token.DIAMOND);
+
+        Token[] tokens;
+
+        Shape(Token... tokens) {
+            this.tokens = tokens;
+        }
+
+        Type compile(final IdMethod idMethod, final NilMethod nilMethod, final ConsMethod consMethod, Type target) {
+            return process(tokens, new StackReducer<Token, Type, Type>() {
+                public Type reduce(Token t, Type[] operands, Type target) {
+                    switch (t) {
+                        case DIAMOND: return Type.LIST_Z.asSubtypeOf(target);
+                        case NIL: return nilMethod.apply(target, operands);
+                        case STRING: return Type.STRING;
+                        case ID: return idMethod.apply(target, operands);
+                        case CONS: return consMethod.apply(target, operands);
+                        default: throw new AssertionError();
+                    }
+                }
+                public Class<Type> resultToken() { return Type.class; }
+                public Type reducerArg(Token item, int i) {
+                    switch (item) {
+                        case ID:
+                            return idMethod.getFormals()[i];
+                        case CONS:
+                            return consMethod.getFormals()[i];
+                        default: return Type.OBJECT;
+                    }
+                }
+            }, target);
+        }
+
+        public String expand(String selector) {
+            return process(tokens, new StackReducer<Token, String, Void>() {
+                public String reduce(Token t, String[] operands, Void _unused) {
+                    switch (t) {
+                        case DIAMOND:
+                        case NIL:
+                        case ID:
+                        case CONS:
+                            StringBuilder buf = new StringBuilder();
+                            String sep = "";
+                            for (int i = 0; i < t.arity; i ++) {
+                                buf.append(sep);
+                                buf.append(operands[i]);
+                                sep = ",";
+                            }
+                            buf.insert(0, "(");
+                            buf.insert(0, t.tokenStr);
+                            buf.append(")");
+                            return buf.toString();
+                        case STRING:
+                            return t.tokenStr;
+                        default: throw new AssertionError();
+                    }
+                }
+                public Class<String> resultToken() { return String.class; }
+                public Void reducerArg(Token item, int i) { return null; }
+            }, null);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/lambda/SourceTargetVersionTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.lambda;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.testng.annotations.Factory;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import tools.javac.combo.*;
+
+/**
+ * SourceTargetVersionTest: 
+ * Test source and class file compatibility by compiling and running lambda specific code 
+ * against some class files compiled separately with different source and target option 
+ * (1.5, 1.6, and 1.7).
+ * The goal is achieved by putting source files in different groups (A, B, C..,), each group 
+ * is set with its own compile options, and we compile in the reverse alphebetic order for the 
+ * groups (..., C, B, A) to set a previously compiled group of files as classpath for the next group. 
+ * And when executing, we Run class Main with classpath A:B:C... in the order. 
+ * 
+ */
+public class SourceTargetVersionTest extends ComboTestBase<SourceTargetVersionTest> {
+    @Factory
+    public static Object[] testSourceTarget() throws Exception {
+        return factory(SourceTargetVersionTest.class);
+    }
+   
+    @DimensionVar("SHAPE") CShapes shapeType;
+    @DimensionVar("CLIENT_CODE") ClientType clientType;
+    @DimensionVar("RELEASE") ReleaseVersion rv;
+    
+    @SourceFile(value="A.java", group="B")
+    String interfaceA = "interface A { #{SHAPE.METHOD} }";    
+    
+    @SourceFile(value="B.java", group="A")
+    String interfaceB = "interface B #{SHAPE.EXTEND} { default String m() { return \"B\"; } }";
+    
+    @SourceFile(value="C.java", group="A")
+    String classC = "class C #{SHAPE.IMPLEMENT} {\n" +
+                    "    #{CLIENT_CODE}\n" +
+                    "}";
+    
+    @SourceFile(value="Main.java", group="A")
+    String classMain = "public class Main {\n" +
+                       "    public String main() {\n" +
+                       "        return new C().m();\n" +                       
+                       "    }\n" +
+                       "}";
+    
+    @TemplateVar("LAMBDA_EXP") String le = "public String m() {\n" +
+                                           "    A a = () -> \"A\";\n" +
+                                           "    return a.m();\n" +
+                                           "}";
+    @TemplateVar("METHOD_REF") String mr = "String foo() {\n" +
+                                           "    return \"foo\";\n" +
+                                           "}\n\n" +
+                                           
+                                           "public String m() {\n" +
+                                           "    A a = this::foo;\n" +
+                                           "    return a.m();\n" +
+                                           "}";
+    
+    @Override
+    protected boolean shouldSkip() {
+        return (shapeType == CShapes.C_AB && clientType != ClientType.DEF_MED) ||
+               (shapeType == CShapes.C && clientType == ClientType.DEF_MED);
+    }
+
+    @Override
+    protected boolean shouldRun() { return true; }
+
+    @Override
+    protected void run(Class<?> clazz) throws ReflectiveOperationException {
+        Method m = clazz.getMethod("main");
+        Object obj = clazz.newInstance();
+        String result = (String) m.invoke(obj);
+        String expected = clientType.returnValue;
+        assertEquals(result, expected);
+    }
+    
+    @Override
+    protected String[] getCompileOptions(String group) {
+        switch(group) {
+            case "B": return new String[]{"-source", rv.versionStr, "-target", rv.versionStr};
+            default: return new String[0];
+        }
+    }
+       
+    enum CShapes implements Template { //shapes of class hirarchy
+        //class C implements interface A, B
+        C_AB("", "", "implements A, B"), 
+        //class C implments interface B, B extends interface A
+        C_B_A("String m();", "extends A", "implements B"), 
+        //class C
+        C("String m();", "", ""); 
+        
+        private final String absMethod;
+        private final String extend;
+        private final String implement;
+        
+        CShapes(String absMethod, String extend, String implement) {
+            this.absMethod = absMethod;
+            this.extend = extend;
+            this.implement = implement;
+        }
+                
+        public String expand(String selector) {
+            switch(selector) {
+                case "METHOD": return absMethod;
+                case "EXTEND": return extend;
+                case "IMPLEMENT": return implement;
+                default: return toString();
+            }
+        }        
+    }
+    
+    enum ClientType implements Template { // jdk8 specific code in client program
+        LAMBDA_EXP("#{LAMBDA_EXP}", "A"), // lambda expressions
+        METHOD_REF("#{METHOD_REF}", "foo"), // method references
+        DEF_MED("", "B"); // default method inheritance
+        
+        private final String clientCode;
+        private final String returnValue;
+        
+        ClientType(String str, String ret) {
+            clientCode = str;
+            returnValue = ret;
+        }
+        
+        public String expand(String selector) {
+            return clientCode;        
+        }
+    }
+    
+    enum ReleaseVersion implements Template {
+        FIVE("1.5"),
+        SIX("1.6"),
+        SEVEN("1.7");
+        
+        final String versionStr;
+        
+        ReleaseVersion(String vstr) {
+            versionStr = vstr;
+        }
+        
+        public String expand(String selector) {
+            return toString();        
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/combo-tests/tests/tools/javac/lambda/StaticMethodTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package tools.javac.lambda;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.testng.annotations.Factory;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import tools.javac.combo.*;
+
+/**
+ * StaticMethodTest: Test static methods in interfaces by running bytecode 
+ *                   compiled at different times; where a static method is added/declared
+ *                   in one interface and only that interface is recompiled.
+ *
+ *                   Static methods in interface are not inherited and 
+ *                   are not visible to any implementing (extending) classes (interfaces).
+ * @bug    8005968
+ * @author sogoel
+ * 
+ */
+public class StaticMethodTest extends ComboTestBase<StaticMethodTest> {
+    @Factory
+    public static Object[] testStaticMethod() throws Exception {
+        return factory(StaticMethodTest.class);
+    }
+    
+    @DimensionVar("SHAPE") CShapes shapeType;
+    
+    @DimensionVar("ADD") AddType addType;
+        
+    @SourceFile(value="B.java", group="A")
+    String interfaceBModified = "interface B #{SHAPE.B_DECL} { #{ADD} }";
+    
+    @SourceFile(value="B.java", group="B")
+    String interfaceB =         "interface B #{SHAPE.B_DECL} {}";
+    
+    @SourceFile(value="A.java", group="B")
+    String interfaceA =         "interface A { static String m() { return \"A\"; } }";
+    
+    @SourceFile(value="C.java", group="B")
+    String classC = "#{SHAPE.C}";
+    
+    @SourceFile(value="Main.java", group="B")
+    String classMain = "public class Main {\n" +
+                       "    public String main() {\n" +
+                       "        return new C().m();\n" +
+                       "    }\n" +
+                       "}";
+
+    @Override
+    protected boolean shouldRun() { return true; }
+
+    @Override
+    protected void run(Class<?> clazz) throws ReflectiveOperationException {
+        Method m = clazz.getMethod("main");
+        Object obj = clazz.newInstance();
+        String result = null, output = null;
+        try {
+            result = (String) m.invoke(obj);
+        } catch (InvocationTargetException ex) {
+            output = ex.getCause().toString();
+        }
+        assertEquals(output, null);
+        assertEquals(result, "C");
+    }
+
+    /*
+     * In order for class Main to compile in group B, object of class C should have
+     * access to a method m(). Therefore, a method m() is needed in class C.
+     * static m() in interfaces A, B is not visible to C.
+     */
+    static String methodSig = "public String m () { return \"C\"; }"; 
+    enum CShapes implements Template { //shapes of class hierarchy
+        //class C implements interface A, B
+        C_AB("",
+           "class C implements A, B { " + methodSig + " }"), 
+        //class C implements interface B, B extends interface A
+        C_B_A("extends A",
+           "class C implements B { " + methodSig + " }"),
+        //class C implements interface AB, AB extends interface A, B
+        C_I_AB("",
+           "interface AB extends A, B {  }\n" +
+           "class C implements AB { " + methodSig + " }"),
+        //class C implements interface AB, AB extends interface A, B and defines its own static method 
+        C_I_AB2("",
+        "interface AB extends A, B { static String m() { return \"AB\"; } }\n" +
+        "class C implements AB { " + methodSig + " }"),
+        //class C extends Class D implements Interface B
+        C_CI("",
+            "class D { public String m() { return \"D\"; } }\n" +
+            "class C extends D implements B { " + methodSig + " }");
+
+        private final String sB_DECL;
+        private final String sC;
+
+        CShapes(String sB_DECL, String sC) {
+            this.sB_DECL = sB_DECL;
+            this.sC = sC;
+        }
+
+        public String expand(String selector) {
+            switch(selector) {
+                case "B_DECL": return sB_DECL;
+                case "C": return sC;
+                default: return toString();
+            }
+        }
+    }
+
+    enum AddType implements Template { // add by adding static method or abstract interface method
+        ADD("static String m() { return \"B\"; }"),
+        REDECLARE("String m();");
+
+        final String newCode;
+
+        AddType(String str) {
+            newCode = str;
+        }
+
+        public String expand(String selector) {
+            return newCode;
+        }
+    }
+}
+
--- a/make/common/internal/Defs-langtools.gmk	Thu Oct 31 16:44:18 2013 -0700
+++ b/make/common/internal/Defs-langtools.gmk	Mon Nov 11 23:17:30 2013 -0800
@@ -28,7 +28,8 @@
 IMPORT_RT_PACKAGES +=               \
       javax/annotation/processing   \
       javax/lang/model              \
-      javax/tools
+      javax/tools                   \
+      com/sun/runtime
 
 IMPORT_TOOLS_PACKAGES +=            \
       com/sun/javadoc               \
--- a/make/docs/NON_CORE_PKGS.gmk	Thu Oct 31 16:44:18 2013 -0700
+++ b/make/docs/NON_CORE_PKGS.gmk	Mon Nov 11 23:17:30 2013 -0800
@@ -84,6 +84,8 @@
 
 SCTPAPI_PKGS     = com.sun.nio.sctp
 
+LAMBDA_RTAPI     = com.sun.runtime
+
 ifeq ($(PLATFORM), macosx)
 APPLE_EXT_PKGS   = com.apple.concurrent   \
                    com.apple.eawt         \
@@ -101,5 +103,6 @@
                    $(HTTPSERVER_PKGS) \
                    $(SMARTCARDIO_PKGS) \
                    $(SCTPAPI_PKGS) \
+                   $(LAMBDA_RTAPI) \
                    $(APPLE_EXT_PKGS)
 
--- a/make/java/java/FILES_java.gmk	Thu Oct 31 16:44:18 2013 -0700
+++ b/make/java/java/FILES_java.gmk	Mon Nov 11 23:17:30 2013 -0800
@@ -300,12 +300,20 @@
 	java/util/EnumMap.java \
     java/util/Arrays.java \
     java/util/ArraysParallelSortHelpers.java \
+    java/util/ArrayPrefixHelpers.java \
+    java/util/ArraySortHelpers.java \
     java/util/DualPivotQuicksort.java \
     java/util/TimSort.java \
     java/util/ComparableTimSort.java \
+    java/util/Comparators.java \
     java/util/ConcurrentModificationException.java \
+    java/util/OptionalDouble.java \
+    java/util/OptionalInt.java \
+    java/util/Optional.java \
+    java/util/OptionalLong.java \
     java/util/ServiceLoader.java \
     java/util/ServiceConfigurationError.java \
+    java/util/StringJoiner.java \
     java/util/Timer.java \
     java/util/TimerTask.java \
     java/util/Objects.java \
@@ -334,6 +342,8 @@
     java/util/concurrent/CyclicBarrier.java \
     java/util/concurrent/DelayQueue.java \
     java/util/concurrent/Delayed.java \
+    java/util/concurrent/DoubleAdder.java \
+    java/util/concurrent/DoubleMaxUpdater.java \
     java/util/concurrent/Exchanger.java \
     java/util/concurrent/ExecutionException.java \
     java/util/concurrent/Executor.java \
@@ -348,6 +358,10 @@
     java/util/concurrent/LinkedBlockingDeque.java \
     java/util/concurrent/LinkedBlockingQueue.java \
     java/util/concurrent/LinkedTransferQueue.java \
+    java/util/concurrent/LongAdder.java \
+    java/util/concurrent/LongAdderTable.java \
+    java/util/concurrent/LongMaxUpdater.java \
+    java/util/concurrent/package-info.java \
     java/util/concurrent/Phaser.java \
     java/util/concurrent/PriorityBlockingQueue.java \
     java/util/concurrent/RecursiveAction.java \
@@ -360,6 +374,8 @@
     java/util/concurrent/ScheduledFuture.java \
     java/util/concurrent/ScheduledThreadPoolExecutor.java \
     java/util/concurrent/Semaphore.java \
+    java/util/concurrent/SequenceLock.java \
+    java/util/concurrent/Striped64.java \
     java/util/concurrent/SynchronousQueue.java \
     java/util/concurrent/ThreadFactory.java \
     java/util/concurrent/ThreadLocalRandom.java \
@@ -379,18 +395,17 @@
     java/util/concurrent/atomic/AtomicReferenceArray.java \
     java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java \
     java/util/concurrent/atomic/AtomicStampedReference.java \
-    java/util/concurrent/atomic/DoubleAccumulator.java \
-    java/util/concurrent/atomic/DoubleAdder.java \
-    java/util/concurrent/atomic/LongAccumulator.java \
-    java/util/concurrent/atomic/LongAdder.java \
-    java/util/concurrent/atomic/Striped64.java \
+    java/util/concurrent/atomic/package-info.java \
+    java/util/concurrent/extra/AtomicDoubleArray.java \
+    java/util/concurrent/extra/AtomicDouble.java \
+    java/util/concurrent/extra/ReadMostlyVector.java \
     java/util/concurrent/locks/AbstractOwnableSynchronizer.java \
     java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java \
     java/util/concurrent/locks/AbstractQueuedSynchronizer.java \
-    java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java \
     java/util/concurrent/locks/Condition.java \
     java/util/concurrent/locks/Lock.java \
     java/util/concurrent/locks/LockSupport.java \
+    java/util/concurrent/locks/package-info.java \
     java/util/concurrent/locks/ReadWriteLock.java \
     java/util/concurrent/locks/ReentrantLock.java \
     java/util/concurrent/locks/ReentrantReadWriteLock.java \
--- a/make/java/java/Makefile	Thu Oct 31 16:44:18 2013 -0700
+++ b/make/java/java/Makefile	Mon Nov 11 23:17:30 2013 -0800
@@ -37,7 +37,7 @@
 JAVAC_MAX_WARNINGS=true
 include $(BUILDDIR)/common/Defs.gmk
 
-AUTO_FILES_JAVA_DIRS = java/util/function
+AUTO_FILES_JAVA_DIRS = java/util/concurrent java/util/function java/util/stream
 
 # windows compiler flags
 ifeq ($(PLATFORM),windows)
@@ -51,7 +51,7 @@
 OTHER_CFLAGS += -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \
                 -DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"' \
                 -DJDK_MICRO_VERSION='"$(JDK_MICRO_VERSION)"' \
-                -DJDK_BUILD_NUMBER='"$(JDK_BUILD_NUMBER)"' 
+                -DJDK_BUILD_NUMBER='"$(JDK_BUILD_NUMBER)"'
 
 ifdef JDK_UPDATE_VERSION
 OTHER_CFLAGS += -DJDK_UPDATE_VERSION='"$(JDK_UPDATE_VERSION)"'
@@ -281,7 +281,7 @@
 $(GENSRCDIR)/java/lang/UNIXProcess.java: $(PLATFORM_UNIX_PROCESS)
 	$(install-file)
 
-clean:: 
+clean::
 	$(RM) $(GENSRCDIR)/java/lang/UNIXProcess.java
 
 endif
@@ -295,10 +295,10 @@
 #
 # Special rules.
 #
-clean:: 
+clean::
 	$(RM) -r $(CLASSHDRDIR)
 
-clobber:: 
+clobber::
 	$(RM) -r $(CLASSBINDIR)/java/io $(CLASSBINDIR)/java/lang \
 		$(CLASSBINDIR)/java/security $(CLASSBINDIR)/java/util \
 		$(CLASSBINDIR)/sun/misc
@@ -315,12 +315,6 @@
 CAL_PROPS = calendars.properties
 
 #
-# Rule to copy Hijrah-umalqura calendar properties file.
-#
-HIJRAH_UMALQURA_PROPS = hijrah-config-umalqura.properties
-
-
-#
 # Rule to copy tzmappings file on Windows
 #
 ifeq ($(PLATFORM), windows)
@@ -332,7 +326,7 @@
 	$(call chmod-file, 444)
 endif
 
-build: $(LIBDIR)/$(PROPS) $(LIBDIR)/$(CAL_PROPS) $(LIBDIR)/$(HIJRAH_UMALQURA_PROPS) $(TZMAP)
+build: $(LIBDIR)/$(PROPS) $(LIBDIR)/$(CAL_PROPS) $(TZMAP)
 
 $(LIBDIR)/$(PROPS): $(PLATFORM_SRC)/lib/$(PROPS)
 	$(install-file)
@@ -340,10 +334,7 @@
 $(LIBDIR)/$(CAL_PROPS): $(SHARE_SRC)/lib/$(CAL_PROPS)
 	$(install-file)
 
-$(LIBDIR)/$(HIJRAH_UMALQURA_PROPS): $(SHARE_SRC)/lib/$(HIJRAH_UMALQURA_PROPS)
-	$(install-file)
-
-clean:: 
+clean::
 	$(RM) -r $(LIBDIR)/$(PROPS) $(TZMAP)
 
 #
@@ -364,12 +355,12 @@
 	$(MV) $@.temp $@
 	$(call chmod-file, 444)
 
-clean:: 
+clean::
 	$(RM) $(CURDATA)
 
 
 #
-# Rules to create $(GENSRCDIR)/sun/lang/CharacterData*.java 
+# Rules to create $(GENSRCDIR)/sun/lang/CharacterData*.java
 #
 CHARACTERDATA = $(BUILDDIR)/tools/GenerateCharacter
 UNICODEDATA   = $(BUILDDIR)/tools/UnicodeData
@@ -424,12 +415,12 @@
 	$(install-file)
 
 clean::
-	$(RM) $(GENSRCDIR)/java/lang/CharacterDataLatin1.java 
+	$(RM) $(GENSRCDIR)/java/lang/CharacterDataLatin1.java
 	$(RM) $(GENSRCDIR)/java/lang/CharacterData00.java
-	$(RM) $(GENSRCDIR)/java/lang/CharacterData01.java 
+	$(RM) $(GENSRCDIR)/java/lang/CharacterData01.java
 	$(RM) $(GENSRCDIR)/java/lang/CharacterData02.java
 	$(RM) $(GENSRCDIR)/java/lang/CharacterData0E.java
-	$(RM) $(GENSRCDIR)/java/lang/CharacterDataUndefined.java 
+	$(RM) $(GENSRCDIR)/java/lang/CharacterDataUndefined.java
 	$(RM) $(GENSRCDIR)/java/lang/CharacterDataPrivateUse.java
 
 #
@@ -450,7 +441,7 @@
 	build.tools.generatecharacter.CharacterName \
 		$(UNICODEDATA)/UnicodeData.txt $(UNINAME)
 
-clean:: 
+clean::
 	$(RM) $(UNINAME)
 
 #
@@ -458,15 +449,15 @@
 #
 
 #
-# Rule to precompile CoreResourceBundleControl.java 
+# Rule to precompile CoreResourceBundleControl.java
 #
 LOCALES_GEN_SH = localelist.sh
 
 $(GENSRCDIR)/sun/util/CoreResourceBundleControl.java: \
 	$(SHARE_SRC)/classes/sun/util/CoreResourceBundleControl-XLocales.java.template $(LOCALES_GEN_SH)
-	@$(prep-target) 
+	@$(prep-target)
 	NAWK="$(NAWK)" SED="$(SED)" $(SH) $(LOCALES_GEN_SH) "$(JRE_NONEXIST_LOCALES)" \
-		$< $@ 
+		$< $@
 clean::
 	$(RM) $(GENSRCDIR)/sun/util/CoreResourceBundleControl.java
 
--- a/make/netbeans/common/shared.xml	Thu Oct 31 16:44:18 2013 -0700
+++ b/make/netbeans/common/shared.xml	Mon Nov 11 23:17:30 2013 -0800
@@ -77,10 +77,10 @@
         <echo level="verbose">System configuration claims architecture is ${platform}-${arch}</echo>
         <property name="build.dir" location="${root}/build/${platform}-${arch}"/>
         <property name="bin.dir" location="${build.dir}/bin"/>
-        <property name="make.dir" location="${root}/make"/> <!-- this is old build make files! -->
+        <property name="make.dir" location="${root}/makefiles"/>
         <property name="gensrc.dir" location="${build.dir}/gensrc"/>
         <property name="classes.dir" location="${build.dir}/classes"/>
-        <property name="jtreg.dir" location="${build.dir}/jtreg/${ant.project.name}"/>
+        <property name="jtreg.dir" location="${build.dir}/testoutput"/>
         <property name="dist.dir" value="${root}/dist"/>
         <property name="includes" value="(nothing)"/>
         <property name="excludes" value=""/>
--- a/make/org/Makefile	Thu Oct 31 16:44:18 2013 -0700
+++ b/make/org/Makefile	Mon Nov 11 23:17:30 2013 -0800
@@ -31,7 +31,7 @@
 PRODUCT = org
 include $(BUILDDIR)/common/Defs.gmk
 
-SUBDIRS = ietf jcp
+SUBDIRS = asm ietf jcp
 include $(BUILDDIR)/common/Subdirs.gmk
 
 all build clean clobber::
--- a/src/share/classes/sun/reflect/NativeConstructorAccessorImpl.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/src/share/classes/sun/reflect/NativeConstructorAccessorImpl.java	Mon Nov 11 23:17:30 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package sun.reflect;
 
 import java.lang.reflect.*;
+import sun.reflect.misc.ReflectUtil;
 
 /** Used only for the first few invocations of a Constructor;
     afterward, switches to bytecode-based implementation */
@@ -44,7 +45,11 @@
                IllegalArgumentException,
                InvocationTargetException
     {
-        if (++numInvocations > ReflectionFactory.inflationThreshold()) {
+        // We can't inflate a constructor belonging to a vm-anonymous class
+        // because that kind of class can't be referred to by name, hence can't
+        // be found from the generated bytecode.
+        if (++numInvocations > ReflectionFactory.inflationThreshold()
+                && !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) {
             ConstructorAccessorImpl acc = (ConstructorAccessorImpl)
                 new MethodAccessorGenerator().
                     generateConstructor(c.getDeclaringClass(),
--- a/src/share/classes/sun/reflect/NativeMethodAccessorImpl.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/src/share/classes/sun/reflect/NativeMethodAccessorImpl.java	Mon Nov 11 23:17:30 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package sun.reflect;
 
 import java.lang.reflect.*;
+import sun.reflect.misc.ReflectUtil;
 
 /** Used only for the first few invocations of a Method; afterward,
     switches to bytecode-based implementation */
@@ -42,7 +43,11 @@
     public Object invoke(Object obj, Object[] args)
         throws IllegalArgumentException, InvocationTargetException
     {
-        if (++numInvocations > ReflectionFactory.inflationThreshold()) {
+        // We can't inflate methods belonging to vm-anonymous classes because
+        // that kind of class can't be referred to by name, hence can't be
+        // found from the generated bytecode.
+        if (++numInvocations > ReflectionFactory.inflationThreshold()
+                && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {
             MethodAccessorImpl acc = (MethodAccessorImpl)
                 new MethodAccessorGenerator().
                     generateMethod(method.getDeclaringClass(),
--- a/src/share/classes/sun/reflect/misc/ReflectUtil.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/src/share/classes/sun/reflect/misc/ReflectUtil.java	Mon Nov 11 23:17:30 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -298,4 +298,13 @@
         }
         return false;
     }
+
+    /**
+     * Checks if {@code Class cls} is a VM-anonymous class
+     * as defined by {@link sun.misc.Unsafe#defineAnonymousClass}
+     * (not to be confused with a Java Language anonymous inner class).
+     */
+    public static boolean isVMAnonymousClass(Class<?> cls) {
+        return cls.getSimpleName().contains("/");
+    }
 }
--- a/src/share/lib/security/java.security-linux	Thu Oct 31 16:44:18 2013 -0700
+++ b/src/share/lib/security/java.security-linux	Mon Nov 11 23:17:30 2013 -0800
@@ -199,14 +199,12 @@
                com.sun.org.apache.xalan.internal.xsltc.trax.,\
                com.sun.org.apache.xalan.internal.xsltc.util.,\
                com.sun.org.apache.xml.internal.res.,\
-               com.sun.org.apache.xml.internal.security.,\
                com.sun.org.apache.xml.internal.serializer.utils.,\
                com.sun.org.apache.xml.internal.utils.,\
                com.sun.org.glassfish.,\
                com.oracle.xmlns.internal.,\
                com.oracle.webservices.internal.,\
 	       oracle.jrockit.jfr.,\
-               org.jcp.xml.dsig.internal.,\
                jdk.internal.,\
                jdk.nashorn.internal.,\
                jdk.nashorn.tools.
@@ -245,14 +243,12 @@
                    com.sun.org.apache.xalan.internal.xsltc.trax.,\
                    com.sun.org.apache.xalan.internal.xsltc.util.,\
                    com.sun.org.apache.xml.internal.res.,\
-                   com.sun.org.apache.xml.internal.security.,\
                    com.sun.org.apache.xml.internal.serializer.utils.,\
                    com.sun.org.apache.xml.internal.utils.,\
                    com.sun.org.glassfish.,\
                    com.oracle.xmlns.internal.,\
                    com.oracle.webservices.internal.,\
 		   oracle.jrockit.jfr.,\
-                   org.jcp.xml.dsig.internal.,\
                    jdk.internal.,\
                    jdk.nashorn.internal.,\
                    jdk.nashorn.tools.
--- a/src/share/native/common/check_code.c	Thu Oct 31 16:44:18 2013 -0700
+++ b/src/share/native/common/check_code.c	Mon Nov 11 23:17:30 2013 -0800
@@ -1307,7 +1307,10 @@
                    && clazz_info != context->currentclass_info
                    && clazz_info != context->superclass_info) {
                 int not_found = 1;
-
+                jclass cb = object_fullinfo_to_classclass(context, clazz_info);
+                int is_interface = cb && JVM_IsInterface(env, cb);
+
+                if (!is_interface) {
                 jclass super = (*env)->GetSuperclass(env, context->class);
                 while(super != 0) {
                     jclass tmp_cb;
@@ -1335,6 +1338,7 @@
                 }
             }
         }
+        }
         if (opcode == JVM_OPC_invokeinterface) {
             unsigned int args1;
             unsigned int args2;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/README	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,20 @@
+Running the TestNG based unit tests requires downloading the TestNG
+library and placing its jar file into the lib subdirectory:
+
+   # download and install TestNG
+   wget http://testng.org/testng-x.y.z.zip
+   unzip testng-x.y.z.zip
+   mkdir lib
+   cp testng-x.y.z/testng.jar lib
+
+   # run tests
+   ant test
+
+This will fail with a message like
+
+    taskdef class org.testng.TestNGAntTask cannot be found
+
+if the TestNG jar file is not installed properly or if the wrong
+version is present. (Check build.xml to find the version of TestNG
+that is required.)  Only the jar file is necessary. The unzipped
+hierarchy can be removed.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/agent/Readme	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,118 @@
+To run this:
+   1.  unzip the bundle to a dir called agent (you should have already done 
+       so, to be reading this)
+   2.  have the latest version of lambda repo built fully and in your PATH
+   3.  you can use the pre-built dist/SerializationInjector.jar if not you
+       can build it with "ant -f agent/make/build.xml dist"
+   4.  before running this modify the conf/agent.props if required, but not
+       necessary.
+   5.  At the time of this writing only test-ng's test-libs are supported.
+
+       make the following changes in the lambda/jdk/test-ng/build.xml
+       for the test-libs target, you might want to bump the heap from 2g
+       to 4g if your choice of platform and the JVM allows.
+
+       <jvmarg value="-javaagent:/YOUR_PATH/agent/dist/SerializationInjectorAgent.jar=/YOUR_PATH/agent/conf/agent.props"/>
+
+       actual patch shown in appendix
+
+   6.  to run simply run the test-ng test as "ant test-libs"
+       Note: make sure are running with the very latest lambda build
+   7.  what you expect to see is in the Appendix.
+       Note: you will see on failure which is a serialization negative test
+
+Details:
+Directory structure:
+    src   - containing the sources
+    build - intermediate classes
+    dist  - jar used as an agent
+    make  - build.xml and an nbproject, feel free to modify it
+            requires jdk8 with asm that recognizes v52.0 classfiles
+    conf  - config files
+
+Description of sources:
+    Agent.java: installs an agent.
+    SerializationInjector: does the following
+       * parses properties and initializes the output
+       * initialize and install the VM shutdown hook, to print the test
+         statistics.
+       * using asm interrogates the target class, upon encountering an
+         indy, will save the params, invokes the indy, and restores the
+         original args to the indy 
+       * invoke the indy
+       * invoke the SerializeAndDeserializeTest (SAND).
+         with the lambdaObject returned by the indy and the
+         non-primitive parameters and these will be passed to SAND.
+	     Primitives are excluded
+     TestLambdaSerialization:
+       * the SAND will check the arguments if they are Serializable, if so,
+         then the LamdbaObject will be Serialized and Deserialized, and the 
+         deserialized LambdaObject will be returned, otherwise the original
+         LambdaObject will be returned,  the outcome and exception if any 
+         will be recorded.
+         
+         The final report will be printed out when the JVM terminates.
+     
+Running the agent:
+java -jar path_to/jtreg.jar \
+     -javaoption:"-javaagent:path_to/agent/dist/SerializationInjectorAgent.jar=/w/ksrini/Lambda/agent.props" \
+     test/foo/Lambda2.java
+
+agent.props is a property file by which one can specify
+   * a regular expression to exclude classes
+   * specify an output file to log details
+   * specifiy debugging if required
+
+ex:
+com.oracle.lambda.exclude.files=^java.*|^sun.misc.*|^javax.*
+com.oracle.lambda.log.file=some_path/agent.log
+com.oracle.lambda.debug=true
+
+A note about logfiles, the agent is installed into jtreg, however jtreg
+may invoke a test in a different VM as specified by the test and/or command
+line. 
+
+Thus if a file exists the agent will create a unique file in the specified 
+directory. Therefore it is recommended that the desired output directory is
+clean before starting a new test.
+
+
+Appendix:
+
+1. Patch to install the agent into test-ng
+diff --git a/test-ng/build.xml b/test-ng/build.xml
+--- a/test-ng/build.xml
++++ b/test-ng/build.xml
+@@ -55,6 +56,7 @@
+             <jvmarg value="-esa" />
+             <jvmarg value="-Xverify:all" />
+             <jvmarg value="-Xmx2g" />
++            <jvmarg value="-javaagent:/YOUR_PATH/agent/dist/SerializationInjectorAgent.jar=/YOUR_PATH/agent/conf/agent.props"/>
+         </testng>
+     </target>
+
+
+2. sample log
+[testng] [TestNG] Running:
+   [testng]   Ant suite
+   [testng]
+   [testng]
+   [testng] ===============================================
+   [testng] Ant suite
+   [testng] Total tests run: 7338, Failures: 1, Skips: 0
+   [testng] ===============================================
+   [testng]
+   [testng] Lambda Serialization Test Status:
+   [testng]   success: 2432727
+   [testng]   failed : 1099035
+   [testng] Non Serializable Class(es):
+   [testng]   NonSerializableObject: java.util.stream.op.Nodes$ArrayNode [92]
+   [testng] Throwable:
+   [testng]   null
+   [testng]
+   [testng]   NonSerializableObject: java.util.stream.op.Nodes$ConcNode [71]
+   [testng] Throwable:
+   [testng]   null
+   [testng]
+   [testng]   NonSerializableObject: org.openjdk.tests.java.util.stream.op.Group
+........
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/agent/conf/agent.props	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,6 @@
+#com.oracle.lambda.exclude.files=java..*|sun.*|javax.*|org.testng.*|com.google.*|com.sun.tools.javac.*|.*javatest.*|com.sun.tools.classfile.*|com.beust.*|.*TTShape.*|.*TestHarness.*
+#com.oracle.lambda.log.file=/tmp/agent_log/agent.log
+#com.oracle.lambda.debug=true
+#com.oracle.lambda.serialize.file=$CUSTOM/serialize.list
+com.oracle.lambda.storeStackTraces=true
+#com.oracle.lambda.deserialization.workaround=true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/agent/conf/serialize.list	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,59 @@
+java/lang/invoke/MagicLambdaImpl
+java/util/Optional
+java/util/OptionalDouble
+java/util/OptionalLong
+java/util/OptionalInt
+java/util/Spliterator
+java/util/ArrayList\$SubList
+java/util/SubList
+java/util/RandomAccessSubList
+java/util/HashMap\$.*Spliterator
+java/util/TreeMap\$.*Spliterator
+java/util/function/Function\$\$Lambda.*
+java/util/function/Functions\$\$Lambda.*
+java/util/stream/Collectors.*
+java/util/stream/LambdaTestHelpers\$\$Lambda.*
+java/util/stream/Nodes.*NodeBuilder
+java/util/stream/Nodes\$.*Node
+java/util/stream/AbstractSpinedBuffer
+java/util/stream/SpinedBuffer
+java/util/stream/.*Pipeline
+java/util/stream/AbstractPipeline\$.*
+java/util/stream/IntermediateOp
+java/util/stream/.*StreamTestData\$.*
+java/util/stream/.*NodeTest
+java/util/stream/TestData\$AbstractTestData.*
+org/openjdk/tests/java/util/stream/OpTestCase\$TestData
+org/openjdk/tests/java/util/stream/OpTestCase\$ExerciseDataStreamBuilder
+org/openjdk/tests/java/util/stream/OpTestCase\$ExerciseDataTerminalBuilder
+org/openjdk/tests/java/util/stream/IntNodeTest
+org/openjdk/tests/java/util/stream/UnorderedStreamTest
+org/openjdk/tests/java/util/stream/GroupByOpTest
+org/openjdk/tests/java/util/stream/TabulatorsTest
+org/openjdk/tests/java/util/stream/TabulatorsTest\$.*Assertion
+org/openjdk/tests/java/util/stream/StreamLinkTest
+org.openjdk.tests.java.util.stream.SpliteratorLateBindingFailFastTest\$SpliteratorDataBuilder.*
+org.openjdk.tests.java.util.stream.SpliteratorTraversingAndSplittingTest\$SpliteratorDataBuilder.*
+org.openjdk.tests.java.util.stream.SliceOpTest.*
+org.openjdk.tests.java.util.stream.MatchOpTest.*
+org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest.*
+java.util.HashMap\$Values
+java.util.LinkedHashMap\$KeyIterator
+java.util.HashMap\$Entry
+java.util.LinkedList\$Node
+java.util.TreeMap\$Entry
+java.util.HashMap\$EntrySet
+java.util.HashMap\$KeySet 
+java.util.IdentityHashMap\$KeySet
+java.util.LinkedHashMap\$ValueIterator
+java.util.TreeMap\$KeySet
+java.util.TreeMap\$EntrySet
+java.util.TreeMap\$Values
+java.util.WeakHashMap
+java.util.WeakHashMap\$EntrySet
+java.util.WeakHashMap\$KeySet
+java.util.WeakHashMap\$Values
+java.util.LinkedHashMap\$EntryIterator
+java.util.IdentityHashMap\$EntrySet
+java.util.IdentityHashMap\$Values
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/agent/make/build.xml	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,75 @@
+<project name="SerializationInjectorAgent" default="dist" basedir="..">
+  <!-- Requires ant 1.6.1+ and Lambda (NOT TL)+-->
+
+  <!-- set global properties for this build -->
+  <property name="build.sysclasspath" value="ignore"/>
+  <property name="build.dir" value="../../../build/test-ng/agent" />
+  <property name="src"      value="${basedir}/src"/>
+  <property name="make"     value="${basedir}/make"/>
+  <property name="conf"     value="${basedir}/conf"/>
+  <property name="classes"  value="${build.dir}/classes"/>
+  <property name="dist"     value="${build.dir}/dist"/>
+
+  <target name="init">
+    <!-- Create the time stamp -->
+    <tstamp/>
+    <!-- Create the build directory structure used by compile -->
+    <mkdir dir="${build.dir}"/>
+    <mkdir dir="${dist}"/>
+    <mkdir dir="${classes}"/>
+    <echo message="${java.home}"/>
+  </target>
+
+  <target name="compile" depends="init">
+    <!-- Compile the java code from ${src} into ${build} -->
+    <javac 
+	source="1.7"
+	srcdir="${src}"
+	destdir="${build.dir}/classes"
+	verbose="no"
+	debug="on"
+    >
+    <compilerarg value="-XDignore.symbol.file=true"/>
+    </javac>
+  </target>
+  <target name="dist" depends="compile">
+    <!-- Put everything in jar file -->
+    <jar destfile="${dist}/SerializationInjectorAgent.jar">
+	<manifest>
+	   <attribute name="Main-Class" value="com.oracle.lambda.Main"/>
+           <attribute name="PreMain-Class" value="com.oracle.lambda.Agent"/>
+	</manifest>
+	<fileset dir="${classes}"/>
+    </jar>
+  </target>
+  <target name="run" depends="dist">
+    <condition property="run.arg" value="-o /tmp/ksrini/XX.jar -f /w/ksrini/JDK/hg-lambda/jdk8/jdk/test-ng/serialize.list /tmp/ksrini/rt.jar">
+        <not>
+            <isset property="run.arg"/>
+        </not> 
+    </condition>
+    <java jar="${dist}/SerializationInjectorAgent.jar"
+        dir="."
+        fork="true"  
+    >
+   <jvmarg value="-Dcom.oracle.lambda.debug=true"/>
+   <arg value="${run.arg}"/>
+    </java>
+  </target>
+  <target name="clean">
+    <!-- Delete the ${build} and ${dist} directory trees -->
+    <delete dir="${build}"/>
+    <delete dir="${dist}"/>
+  </target>
+  <target name="bundle" depends="clean, dist">
+      <zip destfile="${dist}/bundle.zip">
+          <zipfileset dir="${src}"/>
+          <zipfileset file="${dist}/SerializationInjectorAgent.jar"/>
+          <zipfileset dir="${make}" excludes="**/netbeans/**"/>
+          <zipfileset dir="${conf}"/>
+          <zipfileset file="Readme"/>
+      </zip>
+      
+  </target>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/agent/src/com/oracle/lambda/Agent.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.lambda;
+
+import java.io.IOException;
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.lang.instrument.Instrumentation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.security.ProtectionDomain;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.TreeSet;
+
+public class Agent {
+    public static void premain(String agentArgs, Instrumentation instrumentation)
+            throws IOException, NoSuchFieldException, IllegalAccessException {
+        // If run without a config file, all we do is set up the shutdown hook
+        if (agentArgs != null) {
+            final SerializationInjector si = new SerializationInjector();
+            instrumentation.addTransformer(new ClassFileTransformer() {
+                @Override
+                public byte[] transform(final ClassLoader cl, String string,
+                                        Class<?> type, ProtectionDomain pd,
+                                        byte[] bytes) throws IllegalClassFormatException {
+                    return si.transformClass(cl, bytes, EnumSet.noneOf(SerializationInjector.Options.class));
+                }
+            });
+        }
+        else {
+            // Horrible horrible hack.
+            // TreeSet/HashSet are based off of HashSet/HashMap, and serializing their spliterators
+            // tries to serialize the underlying map, which uses a non-serializable sentinel object.
+            // This hack swaps that out for a serializable sentinel
+            Field f = HashSet.class.getDeclaredField("PRESENT");
+            f.setAccessible(true);
+            Field modifiersField = Field.class.getDeclaredField("modifiers");
+            modifiersField.setAccessible(true);
+            modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);
+            f.set(null, Boolean.TRUE);
+
+            f = TreeSet.class.getDeclaredField("PRESENT");
+            f.setAccessible(true);
+            modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);
+            f.set(null, Boolean.TRUE);
+
+            TestLambdaSerialization.initializeShutDownHook();
+        }
+    }
+ }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/agent/src/com/oracle/lambda/Main.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.lambda;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.regex.Pattern;
+
+import jdk.internal.org.objectweb.asm.ClassReader;
+import static java.nio.file.StandardOpenOption.*;
+import static java.nio.file.StandardCopyOption.*;
+
+/**
+ *
+ * @author kumasrin
+ */
+public class Main {
+
+    static void usage() {
+        System.out.println("usage: -o output_dir path_to/SomeClass.class");
+        System.out.println("usage: -o output_dir path_to_classes");
+        System.out.println("usage: -o output_dir -s path_to_jar");
+        System.exit(1);
+    }
+
+    /*
+     * a standalone tester for this
+     */
+    public static void main(String... inargs) throws Exception {
+        String[] args = inargs;
+        if (inargs != null && inargs.length == 1) {
+            args = inargs[0].split("\\s");
+        }
+        if (args == null || args.length < 3) {
+            usage();
+        }
+        File outDir = null;
+        File inFile = null;
+        boolean serializeOnly = false;
+        for (int i = 0 ; i < args.length ; i++) {
+            switch (args[i]) {
+                case "-o":
+                    i++;
+                    outDir = new File(args[i]);
+                    break;
+                case "-s":
+                    serializeOnly = true;
+                    break;
+                default:
+                    inFile = new File(args[i]);
+            }
+        }
+        if (inFile.isDirectory()) {
+            if (outDir.exists()) {
+                outDir.mkdirs();
+            }
+            URL[] urls = {inFile.toURI().toURL()};
+            ClassLoader cl = new URLClassLoader(urls, ClassLoader.getSystemClassLoader());
+            try (DirectoryStream<Path> paths =
+                    Files.newDirectoryStream(inFile.toPath(), "*")) {
+                for (Path p : paths) {
+                    doFile(inFile, outDir, p.toFile(), cl);
+                }
+            }
+        } else if (inFile.getName().endsWith(".jar")) {
+            if (outDir.exists()) {
+                outDir.mkdirs();
+            }
+            URL[] urls = {inFile.toURI().toURL()};
+            ClassLoader cl = new URLClassLoader(urls, ClassLoader.getSystemClassLoader());
+            Pattern pattern = Pattern.compile(".*");
+            EnumSet<SerializationInjector.Options> options
+                    = serializeOnly ? EnumSet.of(SerializationInjector.Options.SERIALIZE_ONLY) : EnumSet.noneOf(SerializationInjector.Options.class);
+            doJar(inFile, outDir, cl, pattern, options);
+        } else {
+            outDir.mkdirs();
+            URL[] urls = {inFile.getParentFile().toURI().toURL()};
+            ClassLoader cl = new URLClassLoader(urls, ClassLoader.getSystemClassLoader());
+            doFile(null, outDir, inFile, cl);
+        }
+    }
+    static void copyStream(InputStream in, OutputStream out) throws IOException {
+        byte[] buf = new byte[8192];
+        int n = in.read(buf);
+        while (n > 0) {
+            out.write(buf, 0, n);
+            n = in.read(buf);
+        }
+    }
+
+    static byte[] readFully(InputStream is) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        copyStream(is, baos);
+        return baos.toByteArray();
+    }
+
+    static void doJar(File inFile, File outDir, ClassLoader cl, Pattern pattern,
+                      EnumSet<SerializationInjector.Options> options) throws IOException {
+        JarFile jf = new JarFile(inFile);
+        byte[] buffer;
+        SerializationInjector si = new SerializationInjector();
+        FileSystem fs = null;
+        boolean jarOut = outDir.getName().endsWith(".jar");
+        Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxrwxrwx");
+        FileAttribute<Set<PosixFilePermission>> attr =
+                PosixFilePermissions.asFileAttribute(perms);
+        Map<String, String> env = new HashMap<>();
+        env.put("create", "true");
+        if (jarOut) {
+            URI uri = URI.create("jar:file:" + outDir.getAbsolutePath());
+            if (outDir.exists())
+                outDir.delete();
+            fs = FileSystems.newFileSystem(uri, env);
+        } else {
+            fs = FileSystems.getDefault();
+        }
+        for (JarEntry je : Collections.list(jf.entries())) {
+            String fname = je.getName();
+            if (fname.endsWith("/")) continue;
+            if (pattern.matcher(fname).matches()) {
+                buffer = readFully(jf.getInputStream(je));
+                if (fname.endsWith(".class"))
+                    buffer = si.transformClass(cl, buffer, options);
+                Path opath = jarOut ? fs.getPath(fname) : fs.getPath(outDir.getAbsolutePath(), fname);
+                Files.createDirectories(opath.getParent(), attr);
+                Files.write(opath, buffer, CREATE, TRUNCATE_EXISTING);
+            }
+        }
+        if (jarOut)
+            fs.close();
+    }
+
+    static String getRelativePath(File baseDir, File inFile) {
+        String bname = baseDir.getAbsolutePath();
+        String fname = inFile.getAbsolutePath();
+        return fname.substring(bname.length() + 1);
+    }
+
+    static void doFile(File inDir, File outDir, File iFile, ClassLoader cl) throws Exception {
+        if (!iFile.getName().endsWith(".class")) {
+            Path p = new File(getRelativePath(inDir, iFile)).toPath();
+            Files.copy(iFile.toPath(), p, COPY_ATTRIBUTES, REPLACE_EXISTING);
+            return;
+        }
+        byte[] classBuffer = Files.readAllBytes(iFile.toPath());
+        ClassReader cr = new ClassReader(classBuffer);
+        File oFile = new File(outDir, cr.getClassName() + ".class");
+        SerializationInjector si = new SerializationInjector();
+        System.err.print("Transforming: " + iFile.getAbsolutePath());
+        System.err.println(" to: " + oFile.getAbsolutePath());
+        oFile.getParentFile().mkdirs();
+        Files.write(oFile.toPath(),
+                si.transformClass(cl, classBuffer, EnumSet.noneOf(SerializationInjector.Options.class)), CREATE, TRUNCATE_EXISTING);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/agent/src/com/oracle/lambda/SerializationInjector.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.lambda;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Handle;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+import jdk.internal.org.objectweb.asm.Type;
+
+import static java.nio.file.StandardOpenOption.*;
+
+
+public class SerializationInjector {
+    static final String PREFIX = "com.oracle.lambda";
+    static final String INCLUDES = "java.util.*|org.openjdk.tests.java.*"; // also should include java.util...
+    static final String SERIALIZE = "";
+
+    // properties that can be set
+    static final String INCLUDE_FILES  = PREFIX + ".include.files";
+    static final String SERIALIZE_FILE = PREFIX + ".serialize.file";
+    static final String STORE_FRAMES   = PREFIX + ".store.frames";
+    static final String LOGFILE        = PREFIX + ".log.file";
+    static final String DEBUG          = PREFIX + ".debug";
+    static final String NROUNDS        = PREFIX + ".nrounds";
+
+    static boolean storeFrames = true;
+    static boolean deserializationWorkaround;
+
+    final DebugPrint debug;
+    final Pattern includePattern;
+    final Pattern serializePattern;
+    final boolean serializeOnly;
+
+    public enum Options { SERIALIZE_ONLY, FORCE_SERIALIZE }
+
+    public SerializationInjector() throws IOException {
+        includePattern   = propToPattern(INCLUDE_FILES, INCLUDES);
+        serializePattern = fileToPattern(SERIALIZE_FILE, SERIALIZE);
+        debug = new DebugPrint();
+        TestLambdaSerialization.initializeShutDownHook();
+        storeFrames = Boolean.getBoolean(STORE_FRAMES);
+        deserializationWorkaround = false;
+        serializeOnly = false;
+    }
+    final Pattern propToPattern(String propKey, String defValue) {
+        return Pattern.compile(System.getProperty(propKey, defValue));
+    }
+    final Pattern fileToPattern(String propKey, String defValue) throws IOException {
+        String fname = System.getProperty(propKey, null);
+        if (fname != null) {
+            File pFile = new File(fname);
+            if (pFile.canRead()) {
+                return fileToPattern(pFile);
+            }
+        }
+        return Pattern.compile(defValue);
+    }
+    final Pattern fileToPattern(File inFile) throws IOException {
+        List<String> serList = Files.readAllLines(inFile.toPath(),
+                Charset.defaultCharset());
+        String regStr = "";
+        boolean first = true;
+        for (String s : serList) {
+            String x = s.trim();
+            if (x.startsWith("#")) {
+                continue;
+            }
+            regStr = regStr.concat((first ? "" : "|") + x);
+            first = false;
+        }
+        System.out.println("serialization: " + regStr);
+        return Pattern.compile(regStr);
+    }
+
+    byte[] transformClass(ClassLoader cl, byte[] classBuffer, EnumSet<Options> options) {
+        byte[] xBuffer = classBuffer;
+        ClassReader classReader = new ClassReader(xBuffer);
+        String cname = classReader.getClassName();
+
+        if (options.contains(Options.FORCE_SERIALIZE) || serializePattern.matcher(cname).matches()) {
+            debug.println("Implementing Serialization: " + cname);
+            xBuffer = injectSerialization(xBuffer, cl);
+        }
+        if (serializeOnly || options.contains(Options.SERIALIZE_ONLY)) {
+            return xBuffer;
+        }
+        if (!includePattern.matcher(cname).matches()) {
+            debug.println("Excluding SAND: " + cname);
+            return xBuffer;
+        }
+        debug.println("Visiting: " + cname);
+        return injectSAND(xBuffer, cl);
+    }
+
+    byte[] injectSAND(byte[] classBuffer, ClassLoader cl) {
+        Map<String, Integer> locals = getLocals(classBuffer);
+        ClassReader classReader = new ClassReader(classBuffer);
+        ClassWriter classWriter = new ClassWriter(classReader,
+                ClassWriter.COMPUTE_MAXS /*| ClassWriter.COMPUTE_FRAMES*/);
+        classReader.accept(makeSANDVisitor(classWriter, locals), 0);
+        byte[] byteArray = classWriter.toByteArray();
+//        CheckClassAdapter.verify(new ClassReader(byteArray), cl, false,
+//                                 new PrintWriter(System.err));
+        return byteArray;
+    }
+
+    Map<String, Integer> getLocals(byte[] classBuffer) {
+        ClassReader cr = new ClassReader(classBuffer);
+        final Map<String, Integer> locals = new HashMap<>();
+        cr.accept(new ClassVisitor(ASM4, null) {
+            String cname;
+            @Override
+            public void visit(int version, int access, String name,
+                    String signature, String superName,
+                    String[] interfaces) {
+                cname = name;
+                super.visit(version, access, name, signature, superName, interfaces);
+            }
+            @Override
+            public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+                final String mid = cname + "+" + name + "+" + desc + "+" + signature;
+                return new MethodVisitor(ASM4,
+                        super.visitMethod(access, name, desc, signature, exceptions)) {
+                    @Override
+                    public void visitMaxs(int maxStack, int maxLocals) {
+                        super.visitEnd();
+                        super.visitMaxs(maxStack, maxLocals);
+                        //debug.println("Pre-Visiting:" + mid + ", stack=" + maxLocals);
+                        locals.put(mid, maxLocals);
+                    }
+                };
+            }
+        }, 0);
+
+        return locals;
+    }
+
+    ClassVisitor makeSANDVisitor(ClassWriter cw, final Map<String, Integer>methodLocals) {
+        return new ClassVisitor(ASM4, cw) {
+            String cname = null;
+            @Override
+            public void visit(int version, int access, String name,
+                              String signature, String superName,
+                              String[] interfaces) {
+                cname = name;
+                super.visit(version, access, name, signature, superName, interfaces);
+            }
+            @Override
+            public MethodVisitor visitMethod(int access, final String name,
+                                             final String desc, final String signature,
+                                             String[] exceptions) {
+                if (name.equals("$deserializeLambda$")) {
+                    return super.visitMethod(access, name, desc, signature, exceptions);
+                }
+                return new MethodVisitor(ASM4,
+                        super.visitMethod(access, name, desc, signature, exceptions)) {
+                    final String mid = cname + "+" + name + "+" + desc + "+" + signature;
+                    int locals = methodLocals.containsKey(mid) ? methodLocals.get(mid) : 0;
+
+                    int saveArgs(Type[] types) {
+                        final int n = locals + 1;
+                        final int tlen = types.length;
+                        int count = 0;
+                        // store in LIFO order
+                        for (int i = 0; i < tlen; i++) {
+                            int pos = tlen - 1 - i;
+                            super.visitVarInsn(types[pos].getOpcode(ISTORE), n + pos);
+                        }
+                        // restore back in  FIFO order
+                        for (int i = 0 ; i < tlen; i++) {
+                            if (isNotPrimitive(types[i])) {
+                                count++;
+                            }
+                            super.visitVarInsn(types[i].getOpcode(ILOAD), n + i);
+                        }
+                        return count;
+                    }
+                    boolean isNotPrimitive(Type t) {
+                        int i = t.getSort();
+                        return i == Type.OBJECT || i == Type.ARRAY;
+                    }
+                    void restoreArgs(Type[] types, int count) {
+                        final int n = locals + 1;
+                        final int tlen = types.length;
+                        // create the array
+                        visitIntInsn(BIPUSH, count);
+                        visitTypeInsn(ANEWARRAY, "java/lang/Object");
+                        int ncount = 0;
+                        for (int i = 0 ; i < tlen ; i++ ) {
+                            Type t = types[i];
+                            if (isNotPrimitive(t)) {
+                                debug.println("injecting:" + t);
+                                super.visitInsn(DUP);
+                                super.visitIntInsn(BIPUSH, ncount);
+                                super.visitVarInsn(t.getOpcode(ILOAD), n + i);
+                                super.visitInsn(AASTORE);
+                                ncount++;
+                            }
+                        }
+                    }
+                    @Override
+                    public void visitInvokeDynamicInsn(String callsite,
+                            String sig, Handle handle, Object... bsmArgs) {
+                        // instrument  only! lambda objects
+                        final boolean needsTransform = handle.getName().equals("metafactory");
+                        final boolean injectSand = needsTransform ||
+                                handle.getName().equals("altMetafactory");
+                        if (!injectSand) {
+                            super.visitInvokeDynamicInsn(callsite, sig, handle, bsmArgs);
+                            return;
+                        }
+                        debug.println("indy:" + mid + ", locals = " + locals);
+                        debug.println("  fixing: " + callsite + ":" + sig);
+                        Handle nHandle = handle;
+                        Object[] nbsmArgs = bsmArgs;
+                        if (needsTransform) {
+                            String ndesc = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;";
+                            nHandle =  new Handle(handle.getTag(), handle.getOwner(),
+                                    "altMetafactory", ndesc);
+
+                            ArrayList<Object> largs = new ArrayList<>(Arrays.asList(bsmArgs));
+                            largs.add(1);
+                            largs.add(Type.getType(java.io.Serializable.class));
+                            nbsmArgs = new Object[largs.size()];
+                            largs.toArray(nbsmArgs);
+                            debug.println("old: " + handle.toString());
+                            debug.println("new: " + nHandle.toString());
+                        }
+                        Type[] types = Type.getArgumentTypes(sig);
+                        int count = saveArgs(types);
+                        super.visitInvokeDynamicInsn(callsite, sig, nHandle, nbsmArgs);
+                        restoreArgs(types, count);
+                        super.visitMethodInsn(INVOKESTATIC,
+                                              "com/oracle/lambda/TestLambdaSerialization",
+                                              (needsTransform && deserializationWorkaround)
+                                                    ? "serializeOnly"
+                                                    : "serializeAndDeserialize",
+                                              "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
+                    }
+                };
+            }
+        };
+    }
+
+    void dumpClass(byte[] array, String prefix) {
+        try {
+            Path f = Files.createTempFile(new File("/tmp").toPath(),
+                                          prefix, ".class");
+            System.out.println("dumping to:" + f.toString());
+            Files.write(f, array, CREATE, TRUNCATE_EXISTING);
+        } catch (IOException ex) {
+            Logger.getLogger(SerializationInjector.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    private byte[] injectSerialization(byte[] classBuffer, ClassLoader cl) {
+        ClassReader classReader = new ClassReader(classBuffer);
+        ClassWriter classWriter = new ClassWriter(classReader,
+                ClassWriter.COMPUTE_MAXS /*| ClassWriter.COMPUTE_FRAMES*/);
+        boolean hasNoArgCtor = hasNoArgCtor(classBuffer);
+        classReader.accept(makeSerializationVisitor(classWriter, !hasNoArgCtor), 0);
+        byte[] byteArray = classWriter.toByteArray();
+        // Needed to comment this out because some classes are actually loaded during this verification
+        // and they fail the package name test (java.*)
+//        CheckClassAdapter.verify(new ClassReader(byteArray), cl, false,
+//                new PrintWriter(System.err));
+
+//        dumpClass(classBuffer, "pre-serialization");
+//        dumpClass(byteArray, "post-serialization");
+        return byteArray;
+    }
+
+    private boolean hasNoArgCtor(byte[] buffer) {
+        final AtomicBoolean foundNoArg = new AtomicBoolean();
+        new ClassReader(buffer).accept(new ClassVisitor(ASM4, null) {
+            @Override
+            public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+                if (name.equals("<init>") && desc.equals("()V"))
+                    foundNoArg.set(true);
+                return super.visitMethod(access, name, desc, signature, exceptions);
+            }
+        }, 0);
+        return foundNoArg.get();
+    }
+
+    ClassVisitor makeSerializationVisitor(final ClassWriter cw, final boolean injectNoArg) {
+        return new ClassVisitor(ASM4, cw) {
+            @Override
+            public void visit(int version, int access, String name,
+                              String signature, String superName,
+                              String[] interfaces) {
+                String sername = java.io.Serializable.class.getName().replace('.', '/');
+                boolean foundSer = false;
+                for (String x : interfaces) {
+                    foundSer = foundSer || x.contains(sername);
+                }
+                if (!foundSer) {
+                    debug.println("Injecting serialization: " + name);
+                    int n = interfaces.length;
+                    interfaces = Arrays.copyOf(interfaces, n + 1);
+                    interfaces[n] = sername;
+                    if (signature != null)
+                        signature += "L" + sername + ";";
+                }
+                super.visit(version, access, name, signature, superName, interfaces);
+                if (injectNoArg && (access & ACC_INTERFACE) == 0) {
+                    debug.println("Injecting <init>: " + name);
+                    MethodVisitor ctor = visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+                    ctor.visitCode();
+                    ctor.visitVarInsn(ALOAD, 0);
+                    ctor.visitMethodInsn(INVOKESPECIAL, superName, "<init>", "()V");
+                    ctor.visitInsn(RETURN);
+                    ctor.visitMaxs(-1, -1);
+                    ctor.visitEnd();
+                }
+            }
+        };
+    }
+}
+class DebugPrint {
+    final PrintStream out;
+    final boolean mustPrint;
+    final boolean shouldClose;
+
+    DebugPrint() throws IOException {
+        mustPrint = Boolean.getBoolean(SerializationInjector.DEBUG);
+        String output = System.getProperty(SerializationInjector.LOGFILE, "out");
+        switch (output) {
+            case "out":
+                out = System.out;
+                shouldClose = false;
+                break;
+            case "err":
+                out = System.err;
+                shouldClose = false;
+                break;
+            default:
+                File f = new File(output);
+                if (f.exists()) {
+                    File dir = f.getParentFile();
+                    f = File.createTempFile("agent", ".log", dir);
+                }
+                FileOutputStream fos = new FileOutputStream(f);
+                out = new PrintStream(new BufferedOutputStream(fos));
+                shouldClose = true;
+        }
+    }
+
+    void println(String s) {
+        if (mustPrint)
+            out.println(s);
+    }
+    void print(String s) {
+        if (mustPrint)
+            out.print(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/agent/src/com/oracle/lambda/TestLambdaSerialization.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.lambda;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class TestLambdaSerialization {
+
+    private static final Map<String, SerializableStatus> nonSerializableClasses =
+            Collections.synchronizedMap(new HashMap<String, SerializableStatus>());
+    private static final Map<String, SerializableStatus> serializableButFailedClasses =
+            Collections.synchronizedMap(new HashMap<String, SerializableStatus>());
+    private static final Map<String, SerializableStatus> deserFailures =
+            Collections.synchronizedMap(new HashMap<String, SerializableStatus>());
+    private static final CounterSet serCounters = new CounterSet();
+    private static final CounterSet deserCounters = new CounterSet();
+    private static final int nRounds =
+            Integer.parseInt(System.getProperty(SerializationInjector.NROUNDS, "1"));
+
+    public static void printStats() {
+        PrintStream rpt = System.out;
+        try {
+            rpt.println("Lambda Serialization Test Status:");
+            rpt.println("  serializations attempted:       " + serCounters.attempted);
+            rpt.println("  serializations succeeded:       " + serCounters.succeeded);
+            rpt.println("  serializations failed:          " + serCounters.failed);
+            rpt.println("  serializations not attempted:   " + serCounters.notAttempted);
+            rpt.println("  deserializations attempted:     " + deserCounters.attempted);
+            rpt.println("  deserializations succeeded:     " + deserCounters.succeeded);
+            rpt.println("  deserializations failed:        " + deserCounters.failed);
+            rpt.println("  deserializations not attempted: " + deserCounters.notAttempted);
+            if (nonSerializableClasses.size() > 0) {
+                rpt.println("Non Serializable Class(es):");
+                for (Entry<String, SerializableStatus> e : nonSerializableClasses.entrySet()) {
+                    rpt.println("  " + e.getValue());
+                }
+            }
+            if (serializableButFailedClasses.size() > 0) {
+                rpt.println("Serializable class(es) but failed serialization:");
+                for (Entry<String, SerializableStatus> e : serializableButFailedClasses.entrySet()) {
+                    rpt.println("  " + e.getValue());
+                }
+            }
+            if (deserFailures.size() > 0) {
+                rpt.println("Failed deserialization:");
+                for (Entry<String, SerializableStatus> e : deserFailures.entrySet()) {
+                    rpt.println("  " + e.getValue());
+                }
+            }
+        } finally {
+            rpt.flush();
+        }
+    }
+
+    public static Object serializeOnly(Object lambdaObj, Object... args) {
+        Object lObj = lambdaObj;
+        for (int i = 0 ; i < nRounds; i++)
+            lObj = serializeAndDeserialize0(true, lObj, args);
+        return lObj;
+    }
+
+    public static Object serializeAndDeserialize(Object lambdaObj, Object... args) {
+        Object lObj = lambdaObj;
+        for (int i = 0; i < nRounds; i++)
+            lObj = serializeAndDeserialize0(false, lObj, args);
+        return lObj;
+    }
+
+    private static Object serializeAndDeserialize0(boolean serializeonly,
+            Object lambdaObj, Object... args) {
+        boolean argsSerializable = true;
+        for (Object a : args) {
+            if (!(a instanceof java.io.Serializable)) {
+                argsSerializable = false;
+                String name = a.getClass().getName();
+                SerializableStatus s = nonSerializableClasses.get(name);
+                if (s == null) {
+                    s = new SerializableStatus("NonSerializableObject", name,
+                            SerializationInjector.storeFrames
+                                ? new Exception(name) : null);
+                    nonSerializableClasses.put(name, s);
+
+                } else {
+                    s.incrementCount();
+                }
+            }
+        }
+
+        byte[] serBytes;
+        if (argsSerializable) {
+            try {
+                serCounters.attempted.incrementAndGet();
+                ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                ObjectOutputStream oos = new ObjectOutputStream(bos);
+                oos.writeObject(lambdaObj);
+                oos.close();
+                serBytes = bos.toByteArray();
+                serCounters.succeeded.incrementAndGet();
+            } catch (java.io.NotSerializableException e) {
+                serCounters.failed.incrementAndGet();
+                String name = e.getMessage();
+                SerializableStatus s = nonSerializableClasses.get(name);
+                if (s == null) {
+                    s = new SerializableStatus("NonSerializableObject", name,
+                                               SerializationInjector.storeFrames ? e : null);
+                    nonSerializableClasses.put(name, s);
+                } else {
+                    s.incrementCount();
+                }
+                return lambdaObj;
+            } catch (RuntimeException | IOException | Error e) {
+                serCounters.failed.incrementAndGet();
+                String cname = lambdaObj.getClass().getName();
+                SerializableStatus s = serializableButFailedClasses.get(cname);
+                if (s == null) {
+                    serializableButFailedClasses.put(cname, new SerializableStatus("LambdaObject",
+                            lambdaObj, SerializationInjector.storeFrames ? e : null));
+                } else {
+                    s.incrementCount();
+                }
+                return lambdaObj;
+            }
+        } else {
+            serCounters.notAttempted.incrementAndGet();
+            return lambdaObj;
+        }
+
+        if (serializeonly) {
+            deserCounters.notAttempted.incrementAndGet();
+            return lambdaObj;
+        }
+
+        deserCounters.attempted.incrementAndGet();
+        try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(serBytes))) {
+            Object nlambdaObj = ois.readObject();
+            deserCounters.succeeded.incrementAndGet();
+            return nlambdaObj;
+        } catch (Exception e) {
+            deserCounters.failed.incrementAndGet();
+            String cname = lambdaObj.getClass().getName();
+            SerializableStatus s = deserFailures.get(cname);
+            if (s == null) {
+                deserFailures.put(cname, new SerializableStatus("NonDeserializableObject",
+                        lambdaObj, SerializationInjector.storeFrames ? e : null));
+            } else {
+                s.incrementCount();
+            }
+            return lambdaObj;
+        }
+    }
+
+    /*
+     * a unit tester for this class
+     */
+
+    public static void main(String... args) {
+        String s = "Lambda";
+        Object o = new Object();
+        Object[] array = {
+            "one",
+            "two",
+            "three"
+        };
+        serializeAndDeserialize(s, "Hi", array);
+        serializeAndDeserialize(s, "Bye", array);
+    }
+
+    static AtomicBoolean initialized = new AtomicBoolean();
+    static {
+        initializeShutDownHook();
+    }
+
+    static void initializeShutDownHook() {
+        if (initialized.compareAndSet(false, true)) {
+            Runtime.getRuntime().addShutdownHook(
+                    new Thread() {
+                        @Override
+                        public void run() {
+                            printStats();
+                        }
+                    }
+            );
+        }
+    }
+}
+
+class CounterSet {
+    AtomicInteger notAttempted = new AtomicInteger(0);
+    AtomicInteger attempted = new AtomicInteger(0);
+    AtomicInteger succeeded = new AtomicInteger(0);
+    AtomicInteger failed = new AtomicInteger(0);
+}
+
+class SerializableStatus {
+    String type;
+    Object obj;
+    Throwable exception;
+    AtomicInteger count = new AtomicInteger(1);
+
+    public SerializableStatus(String type, Object obj, Throwable exception) {
+        this.type = type;
+        this.obj = obj;
+        this.exception = exception;
+    }
+
+    public void incrementCount() {
+        count.incrementAndGet();
+    }
+
+    public String toString() {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        pw.printf("%s: %s [ %d ]%n", type, obj, count.get());
+        if (exception != null) {
+            pw.printf("    Throwable: %s", exception);
+            exception.printStackTrace(pw);
+        }
+        return sw.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/build.xml	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+        * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+        *
+        * This code is free software; you can redistribute it and/or modify it
+        * under the terms of the GNU General Public License version 2 only, as
+        * published by the Free Software Foundation.  Oracle designates this
+        * particular file as subject to the "Classpath" exception as provided
+        * by Oracle in the LICENSE file that accompanied this code.
+        *
+        * This code is distributed in the hope that it will be useful, but WITHOUT
+        * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+        * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+        * version 2 for more details (a copy is included in the LICENSE file that
+        * accompanied this code).
+        *
+        * You should have received a copy of the GNU General Public License version
+        * 2 along with this work; if not, write to the Free Software Foundation,
+        * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+        *
+        * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+        * or visit www.oracle.com if you need additional information or have any
+        * questions.
+-->
+
+<project name="jdk" default="test">
+
+    <property name="build.dir" value="../../build/test-ng" />
+    <property name="tests.classes.dir" value="${build.dir}/test-classes"/>
+    <property name="mangled.jdk.dir" value="${build.dir}/mangled-jdk"/>
+    <property name="mangled.bootlib.dir" value="${build.dir}/mangled-bootlib"/>
+    <property name="mangled.boottests.dir" value="${build.dir}/mangled-boottests"/>
+    <property name="mangled.tests.dir" value="${build.dir}/mangled-testclasses"/>
+    <property name="boottests.classes.dir" value="${build.dir}/boottest-classes"/>
+    <property name="bootlib.classes.dir" value="${build.dir}/test-bootlib"/>
+    <property name="test.reports.dir" value="${build.dir}/test-reports"/>
+    <property name="lambda.test.dir" value="../test/jdk/lambda" />
+    <property name="spliterator.test.dir" value="../test/java/util/Spliterator" />
+    <property name="tests.src.dir" value="../test/java/util/stream/test"/>
+    <property name="boottests.src.dir" value="../test/java/util/stream/boottest"/>
+    <property name="bootlib.src.dir" value="../test/java/util/stream/bootlib"/>
+    <property name="lib.dir" location="lib" />
+    <property name="test.pattern" value="*" />
+    <property name="lambda.metafactory" value="" />
+    <property name="generated.dir" value="gen-separate"/>
+    <property name="agent.dir"       location="${basedir}/agent"/>
+    <property name="agent.jar"       value="${build.dir}/agent/dist/SerializationInjectorAgent.jar" />
+    <property name="agent.serial.file" value="${agent.dir}/conf/serialize.list" />
+    <property name="agent.rt.jar"    value="${java.home}/lib/rt.jar" />
+    <property name="agent.heap.size" value="-Xmx4g"/>
+    <property name="parallel.mode"    value="classes" />
+    <property name="parallel.suitePool"    value="1" />
+    <property name="parallel.providerPool"    value="1" />
+
+    <property name="lib.testng.jar" value="${lib.dir}/testng.jar"/>
+    <property name="lib.tools.jar" value="${java.home}/../lib/tools.jar"/>
+
+    <path id="compile.class.path">
+        <pathelement location="${bootlib.classes.dir}" />
+        <pathelement location="${tests.classes.dir}" />
+        <pathelement location="${lib.testng.jar}"/>
+        <pathelement location="${lib.tools.jar}"/>
+    </path>
+
+    <path id="test.class.path">
+        <pathelement location="${tests.classes.dir}" />
+        <pathelement location="${lib.testng.jar}"/>
+        <pathelement location="${lib.tools.jar}"/>
+    </path>
+
+    <path id="mangled.class.path">
+        <pathelement location="${mangled.tests.dir}" />
+        <pathelement location="${lib.testng.jar}"/>
+        <pathelement location="${lib.tools.jar}"/>
+    </path>
+
+    <taskdef name="testng" classpathref="test.class.path" classname="org.testng.TestNGAntTask" />
+
+    <target name="prepare">
+        <mkdir dir="${build.dir}"/>
+        <mkdir dir="${mangled.jdk.dir}"/>
+        <mkdir dir="${tests.classes.dir}"/>
+        <mkdir dir="${boottests.classes.dir}"/>
+        <mkdir dir="${bootlib.classes.dir}"/>
+        <mkdir dir="${test.reports.dir}"/>
+    </target>
+
+    <target name="test-compile" depends="prepare">
+        <javac destdir="${bootlib.classes.dir}" debug="on" srcdir="${bootlib.src.dir}" fork="true"
+               classpathref="compile.class.path">
+            <compilerarg value="-Xlint:all"/>
+            <compilerarg value="-XDignore.symbol.file"/>
+        </javac>
+        <javac destdir="${tests.classes.dir}" debug="on" srcdir="${tests.src.dir}:${lambda.test.dir}:${spliterator.test.dir}" fork="true"
+               classpathref="compile.class.path">
+            <compilerarg value="-Xlint:all"/>
+            <compilerarg value="-XDignore.symbol.file"/>
+        </javac>
+        <javac destdir="${boottests.classes.dir}" debug="on" srcdir="${boottests.src.dir}" fork="true"
+               classpathref="compile.class.path">
+            <compilerarg value="-Xlint:all"/>
+            <compilerarg value="-XDignore.symbol.file"/>
+        </javac>
+   </target>
+
+   <target name="test" depends="test-compile" >
+        <echo>Results at: file:${test.reports.dir}/index.html</echo>
+        <delete dir="tmp" />
+        <testng classpathref="test.class.path" outputdir="${test.reports.dir}"
+                listener="org.testng.reporters.DotTestListener, org.testng.reporters.XMLReporter" useDefaultListeners="false">
+            <classfileset dir="${tests.classes.dir}" includes="**/${test.pattern}.class"/>
+            <classfileset dir="${boottests.classes.dir}" includes="**/${test.pattern}.class"/>
+            <jvmarg value="-Xbootclasspath/p:${boottests.classes.dir}"/>
+            <jvmarg value="-Xbootclasspath/p:${bootlib.classes.dir}"/>
+            <jvmarg value="-Xbootclasspath/p:${lib.testng.jar}"/>
+            <jvmarg value="-ea"/>
+            <jvmarg value="-esa"/>
+            <jvmarg value="-Xverify:all"/>
+            <jvmarg value="-Xmx2g"/>
+            <sysproperty key="org.openjdk.java.util.stream.tripwire" value="true"/>
+        </testng>
+    </target>
+
+    <target name="test-libs" depends="test-compile" >
+        <echo>Results at: file:${test.reports.dir}/index.html</echo>
+        <delete dir="tmp" />
+        <testng classpathref="test.class.path" outputdir="${test.reports.dir}"
+                listener="org.testng.reporters.XMLReporter" useDefaultListeners="false"
+                parallel="${parallel.mode}" suiteThreadPoolSize="${parallel.suitePool}" dataProviderThreadCount="${parallel.providerPool}">
+            <classfileset dir="${tests.classes.dir}" includes="org/openjdk/tests/java/**/*.class"/>
+            <classfileset dir="${boottests.classes.dir}" includes="java/**/*.class"/>
+            <jvmarg value="-Xbootclasspath/p:${boottests.classes.dir}"/>
+            <jvmarg value="-Xbootclasspath/p:${bootlib.classes.dir}"/>
+            <jvmarg value="-Xbootclasspath/p:${lib.testng.jar}"/>
+            <jvmarg value="-ea" />
+            <jvmarg value="-esa" />
+            <jvmarg value="-Xverify:all" />
+            <jvmarg value="-Xmx2500m" />
+            <sysproperty key="org.openjdk.java.util.stream.tripwire" value="true"/>
+        </testng>
+    </target>
+
+    <target name="test-notlibs" depends="test-compile" >
+        <echo>Results at: file:${test.reports.dir}/index.html</echo>
+        <delete dir="tmp" />
+        <testng classpathref="test.class.path" outputdir="${test.reports.dir}"
+                listener="org.testng.reporters.XMLReporter" useDefaultListeners="false"
+                parallel="${parallel.mode}" suiteThreadPoolSize="${parallel.suitePool}" dataProviderThreadCount="${parallel.providerPool}" >
+            <classfileset dir="${tests.classes.dir}" excludes="org/openjdk/tests/java/**/*.class"/>
+            <jvmarg value="-Xbootclasspath/p:${boottests.classes.dir}"/>
+            <jvmarg value="-Xbootclasspath/p:${bootlib.classes.dir}"/>
+            <jvmarg value="-Xbootclasspath/p:${lib.testng.jar}"/>
+            <jvmarg value="-ea" />
+            <jvmarg value="-esa" />
+            <jvmarg value="-Xverify:all" />
+            <jvmarg value="-Xmx2500m" />
+            <sysproperty key="org.openjdk.java.util.stream.tripwire" value="true"/>
+        </testng>
+    </target>
+
+    <target name="clean" depends="clean-mangler">
+        <delete includeEmptyDirs="true" failonerror="false">
+            <fileset dir="${build.dir}" />
+            <fileset dir="${generated.dir}" />
+        </delete>
+    </target>
+
+    <!-- mangler related start -->
+    <target name="clean-mangler">
+        <ant antfile="${agent.dir}/make/build.xml" inheritAll="false"
+             target="clean">
+        </ant>
+    </target>
+
+    <target name="build-mangler">
+        <ant antfile="${agent.dir}/make/build.xml" inheritAll="false"
+             target="dist">
+        </ant>
+    </target>
+
+    <target name="mangler-sanity">
+        <condition property="agent.rt.jar.available">
+            <available file="${agent.rt.jar}"/>
+        </condition>
+        <echo message="java.home        : ${java.home}"/>
+        <echo message="agent.rt.jar     : ${agent.rt.jar}"/>
+        <echo message="agent.heap.size  : ${agent.heap.size}"/>
+        <fail message="agent.rt.jar was not found, please set it to a valid rt.jar"
+              unless="agent.rt.jar.available"/>
+    </target>
+
+    <target name="premangle" depends="mangler-sanity, clean, build-mangler, test-compile">
+        <!-- Mangle JDK to mangled.jdk.dir (serialization injection only, no SAND) -->
+        <delete dir="${mangled.jdk.dir}" />
+        <mkdir dir="${mangled.jdk.dir}" />
+        <java jar="${agent.jar}" fork="true" >
+            <jvmarg value="-Dcom.oracle.lambda.serialize.file=${agent.serial.file}"/>
+            <arg value="-s"/>
+            <arg value="-o"/>
+            <arg value="${mangled.jdk.dir}" />
+            <arg value="-s"/>
+            <arg value="${agent.rt.jar}"/>
+        </java>
+        <!-- Mangle boot test classes to mangled.boottests.dir -->
+        <delete dir="${mangled.boottests.dir}" />
+        <mkdir dir="${mangled.boottests.dir}" />
+        <jar destfile="${build.dir}/tmpA.jar" basedir="${boottests.classes.dir}"/>
+        <java jar="${agent.jar}" fork="true" >
+            <jvmarg value="-Dcom.oracle.lambda.serialize.file=${agent.serial.file}"/>
+            <arg value="-o"/>
+            <arg value="${mangled.boottests.dir}" />
+            <arg value="-s"/>
+            <arg value="${build.dir}/tmpA.jar"/>
+        </java>
+        <!-- Mangle boot test classes to mangled.bootlib.dir (serialization injection only, no SAND) -->
+        <delete dir="${mangled.bootlib.dir}" />
+        <mkdir dir="${mangled.bootlib.dir}" />
+        <jar destfile="${build.dir}/tmpB.jar" basedir="${bootlib.classes.dir}"/>
+        <java jar="${agent.jar}" fork="true" >
+            <jvmarg value="-Dcom.oracle.lambda.serialize.file=${agent.serial.file}"/>
+            <arg value="-s"/>
+            <arg value="-o"/>
+            <arg value="${mangled.bootlib.dir}" />
+            <arg value="${build.dir}/tmpB.jar"/>
+        </java>
+        <!-- Mangle test classes to mangled.testdir -->
+        <delete dir="${mangled.tests.dir}" />
+        <mkdir dir="${mangled.tests.dir}" />
+        <jar destfile="${build.dir}/tmpC.jar" basedir="${tests.classes.dir}"/>
+        <java jar="${agent.jar}" fork="true" >
+            <jvmarg value="-Dcom.oracle.lambda.serialize.file=${agent.serial.file}"/>
+            <arg value="-o"/>
+            <arg value="${mangled.tests.dir}" />
+            <arg value="${build.dir}/tmpC.jar"/>
+        </java>
+    </target>
+
+    <!--
+        Some tests are hostile to our serialization testing strategy; these are those where lambdas
+        have side-effects on captured arguments, and then we test properties of the captured arguments
+        separately.  This is because serialization/deserialization severs the aliasing that this test
+        strategy depends on.  So we mark and exclude these classes.
+    -->
+    <target name="test-mangled" depends="mangler-sanity, test-compile, build-mangler" >
+        <delete dir="tmp" />
+        <testng classpathref="mangled.class.path" outputdir="${test.reports.dir}"
+                excludedgroups="serialization-hostile">
+            <classfileset dir="${mangled.tests.dir}" includes="org/openjdk/tests/java/**/*.class"
+                          excludes="**/SerializedLambdaTest.class"/>
+            <classfileset dir="${mangled.boottests.dir}" includes="**/*.class"/>
+            <jvmarg value="-Xbootclasspath/p:${agent.jar}"/>
+            <jvmarg value="-Xbootclasspath/p:${mangled.jdk.dir}"/>
+            <jvmarg value="-Xbootclasspath/p:${mangled.bootlib.dir}"/>
+            <jvmarg value="-Xbootclasspath/p:${mangled.boottests.dir}"/>
+            <jvmarg value="-Xbootclasspath/p:${lib.testng.jar}"/>
+            <!--<jvmarg value="-Dsun.io.serialization.extendedDebugInfo=true" />-->
+            <jvmarg value="-ea" />
+            <jvmarg value="-esa" />
+            <jvmarg value="-Xverify:none" />
+            <jvmarg value="${agent.heap.size}"/>
+            <sysproperty key="org.openjdk.java.util.stream.tripwire" value="true"/>
+            <sysproperty key="org.openjdk.java.util.stream.sand.mode" value="true"/>
+            <!-- properties specific to agent config -->
+            <jvmarg value="-Dcom.oracle.lambda.store.frames=false"/>
+            <jvmarg value="-Dcom.oracle.lambda.nrounds=1"/>
+            <jvmarg value="-javaagent:${agent.jar}"/>
+        </testng>
+    </target>
+
+    <target name="test-mangledp" depends="test-compile, build-mangler" >
+        <delete dir="tmp" />
+        <testng classpathref="mangled.class.path" outputdir="${test.reports.dir}"
+                excludedgroups="serialization-hostile">
+            <classfileset dir="${mangled.tests.dir}" includes="**/${test.pattern}.class"/>
+            <classfileset dir="${mangled.boottests.dir}" includes="**/${test.pattern}.class"/>
+            <jvmarg value="-Xbootclasspath/p:${agent.jar}"/>
+            <jvmarg value="-Xbootclasspath/p:${mangled.jdk.dir}"/>
+            <jvmarg value="-Xbootclasspath/p:${mangled.bootlib.dir}"/>
+            <jvmarg value="-Xbootclasspath/p:${mangled.boottests.dir}"/>
+            <jvmarg value="-Xbootclasspath/p:${lib.testng.jar}"/>
+            <!--<jvmarg value="-Dsun.io.serialization.extendedDebugInfo=true" />-->
+            <jvmarg value="-ea" />
+            <jvmarg value="-esa" />
+            <jvmarg value="-Xverify:none" />
+            <jvmarg value="-Xmx2500m" />
+            <sysproperty key="org.openjdk.java.util.stream.tripwire" value="true"/>
+            <sysproperty key="org.openjdk.java.util.stream.sand.mode" value="true"/>
+            <jvmarg value="-javaagent:${agent.jar}"/>
+        </testng>
+    </target>
+    <!-- mangler related,  end -->
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test-ng/tests/lambda/TestInterfaceBridges.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package lambda;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * TestInterfaceBridges
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class TestInterfaceBridges {
+    public void testCovariantOverrideLambda() {
+        B b = () -> "Foo";
+        assertEquals("Foo", b.make());
+        assertEquals("Foo", ((A) b).make());
+    }
+
+    public void testCovariantOverrideIC() {
+        B b = new B() {
+            @Override
+            public String make() {
+                return "Foo";
+            }
+        };
+        assertEquals("Foo", b.make());
+        assertEquals("Foo", ((A) b).make());
+    }
+
+    public static interface A {
+        Object make();
+    }
+
+    public static interface B extends A {
+        String make();
+    }
+
+    public void testCovariantMerge() {
+        D d = () -> "Foo";
+        assertEquals("Foo", d.make());
+        assertEquals("Foo", ((A) d).make());
+        assertEquals("Foo", ((C) d).make());
+    }
+
+    public static interface C {
+        String make();
+    }
+
+    public static interface D extends A, C {
+    }
+}
--- a/test/ProblemList.txt	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/ProblemList.txt	Mon Nov 11 23:17:30 2013 -0800
@@ -206,6 +206,10 @@
 # 8014719
 sun/net/www/http/HttpClient/ProxyTest.java                       generic-all
 
+# 7150552
+sun/net/www/protocol/http/B6299712.java                         macosx-all
+java/net/CookieHandler/CookieManagerTest.java                   macosx-all
+
 ############################################################################
 
 # jdk_nio
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/io/Serializable/defaultSVID/Child.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+class Child implements Parent, java.io.Serializable { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/io/Serializable/defaultSVID/DefaultSVID.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test default serial version id creation
+ *
+ * @compile ParentA.java Child.java
+ * @run main DefaultSVID moveParentA
+ * @compile ParentB.java
+ * @run main DefaultSVID
+ */
+
+import java.io.IOException;
+import java.io.ObjectStreamClass;
+import java.nio.file.*;
+import static java.nio.file.StandardCopyOption.*;
+
+public class DefaultSVID {
+
+    static String testClasses = System.getProperty("test.classes");
+
+    public static class MyClassLoader extends ClassLoader {
+        final String suffix;
+
+        public MyClassLoader(String suffix) {
+            super(null);
+            this.suffix = suffix;
+        }
+
+        public Class<?> defineAndResolve(String name) {
+            try {
+                String file;
+                if ("Parent".equals(name)) {
+                    file = name + suffix;
+                } else {
+                    file = name;
+                }
+                byte[] classBytes = Files.readAllBytes(Paths.get(testClasses, file + ".class"));
+                Class<?> ret = defineClass(name, classBytes, 0, classBytes.length);
+                resolveClass(ret);
+                return ret;
+            } catch (IOException ioe) {
+                throw new RuntimeException(ioe);
+            }
+        }
+    }
+
+    public static void main(String args[]) throws Exception {
+        if (args.length > 0) {
+            Files.move(Paths.get(testClasses, "Parent.class"),
+                       Paths.get(testClasses, "ParentA.class"),
+                       REPLACE_EXISTING);
+            return;
+        }
+
+        Files.move(Paths.get(testClasses, "Parent.class"),
+                   Paths.get(testClasses, "ParentB.class"),
+                   REPLACE_EXISTING);
+
+        MyClassLoader cl_nodefault = new MyClassLoader("A");
+        MyClassLoader cl_default = new MyClassLoader("B");
+
+        cl_nodefault.defineAndResolve("Parent");
+        cl_default.defineAndResolve("Parent");
+
+        Class<?> child_nodefault = cl_nodefault.defineAndResolve("Child");
+        Class<?> child_default = cl_default.defineAndResolve("Child");
+
+        ObjectStreamClass osc_child_nodefault = ObjectStreamClass.lookup(child_nodefault);
+        ObjectStreamClass osc_child_default = ObjectStreamClass.lookup(child_default);
+        
+        long svid_nodefault = osc_child_nodefault.getSerialVersionUID();
+        long svid_default = osc_child_default.getSerialVersionUID();
+
+        System.out.printf("svid_nodefault : %016X \n  svid_default : %016X\n",
+                          svid_nodefault, svid_default);
+
+        if (svid_nodefault != svid_default) {
+            throw new AssertionError("serial version IDs differ");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/io/Serializable/defaultSVID/ParentA.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+interface Parent {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/io/Serializable/defaultSVID/ParentB.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+interface Parent {
+    default void parent() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/Double/DoubleReducersTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary
+ * @(#) DoubleReducersTest.java
+ * @author Tristan Yan
+ * @run testng DoubleReducersTest
+ */
+
+import java.util.Random;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+public class DoubleReducersTest {
+    private final static int LOOP = 1 << 20;
+
+    private final static Random rand = new Random(System.currentTimeMillis());
+
+    @Test
+    public void testMax() {
+        for(int index = 0; index < LOOP; index++){
+            double d1 = rand.nextDouble();
+            double d2 = rand.nextDouble();
+            double expected = d1 > d2 ? d1 : d2;
+            assertEquals(Double.max(d1, d2), expected);
+        }
+    }
+
+    @Test
+    public void testMin() {
+        for(int index = 0; index < LOOP; index++){
+            double d1 = rand.nextDouble();
+            double d2 = rand.nextDouble();
+            double expected = d1 < d2 ? d1 : d2;
+            assertEquals(Double.min(d1, d2), expected);
+        }
+    }
+
+    @Test
+    public void testSum() {
+        for(int index = 0; index < LOOP; index++){
+            double d1 = rand.nextDouble();
+            double d2 = rand.nextDouble();
+            double expected = d1 + d2;
+            assertEquals(Double.sum(d1, d2), expected);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/Integer/IntegerReducersTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary
+ * @(#) IntegerReducersTest.java
+ * @author Tristan Yan
+ * @run testng IntegerReducersTest
+ */
+
+import java.util.Random;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+public class IntegerReducersTest {
+    private final static int LOOP = 1 << 20;
+
+    private final static Random rand = new Random(System.currentTimeMillis());
+
+    @Test
+    public void testMax() {
+        for(int index = 0; index < LOOP; index++){
+            int i1 = rand.nextInt();
+            int i2 = rand.nextInt();
+            int expected = i1 > i2 ? i1 : i2;
+            assertEquals(Integer.max(i1, i2), expected);
+        }
+    }
+
+    @Test
+    public void testMin() {
+        for(int index = 0; index < LOOP; index++){
+            int i1 = rand.nextInt();
+            int i2 = rand.nextInt();
+            int expected = i1 < i2 ? i1 : i2;
+            assertEquals(Integer.min(i1, i2), expected);
+        }
+    }
+
+    @Test
+    public void testSum() {
+        for(int index = 0; index < LOOP; index++){
+            int i1 = rand.nextInt();
+            int i2 = rand.nextInt();
+            int expected = i1 + i2;
+            assertEquals(Integer.sum(i1, i2), expected);
+        }
+    }
+
+    @Test
+    public void testUnsignedWithoutRadix(){
+        for(int index = 0; index < LOOP; index++){
+            int i = rand.nextInt();
+            assertEquals(Integer.parseUnsignedInt(Integer.toUnsignedString(i)), i);
+            assertEquals(Integer.toUnsignedString(i, 10), Integer.toUnsignedString(i));
+            if(i >= 0)
+                assertEquals(Integer.toUnsignedString(i), Integer.toString(i));
+        }
+    }
+
+    @Test
+    public void testUnsignedWithRadix(){
+        for(int index = 0; index < LOOP; index++){
+            int i = rand.nextInt();
+            int radix = Character.MIN_RADIX + rand.nextInt(Character.MAX_RADIX - Character.MIN_RADIX + 1);
+            assertEquals(Integer.parseUnsignedInt(Integer.toUnsignedString(i, radix), radix), i);
+            if(i >= 0)
+                assertEquals(Integer.toUnsignedString(i, radix), Integer.toString(i, radix));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/Long/LongReducersTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary
+ * @author Tristan Yan
+ * @run testng LongReducersTest
+ */
+
+import java.util.Random;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+public class LongReducersTest {
+    private final static int LOOP = 1 << 20;
+
+    private final static Random rand = new Random(System.currentTimeMillis());
+
+    @Test
+    public void testMax() {
+        for(int index = 0; index < LOOP; index++){
+            long l1 = rand.nextLong();
+            long l2 = rand.nextLong();
+            long expected = l1 > l2 ? l1 : l2;
+            assertEquals(Long.max(l1, l2), expected);
+        }
+    }
+
+    @Test
+    public void testMin() {
+        for(int index = 0; index < LOOP; index++){
+            long l1 = rand.nextLong();
+            long l2 = rand.nextLong();
+            long expected = l1 < l2 ? l1 : l2;
+            assertEquals(Long.min(l1, l2), expected);
+        }
+    }
+
+    @Test
+    public void testSum() {
+        for(int index = 0; index < LOOP; index++){
+            long l1 = rand.nextLong();
+            long l2 = rand.nextLong();
+            long expected = l1 + l2;
+            assertEquals(Long.sum(l1, l2), expected);
+        }
+    }
+
+    @Test
+    public void testUnsignedWithoutRadix(){
+        for(int index = 0; index < LOOP; index++){
+            long l = rand.nextLong();
+            assertEquals(Long.parseUnsignedLong(Long.toUnsignedString(l)), l);
+            assertEquals(Long.toUnsignedString(l, 10), Long.toUnsignedString(l));
+            if(l >= 0)
+                assertEquals(Long.toUnsignedString(l), Long.toString(l));
+        }
+    }
+
+    @Test
+    public void testUnsignedWithRadix(){
+        for(int index = 0; index < LOOP; index++){
+            long l = rand.nextLong();
+            int radix = Character.MIN_RADIX + rand.nextInt(Character.MAX_RADIX - Character.MIN_RADIX + 1);
+            assertEquals(Long.parseUnsignedLong(Long.toUnsignedString(l, radix), radix), l);
+            if(l >= 0)
+                assertEquals(Long.toUnsignedString(l, radix), Long.toString(l, radix));
+        }
+    }
+
+    @Test
+    public void testCompareUnsigned() {
+        for(int index = 0; index < LOOP; index++){
+            long l1 = rand.nextLong();
+            long l2 = rand.nextLong();
+            assertEquals(Long.compareUnsigned(l1, l2),
+                Long.compare(Long.MAX_VALUE + l1, Long.MAX_VALUE + l2));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/String/JoinTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary test for String.join(CharSequence , CharSequence...) and
+ *          String.join(CharSequence , Iterable<? extends CharSequence>).
+ * @(#) JoinTest.java
+ * @author Tristan Yan
+ * @run testng JoinTest
+ */
+
+import java.util.*;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+public class JoinTest {
+    private final String[] LANGUAGES = { "ABAP", "ALGOL", "ActionScript",
+        "AppleScript","AspectJ", "Assembly language", "AutoLISP", "AWK", "Bash",
+        "C", "C Shell", "CICS", "COBOL", "Cool", "CSH", "DCL", "Delphi",
+        "Eiffel", "F#", "Formula", "Fortran", "FoxBase", "FoxPro", "Groovy",
+        "Haskell", "J#", "JCL", "JavaScript", "Ksh", "LINC", "Lisp", "Logo",
+        "MASM", "MATLAB", "NASM", "XML", "Objective-C", "Pascal", "Perl",
+        "PL/I", "PostScript", "PowerBuilder", "PowerShell", "Prolog", "Pro*C",
+        "Python", "QBasic", "REBOL", "Ruby", "Scheme", "Sed", "Smalltalk",
+        "SQL", "VBScript" };
+
+
+    private final String[] DELIMETERS = {"`", "~", "!", "@", "#", "$", "%", "^",
+        "&", "*", "(", ")", "-", "_", "+", "=", "\\", "|", ",", ".", "/", ":",
+        ";", "\"", "\"", "\n", "\t", " ", "\t"};
+
+    @Test
+    public void testJoin() {
+        //HashSet sort data with hashCode(), iterator order by hashCode()
+        List<String> lanugageList = Arrays.asList(LANGUAGES);
+        Set<String> lanugageSet = new HashSet<>(lanugageList);
+        Random rnd = new Random();
+        String delimeter = DELIMETERS[rnd.nextInt(DELIMETERS.length)];
+        StringBuilder sb = new StringBuilder();
+        Iterator<String> it = lanugageSet.iterator();
+        int pos = 0;
+        while(it.hasNext()) {
+            sb.append(it.next());
+            if(++pos < lanugageSet.size())
+                sb.append(delimeter);
+        }
+        String result2 = String.join(delimeter, lanugageSet);
+        String result1 = sb.toString();
+        assertEquals(result2, result1);
+
+        Collections.shuffle(lanugageList, new Random(rnd.nextInt()));
+        String[] shuffledArray = new String[lanugageList.size()];
+        lanugageList.toArray(shuffledArray);
+        result1 = String.join(delimeter, shuffledArray);
+        result2 = String.join(delimeter, lanugageList);
+        StringBuilder expectedSB = new StringBuilder();
+        for(int index = 0; index < lanugageList.size() - 1; index++)
+            expectedSB.append(lanugageList.get(index)).append(delimeter);
+        expectedSB.append(lanugageList.get(lanugageList.size() - 1));
+        assertEquals(expectedSB.toString(), result1);
+        assertEquals(result2, result1);
+
+        String single = LANGUAGES[rnd.nextInt(LANGUAGES.length)];
+        assertEquals(String.join(delimeter, new String[]{single}), single);
+        assertEquals(String.join(delimeter, new String[]{single}), single);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/StringBuilder/AddAllTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary test for StringBuilde/StringBuffer.addAll()
+ * @library /sqeutil
+ * @author Tristan Yan
+ * @run testng AddAllTest
+ */
+
+import java.util.*;
+import java.util.stream.*;
+import static org.testng.Assert.*;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class AddAllTest {
+    private final static int LINE_NUM = 1 << 8;
+
+    private final static int LINE_MIN_CHARACTER_LEN = 2;
+
+    private final static int LINE_MAX_CHARACTER_LEN = 80;
+
+    @Test(dataProvider = "generateData")
+    public void builderAddAll(String[] buff){
+        String str = Arrays.stream(buff).collect(Collectors.joining());
+        int start = 0;
+        for(int index = 0; index < buff.length; index++){
+            assert(start + buff[index].length() <= str.length());
+            assertEquals(str.substring(start, start + buff[index].length()), buff[index]);
+            start += buff[index].length();
+        }
+    }
+
+    @Test(dataProvider = "generateData")
+    public void bufferAddAll(String[] buff){
+        StringBuffer sb = Arrays.stream(buff).collect(StringBuffer::new, StringBuffer::append, (s, o) -> s.append(o));
+        String str = sb.toString();
+        int start = 0;
+        for(int index = 0; index < buff.length; index++){
+            assert(start + buff[index].length() <= str.length());
+            assertEquals(str.substring(start, start + buff[index].length()), buff[index]);
+            start += buff[index].length();
+        }
+    }
+
+    @DataProvider
+    public Object[][] generateData(){
+        Object[][] data = new Object[LINE_NUM][];
+        for(int line = 0; line < LINE_NUM; line++) {
+            List<Object> l = new ArrayList<>();
+            String[] buffer = new String[line];
+            for(int row = 0; row < line; row++)
+                buffer[row] = StringUtilities.randomString(LINE_MAX_CHARACTER_LEN,
+                    0);
+            data[line] = new Object[]{buffer};
+        }
+        return data;
+    }
+}
--- a/test/java/lang/ThreadLocal/Basic.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/java/lang/ThreadLocal/Basic.java	Mon Nov 11 23:17:30 2013 -0800
@@ -30,6 +30,7 @@
 public class Basic {
     static ThreadLocal n = new ThreadLocal() {
         int i = 0;
+        @Override
         protected synchronized Object initialValue() {
             return new Integer(i++);
         }
@@ -43,11 +44,12 @@
         // Start the threads
         for(int i=0; i<threadCount; i++) {
             th[i] = new Thread() {
+                @Override
                 public void run() {
                     int threadId = ((Integer)(n.get())).intValue();
                     for (int j=0; j<threadId; j++) {
                         x[threadId]++;
-                        Thread.currentThread().yield();
+                        Thread.yield();
                     }
                 }
             };
--- a/test/java/lang/ThreadLocal/ImmutableLocal.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/java/lang/ThreadLocal/ImmutableLocal.java	Mon Nov 11 23:17:30 2013 -0800
@@ -33,15 +33,18 @@
      * {@link ThreadLocal} guaranteed to always return the same reference.
      */
     abstract public static class ImmutableThreadLocal extends ThreadLocal {
+        @Override
         public void set(final Object value) {
             throw new RuntimeException("ImmutableThreadLocal set called");
         }
 
         // force override
+        @Override
         abstract protected Object initialValue();
     }
 
     private static final ThreadLocal cache = new ImmutableThreadLocal() {
+        @Override
         public Object initialValue() {
             return Thread.currentThread().getName();
         }
--- a/test/java/lang/ThreadLocal/InitialValue.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/java/lang/ThreadLocal/InitialValue.java	Mon Nov 11 23:17:30 2013 -0800
@@ -34,8 +34,9 @@
 
     public class MyLocal extends ThreadLocal<String> {
         String val;
+        @Override
         protected String initialValue() {
-            other = new ThreadLocal<String>();
+            other = new ThreadLocal<>();
             // This should reuse the map that the containing get() created
             // or visa versa (i.e. instead of a second map being created).
             other.set("Other");
@@ -43,6 +44,7 @@
         }
     }
 
+    @Override
     public void run() {
         MyLocal l = new MyLocal();
         // This should pick up the initial value
--- a/test/java/lang/ThreadLocal/TLRemoveTest.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/java/lang/ThreadLocal/TLRemoveTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -32,6 +32,7 @@
     private static final int REMOVE_SET_VALUE = 102;
 
     static ThreadLocal<Integer> n = new ThreadLocal<Integer>() {
+        @Override
         protected synchronized Integer initialValue() {
             return INITIAL_VALUE;
         }
@@ -51,11 +52,12 @@
         for(int i = 0; i<threadCount; i++) {
             final int threadId = i;
             th[i] = new Thread() {
+                @Override
                 public void run() {
                     try{
                         n.set(threadId); // Sets threadId as threadlocal value...
                         for (int j = 0; j<threadId; j++)
-                            Thread.currentThread().yield();
+                            Thread.yield();
 
                         // To remove the ThreadLocal ....
                         for(int removeId  : removeNode)
--- a/test/java/lang/ThreadLocal/TestThreadId.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/java/lang/ThreadLocal/TestThreadId.java	Mon Nov 11 23:17:30 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,8 +49,9 @@
     }
 
     // Each child thread just publishes its id value for validation
+    @Override
     public void run() {
-        value = id.get();
+        value = ThreadId.get();
     }
 
     public static void main(String args[]) throws Throwable {
--- a/test/java/lang/invoke/lambda/LambdaAccessControlTest.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/java/lang/invoke/lambda/LambdaAccessControlTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -25,11 +25,12 @@
  * @test
  * @bug 8003881
  * @summary tests Lambda expression with a a security manager at top level
- * @compile -XDignore.symbol.file LambdaAccessControlTest.java LUtils.java
+ * @compile -XDignore.symbol.file LambdaAccessControlDoPrivilegedTest.java LambdaAccessControlTest.java
  *
  * @run main/othervm LambdaAccessControlTest
  */
 
+
 public class LambdaAccessControlTest extends LUtils {
     public static void main(String... args) {
         System.setSecurityManager(new SecurityManager());
--- a/test/java/lang/invoke/lambda/LambdaSerialization.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/java/lang/invoke/lambda/LambdaSerialization.java	Mon Nov 11 23:17:30 2013 -0800
@@ -25,6 +25,7 @@
 @test
 @bug 8004970
 @summary Lambda serialization
+
 */
 
 import java.io.*;
@@ -65,11 +66,11 @@
         }
         assertTrue(assertionCount == 3);
     }
-
+    
     static void write(ObjectOutput out, LSI lamb) throws IOException {
         out.writeObject(lamb);
     }
-
+    
     static void readAssert(ObjectInputStream in, String expected)  throws IOException, ClassNotFoundException {
         LSI ls = (LSI) in.readObject();
         String result = ls.convert("X");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/invoke/lambda/MethodReferenceCallerSensitive.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+@test
+@bug 8020816
+@summary Metafactory crashes on code with method reference
+*/
+
+import java.lang.reflect.Field;
+import java.util.function.Function;
+
+public class MethodReferenceCallerSensitive { 
+    private static <T> void test(T arg) { 
+        Function<Class<T>,Field[]> firstFunction = Class<T>::getFields; 
+    } 
+    public static void main(String[] args) { 
+        test("Hello World"); 
+    } 
+} 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/invoke/lambda/RepetitiveLambdaSerialization.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8027681
+ * @summary Lambda serialization fails once reflection proxy generation kicks in
+ * @author  Robert Field
+ * @run main/othervm RepetitiveLambdaSerialization
+ */
+
+import java.io.*;
+
+public class RepetitiveLambdaSerialization {
+
+    static final int REPS = 20;
+
+    public static void main(String[] args) throws Exception {
+        LSI ls = z -> "[" + z + "]";
+        for (int i = 0; i < REPS; ++i) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutput out = new ObjectOutputStream(baos);
+            out.writeObject(ls);
+            out.flush();
+            out.close();
+        }
+        System.out.println("Passed.");
+    }
+}
+
+interface LSI extends Serializable {
+    String convert(String x);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/nio/Files/FilesLambdaTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary function test for Files.list()/find()/walk()/lines()
+ * @library /sqeutil
+ * @(#) FilesLambdaTest.java
+ * @author Tristan Yan
+ * @run testng/othervm FilesLambdaTest
+ */
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.NotDirectoryException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.*;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class FilesLambdaTest {
+    private static final Random rand = new Random(System.nanoTime());
+
+    private static final String TEST_SRC = System.getProperty("test.src");
+
+    private static final String ROOT_NAME = "FilesLambdaTest" + System.nanoTime();
+
+    private static final String LINES_TEST_FILE = "lines" +  System.nanoTime();
+
+    private static final int MAX_FILES_NUMBER = 1 << 6;
+
+    private static final Charset UTF8 = Charset.forName("UTF-8");
+
+    private final static int MIN_LEN = 1 << 2;
+
+    private final static int MAX_LEN = 1 << 8;
+
+    private final static int LINES_NUM = 1 << 8;
+
+    private static final String[][] folders = {
+        {"A01"},
+        {"A01", "AA02"},
+        {"A01", "AB02"},
+        {"A01", "AC02"},
+        {"B01"},
+        {"B01", "BA02"},
+        {"B01", "BA02", "BAA03"},
+        {"B01", "BA02", "BAA03", "BAAA04", "BAAAA05", "BAAAAA06", "BAAAAAA07",
+         "BAAAAAAA08", "BAAAAAAAA09", "BAAAAAAAAA10", "BAAAAAAAAAA11"},
+        {"C01"},
+        {"C01", "CA02"},
+        {"C01", "CD02"},
+        {"D01", "DA02", "DAA03", "DAAA04", "DAAAA05", "DAAAAA06", "DAAAAAA07"},
+        {"E01"},
+        {"E01", "EA02"},
+        {"E01", "EB02", "EBB03"},
+        {"E01", "EC02", "ECC03", "ECCC04"},
+        {"E01", "ED02", "EDD03", "EDDD04", "EDDDD05"},
+        {"E01", "EE02", "EEE03", "EEEE04", "EEEEE05", "EEEEEE06"},
+        {"E01", "EF02", "EFF03", "EFFF04", "EFFFF05", "EFFFFF06"},
+        {"E01", "EG02", "EGG03", "EGGG04", "EGGGG05", "EGGGGG06", "EGGGGGG07"},
+        {"E01", "EH02", "EHH03", "EHHH04", "EHHHH05", "EHHHHH06", "EHHHHHH07",
+         "EHHHHHHH08"},
+        {"E01", "EI02", "EII03", "EIII04", "EIIII05", "EIIIII06", "EIIIIII07",
+         "EIIIIIII08", "EIIIIIIII09"},
+        {"E01", "EJ02", "EJJ03", "EJJJ04", "EJJJJ05", "EJJJJJ06", "EJJJJJJ07",
+         "EJJJJJJJ08", "EJJJJJJJJ09", "EJJJJJJJJJ10"},
+        {"E01", "EK02", "EKK03", "EKKK04", "EKKKK05", "EKKKKK06", "EKKKKKK07",
+         "EKKKKKKK08", "EKKKKKKKK09", "EKKKKKKKKK10", "EJJJJJJJJJJ11"}
+    };
+
+    private Path root;
+
+    private Path testFile;
+
+    private Path notExistPath;
+
+    final Consumer<Path> writeReverseWithLink = path -> {
+        int filesCount = rand.nextInt(MAX_FILES_NUMBER);
+        for(int count = 0; count < filesCount; count++) {
+            String fileName = String.valueOf(rand.nextLong());
+            Path file = path.resolve(fileName);
+            String linkName = String.valueOf(rand.nextLong());
+            Path link = path.resolve(linkName);
+            try (BufferedWriter writer
+                    = Files.newBufferedWriter(Files.createFile(file), UTF8)) {
+                writer.write(new StringBuilder(fileName).reverse().toString(),
+                        0, fileName.length());
+                Files.createSymbolicLink(link, file);
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+    };
+
+    @BeforeClass
+    public void filesSetUp() throws IOException {
+        List<Path> paths = new ArrayList<>();
+        root = Paths.get(TEST_SRC, ROOT_NAME);
+        paths.add(Files.createDirectory(root));
+        for(int i = 0; i < folders.length; i++ ) {
+            String[] toBeCreated = folders[i];
+            Path folder = Paths.get(ROOT_NAME, toBeCreated);
+            paths.add(Files.createDirectories(folder));
+        }
+        paths.forEach(writeReverseWithLink);
+
+        testFile = Paths.get(LINES_TEST_FILE);
+        try (BufferedWriter writer
+                = Files.newBufferedWriter(Files.createFile(testFile), UTF8)) {
+            for(int i = 0; i< LINES_NUM; i++) {
+                String line = StringUtilities.randomString(MAX_LEN, MIN_LEN);
+                writer.write(line, 0, line.length());
+            }
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        }
+
+        String NOT_EXIST = "NOT_EXIST";
+        notExistPath = Paths.get(TEST_SRC, NOT_EXIST);
+    }
+
+    @AfterClass
+    public void filesTearDown() throws IOException {
+        if(root != null) {
+            Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
+                @Override
+                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                    throws IOException {
+                    Files.delete(file);
+                    return FileVisitResult.CONTINUE;
+                }
+                @Override
+                public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+                    throws IOException{
+                    Files.delete(dir);
+                    return FileVisitResult.CONTINUE;
+                }
+            });
+        }
+        if(testFile != null) {
+            Files.delete(testFile);
+        }
+    }
+
+    @Test
+    public void testFilesList() throws IOException {
+        checkFilesList(root);
+    }
+
+    @Test
+    public void testWalk() throws IOException{
+        String[] dir = folders[rand.nextInt(folders.length)];
+        Path walkFolder = Paths.get(ROOT_NAME, dir);
+        final int maxDepth = rand.nextInt(11);
+        List<Path> expectedFullFileList = new ArrayList<>();
+        List<Path> expectedMaxDepthFileList = new ArrayList<>();
+
+        List<Path> expectedFullSymList = new ArrayList<>();
+        List<Path> expectedMaxDepthSymList = new ArrayList<>();
+
+        List<Path> expectedFullDirList = new ArrayList<>();
+        List<Path> expectedMaxDepthDirList = new ArrayList<>();
+
+        Files.walkFileTree(walkFolder, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+                throws IOException {
+                if (walkFolder.relativize(file).getNameCount() <= maxDepth) {
+                    expectedMaxDepthFileList.add(file);
+                    if(Files.isSymbolicLink(file)) {
+                        expectedMaxDepthSymList.add(file);
+                    }
+                }
+                expectedFullFileList.add(file);
+                if(Files.isSymbolicLink(file)) {
+                    expectedFullSymList.add(file);
+                }
+                return FileVisitResult.CONTINUE;
+            }
+            @Override
+            public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+                throws IOException{
+                if (walkFolder.relativize(dir).getNameCount() <= maxDepth
+                        || walkFolder.equals(dir)) {
+                    expectedMaxDepthDirList.add(dir);
+                }
+                expectedFullDirList.add(dir);
+                return FileVisitResult.CONTINUE;
+            }
+        });
+        Collections.sort(expectedFullFileList);
+        Collections.sort(expectedMaxDepthFileList);
+        Collections.sort(expectedFullSymList);
+        Collections.sort(expectedMaxDepthSymList);
+        Collections.sort(expectedFullDirList);
+        Collections.sort(expectedMaxDepthDirList);
+
+        assertEquals(expectedMaxDepthFileList,
+                Files.walk(walkFolder, maxDepth).filter(p -> !Files.isDirectory(p)).
+                sorted().collect(Collectors.toList()));
+        assertEquals(expectedMaxDepthSymList,
+                Files.walk(walkFolder, maxDepth).filter(p -> Files.isSymbolicLink(p)).
+                sorted().collect(Collectors.toList()));
+        assertEquals(expectedMaxDepthDirList,
+                Files.walk(walkFolder, maxDepth).filter(p -> Files.isDirectory(p)).
+                sorted().collect(Collectors.toList()));
+        assertEquals(expectedFullFileList,
+                Files.walk(walkFolder).filter(p -> !Files.isDirectory(p)).
+                sorted().collect(Collectors.toList()));
+        assertEquals(expectedFullSymList,
+                Files.walk(walkFolder).filter(p -> Files.isSymbolicLink(p)).
+                sorted().collect(Collectors.toList()));
+        assertEquals(expectedFullDirList,
+                Files.walk(walkFolder).filter(p -> Files.isDirectory(p)).
+                sorted().collect(Collectors.toList()));
+    }
+
+    @Test
+    public void testFind() throws IOException{
+        String[] dir = folders[rand.nextInt(folders.length)];
+        Path walkFolder = Paths.get(ROOT_NAME, dir);
+        String walkFoderName = dir[dir.length - 1];
+
+        int walkFolderDepth = Integer.parseInt(walkFoderName.substring(walkFoderName.length() - 2));
+        int maxDepth = rand.nextInt(11);
+        Stream<Path> stream
+                = Files.find(walkFolder, maxDepth, (p,bfa) -> Files.isSymbolicLink(p));
+        stream.forEach(p -> {
+            assertTrue(Files.isSymbolicLink(p));
+            assertFalse(Files.isDirectory(p));
+            assertFalse(Files.isRegularFile(p, LinkOption.NOFOLLOW_LINKS));
+            String parentName = p.getParent().toFile().getName();
+            int depth = Integer.parseInt(parentName.substring(parentName.length() - 2));
+            assertTrue(depth - walkFolderDepth < maxDepth);
+        });
+
+        assertEquals(Files.find(walkFolder, maxDepth, (p,bfa) -> Files.isSymbolicLink(p)).toArray(),
+                Files.find(walkFolder, maxDepth, (p,bfa) -> bfa.isSymbolicLink()).toArray());
+    }
+
+    @Test
+    public void testLines() throws IOException{
+        Stream<String> stream = Files.lines(testFile, UTF8);
+        List<String> lines = Files.readAllLines(testFile, UTF8);
+        assertEquals(lines, stream.collect(Collectors.toList()));
+    }
+
+    @Test(expectedExceptions = IOException.class)
+    public void testListNoReadAccess() throws IOException{
+        Files.list(notExistPath);
+    }
+
+    @Test(expectedExceptions = NotDirectoryException.class)
+    public void testListNotDirectory() throws IOException{
+        Files.list(testFile);
+    }
+
+    @Test(expectedExceptions = IOException.class)
+    public void testFindNoExist() throws IOException{
+        Files.find(notExistPath, Integer.MAX_VALUE, (p, bfa) -> true);
+    }
+
+    @Test(expectedExceptions = IOException.class)
+    public void testLinesNoExist() throws IOException{
+        Files.lines(notExistPath, UTF8);
+    }
+
+    @Test(expectedExceptions = IOException.class)
+    public void testWalkNoExist() throws IOException{
+        Files.walk(notExistPath);
+    }
+
+    @Test(expectedExceptions = IOException.class)
+    public void testWalkNoExistWithDepth() throws IOException{
+        Files.walk(notExistPath, Integer.MAX_VALUE);
+    }
+
+    public void checkFilesList(Path checkPath){
+        try {
+            assert(Files.isDirectory(checkPath));
+            Files.list(checkPath).filter(p -> Files.isDirectory(p)).forEach(p -> checkFilesList(p));
+            assertEquals(Files.list(checkPath).filter(p -> Files.isRegularFile(p, LinkOption.NOFOLLOW_LINKS)).count(),
+                    Files.list(checkPath).filter(p -> Files.isSymbolicLink(p)).count());
+            assertTrue(Files.list(checkPath).filter(p -> Files.isRegularFile(p, LinkOption.NOFOLLOW_LINKS)).allMatch(file -> contentRevered(file)));
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    private boolean contentRevered(Path path) {
+        try (BufferedReader reader = Files.newBufferedReader(path, UTF8)){
+            String fileName = path.getName(path.getNameCount() -1).toString();
+            String reversed = new StringBuilder(reader.readLine()).reverse().toString();
+            return (fileName.equals(reversed));
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Arrays/ArraysLambdaTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Lambda unit test for Arrays.
+ * @library /sqeutil
+ * @(#) ArraysTest.java
+ * @author Tristan Yan
+ * @run testng ArraysLambdaTest
+ */
+
+import java.util.Arrays;
+import java.util.Random;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+public class ArraysLambdaTest {
+    private final static int ARRAY_SIZE = 1 << 8;
+
+    private final static int MIN_LEN = 1 << 2;
+
+    private final static int MAX_LEN = 1 << 6;
+
+    private final static Random rand = new Random(System.currentTimeMillis());
+
+    private long[] generateLongData(int size) {
+        long[] array = new long[size];
+        for(int i = 0; i < size; i++) {
+            array[i] = rand.nextLong();
+        }
+        return array;
+    }
+
+    private int[] generateIntData(int size) {
+        int[] array = new int[size];
+        for(int i = 0; i < size; i++) {
+            array[i] = rand.nextInt();
+        }
+        return array;
+    }
+
+    private double[] generateDoubleData(int size) {
+        double[] array = new double[size];
+        //Precision could be changed when do parallel calculation, we only use
+        //integer to test it to prevent precision lost issue
+        for(int i = 0; i < size; i++) {
+            array[i] = rand.nextInt(1024);
+        }
+        return array;
+    }
+
+    private String[] generateStringData(int size) {
+        String[] array = new String[size];
+        for(int i = 0; i < size; i++) {
+            array[i] = StringUtilities.randomString(MAX_LEN, MIN_LEN);
+        }
+        return array;
+    }
+
+    private StringBuilder[] generateSBData(int size) {
+        StringBuilder[] array = new StringBuilder[size];
+        for(int i = 0; i < size; i++) {
+            array[i] = new StringBuilder(StringUtilities.randomString(MAX_LEN, MIN_LEN));
+        }
+        return array;
+    }
+
+    @Test
+    public void testParallelPrefixForInt() {
+        int startIndex = rand.nextInt(ARRAY_SIZE);
+        int endIndex = startIndex + rand.nextInt(ARRAY_SIZE + 1 - startIndex);
+
+        int[] intArr1 = generateIntData(ARRAY_SIZE);
+        int[] intArr2 = Arrays.copyOf(intArr1, ARRAY_SIZE);
+        int[] intBackArr = Arrays.copyOf(intArr1, ARRAY_SIZE);
+        Arrays.parallelPrefix(intArr1, LambdaUtilities.addIntBinaryOperator());
+        assertEquals(intArr1.length, intBackArr.length);
+        int totalInt = 0;
+        for(int i = 0; i < ARRAY_SIZE; i++) {
+            totalInt += intBackArr[i];
+            assertEquals(totalInt, intArr1[i]);
+        }
+        Arrays.parallelPrefix(intArr2, startIndex, endIndex, LambdaUtilities.addIntBinaryOperator());
+        totalInt = 0;
+        for(int i = startIndex; i < endIndex; i++) {
+            totalInt += intBackArr[i];
+            assertEquals(totalInt, intArr2[i]);
+        }
+    }
+
+    @Test
+    public void testParallelPrefixForLong() {
+        int startIndex = rand.nextInt(ARRAY_SIZE);
+        int endIndex = startIndex + rand.nextInt(ARRAY_SIZE + 1 - startIndex);
+        long[] longArr1 = generateLongData(ARRAY_SIZE);
+        long[] longArr2 = Arrays.copyOf(longArr1, ARRAY_SIZE);
+        long[] longBackArr = Arrays.copyOf(longArr1, ARRAY_SIZE);
+        Arrays.parallelPrefix(longArr1, LambdaUtilities.addLongBinaryOperator());
+        assertEquals(longArr1.length, longBackArr.length);
+        long totalLong = 0;
+        for(int i = 0; i < ARRAY_SIZE; i++) {
+            totalLong += longBackArr[i];
+            assertEquals(totalLong, longArr1[i]);
+        }
+        Arrays.parallelPrefix(longArr2, startIndex, endIndex, LambdaUtilities.addLongBinaryOperator());
+        totalLong = 0;
+        for(int i = startIndex; i < endIndex; i++) {
+            totalLong += longBackArr[i];
+            assertEquals(totalLong, longArr2[i]);
+        }
+    }
+
+    @Test
+    public void testParallelPrefixForDouble() {
+        int startIndex = rand.nextInt(ARRAY_SIZE);
+        int endIndex = startIndex + rand.nextInt(ARRAY_SIZE + 1 - startIndex);
+        double[] doubleArr1 = generateDoubleData(ARRAY_SIZE);
+        double[] doubleArr2 = Arrays.copyOf(doubleArr1, ARRAY_SIZE);
+        double[] doubleBackArr = Arrays.copyOf(doubleArr1, ARRAY_SIZE);
+        Arrays.parallelPrefix(doubleArr1, LambdaUtilities.addDoubleBinaryOperator());
+        assertEquals(doubleArr1.length, doubleBackArr.length);
+        double totalDouble = 0;
+        for(int i = 0; i < ARRAY_SIZE; i++) {
+            totalDouble += doubleBackArr[i];
+            assertEquals(totalDouble, doubleArr1[i]);
+        }
+        Arrays.parallelPrefix(doubleArr2, startIndex, endIndex, LambdaUtilities.addDoubleBinaryOperator());
+        totalDouble = 0;
+        for(int i = startIndex; i < endIndex; i++) {
+            totalDouble += doubleBackArr[i];
+            assertEquals(totalDouble, doubleArr2[i]);
+        }
+    }
+
+    @Test
+    public void testParallelPrefix() {
+        int startIndex = rand.nextInt(ARRAY_SIZE);
+        int endIndex = startIndex + rand.nextInt(ARRAY_SIZE + 1 - startIndex);
+        StringBuilder[] sbArr1 = generateSBData(ARRAY_SIZE);
+        StringBuilder[] sbArr2 = Arrays.copyOf(sbArr1, ARRAY_SIZE);
+        StringBuilder[] sbBackArr = Arrays.copyOf(sbArr1, ARRAY_SIZE);
+        Arrays.parallelPrefix(sbArr1, LambdaUtilities.appendSBBinaryOperator());
+        assertEquals(sbArr1.length, sbBackArr.length);
+        StringBuilder sbTotal = new StringBuilder();
+        for(int i = 0; i < ARRAY_SIZE; i++) {
+            sbTotal.append(sbBackArr[i]);
+            assertEquals(sbTotal.toString(), sbArr1[i].toString());
+        }
+        Arrays.parallelPrefix(sbArr2, startIndex, endIndex, LambdaUtilities.appendSBBinaryOperator());
+        sbTotal = new StringBuilder();
+        for(int i = startIndex; i < endIndex; i++) {
+            sbTotal.append(sbBackArr[i]);
+            assertEquals(sbTotal.toString(), sbArr2[i].toString());
+        }
+    }
+
+    @Test
+    public void testSetAll() {
+        boolean[] both = new boolean[]{true, false};
+        for(boolean isParallel:both) {
+            //test Arrays.setAll(double[], IntFunction)
+            int[] iArray = new int[ARRAY_SIZE];
+            if (isParallel)
+                Arrays.parallelSetAll(iArray, i -> 2 * i);
+            else
+                Arrays.setAll(iArray, i -> 2 * i);
+            for(int i = 0; i < iArray.length; i++)
+                assertEquals(iArray[i], 2 * i);
+
+            //test Arrays.setAll(long[], IntFunction)
+            long[] lArray = new long[ARRAY_SIZE];
+            if (isParallel)
+                Arrays.parallelSetAll(lArray, i -> (long)i << 32);
+            else
+                Arrays.setAll(lArray, i -> (long)i << 32);
+            for(int i = 0; i < lArray.length; i++)
+                assertEquals(lArray[i] >> 32, i);
+
+            //test Arrays.setAll(double[], IntToDoubleFunction)
+            double[] dArray = new double[ARRAY_SIZE];
+            if (isParallel)
+                Arrays.parallelSetAll(dArray, i -> Math.sin(i));
+            else
+                Arrays.setAll(dArray, i -> Math.sin(i));
+            for(int i = 0; i < dArray.length; i++)
+                assertEquals(dArray[i], Math.sin(i));
+
+            //test Arrays.setAll(T[], IntFunction<? extends T>)
+            //This is a other version of Arrays.copy()
+            String[] sArrExpected = generateStringData(ARRAY_SIZE);
+            String[] sArr = new String[ARRAY_SIZE];
+            if (isParallel)
+                Arrays.parallelSetAll(sArr, i -> sArrExpected[i]);
+            else
+                Arrays.setAll(sArr, i -> sArrExpected[i]);
+            for(int i = 0; i < sArr.length; i++)
+                assertEquals(sArrExpected[i], sArrExpected[i]); 
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Arrays/ParallelSet.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary unit test for Arrays.ParallelSet()/set().
+ * @author Tristan Yan
+ * @run testng ParallelSet
+ */
+
+import java.util.Arrays;
+import java.util.function.IntFunction;
+import java.util.function.IntToDoubleFunction;
+import java.util.function.IntToLongFunction;
+import java.util.function.IntUnaryOperator;
+import static org.testng.Assert.*;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class ParallelSet {
+    //Array size less than MIN_PARTITION
+    private final static int SMALL_ARRAY_SIZE = 1 << 3;
+    
+    //Array size equals MIN_PARTITION
+    private final static int THRESHOLD_ARRAY_SIZE = 1 << 4;
+
+    //Array size greater than MIN_PARTITION
+    private final static int MEDIUM_ARRAY_SIZE = 1 << 8;
+
+    //Array size much greater than MIN_PARTITION
+    private final static int LARGE_ARRAY_SIZE = 1 << 12;
+    
+    private final static int[] ARRAY_SIZE_COLLECTION  = new int[]{ 
+        SMALL_ARRAY_SIZE, THRESHOLD_ARRAY_SIZE,MEDIUM_ARRAY_SIZE, LARGE_ARRAY_SIZE};
+
+    @DataProvider
+    public static Object[][] intSet(){
+        return genericData("Arrays.parrallelSetAll/setAll(new int[%d],IntUnaryOperator)",
+                int[]::<Integer>new, new IntUnaryOperator[]{i -> i * 2, i -> i * 2 + 1});
+    }
+
+    @DataProvider
+    public static Object[][] longSet(){
+        return genericData("Arrays.parrallelSetAll/setAll(new long[%d],IntToLongeFunction)",
+                long[]::<Integer>new, new IntToLongFunction[]{ i -> i * 2, i -> i * 2 + 1});
+    }
+
+    @DataProvider
+    public static Object[][] doubleSet(){
+        return genericData("Arrays.parallelSetAll/setAll(new double[%d],IntToDoubleFunction)",
+                double[]::<Integer>new, new IntToDoubleFunction[]{i -> i * 2, i -> i * 2 + 1});
+    }
+    
+    @DataProvider
+    public static Object[][] stringSet(){
+        return genericData("Arrays.parallelSetAll/setAll(new String[%d],IntFunction<String>)",
+                String[]::<Integer>new, new IntFunction[]{Integer::toString});
+    }
+
+    private static <T, OPS> Object[][] genericData(String description, IntFunction<T> generateFunc, OPS[] funcs) {
+        //test arrays which size is equals n-1, n, n+1
+        Object[][] data = new Object[ARRAY_SIZE_COLLECTION.length * 3 * funcs.length][4];
+        for(int n = 0; n < ARRAY_SIZE_COLLECTION.length; n++ ) {
+            for(int testValue = -1 ; testValue <= 1; testValue++) {
+                int array_size = ARRAY_SIZE_COLLECTION[n] + testValue;
+                for(int funcN = 0; funcN < funcs.length; funcN++) {
+                    int index = n * 3 * funcs.length + (testValue + 1) * funcs.length + funcN;
+                    data[index][0] = String.format(description, array_size);
+                    data[index][1] = array_size;
+                    data[index][2] = generateFunc;
+                    data[index][3] = funcs[funcN];
+                }
+            }
+        }
+        return data;
+    }
+
+    @Test(dataProvider="intSet")
+    public void testSetAllForInt(String description,int size, IntFunction<int[]> dataFunc, IntUnaryOperator iuo) {
+        int[] expectedResult = dataFunc.apply(size);
+        for(int i = 0; i < size; i++)
+            expectedResult[i] = iuo.applyAsInt(i);
+                
+        int[] sequentialResult = dataFunc.apply(size);
+        Arrays.setAll(sequentialResult, iuo);
+        assertEquals(sequentialResult, expectedResult);
+
+        int[] parallelResult  = dataFunc.apply(size);
+        Arrays.setAll(parallelResult, iuo);
+        assertEquals(sequentialResult, expectedResult);
+    }
+
+    @Test(dataProvider="longSet")
+    public void testSetAllForLong(String description, int size, IntFunction<long[]> dataFunc,  IntToLongFunction itlf) {
+        long[] expectedResult = dataFunc.apply(size);
+        for(int i = 0; i < size; i++)
+            expectedResult[i] = itlf.applyAsLong(i);
+                
+        long[] sequentialResult = dataFunc.apply(size);
+        Arrays.setAll(sequentialResult, itlf);
+        assertEquals(sequentialResult, expectedResult);
+
+        long[] parallelResult  = dataFunc.apply(size);
+        Arrays.setAll(parallelResult, itlf);
+        assertEquals(sequentialResult, expectedResult);
+    }
+
+    @Test(dataProvider="doubleSet")
+    public void testSetAllForDouble(String description,int size, IntFunction<double[]> dataFunc,  IntToDoubleFunction itdf) {
+        double[] expectedResult = dataFunc.apply(size);
+        for(int i = 0; i < size; i++)
+            expectedResult[i] = itdf.applyAsDouble(i);
+                
+        double[] sequentialResult = dataFunc.apply(size);
+        Arrays.setAll(sequentialResult, itdf);
+        assertEquals(sequentialResult, expectedResult);
+
+        double[] parallelResult  = dataFunc.apply(size);
+        Arrays.setAll(parallelResult, itdf);
+        assertEquals(sequentialResult, expectedResult);
+    }
+
+    @Test(dataProvider="stringSet")
+    public void testSetAllForString(String description,int size, IntFunction<String[]> dataFunc,  IntFunction<String> itsf) {
+        String[] expectedResult = dataFunc.apply(size);
+        for(int i = 0; i < size; i++)
+            expectedResult[i] = itsf.apply(i);
+                
+        String[] sequentialResult = dataFunc.apply(size);
+        Arrays.setAll(sequentialResult, itsf);
+        assertEquals(sequentialResult, expectedResult);
+
+        String[] parallelResult  = dataFunc.apply(size);
+        Arrays.setAll(parallelResult, itsf);
+        assertEquals(sequentialResult, expectedResult);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Collection/IntRemovePredicateAllTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary sanity tests for Collection.removeIf()/forEach()
+ * @library /sqeutil
+ * @(#) IntRemovePredicateAllTest.java
+ * @author Tristan Yan
+ * @run testng IntRemovePredicateAllTest
+ */
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Predicate;
+import static org.testng.Assert.*;
+import org.testng.annotations.Factory;
+import org.testng.annotations.Test;
+
+public class IntRemovePredicateAllTest <T extends Collection<Integer>> {
+    private final static Random rand = new Random(System.currentTimeMillis());
+
+    //1K data is best we can optimize for now.
+    private final static int MAX_SIZE = 1 << 10;
+
+    //At least we should have 4 elements in the list
+    private final static int MIN_SIZE = 1 << 2;
+
+    T t;
+
+    public IntRemovePredicateAllTest(T typeObject1){
+        t = typeObject1;
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    private static Collection<Integer>
+        generateData(Class<? extends Collection<Integer>> cls,
+            int... initValue) throws InstantiationException,
+            IllegalAccessException, NoSuchMethodException,
+            IllegalArgumentException, InvocationTargetException{
+        Collection<Integer> c;
+        int t1Size = 0;
+        if(initValue.length == 0) {
+            c = cls.newInstance();
+            t1Size= rand.nextInt(MAX_SIZE);
+            if(t1Size < MIN_SIZE) t1Size = MIN_SIZE;
+        } else {
+            Constructor con = cls.getConstructor(int.class);
+            c = (Collection<Integer>)con.newInstance(initValue[0]);
+            t1Size = initValue.length == 2 ? initValue[1] : initValue[0];
+        }
+        for(int i = 0; i < t1Size; i++)
+            c.add(rand.nextInt());
+        return c;
+    }
+
+    @Factory
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static Object[] create() throws Exception{
+        List<IntRemovePredicateAllTest> result = new ArrayList<>();
+        Class[] defaultConstructorClazz = {
+            (Class<ArrayDeque<Integer>>)(Class<?>)(ArrayDeque.class),
+            (Class<ArrayList<Integer>>)(Class<?>)(ArrayList.class),
+            (Class<ConcurrentLinkedDeque<Integer>>)(Class<?>)(ConcurrentLinkedDeque.class),
+            (Class<ConcurrentLinkedQueue<Integer>>)(Class<?>)(ConcurrentLinkedQueue.class),
+            (Class<ConcurrentSkipListSet<Integer>>)(Class<?>)(ConcurrentSkipListSet.class),
+            (Class<HashSet<Integer>>)(Class<?>)(HashSet.class),
+            (Class<LinkedBlockingDeque<Integer>>)(Class<?>)(LinkedBlockingDeque.class),
+            (Class<LinkedBlockingQueue<Integer>>)(Class<?>)(LinkedBlockingQueue.class),
+            (Class<LinkedHashSet<Integer>>)(Class<?>)(LinkedHashSet.class),
+            (Class<LinkedList<Integer>>)(Class<?>)(LinkedList.class),
+            (Class<LinkedTransferQueue<Integer>>)(Class<?>)(LinkedTransferQueue.class),
+            (Class<PriorityBlockingQueue<Integer>>)(Class<?>)(PriorityBlockingQueue.class),
+            (Class<PriorityQueue<Integer>>)(Class<?>)(PriorityQueue.class),
+            (Class<Stack<Integer>>)(Class<?>)(Stack.class),
+            (Class<TreeSet<Integer>>)(Class<?>)(TreeSet.class),
+            (Class<Vector<Integer>>)(Class<?>)(Vector.class)
+        };
+
+        Class[] capacityConstructorClazz = {
+            (Class<ArrayBlockingQueue<Integer>>)(Class<?>)(ArrayBlockingQueue.class),
+            (Class<ArrayDeque<Integer>>)(Class<?>)(ArrayDeque.class),
+            (Class<ArrayList<Integer>>)(Class<?>)(ArrayList.class),
+            (Class<HashSet<Integer>>)(Class<?>)(HashSet.class),
+            (Class<LinkedBlockingDeque<Integer>>)(Class<?>)(LinkedBlockingDeque.class),
+            (Class<LinkedBlockingQueue<Integer>>)(Class<?>)(LinkedBlockingQueue.class),
+            (Class<LinkedHashSet<Integer>>)(Class<?>)(LinkedHashSet.class),
+            (Class<PriorityBlockingQueue<Integer>>)(Class<?>)(PriorityBlockingQueue.class),
+            (Class<PriorityQueue<Integer>>)(Class<?>)(PriorityQueue.class),
+            (Class<Vector<Integer>>)(Class<?>)(Vector.class)
+        };
+
+        for(int i = 0; i < defaultConstructorClazz.length
+                + capacityConstructorClazz.length; i++) {
+            int initSize1 = rand.nextInt(MAX_SIZE);
+            if(initSize1 < MIN_SIZE) initSize1 = MIN_SIZE;
+            Collection<Integer> c = i < defaultConstructorClazz.length ?
+                generateData(defaultConstructorClazz[i]) :
+                generateData(capacityConstructorClazz[i - defaultConstructorClazz.length],
+                    initSize1);
+            result.add(new IntRemovePredicateAllTest(c));
+        }
+        return result.toArray();
+    }
+
+    @Test
+    public void testRemoveIf() {
+        int limit = rand.nextInt();
+        boolean isUP = rand.nextBoolean();
+        Predicate<Integer> p = LambdaUtilities.randomIntegerPredicate(isUP, limit);
+        t.removeIf(p);
+        assertTrue(verifyMatch(t, limit, !isUP, true));
+    }
+
+    @Test
+    public void testForEach() {
+        final AtomicInteger accumulator = new AtomicInteger(0);
+        t.forEach(t -> accumulator.addAndGet(t));
+
+        Optional<Integer> opi = t.stream().reduce((i1, i2) -> i1 + i2);
+        assertTrue(opi.isPresent());
+        assertEquals(accumulator.get(), opi.get().intValue());
+    }
+
+    private boolean verifyMatch(Collection<Integer> c, int limit, boolean isUP,
+            boolean all) {
+        Iterator<Integer> it = c.iterator();
+        while(it.hasNext()) {
+            int current = it.next();
+            if(isUP) {
+                if(all) {
+                    if(current < limit) return false;
+                } else {
+                    if(current >= limit) return true;
+                }
+            } else {
+                if(all) {
+                    if(current >= limit) return false;
+                } else {
+                    if(current < limit) return true;
+                }
+            }
+        }
+        return all;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/List/ExtensionsTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Basic tests for List's extension methods
+ * @library /sqeutil
+ * @(#) ListTest.java
+ * @author Tristan Yan
+ * @run testng ExtensionsTest
+ */
+
+import java.util.*;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.stream.Stream;
+import static org.testng.Assert.*;
+import org.testng.annotations.*;
+
+public class ExtensionsTest<T extends List<Integer>> {
+    protected Class<T> typeObject;
+
+    protected boolean hasIni;
+
+    protected int initSize;
+
+    protected final static int START = -1 << 6;
+
+    protected final static int END = 1 << 6;
+
+    protected final static Random rand = new Random(System.currentTimeMillis());
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    protected static Class[] defaultConstructorClazz = {
+        (Class<ArrayList<Integer>>)(Class<?>)(ArrayList.class),
+        (Class<CopyOnWriteArrayList<Integer>>)(Class<?>)(CopyOnWriteArrayList.class),
+        (Class<LinkedList<Integer>>)(Class<?>)(LinkedList.class),
+        (Class<Stack<Integer>>)(Class<?>)(Stack.class),
+        (Class<Vector<Integer>>)(Class<?>)(Vector.class)
+    };
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    protected static Class[] capacityConstructorClazz = {
+        (Class<ArrayList<Integer>>)(Class<?>)(ArrayList.class),
+        (Class<Vector<Integer>>)(Class<?>)(Vector.class)
+    };
+
+    public ExtensionsTest(Class<T> clazz, int... initSizes){
+        this.typeObject = clazz;
+        assert(initSizes.length <= 1);
+        if(initSizes.length == 1) {
+            hasIni = true;
+            this.initSize = initSizes[0];
+        }
+    }
+
+    protected List<Integer> generateList(int start, int end, int size)
+            throws Exception{
+        List<Integer> list =  hasIni ?
+            (List<Integer>)LambdaUtilities.create(typeObject, initSize) :
+            (List<Integer>)LambdaUtilities.create(typeObject);
+        for(int i = 0; i < size; i++) {
+            int element = start + rand.nextInt(end - start);
+            list.add(element);
+        }
+        return list;
+    }
+
+    protected List<Integer> generateList(int start, int end) throws Exception{
+        return generateList(start, end, end - start);
+    }
+
+    @Factory
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static Object[] create(){
+        List<ExtensionsTest> result = new ArrayList<>();
+        Stream<Class> stream1 = Arrays.stream(defaultConstructorClazz);
+        Stream<Class> stream2 = Arrays.stream(capacityConstructorClazz);
+        stream1.forEach(clazz -> result.add(new ExtensionsTest(clazz)));
+        stream2.forEach(clazz -> result.add(new ExtensionsTest(clazz,
+                END - START + rand.nextInt(END - START))));
+        return result.toArray();
+    }
+
+    @Test
+    public void testReplaceAll() throws Exception {
+        List<Integer> list = generateList(START, END);
+        List<Integer> listCloned =  hasIni ?
+            (List<Integer>)LambdaUtilities.create(typeObject, initSize) :
+            (List<Integer>)LambdaUtilities.create(typeObject);
+        listCloned.addAll(list);
+        EnumSet<LambdaUtilities.IntOp> set = EnumSet.allOf(LambdaUtilities.IntOp.class);
+        LambdaUtilities.IntOp[] ops = new LambdaUtilities.IntOp[set.size()];
+        set.toArray(ops);
+        LambdaUtilities.IntOp op = ops[rand.nextInt(ops.length)];
+        int value = START + rand.nextInt(END - START);
+        if( op == LambdaUtilities.IntOp.DIVIDE || op == LambdaUtilities.IntOp.MOD)
+            while(value == 0)
+                value = START + rand.nextInt(END - START);
+        list.replaceAll(LambdaUtilities.opIntegerUnaryOperator(op, value));
+        checkReplace(listCloned, list, op, value);
+    }
+
+    @Test
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public void testSort() throws Exception{
+        Comparator[] cs = { Comparator.<Integer>naturalOrder(),
+            Comparator.<Integer>reverseOrder(),
+            Comparator.comparingInt(LambdaUtilities.highestPosValueIntFunction() ),
+            Comparator.comparingInt(LambdaUtilities.lowestPosValueIntFunction() ),
+        };
+
+        Iterator<Comparator> csit = Arrays.stream(cs).iterator();
+        while(csit.hasNext())
+            testComparator((Comparator<Integer>)csit.next());
+    }
+
+    @Test
+    public void testRemoveAll() throws Exception {
+        List<Integer> list = generateList(START, END);
+        int limit = rand.nextInt(2 * (END - START)) + 2 * START;
+        boolean isUP = rand.nextBoolean();
+        list.removeIf(LambdaUtilities.randomIntegerPredicate(isUP, limit));
+        assertTrue(verifyMatch(list, limit, !isUP, true));
+    }
+
+    @Test
+    public void testForEach() throws Exception {
+        List<Integer> list = generateList(START, END);
+        List<Integer> listCloned =  hasIni ?
+            (List<Integer>)LambdaUtilities.create(typeObject, initSize) :
+            (List<Integer>)LambdaUtilities.create(typeObject);
+        list.forEach(LambdaUtilities.copyConsumer(listCloned));
+        assertEquals(list, listCloned);
+    }
+    private void checkReplace(List<Integer> orig, List<Integer> replaced,
+            LambdaUtilities.IntOp op, int value) {
+        assertEquals(orig.size(), replaced.size());
+        for(int index = 0; index < orig.size(); index++)
+            switch(op) {
+                case ADD:
+                    assertTrue(orig.get(index) + value == replaced.get(index));
+                    break;
+                case SUBTRACT:
+                    assertTrue(orig.get(index) - value == replaced.get(index));
+                    break;
+                case MULTIPLY:
+                    assertTrue(orig.get(index) * value == replaced.get(index));
+                    break;
+                case DIVIDE:
+                    assertTrue(orig.get(index) / value == replaced.get(index));
+                    break;
+                default:
+                    assertTrue(orig.get(index) % value == replaced.get(index));
+                    break;
+            }
+    }
+
+    private void testComparator(Comparator<Integer> c) throws Exception {
+        List<Integer> list = generateList(START, END);
+        List<Integer> listCloned =  hasIni ?
+            (List<Integer>)LambdaUtilities.create(typeObject, initSize) :
+            (List<Integer>)LambdaUtilities.create(typeObject);
+        listCloned.addAll(list);
+        list.sort(c);
+        for(int i = 0; i < list.size() - 1; i++)
+            assertTrue(c.compare(list.get(i), list.get(i+1)) <= 0);
+        //assertEquals(list, listCloned);
+    }
+
+    private boolean verifyMatch(Collection<Integer> c, int limit, boolean isUP,
+            boolean all) {
+        Iterator<Integer> it = c.iterator();
+        while(it.hasNext()) {
+            int current = it.next();
+            if(isUP) {
+                if(all) {
+                    if(current < limit) return false;
+                } else {
+                    if(current >= limit) return true;
+                }
+            } else {
+                if(all) {
+                    if(current >= limit) return false;
+                } else {
+                    if(current < limit) return true;
+                }
+            }
+        }
+        return all;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/List/SortAndReplaceAllTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary test for List default methods replaceAll() and sort();
+ * @(#) SortAndReplaceAllTest.java
+ * @library /sqeutil
+ * @author Tristan Yan
+ * @run testng SortAndReplaceAllTest
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.Stack;
+import java.util.Vector;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import static org.testng.Assert.*;
+import org.testng.annotations.Factory;
+import org.testng.annotations.Test;
+
+public class SortAndReplaceAllTest <T extends List<Integer>>{
+    protected Class<T> typeObject;
+
+    protected boolean hasIni;
+
+    protected int initSize;
+
+    protected final static int START = -1 << 6;
+
+    protected final static int END = 1 << 6;
+
+    protected final static Random rand = new Random(System.currentTimeMillis());
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    protected static Class[] defaultConstructorClazz = {
+        (Class<ArrayList<Integer>>)(Class<?>)(ArrayList.class),
+        (Class<CopyOnWriteArrayList<Integer>>)(Class<?>)(CopyOnWriteArrayList.class),
+        (Class<LinkedList<Integer>>)(Class<?>)(LinkedList.class),
+        (Class<Stack<Integer>>)(Class<?>)(Stack.class),
+        (Class<Vector<Integer>>)(Class<?>)(Vector.class)
+    };
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    protected static Class[] capacityConstructorClazz = {
+        (Class<ArrayList<Integer>>)(Class<?>)(ArrayList.class),
+        (Class<Vector<Integer>>)(Class<?>)(Vector.class)
+    };
+
+    public SortAndReplaceAllTest(Class<T> clazz, int... initSizes){
+        this.typeObject = clazz;
+        assert(initSizes.length <= 1);
+        if(initSizes.length == 1) {
+            hasIni = true;
+            this.initSize = initSizes[0];
+        }
+    }
+
+    private List<Integer> generateList(int start, int end, int size)
+            throws Exception{
+        List<Integer> list =  hasIni ?
+            (List<Integer>)LambdaUtilities.create(typeObject, initSize) :
+            (List<Integer>)LambdaUtilities.create(typeObject);
+        for(int i = 0; i < size; i++) {
+            int element = start + rand.nextInt(end - start);
+            list.add(element);
+        }
+        return list;
+    }
+
+    protected List<Integer> generateList(int start, int end) throws Exception{
+        return generateList(start, end, end - start);
+    }
+
+    @Factory
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static Object[] create(){
+        List<SortAndReplaceAllTest> result = new ArrayList<>();
+        Stream<Class> stream1 = Arrays.stream(defaultConstructorClazz);
+        Stream<Class> stream2 = Arrays.stream(capacityConstructorClazz);
+        stream1.forEach(clazz -> result.add(new SortAndReplaceAllTest(clazz)));
+        stream2.forEach(clazz -> result.add(new SortAndReplaceAllTest(clazz,
+                END - START + rand.nextInt(END - START))));
+        return result.toArray();
+    }
+
+    @Test
+    public void testReplaceAll() throws Exception {
+        List<Integer> list = generateList(START, END);
+        List<Integer> listCloned =  hasIni ?
+            (List<Integer>)LambdaUtilities.create(typeObject, initSize) :
+            (List<Integer>)LambdaUtilities.create(typeObject);
+        listCloned.addAll(list);
+        EnumSet<LambdaUtilities.IntOp> set = EnumSet.allOf(LambdaUtilities.IntOp.class);
+        LambdaUtilities.IntOp[] ops = new LambdaUtilities.IntOp[set.size()];
+        set.toArray(ops);
+        LambdaUtilities.IntOp op = ops[rand.nextInt(ops.length)];
+        int value = START + rand.nextInt(END - START);
+        if( op == LambdaUtilities.IntOp.DIVIDE || op == LambdaUtilities.IntOp.MOD) {
+            while(value == 0) {
+                value = START + rand.nextInt(END - START);
+            }
+        }
+        list.replaceAll(LambdaUtilities.opIntegerUnaryOperator(op, value));
+        checkReplace(listCloned, list, op, value);
+    }
+
+    @Test
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public void testSort() throws Exception{
+        final Function<Integer, String> i2s = i -> String.valueOf(i);
+        Comparator[] cs = { Comparator.<Integer>naturalOrder(),
+            Comparator.<Integer>reverseOrder(),
+            Comparator.comparingInt(LambdaUtilities.highestPosValueIntFunction()),
+            Comparator.comparingInt(LambdaUtilities.lowestPosValueIntFunction()),
+            Comparator.comparing(i2s, Comparator.<String>naturalOrder()),
+            Comparator.comparing(i2s, Comparator.<String>reverseOrder()),
+        };
+
+        Iterator<Comparator> csit = Arrays.stream(cs).iterator();
+        while(csit.hasNext()) {
+            testComparator((Comparator<Integer>)csit.next());
+        }
+    }
+
+    private void checkReplace(List<Integer> orig, List<Integer> replaced,
+            LambdaUtilities.IntOp op, int value) {
+        assertEquals(orig.size(), replaced.size());
+        for(int index = 0; index < orig.size(); index++) {
+            switch(op) {
+                case ADD:
+                    assertTrue(orig.get(index) + value == replaced.get(index));
+                    break;
+                case SUBTRACT:
+                    assertTrue(orig.get(index) - value == replaced.get(index));
+                    break;
+                case MULTIPLY:
+                    assertTrue(orig.get(index) * value == replaced.get(index));
+                    break;
+                case DIVIDE:
+                    assertTrue(orig.get(index) / value == replaced.get(index));
+                    break;
+                default:
+                    assertTrue(orig.get(index) % value == replaced.get(index));
+                    break;
+            }
+        }
+    }
+
+    private void testComparator(Comparator<Integer> c) throws Exception {
+        List<Integer> list = generateList(START, END);
+        List<Integer> listCloned =  hasIni ?
+            (List<Integer>)LambdaUtilities.create(typeObject, initSize) :
+            (List<Integer>)LambdaUtilities.create(typeObject);
+        listCloned.addAll(list);
+        list.sort(c);
+        for(int i = 0; i < list.size() - 1; i++) {
+            assertTrue(c.compare(list.get(i), list.get(i+1)) <= 0);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Map/LambdaTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary sanity test forEach on Map<String,Integer>
+ * @library /sqeutil
+ * @(#)LambdaTest.java
+ * @author Yong Lu/Tristan Yan
+ * @run testng LambdaTest
+ */
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.stream.Stream;
+import static org.testng.Assert.*;
+import org.testng.ITest;
+import org.testng.annotations.Factory;
+import org.testng.annotations.Test;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class LambdaTest<T extends Map<String, Integer>> implements ITest  {
+    private final static Random rand = new Random(System.currentTimeMillis());
+    private Class<T> typeObject;
+    private boolean hasIni;
+    private int initSize;
+
+    private final static int START = -1 << 6;
+    private final static int END = 1 << 6;
+
+    private static Class[] defaultConstructorClazz = {
+        (Class<ConcurrentHashMap<String, Integer>>) (Class<?>) (ConcurrentHashMap.class),
+        (Class<ConcurrentSkipListMap<String, Integer>>) (Class<?>) (ConcurrentSkipListMap.class),
+        (Class<HashMap<String, Integer>>) (Class<?>) (HashMap.class),
+        (Class<Hashtable<String, Integer>>) (Class<?>) (Hashtable.class),
+        (Class<LinkedHashMap<String, Integer>>) (Class<?>) (LinkedHashMap.class),
+        (Class<IdentityHashMap<String, Integer>>) (Class<?>) (IdentityHashMap.class),
+        (Class<WeakHashMap<String, Integer>>) (Class<?>) (WeakHashMap.class)
+    };
+
+    public LambdaTest(Class<T> clazz, int... initSizes) {
+        this.typeObject = clazz;
+        assert (initSizes.length <= 1);
+        if (initSizes.length == 1) {
+            hasIni = true;
+            this.initSize = initSizes[0];
+        }
+    }
+
+    protected Map<String, Integer> generateData(int start, int end, int size) throws Exception {
+        Map<String, Integer> m = LambdaUtilities.createMap(typeObject);
+        for (int i = 0; i < size; i++) {
+            int element = start + rand.nextInt(end - start);
+            if (element != Integer.SIZE) {
+                m.put(String.valueOf(element), new Integer(element));
+            }
+        }
+        return m;
+    }
+
+    protected Map<String, Integer> generateData(int start, int end) throws Exception {
+        return generateData(start, end, end - start);
+    }
+
+    @Factory
+    public static Object[] create(){
+        List<LambdaTest> result = new ArrayList<>();
+        Stream<Class> stream = Arrays.stream(defaultConstructorClazz);
+        stream.forEach(clazz -> result.add(new LambdaTest(clazz)));
+        return result.toArray();
+    }
+
+    @Test
+    public void testForEach() throws Exception{
+        Map<String, Integer> m1 = generateData(START, END);
+        m1.forEach((x,y) -> assertTrue(m1.get(x).equals(y)));
+
+        Map<String, Integer> m2 = LambdaUtilities.createMap(typeObject);
+        m1.forEach((x,y) -> m2.put(x, y));
+        m2.forEach((x,y) -> assertTrue(m1.get(x).equals(y)));
+
+        m1.forEach((x,y) -> {
+                m1.put(x, Integer.SIZE);
+                assertFalse(m1.containsValue(y));
+        });
+    }
+
+    @Test
+    public void testReplaceAll() throws Exception{
+        //ConcurrentSkipListMap doesn't replaceAll
+        if(typeObject.getName().endsWith("ConcurrentSkipListMap"))
+            return;
+        Map<String, Integer> m = generateData(START, END);
+        Map<String, Integer> mCloned = LambdaUtilities.createMap(typeObject);
+        mCloned.putAll(m);
+        EnumSet<LambdaUtilities.IntOp> set = EnumSet.allOf(LambdaUtilities.IntOp.class);
+        LambdaUtilities.IntOp[] ops = new LambdaUtilities.IntOp[set.size()];
+        set.toArray(ops);
+        LambdaUtilities.IntOp op = ops[rand.nextInt(ops.length)];
+        int value = START + rand.nextInt(END - START);
+        while((value = START + rand.nextInt(END - START)) == 0);
+        m.replaceAll(LambdaUtilities.opBiFunction(op, value));
+        checkReplace(mCloned, m, op, value);
+    }
+
+    @Test
+    public void testCompute() throws Exception{
+        Map<String, Integer> m = generateData(START, END);
+        Map<String, Integer> mCloned = LambdaUtilities.createMap(typeObject);
+        mCloned.putAll(m);
+        final int value = START + rand.nextInt(END - START);
+        EnumSet<LambdaUtilities.IntOp> set = EnumSet.allOf(LambdaUtilities.IntOp.class);
+        LambdaUtilities.IntOp[] ops = new LambdaUtilities.IntOp[set.size()];
+        set.toArray(ops);
+        LambdaUtilities.IntOp op = ops[rand.nextInt(ops.length)];
+        mCloned.keySet().forEach(t -> m.compute(t, LambdaUtilities.opBiFunction(op, value)));
+        checkReplace(mCloned, m, op, value);
+    }
+
+    @Test
+    public void testMerge() throws Exception{
+        Map<String, Integer> m = generateData(START, END);
+        Map<String, Integer> mCloned = LambdaUtilities.createMap(typeObject);
+        mCloned.putAll(m);
+        final int value = START + rand.nextInt(END - START);
+        EnumSet<LambdaUtilities.IntOp> set = EnumSet.allOf(LambdaUtilities.IntOp.class);
+        LambdaUtilities.IntOp[] ops = new LambdaUtilities.IntOp[set.size()];
+        set.toArray(ops);
+        LambdaUtilities.IntOp op = ops[rand.nextInt(ops.length)];
+        mCloned.keySet().forEach(t -> m.merge(t, value, LambdaUtilities.opBiFunction(op)));
+        checkReplace(mCloned, m, op, value);
+    }
+
+    @Test
+    public void testReplace() throws Exception{
+        Map<String, Integer> m = generateData(START, END);
+        Map<String, Integer> mCloned = LambdaUtilities.createMap(typeObject);
+        mCloned.putAll(m);
+        final int value = START + rand.nextInt(END - START);
+        EnumSet<LambdaUtilities.IntOp> set = EnumSet.allOf(LambdaUtilities.IntOp.class);
+        LambdaUtilities.IntOp[] ops = new LambdaUtilities.IntOp[set.size()];
+        set.toArray(ops);
+        LambdaUtilities.IntOp op = ops[rand.nextInt(ops.length)];
+        mCloned.keySet().forEach(t -> m.replace(t, mCloned.get(t), LambdaUtilities.opBiFunction(op).apply(mCloned.get(t), value)));
+        checkReplace(mCloned, m, op, value);
+    }
+
+    private void checkReplace(Map<String, Integer> orig, Map<String, Integer> replaced,
+            LambdaUtilities.IntOp op, int value) {
+        assertEquals(orig.size(), replaced.size());
+        Iterator<String> it = orig.keySet().iterator();
+        while(it.hasNext()) {
+            String k = it.next();
+            if(value == 0){
+                assertEquals(orig.get(k), replaced.get(k));
+                continue;
+            }
+            switch(op) {
+                case ADD:
+                    assertTrue(orig.get(k) + value == replaced.get(k));
+                    break;
+                case SUBTRACT:
+                    assertTrue(orig.get(k) - value == replaced.get(k));
+                    break;
+                case MULTIPLY:
+                    assertTrue(orig.get(k) * value == replaced.get(k));
+                    break;
+                case DIVIDE:
+                    assertTrue(orig.get(k) / value == replaced.get(k));
+                    break;
+                default:
+                    assertTrue(orig.get(k) % value == replaced.get(k));
+                    break;
+            }
+        }
+    }
+
+    @Test
+    public void testRemove() throws Exception {
+        Map<String, Integer> m = generateData(START, END);
+        Map<String, Integer> mCloned = LambdaUtilities.createMap(typeObject);
+        mCloned.putAll(m);
+        mCloned.keySet().forEach(t -> m.remove(t));
+        assertTrue(m.isEmpty());
+    }
+
+    @Test
+    public void testComputeIfAbsent() throws Exception {
+        Map<String, Integer> m = generateData(START, END);
+        Map<String, Integer> mCloned = LambdaUtilities.createMap(typeObject);
+        final int value = START + rand.nextInt(END - START);
+        EnumSet<LambdaUtilities.IntOp> set = EnumSet.allOf(LambdaUtilities.IntOp.class);
+        LambdaUtilities.IntOp[] ops = new LambdaUtilities.IntOp[set.size()];
+        set.toArray(ops);
+        LambdaUtilities.IntOp op = ops[rand.nextInt(ops.length)];
+        m.keySet().forEach(t -> mCloned.computeIfAbsent(t, LambdaUtilities.mappingFunction(m, op, value)));
+        checkReplace(m, mCloned, op, value);
+    }
+
+    @Override
+    public String getTestName() {
+        return typeObject.getName() + "<String,Integer>";
+    }
+}
--- a/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -513,6 +513,12 @@
 
     @Test(dataProvider = "Spliterator<Integer>")
     @SuppressWarnings({"unchecked", "rawtypes"})
+    public void testMixedTraverseAndSplit(String description, Collection exp, Supplier<Spliterator> s) {
+        testMixedTraverseAndSplit(exp, s, (Consumer<Object> b) -> b);
+    }
+
+    @Test(dataProvider = "Spliterator<Integer>")
+    @SuppressWarnings({"unchecked", "rawtypes"})
     public void testSplitAfterFullTraversal(String description, Collection exp, Supplier<Spliterator> s) {
         testSplitAfterFullTraversal(s, (Consumer<Object> b) -> b);
     }
@@ -669,6 +675,11 @@
     }
 
     @Test(dataProvider = "Spliterator.OfInt")
+    public void testIntMixedTraverseAndSplit(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
+        testMixedTraverseAndSplit(exp, s, intBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfInt")
     public void testIntSplitAfterFullTraversal(String description, Collection<Integer> exp, Supplier<Spliterator.OfInt> s) {
         testSplitAfterFullTraversal(s, intBoxingConsumer());
     }
@@ -829,6 +840,11 @@
     }
 
     @Test(dataProvider = "Spliterator.OfLong")
+    public void testLongMixedTraverseAndSplit(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
+        testMixedTraverseAndSplit(exp, s, longBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfLong")
     public void testLongSplitAfterFullTraversal(String description, Collection<Long> exp, Supplier<Spliterator.OfLong> s) {
         testSplitAfterFullTraversal(s, longBoxingConsumer());
     }
@@ -989,6 +1005,11 @@
     }
 
     @Test(dataProvider = "Spliterator.OfDouble")
+    public void testDoubleMixedTraverseAndSplit(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
+        testMixedTraverseAndSplit(exp, s, doubleBoxingConsumer());
+    }
+
+    @Test(dataProvider = "Spliterator.OfDouble")
     public void testDoubleSplitAfterFullTraversal(String description, Collection<Double> exp, Supplier<Spliterator.OfDouble> s) {
         testSplitAfterFullTraversal(s, doubleBoxingConsumer());
     }
@@ -1097,6 +1118,53 @@
         }
     }
 
+    private static <T, S extends Spliterator<T>> void testMixedTraverseAndSplit(
+            Collection<T> exp,
+            Supplier<S> supplier,
+            UnaryOperator<Consumer<T>> boxingAdapter) {
+        S spliterator = supplier.get();
+        long sizeIfKnown = spliterator.getExactSizeIfKnown();
+        boolean isOrdered = spliterator.hasCharacteristics(Spliterator.ORDERED);
+
+        ArrayList<T> dest = new ArrayList<>();
+        spliterator = supplier.get();
+        Consumer<T> b = boxingAdapter.apply(dest::add);
+
+        Spliterator<T> spl1, spl2, spl3;
+        spliterator.tryAdvance(b);
+        spl2 = spliterator.trySplit();
+        if (spl2 != null) {
+            spl2.tryAdvance(b);
+            spl1 = spl2.trySplit();
+            if (spl1 != null) {
+                spl1.tryAdvance(b);
+                spl1.forEachRemaining(b);
+            }
+            spl2.tryAdvance(b);
+            spl2.forEachRemaining(b);
+        }
+        spliterator.tryAdvance(b);
+        spl3 = spliterator.trySplit();
+        if (spl3 != null) {
+            spl3.tryAdvance(b);
+            spl3.forEachRemaining(b);
+        }
+        spliterator.tryAdvance(b);
+        spliterator.forEachRemaining(b);
+
+        if (sizeIfKnown >= 0) {
+            assertEquals(sizeIfKnown, dest.size());
+        }
+        assertEquals(dest.size(), exp.size());
+
+        if (isOrdered) {
+            assertEquals(dest, exp);
+        }
+        else {
+            assertContentsUnordered(dest, exp);
+        }
+    }
+
     private static <T, S extends Spliterator<T>> void testSplitAfterFullTraversal(
             Supplier<S> supplier,
             UnaryOperator<Consumer<T>> boxingAdapter) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/StringJoiner/BasicTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Sanity Test for StringJoiner
+ * @(#) BasicTest.java
+ * @library /sqeutil
+ * @author Tristan Yan
+ * @run testng BasicTest
+ */
+
+import java.util.*;
+import java.util.stream.Collectors;
+import static org.testng.Assert.*;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class BasicTest {
+    protected final static int STRING_ARR_SIIE = 1 << 8;
+
+    protected final static int STRING_LEN = 1 << 10;
+
+    protected final static int TIMES = 1 << 4;
+
+    protected final static Random rnd = new Random(System.currentTimeMillis());
+
+    protected String[] randomStringArray(){
+       String[] arr = new String[STRING_ARR_SIIE];
+       for(int index = 0; index < STRING_ARR_SIIE; index++)
+           arr[index] = StringUtilities.randomAlphabetic(rnd.nextInt(STRING_LEN));
+       return arr;
+    }
+
+    @DataProvider(name = "Connector-Provider")
+    public Object[][] notAlphanumeric(){
+        Object[][] data = new Object[TIMES][3];
+        for(int i = 0; i < TIMES; i++) {
+            List<String> list = new ArrayList<>();
+            for(char c=32; c < 127; c++) {
+                if(!Character.isAlphabetic(c) && !Character.isDigit(c))
+                    list.add(String.valueOf(c));
+            }
+            Collections.shuffle(list);
+            int infixPos = rnd.nextInt(list.size()/2);
+            if(infixPos < 1) infixPos = 1;
+            int prefixPos = infixPos + rnd.nextInt(list.size() - infixPos);
+            if(prefixPos == infixPos) prefixPos = infixPos + 1;
+            data[i] = new String[]{ list.subList(0, infixPos).stream().collect(Collectors.joining("")).toString(),
+                    list.subList(infixPos, prefixPos).stream().collect(Collectors.joining("")).toString(),
+                    list.subList(prefixPos, list.size()).stream().collect(Collectors.joining("")).toString()
+            };
+        }
+        return data;
+    }
+
+    @Test(dataProvider = "Connector-Provider")
+    public void constructorTest(String INFIX, String PREFIX, String SUFFIX) {
+        //Test constructor with only infix
+        //String[] sj = notAlphanumeric();
+        String[] rndStrings = randomStringArray();
+        final StringJoiner nofixsj = new StringJoiner(INFIX);
+        Arrays.stream(rndStrings).forEach(t -> {nofixsj.add(t); });
+        String longStr1 = nofixsj.toString();
+        int index = 0;
+        int pos = 0;
+        while(index < rndStrings.length) {
+            if(index < rndStrings.length - 1) {
+                assertEquals(longStr1.substring(pos, pos + rndStrings[index].length()), rndStrings[index]);
+                pos += rndStrings[index++].length();
+                assertEquals(longStr1.substring(pos, pos + INFIX.length()), INFIX);
+                pos += INFIX.length();
+            } else
+                assertEquals(longStr1.substring(pos, pos + rndStrings[index].length()), rndStrings[index++]);
+        }
+
+        //Test constructor with infix, prefix and suffix
+        final StringJoiner hasfixsj = new StringJoiner(INFIX, PREFIX, SUFFIX);
+        Arrays.stream(rndStrings).forEach(t -> {hasfixsj.add(t); });
+        String longStr2 = hasfixsj.toString();
+        index = 0;
+        pos = 0;
+        assertEquals(longStr2.substring(pos, pos + PREFIX.length()), PREFIX);
+        pos += PREFIX.length();
+        while(index < rndStrings.length) {
+            if(index < rndStrings.length - 1) {
+                assertEquals(longStr2.substring(pos, pos + rndStrings[index].length()), rndStrings[index]);
+                pos += rndStrings[index++].length();
+                assertEquals(longStr2.substring(pos, pos + INFIX.length()), INFIX);
+                pos += INFIX.length();
+            } else {
+                assertEquals(longStr2.substring(pos, pos + rndStrings[index].length()), rndStrings[index]);
+                pos += rndStrings[index++].length();
+            }
+        }
+        assertEquals(longStr2.substring(pos, pos + SUFFIX.length()), SUFFIX);
+    }
+
+    @Test(dataProvider = "Connector-Provider")
+    public void addTest(String INFIX, String PREFIX, String SUFFIX) {
+        StringJoiner nofixsj = new StringJoiner(INFIX);
+        String randAddStr1 = StringUtilities.randomAlphabetic(rnd.nextInt(STRING_LEN));
+        assertEquals(nofixsj.add(randAddStr1).toString(), randAddStr1);
+        String randAddStr2 = StringUtilities.randomAlphabetic(rnd.nextInt(STRING_LEN));
+        assertEquals(nofixsj.add(randAddStr2).toString(), randAddStr1 + INFIX + randAddStr2);
+
+        //Test constructor with infix, prefix and suffix
+        StringJoiner hasfixsj = new StringJoiner(INFIX, PREFIX, SUFFIX);
+        assertEquals(hasfixsj.add(randAddStr1).toString(), PREFIX + randAddStr1 + SUFFIX);
+        assertEquals(hasfixsj.add(randAddStr2).toString(), PREFIX + randAddStr1 + INFIX + randAddStr2 + SUFFIX);
+    }
+
+    @Test(dataProvider = "Connector-Provider")
+    public void testsetEmptyValue(String INFIX, String PREFIX, String SUFFIX) {
+        StringJoiner nofixsj = new StringJoiner(INFIX);
+        String emptyExpectedStr = StringUtilities.randomAlphabetic(rnd.nextInt(STRING_LEN));
+        assertEquals(nofixsj.toString().length(), 0);
+        nofixsj.setEmptyValue(emptyExpectedStr);
+        assertEquals(nofixsj.toString(), emptyExpectedStr);
+        String randAddStr = StringUtilities.randomAlphabetic(rnd.nextInt(STRING_LEN));
+        assertEquals(nofixsj.add(randAddStr).toString(), randAddStr);
+
+        //Test constructor with infix, prefix and suffix
+        StringJoiner hasfixsj = new StringJoiner(INFIX, PREFIX, SUFFIX);
+        assertEquals(hasfixsj.toString(), PREFIX + SUFFIX);
+        hasfixsj.setEmptyValue(emptyExpectedStr);
+        assertEquals(hasfixsj.toString(), emptyExpectedStr);
+
+        assertEquals(hasfixsj.add(randAddStr).toString(), PREFIX + randAddStr + SUFFIX);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/AtomicInteger/LambdaTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary test for AtomicInteger.updateAndGet()/getAndUpdate() and
+ * AtomicInteger.accumulateAndGet()/getAndAccumulate();
+ * @(#) LambdaTest.java
+ * @library /sqeutil
+ * @author Tristan Yan
+ * @bug 8001666
+ * @run testng LambdaTest
+ */
+
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.atomic.AtomicInteger;
+import static org.testng.Assert.*;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class LambdaTest {
+    private static enum Type{updateAndGet, getAndUpdate, accumulateAndGet, getAndAccumulate};
+
+    private static Random rand = new Random(System.currentTimeMillis());
+
+    private final static int MAX_VALUE = 1 << 24;
+
+    private final static int MIN_VALUE = -1 << 24;
+
+    private final static int OP_TIMES = 1 << 10;
+
+    private final static int THREAD_NUM = 1 << 4;
+
+    @DataProvider
+    public Object[][] booleanProvider(){
+        Object[][] providersParam = new Object[Type.values().length][];
+        Object[] a = Type.values();
+        for(int i = 0; i < a.length; i++)
+            providersParam[i] = new Object[]{a[i]};
+        return providersParam;
+    }
+
+    @Test(dataProvider = "booleanProvider")
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public void test(final Type type) throws InterruptedException,
+            ExecutionException {
+        int initValue = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE);
+        final AtomicInteger ai = new AtomicInteger(initValue);
+        final int randPlus = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE);
+        final int randMinus = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE);
+        switch(type) {
+            case updateAndGet: 
+                assertEquals(ai.updateAndGet(LambdaUtilities.addIntUnaryOperator(randPlus))
+                    , initValue + randPlus);
+                assertEquals(ai.updateAndGet(LambdaUtilities.subIntUnaryOperator(randMinus))
+                    , initValue + randPlus - randMinus);
+                break;
+            case getAndUpdate:
+                assertEquals(ai.getAndUpdate(LambdaUtilities.addIntUnaryOperator(randPlus))
+                    , initValue);
+                assertEquals(ai.getAndUpdate(LambdaUtilities.subIntUnaryOperator(randMinus))
+                    , initValue + randPlus);
+                break;
+            case accumulateAndGet:
+                assertEquals(ai.accumulateAndGet(randPlus,LambdaUtilities.addIntBinaryOperator())
+                    , initValue + randPlus);
+                assertEquals(ai.accumulateAndGet(randMinus,LambdaUtilities.subIntBinaryOperator())
+                    , initValue + randPlus - randMinus);
+                break;
+            case getAndAccumulate:
+                assertEquals(ai.getAndAccumulate(randPlus,LambdaUtilities.addIntBinaryOperator())
+                    , initValue);
+                assertEquals(ai.getAndAccumulate(randMinus,LambdaUtilities.subIntBinaryOperator())
+                    , initValue + randPlus);
+                break;
+        }
+        assertEquals(ai.get(), initValue + randPlus - randMinus);
+
+        ai.set(initValue);
+        Callable<Integer> ac = new Callable<Integer>(){
+            @Override
+            public Integer call() throws Exception {
+                int plusTimes1 = 0;
+                for(int index = 0; index < OP_TIMES; index++) {
+                    boolean plus = rand.nextBoolean();
+                    if(plus) plusTimes1++;
+                    switch(type) {
+                        case updateAndGet:
+                            ai.updateAndGet(plus ?
+                                LambdaUtilities.addIntUnaryOperator(randPlus) :
+                                LambdaUtilities.subIntUnaryOperator(randMinus));
+                            break;
+                        case getAndUpdate:
+                            ai.getAndUpdate(plus ?
+                                LambdaUtilities.addIntUnaryOperator(randPlus) :
+                                LambdaUtilities.subIntUnaryOperator(randMinus));
+                            break;
+                        case accumulateAndGet:
+                            ai.accumulateAndGet(plus ? randPlus : randMinus,
+                                plus ? LambdaUtilities.addIntBinaryOperator() :
+                                    LambdaUtilities.subIntBinaryOperator());
+                            break;
+                        case getAndAccumulate:
+                            ai.getAndAccumulate(plus ? randPlus : randMinus,
+                                plus ? LambdaUtilities.addIntBinaryOperator() :
+                                    LambdaUtilities.subIntBinaryOperator());
+                    }
+                }
+                return plusTimes1;
+            }
+
+        };
+        FutureTask[] futures = new FutureTask[THREAD_NUM -1];
+        for(int i = 0; i < THREAD_NUM -1; i++) {
+            futures[i] = new FutureTask<Integer>(ac);
+            new Thread(futures[i]).start();
+        }
+
+        int plusTimes = 0;
+        for(int index = 0; index < OP_TIMES; index++) {
+            boolean plus = rand.nextBoolean();
+            if(plus) plusTimes++;
+            switch(type) {
+                case updateAndGet:
+                    ai.updateAndGet(plus ?
+                        LambdaUtilities.addIntUnaryOperator(randPlus) :
+                        LambdaUtilities.subIntUnaryOperator(randMinus));
+                    break;
+                case getAndUpdate:
+                    ai.getAndUpdate(plus ?
+                        LambdaUtilities.addIntUnaryOperator(randPlus) :
+                        LambdaUtilities.subIntUnaryOperator(randMinus));
+                    break;
+                case accumulateAndGet:
+                    ai.accumulateAndGet(plus ? randPlus : randMinus,
+                        plus ? LambdaUtilities.addIntBinaryOperator() :
+                            LambdaUtilities.subIntBinaryOperator());
+                    break;
+                case getAndAccumulate:
+                    ai.getAndAccumulate(plus ? randPlus : randMinus,
+                        plus ? LambdaUtilities.addIntBinaryOperator() :
+                            LambdaUtilities.subIntBinaryOperator());
+            }
+        }
+        for(int i = 0; i < THREAD_NUM -1; i++) {
+            plusTimes += ((FutureTask<Integer>)futures[i]).get();
+        }
+        int expected = initValue + plusTimes * randPlus -
+                (THREAD_NUM * OP_TIMES - plusTimes) * randMinus;
+        assertEquals(expected, ai.get());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/AtomicIntegerFieldUpdater/LambdaTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/**
+ * @test
+ * @summary test for AtomicIntegerUpdateField.updateAndGet()/getAndUpdate() and 
+ * AtomicIntegerUpdateField.accumulateAndGet()/getAndAccumulate();
+ * @(#) LambdaTest.java
+ * @library /sqeutil
+ * @author Tristan Yan
+ * @run testng LambdaTest
+ * @bug 8001666
+ */
+
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import static org.testng.Assert.*;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class LambdaTest {
+    private static enum Type{updateAndGet, getAndUpdate, accumulateAndGet, getAndAccumulate};
+
+    private static Random rand = new Random(System.currentTimeMillis());
+
+    private final static int MAX_VALUE = 1 << 24;
+
+    private final static int MIN_VALUE = -1 << 24;
+
+    private final static int OP_TIMES = 1 << 10;
+
+    private final static int THREAD_NUM = 1 << 4;
+
+    @DataProvider
+    public Object[][] booleanProvider(){
+        Object[][] providersParam = new Object[Type.values().length][];
+        Object[] a = Type.values();
+        for(int i = 0; i < a.length; i++)
+            providersParam[i] = new Object[]{a[i]};
+        return providersParam;
+    }
+
+    @Test(dataProvider = "booleanProvider")
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public void test(final Type type) throws InterruptedException,
+            ExecutionException {
+        final Updater u = new Updater();
+        final AtomicIntegerFieldUpdater<Updater> accAIFU = AtomicIntegerFieldUpdater.<Updater>newUpdater((Class<Updater>)(Class<?>)u.getClass(), "accumulation");
+        final int randPlus = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE);
+        final int randMinus = MIN_VALUE + rand.nextInt(MAX_VALUE - MIN_VALUE);
+        switch(type) {
+            case updateAndGet: 
+                assertEquals(accAIFU.updateAndGet(u, 
+                        LambdaUtilities.addIntUnaryOperator(randPlus)), randPlus);
+                assertEquals(accAIFU.updateAndGet(u, 
+                        LambdaUtilities.subIntUnaryOperator(randMinus)), randPlus - randMinus);
+                break;
+            case getAndUpdate:
+                assertEquals(accAIFU.getAndUpdate(u, 
+                        LambdaUtilities.addIntUnaryOperator(randPlus)), 0);
+                assertEquals(accAIFU.getAndUpdate(u, 
+                        LambdaUtilities.subIntUnaryOperator(randMinus)), randPlus);
+                break;
+            case accumulateAndGet:
+                assertEquals(accAIFU.accumulateAndGet(u, randPlus, 
+                        LambdaUtilities.addIntBinaryOperator()), randPlus);
+                assertEquals(accAIFU.accumulateAndGet(u, randMinus,
+                        LambdaUtilities.subIntBinaryOperator()), randPlus - randMinus);
+                break;
+            case getAndAccumulate:
+                assertEquals(accAIFU.getAndAccumulate(u, randPlus, 
+                        LambdaUtilities.addIntBinaryOperator()), 0);
+                assertEquals(accAIFU.getAndAccumulate(u, randMinus,
+                        LambdaUtilities.subIntBinaryOperator()), randPlus);
+                break;
+        }
+        assertEquals(u.accumulation, randPlus - randMinus);
+
+        u.accumulation = 0;
+
+        Callable<Integer> ac = new Callable<Integer>(){
+            @Override
+            public Integer call() throws Exception {
+                int plusTimes = 0;
+                for(int index = 0; index < OP_TIMES; index++) {
+                    boolean plus = rand.nextBoolean();
+                    if(plus) plusTimes++;
+                    switch(type) {
+                        case updateAndGet:
+                            accAIFU.updateAndGet(u, plus ?
+                                LambdaUtilities.addIntUnaryOperator(randPlus) :
+                                LambdaUtilities.subIntUnaryOperator(randMinus));
+                            break;
+                        case getAndUpdate:
+                            accAIFU.getAndUpdate(u, plus ?
+                                LambdaUtilities.addIntUnaryOperator(randPlus) :
+                                LambdaUtilities.subIntUnaryOperator(randMinus));
+                            break;
+                        case accumulateAndGet:
+                            accAIFU.accumulateAndGet(u, plus ? randPlus : randMinus,
+                                plus ? LambdaUtilities.addIntBinaryOperator() :
+                                    LambdaUtilities.subIntBinaryOperator());
+                            break;
+                        case getAndAccumulate:
+                            accAIFU.getAndAccumulate(u, plus ? randPlus : randMinus,
+                                plus ? LambdaUtilities.addIntBinaryOperator() :
+                                    LambdaUtilities.subIntBinaryOperator());
+                            break;
+                    }
+                }
+                return plusTimes;
+            }
+        };
+
+        FutureTask[] futures = new FutureTask[THREAD_NUM -1];
+        for(int i = 0; i < THREAD_NUM -1; i++) {
+            futures[i] = new FutureTask<Integer>(ac);
+            new Thread(futures[i]).start();
+        }
+        int plusTimes = 0;
+        for(int index = 0; index < OP_TIMES; index++) {
+            boolean plus = rand.nextBoolean();
+            if(plus) plusTimes++;
+            switch(type) {
+                case updateAndGet:
+                    accAIFU.updateAndGet(u, plus ?
+                        LambdaUtilities.addIntUnaryOperator(randPlus) :
+                        LambdaUtilities.subIntUnaryOperator(randMinus));
+                    break;
+                case getAndUpdate:
+                    accAIFU.getAndUpdate(u, plus ?
+                        LambdaUtilities.addIntUnaryOperator(randPlus) :
+                        LambdaUtilities.subIntUnaryOperator(randMinus));
+                    break;
+                case accumulateAndGet:
+                    accAIFU.accumulateAndGet(u, plus ? randPlus : randMinus,
+                        plus ? LambdaUtilities.addIntBinaryOperator() :
+                            LambdaUtilities.subIntBinaryOperator());
+                    break;
+                case getAndAccumulate:
+                    accAIFU.getAndAccumulate(u, plus ? randPlus : randMinus,
+                        plus ? LambdaUtilities.addIntBinaryOperator() :
+                            LambdaUtilities.subIntBinaryOperator());
+                    break;
+            }
+        }
+        for(int i = 0; i < THREAD_NUM -1; i++) {
+            plusTimes += ((FutureTask<Integer>)futures[i]).get();
+        }
+        int expected = plusTimes * randPlus -
+                (THREAD_NUM * OP_TIMES - plusTimes) * randMinus;
+        assertEquals(expected, u.accumulation);
+    }
+
+    static class Updater{
+        public volatile int accumulation;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/AtomicLong/LambdaTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary test AtomicLong.updateAndGet()/getAndUpdate() and
+ * AtomicLong.accumulateAndGet()/getAndAccumulate();
+ * @(#) LambdaTest.java
+ * @library /sqeutil
+ * @author Tristan Yan
+ * @run testng LambdaTest
+ * @bug 8001666
+ */
+
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicLong;
+import static org.testng.Assert.*;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+
+public class LambdaTest {
+    private static enum Type{updateAndGet, getAndUpdate, accumulateAndGet, getAndAccumulate};
+
+    private static Random rand = new Random(System.currentTimeMillis());
+
+    private final static int MAX_VALUE = 1 << 24;
+
+    private final static int MIN_VALUE = -1 << 24;
+
+    private final static int OP_TIMES = 1 << 10;
+
+    private final static int THREAD_NUM = 1 << 4;
+
+    @DataProvider
+    public Object[][] booleanProvider(){
+        Object[][] providersParam = new Object[Type.values().length][];
+        Object[] a = Type.values();
+        for(int i = 0; i < a.length; i++)
+            providersParam[i] = new Object[]{a[i]};
+        return providersParam;
+    }
+
+    @Test(dataProvider = "booleanProvider")
+    public void test(final Type type) throws InterruptedException,
+            ExecutionException {
+        long initValue = rand.nextLong();
+        final AtomicLong al = new AtomicLong(initValue);
+        long tl1 = rand.nextLong();
+        if(((byte)(tl1 >> 63) & (byte)(initValue >> 63)) == 0){
+            if(initValue > 0) {
+                if(tl1 > Long.MAX_VALUE - initValue)
+                    tl1 = - tl1;
+            } else {
+                if(tl1 < Long.MIN_VALUE - initValue)
+                    tl1 = - tl1;
+            }
+        }
+        final long randPlus = tl1;
+
+        long tl2 = rand.nextLong();
+        if(((byte)(tl2 >> 63) & (byte)(initValue + randPlus >> 63)) == 1){
+            if(initValue + randPlus > 0) {
+                if(-tl2 > Long.MAX_VALUE - (initValue + randPlus))
+                    tl2 = - tl2;
+            } else {
+                if(tl2 < Long.MIN_VALUE + (initValue + randPlus))
+                    tl2 = - tl2;
+            }
+        }
+        final long randMinus = tl2;
+        switch(type) {
+            case updateAndGet: 
+                assertEquals(al.updateAndGet(LambdaUtilities.addLongUnaryOperator(randPlus))
+                    , initValue + randPlus);
+                assertEquals(al.updateAndGet(LambdaUtilities.subLongUnaryOperator(randMinus))
+                    , initValue + randPlus - randMinus);
+                break;
+            case getAndUpdate:
+                assertEquals(al.getAndUpdate(LambdaUtilities.addLongUnaryOperator(randPlus))
+                    , initValue);
+                assertEquals(al.getAndUpdate(LambdaUtilities.subLongUnaryOperator(randMinus))
+                    , initValue + randPlus);
+                break;
+            case accumulateAndGet: 
+                assertEquals(al.accumulateAndGet(randPlus, LambdaUtilities.addLongBinaryOperator())
+                    , initValue + randPlus);
+                assertEquals(al.accumulateAndGet(randMinus, LambdaUtilities.subLongBinaryOperator())
+                    , initValue + randPlus - randMinus);
+                break;
+            case getAndAccumulate:
+                assertEquals(al.getAndAccumulate(randPlus, LambdaUtilities.addLongBinaryOperator())
+                    , initValue);
+                assertEquals(al.getAndAccumulate(randMinus, LambdaUtilities.subLongBinaryOperator())
+                    , initValue + randPlus);
+                break;
+        }
+        assertEquals(al.get() , initValue + randPlus - randMinus);
+
+        final long randPlus1 = rand.nextBoolean() ? (long)rand.nextInt(MAX_VALUE) : -(long)rand.nextInt(MAX_VALUE);
+        final long randMinus1 = rand.nextBoolean() ? (long)rand.nextInt(MAX_VALUE) : -(long)rand.nextInt(MAX_VALUE);
+        al.set(initValue);
+        final int mainPLusTimes = 0;
+        int minusPLusTimes = 0;
+
+        class UpdateThread  extends Thread{
+            OpTimes ops;
+            CountDownLatch latch;
+            UpdateThread(OpTimes ops, CountDownLatch latch){
+                this.ops = ops;
+                this.latch = latch;
+            }
+            @Override
+            public void run() {
+                int plusTimes = 0;
+                int minusTimes = 0;
+                for(int index = 0; index < OP_TIMES; index++) {
+                    boolean plus = rand.nextBoolean();
+                    if(plus) {
+                        if (randPlus1 > 0 && al.get() > Long.MAX_VALUE - randPlus1
+                                || randPlus1 < 0 && al.get() < Long.MIN_VALUE - randPlus1)
+                            continue;
+                    }
+                    else  {
+                        if (randPlus1 > 0 && al.get() < Long.MIN_VALUE + randPlus1
+                                || randPlus1 > 0 && al.get() > Long.MAX_VALUE - randPlus1)
+                            continue;
+                    }
+                    switch(type) {
+                        case updateAndGet: 
+                            al.updateAndGet(plus ?
+                                LambdaUtilities.addLongUnaryOperator(randPlus1) :
+                                LambdaUtilities.subLongUnaryOperator(randMinus1));
+                            break;
+                        case getAndUpdate:
+                            al.getAndUpdate(plus ?
+                                LambdaUtilities.addLongUnaryOperator(randPlus1) :
+                                LambdaUtilities.subLongUnaryOperator(randMinus1));
+                            break;
+                        case accumulateAndGet: 
+                            al.accumulateAndGet(plus ? randPlus1 : randMinus1,
+                                plus ? LambdaUtilities.addLongBinaryOperator() :
+                                    LambdaUtilities.subLongBinaryOperator());
+                            break;
+                        case getAndAccumulate:
+                            al.getAndAccumulate(plus ? randPlus1 : randMinus1,
+                                plus ? LambdaUtilities.addLongBinaryOperator() :
+                                    LambdaUtilities.subLongBinaryOperator());
+                            break;
+                    }
+                    if(plus)
+                        plusTimes++;
+                    else
+                        minusTimes++;
+                }
+                ops.plus = plusTimes;
+                ops.minus = minusTimes;
+                latch.countDown();
+            }
+
+        };
+        OpTimes[] opts = new OpTimes[THREAD_NUM -1];
+        CountDownLatch latch = new CountDownLatch(THREAD_NUM -1);
+        for(int i = 0; i < THREAD_NUM -1; i++) {
+            opts[i] = new OpTimes();
+            new UpdateThread(opts[i], latch).start();
+        }
+        int plusTimes = 0;
+        int minusTimes = 0;
+        for(int index = 0; index < OP_TIMES; index++) {
+            boolean plus = rand.nextBoolean();
+            if(plus) {
+                if (randPlus1 > 0 && al.get() > Long.MAX_VALUE - randPlus1
+                        || randPlus1 < 0 && al.get() < Long.MIN_VALUE - randPlus1)
+                    continue;
+            }
+            else  {
+                if (randPlus1 > 0 && al.get() < Long.MIN_VALUE + randPlus1
+                        || randPlus1 > 0 && al.get() > Long.MAX_VALUE - randPlus1)
+                    continue;
+            }
+            switch(type) {
+                case updateAndGet: 
+                    al.updateAndGet(plus ?
+                        LambdaUtilities.addLongUnaryOperator(randPlus1) :
+                        LambdaUtilities.subLongUnaryOperator(randMinus1));
+                    break;
+                case getAndUpdate:
+                    al.getAndUpdate(plus ?
+                        LambdaUtilities.addLongUnaryOperator(randPlus1) :
+                        LambdaUtilities.subLongUnaryOperator(randMinus1));
+                    break;
+                case accumulateAndGet: 
+                    al.accumulateAndGet(plus ? randPlus1 : randMinus1,
+                        plus ? LambdaUtilities.addLongBinaryOperator() :
+                            LambdaUtilities.subLongBinaryOperator());
+                    break;
+                case getAndAccumulate:
+                    al.getAndAccumulate(plus ? randPlus1 : randMinus1,
+                        plus ? LambdaUtilities.addLongBinaryOperator() :
+                            LambdaUtilities.subLongBinaryOperator());
+                    break;
+            }
+            if(plus)
+                plusTimes++;
+            else
+                minusTimes++;
+        }
+        latch.await();
+        for(int i = 0; i < THREAD_NUM -1; i++) {
+            plusTimes += opts[i].plus;
+            minusTimes += opts[i].minus;
+        }
+        long expected = initValue + plusTimes * randPlus1 -
+                minusTimes * randMinus1;
+        assertEquals(expected, al.get());
+    }
+}
+class OpTimes{
+    public int plus;
+
+    public int minus;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/AtomicLongFieldUpdater/LambdaTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary test AtomicLongFieldUpdater.updateAndGet()/getAndUpdate() and
+ * AtomicLongFieldUpdater.accumulateAndGet()/getAndAccumulate();
+ * @(#) LambdaTest.java
+ * @library /sqeutil
+ * @author Tristan Yan
+ * @run testng LambdaTest
+ * @bug 8001666
+ */
+
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+import static org.testng.Assert.*;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class LambdaTest {
+    private static enum Type{updateAndGet, getAndUpdate, accumulateAndGet, getAndAccumulate};
+
+    private static Random rand = new Random(System.currentTimeMillis());
+
+    private final static int OP_TIMES = 1 << 10;
+
+    private final static int THREAD_NUM = 1 << 4;
+
+    @DataProvider
+    public Object[][] booleanProvider(){
+        Object[][] providersParam = new Object[Type.values().length][];
+        Object[] a = Type.values();
+        for(int i = 0; i < a.length; i++)
+            providersParam[i] = new Object[]{a[i]};
+        return providersParam;
+    }
+
+    @Test(dataProvider = "booleanProvider")
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public void test(final Type type) throws InterruptedException,
+            ExecutionException {
+        long initValue = rand.nextLong();
+        final Updater u = new Updater();
+        u.accumulation = initValue;
+        final AtomicLongFieldUpdater<Updater> accAIFU
+                = AtomicLongFieldUpdater.<Updater>newUpdater((Class<Updater>)(Class<?>)u.getClass(), "accumulation");
+        final long randPlus = rand.nextLong();
+        final long randMinus = rand.nextLong();
+        switch(type) {
+            case updateAndGet: 
+                assertEquals(accAIFU.updateAndGet(u, 
+                        LambdaUtilities.addLongUnaryOperator(randPlus)), 
+                        initValue + randPlus);
+                assertEquals(accAIFU.updateAndGet(u, 
+                        LambdaUtilities.subLongUnaryOperator(randMinus)), 
+                        initValue + randPlus - randMinus);
+                break;
+            case getAndUpdate:
+                assertEquals(accAIFU.getAndUpdate(u,
+                        LambdaUtilities.addLongUnaryOperator(randPlus)),
+                        initValue);
+                assertEquals(accAIFU.getAndUpdate(u,
+                        LambdaUtilities.subLongUnaryOperator(randMinus)),
+                        initValue + randPlus);
+                break;
+            case accumulateAndGet: 
+                assertEquals(accAIFU.accumulateAndGet(u, randPlus,
+                        LambdaUtilities.addLongBinaryOperator()), 
+                        initValue + randPlus);
+                assertEquals(accAIFU.accumulateAndGet(u, randMinus,
+                        LambdaUtilities.subLongBinaryOperator()), 
+                        initValue + randPlus - randMinus);
+                break;
+            case getAndAccumulate:
+                assertEquals(accAIFU.getAndAccumulate(u, randPlus,
+                        LambdaUtilities.addLongBinaryOperator()),
+                        initValue);
+                assertEquals(accAIFU.getAndAccumulate(u, randMinus,
+                        LambdaUtilities.subLongBinaryOperator()),
+                        initValue + randPlus);
+                break;
+        }
+        assertEquals(u.accumulation, initValue + randPlus - randMinus);
+
+        class UpdateThread  extends Thread{
+            OpTimes ops;
+
+            CountDownLatch latch;
+            UpdateThread(OpTimes ops, CountDownLatch latch){
+                this.ops = ops;
+                this.latch = latch;
+            }
+            @Override
+            public void run() {
+                int plusTimes = 0;
+                int minusTimes = 0;
+                for(int index = 0; index < OP_TIMES; index++) {
+                    boolean plus = rand.nextBoolean();
+                    switch(type) {
+                        case updateAndGet:
+                            accAIFU.updateAndGet(u, plus ?
+                                LambdaUtilities.addLongUnaryOperator(randPlus) :
+                                LambdaUtilities.subLongUnaryOperator(randMinus));
+                            break;
+                        case getAndUpdate:
+                            accAIFU.getAndUpdate(u, plus ?
+                                LambdaUtilities.addLongUnaryOperator(randPlus) :
+                                LambdaUtilities.subLongUnaryOperator(randMinus));
+                            break;
+                        case accumulateAndGet:
+                            accAIFU.accumulateAndGet(u, plus ? randPlus : randMinus,
+                                plus ? LambdaUtilities.addLongBinaryOperator() :
+                                    LambdaUtilities.subLongBinaryOperator());
+                            break;
+                        case getAndAccumulate:
+                            accAIFU.getAndAccumulate(u, plus ? randPlus : randMinus,
+                                plus ? LambdaUtilities.addLongBinaryOperator() :
+                                    LambdaUtilities.subLongBinaryOperator());
+                            break;
+                    }
+                    if(plus)
+                        plusTimes++;
+                    else
+                        minusTimes++;
+                }
+                ops.plus = plusTimes;
+                ops.minus = minusTimes;
+                latch.countDown();
+            }
+        };
+        u.accumulation = initValue;
+
+        int plusTimes = 0;
+        int minusTimes = 0;
+        OpTimes[] opts = new OpTimes[THREAD_NUM -1];
+        CountDownLatch latch = new CountDownLatch(THREAD_NUM -1);
+        for(int i = 0; i < THREAD_NUM -1; i++) {
+            opts[i] = new OpTimes();
+            new UpdateThread(opts[i], latch).start();
+        }
+
+        for(int index = 0; index < OP_TIMES; index++) {
+            boolean plus = rand.nextBoolean();
+            switch(type) {
+                case updateAndGet:
+                    accAIFU.updateAndGet(u, plus ?
+                        LambdaUtilities.addLongUnaryOperator(randPlus) :
+                        LambdaUtilities.subLongUnaryOperator(randMinus));
+                    break;
+                case getAndUpdate:
+                    accAIFU.getAndUpdate(u, plus ?
+                        LambdaUtilities.addLongUnaryOperator(randPlus) :
+                        LambdaUtilities.subLongUnaryOperator(randMinus));
+                    break;
+                case accumulateAndGet:
+                    accAIFU.accumulateAndGet(u, plus ? randPlus : randMinus,
+                        plus ? LambdaUtilities.addLongBinaryOperator() :
+                            LambdaUtilities.subLongBinaryOperator());
+                    break;
+                case getAndAccumulate:
+                    accAIFU.getAndAccumulate(u, plus ? randPlus : randMinus,
+                        plus ? LambdaUtilities.addLongBinaryOperator() :
+                            LambdaUtilities.subLongBinaryOperator());
+                    break;
+            }
+            if(plus)
+                plusTimes++;
+            else
+                minusTimes++;
+        }
+        latch.await();
+        for(int i = 0; i < THREAD_NUM -1; i++) {
+            plusTimes += opts[i].plus;
+            minusTimes += opts[i].minus;
+        }
+        long expected = initValue + plusTimes * randPlus -
+                minusTimes * randMinus;
+        assertEquals(expected, u.accumulation);
+    }
+
+    static class Updater{
+        public volatile long accumulation;
+    }
+
+    static class OpTimes{
+        public int plus;
+
+        public int minus;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/AtomicReference/LambdaTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary test for AtomicReference.updateAndGet()/getAndUpdate() and
+ * AtomicReference.accumulateAndGet()/getAndAccumulate();
+ * @(#) LambdaTest.java
+ * @library ../../
+ * @author Tristan Yan
+ * @run testng LambdaTest
+ * @bug 8001666
+ */
+
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BinaryOperator;
+import java.util.function.UnaryOperator;
+import static org.testng.Assert.*;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class LambdaTest {
+    private static enum Type{updateAndGet, getAndUpdate, accumulateAndGet, getAndAccumulate};
+
+    private static Random rand = new Random(System.currentTimeMillis());
+
+    private final static int OP_TIMES = 1 << 10;
+
+    private final static int THREAD_NUM = 1 << 4;
+
+    @DataProvider
+    public Object[][] booleanProvider(){
+        Object[][] providersParam = new Object[Type.values().length][];
+        Object[] a = Type.values();
+        for(int i = 0; i < a.length; i++)
+            providersParam[i] = new Object[]{a[i]};
+        return providersParam;
+    }
+
+    @Test(dataProvider = "booleanProvider")
+    public void test(final Type type) throws InterruptedException{
+        int initPlus = rand.nextInt();
+        int initMinus = rand.nextInt();
+        final AtomicReference<OpValues> ar
+                = new AtomicReference<>(new OpValues(initPlus, initMinus));
+        final int oprnd = rand.nextInt();
+        boolean startFromPlus = rand.nextBoolean();
+        switch(type) {
+            case updateAndGet:
+                assertEquals(ar.updateAndGet(opUnaryOperator(startFromPlus, oprnd))
+                    , startFromPlus ? new OpValues(initPlus + oprnd, initMinus) :
+                    new OpValues(initPlus, initMinus - oprnd));
+                assertEquals(ar.updateAndGet(opUnaryOperator(!startFromPlus, oprnd))
+                    , new OpValues(initPlus + oprnd, initMinus - oprnd));
+                break;
+            case getAndUpdate:
+                assertEquals(ar.getAndUpdate(opUnaryOperator(startFromPlus, oprnd))
+                    , new OpValues(initPlus, initMinus));
+                assertEquals(ar.getAndUpdate(opUnaryOperator(!startFromPlus, oprnd))
+                    ,  startFromPlus ? new OpValues(initPlus + oprnd, initMinus) :
+                    new OpValues(initPlus, initMinus - oprnd));
+                break;
+            case accumulateAndGet:
+                assertEquals(ar.accumulateAndGet(
+                        new OpValues(oprnd, oprnd), 
+                        opBinaryOperator(startFromPlus))
+                    , startFromPlus ? new OpValues(initPlus + oprnd, initMinus) :
+                    new OpValues(initPlus, initMinus - oprnd));
+                assertEquals(ar.accumulateAndGet(
+                        new OpValues(oprnd, oprnd),
+                        opBinaryOperator(!startFromPlus))
+                    ,  new OpValues(initPlus + oprnd, initMinus - oprnd));
+                break;
+            case getAndAccumulate:
+                assertEquals(ar.getAndAccumulate(
+                        new OpValues(oprnd, oprnd), 
+                        opBinaryOperator(startFromPlus))
+                    , new OpValues(initPlus, initMinus));
+                assertEquals(ar.getAndAccumulate(
+                        new OpValues(oprnd, oprnd),
+                        opBinaryOperator(!startFromPlus))
+                    ,  startFromPlus ? new OpValues(initPlus + oprnd, initMinus) :
+                    new OpValues(initPlus, initMinus - oprnd));
+                break;
+        }
+        class UpdateThread  extends Thread{
+            CountDownLatch latch;
+            private int plusTimes = 0;
+            private int minusTimes = 0;
+
+            UpdateThread(CountDownLatch latch){
+                this.latch = latch;
+            }
+            @Override
+            public void run() {
+                for(int index = 0; index < OP_TIMES; index++) {
+                    boolean plus = rand.nextBoolean();
+                    switch(type) {
+                        case updateAndGet:
+                            ar.updateAndGet(opUnaryOperator(plus, oprnd));
+                            break;
+                        case getAndUpdate:
+                            ar.getAndUpdate(opUnaryOperator(plus, oprnd));
+                            break;
+                        case accumulateAndGet:
+                            ar.accumulateAndGet(new OpValues(oprnd, oprnd),
+                                    opBinaryOperator(plus));
+                            break;
+                        case getAndAccumulate:
+                            ar.getAndAccumulate(new OpValues(oprnd, oprnd),
+                                    opBinaryOperator(plus));
+                            break;
+                    }
+                    if(plus)
+                        plusTimes++;
+                    else
+                        minusTimes++;
+                }
+                latch.countDown();
+            }
+            int plusTimes(){ return plusTimes; }
+            int minusTimes(){ return minusTimes; }
+        };
+        UpdateThread[] threads = new UpdateThread[THREAD_NUM -1];
+        CountDownLatch latch = new CountDownLatch(THREAD_NUM -1);
+        for(int i = 0; i < THREAD_NUM -1; i++) {
+            threads[i] = new UpdateThread(latch);
+            threads[i].start();
+        }
+        int plusTimes = 0;
+        int minusTimes = 0;
+        for(int index = 0; index < OP_TIMES; index++) {
+            boolean isPlus = rand.nextBoolean();
+            switch(type) {
+                case updateAndGet:
+                    ar.updateAndGet(opUnaryOperator(isPlus, oprnd));
+                    break;
+                case getAndUpdate:
+                    ar.getAndUpdate(opUnaryOperator(isPlus, oprnd));
+                    break;
+                case accumulateAndGet:
+                    ar.accumulateAndGet(new OpValues(oprnd, oprnd),
+                            opBinaryOperator(isPlus));
+                    break;
+                case getAndAccumulate:
+                    ar.getAndAccumulate(new OpValues(oprnd, oprnd),
+                            opBinaryOperator(isPlus));
+                    break;
+            }
+            if(isPlus)
+                plusTimes++;
+            else
+                minusTimes++;
+        }
+        latch.await();
+        for(int i = 0; i < THREAD_NUM -1; i++) {
+            plusTimes += threads[i].plusTimes();
+            minusTimes += threads[i].minusTimes();
+        }
+        assertEquals(ar.get().getPlusAccumulated(), initPlus + plusTimes * oprnd + oprnd);
+        assertEquals(ar.get().getMinusAccumulated(), initMinus - minusTimes * oprnd - oprnd);
+    }
+
+    static final class OpValues{
+        final int plusAccumulated;
+
+        final int minusAccumulated;
+
+        OpValues(int plusAccumulated, int minusAccumulated){
+            this.plusAccumulated = plusAccumulated;
+            this.minusAccumulated = minusAccumulated;
+        }
+
+        OpValues operate(boolean isPlus, int value) {
+            if(isPlus)
+                return new OpValues(plusAccumulated + value, minusAccumulated);
+            else
+                return new OpValues(plusAccumulated, minusAccumulated - value);
+        }
+
+        int getPlusAccumulated(){    return plusAccumulated;  }
+        int getMinusAccumulated(){    return minusAccumulated;  }
+
+        @Override
+        public boolean equals(Object o){
+            OpValues opv = (OpValues)o;
+            return (opv.plusAccumulated == plusAccumulated)
+                    && (opv.minusAccumulated == minusAccumulated);
+        }
+    }
+
+    public static UnaryOperator<OpValues> opUnaryOperator(boolean isPlus, int value) {
+        return t -> t.operate(isPlus, value);
+    }
+
+    public static BinaryOperator<OpValues> opBinaryOperator(boolean isPlus) {
+        return (t1, t2) -> t1.operate(isPlus, isPlus ? t2.getPlusAccumulated() : t2.getMinusAccumulated());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/AtomicReferenceFieldUpdater/LambdaTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary test for AtomicReferenceFieldUpdater.updateAndGet()/getAndUpdate()
+ * and AtomicReferenceFieldUpdater.accumulateAndGet()/getAndAccumulate();
+ * @(#) LambdaTest.java
+ * @library ../../
+ * @author Tristan Yan
+ * @run testng LambdaTest
+ * @bug 8001666
+ */
+
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import java.util.function.BinaryOperator;
+import java.util.function.UnaryOperator;
+import static org.testng.Assert.*;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class LambdaTest {
+    private static enum Type{updateAndGet, getAndUpdate, accumulateAndGet, getAndAccumulate};
+
+    private static Random rand = new Random(System.currentTimeMillis());
+
+    private final static int OP_TIMES = 1 << 10;
+
+    private final static int THREAD_NUM = 1 << 4;
+
+    @DataProvider
+    public Object[][] booleanProvider(){
+        Object[][] providersParam = new Object[Type.values().length][];
+        Object[] a = Type.values();
+        for(int i = 0; i < a.length; i++)
+            providersParam[i] = new Object[]{a[i]};
+        return providersParam;
+    }
+
+    @Test(dataProvider = "booleanProvider")
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public void test(final Type type) throws InterruptedException{
+        int initValue = rand.nextInt();
+        final Updater u = new Updater();
+        u.accumulation = new OpValues(initValue);
+        final AtomicReferenceFieldUpdater<Updater, OpValues> accARFU
+                = AtomicReferenceFieldUpdater.<Updater, OpValues>newUpdater((Class<Updater>)(Class<?>)u.getClass(), (Class<OpValues>)(Class<?>)u.accumulation.getClass(),  "accumulation");
+
+        final int oprnd = rand.nextInt();
+        boolean startFromPlus = rand.nextBoolean();
+        switch(type) {
+            case updateAndGet:
+                assertEquals(accARFU.updateAndGet(u,opUnaryOperator(startFromPlus, oprnd))
+                    , new OpValues(startFromPlus ? initValue + oprnd : initValue - oprnd));
+                assertEquals(accARFU.updateAndGet(u,opUnaryOperator(!startFromPlus, oprnd))
+                    , new OpValues(initValue));
+                break;
+            case getAndUpdate:
+                assertEquals(accARFU.getAndUpdate(u,opUnaryOperator(startFromPlus, oprnd))
+                    , new OpValues(initValue));
+                assertEquals(accARFU.getAndUpdate(u,opUnaryOperator(!startFromPlus, oprnd))
+                    , new OpValues(startFromPlus ? initValue + oprnd : initValue - oprnd));
+                break;
+            case accumulateAndGet:
+                assertEquals(accARFU.accumulateAndGet(u, new OpValues(oprnd),
+                        opBinaryOperator(startFromPlus))
+                    , new OpValues(startFromPlus ? initValue + oprnd : initValue - oprnd));
+                assertEquals(accARFU.accumulateAndGet(u, new OpValues(oprnd),
+                        opBinaryOperator(!startFromPlus))
+                    , new OpValues(initValue));
+                break;
+            case getAndAccumulate:
+                assertEquals(accARFU.getAndAccumulate(u, new OpValues(oprnd),
+                        opBinaryOperator(startFromPlus))
+                    , new OpValues(initValue));
+                assertEquals(accARFU.getAndAccumulate(u, new OpValues(oprnd),
+                        opBinaryOperator(!startFromPlus))
+                    , new OpValues(startFromPlus ? initValue + oprnd : initValue - oprnd));
+                break;
+        }
+        class UpdateThread  extends Thread{
+            CountDownLatch latch;
+            private int plusTimes = 0;
+            private int minusTimes = 0;
+
+            UpdateThread(CountDownLatch latch){
+                this.latch = latch;
+            }
+            @Override
+            public void run() {
+                for(int index = 0; index < OP_TIMES; index++) {
+                    boolean plus = rand.nextBoolean();
+                    switch(type) {
+                        case updateAndGet:
+                            accARFU.updateAndGet(u,opUnaryOperator(plus, oprnd));
+                            break;
+                        case getAndUpdate:
+                            accARFU.getAndUpdate(u,opUnaryOperator(plus, oprnd));
+                            break;
+                        case accumulateAndGet:
+                            accARFU.accumulateAndGet(u, new OpValues(oprnd),
+                                    opBinaryOperator(plus));
+                            break;
+                        case getAndAccumulate:
+                            accARFU.getAndAccumulate(u, new OpValues(oprnd),
+                                    opBinaryOperator(plus));
+                            break;
+                    }
+                    if(plus)
+                        plusTimes++;
+                    else
+                        minusTimes++;
+                }
+                latch.countDown();
+            }
+            int plusTimes(){ return plusTimes; }
+            int minusTimes(){ return minusTimes; }
+        };
+        UpdateThread[] threads = new UpdateThread[THREAD_NUM -1];
+        CountDownLatch latch = new CountDownLatch(THREAD_NUM -1);
+        for(int i = 0; i < THREAD_NUM -1; i++) {
+            threads[i] = new UpdateThread(latch);
+            threads[i].start();
+        }
+        int plusTimes = 0;
+        int minusTimes = 0;
+        for(int index = 0; index < OP_TIMES; index++) {
+            boolean isPlus = rand.nextBoolean();
+            switch(type) {
+                case updateAndGet:
+                    accARFU.updateAndGet(u,opUnaryOperator(isPlus, oprnd));
+                    break;
+                case getAndUpdate:
+                    accARFU.getAndUpdate(u,opUnaryOperator(isPlus, oprnd));
+                    break;
+                case accumulateAndGet:
+                    accARFU.accumulateAndGet(u, new OpValues(oprnd),
+                            opBinaryOperator(isPlus));
+                    break;
+                case getAndAccumulate:
+                    accARFU.getAndAccumulate(u, new OpValues(oprnd),
+                            opBinaryOperator(isPlus));
+                    break;
+            }
+            if(isPlus)
+                plusTimes++;
+            else
+                minusTimes++;
+        }
+        latch.await();
+        for(int i = 0; i < THREAD_NUM -1; i++) {
+            plusTimes += threads[i].plusTimes();
+            minusTimes += threads[i].minusTimes();
+        }
+        assertEquals(accARFU.get(u).getAccumulated(), initValue + plusTimes * oprnd - minusTimes * oprnd);
+    }
+
+    static final class OpValues{
+        int accumulated;
+
+        OpValues(int accumulated){
+            this.accumulated = accumulated;
+        }
+
+        OpValues operate(boolean isPlus, int value) {
+            if(isPlus)
+                return new OpValues(accumulated + value);
+            else
+                return new OpValues(accumulated - value);
+        }
+
+        int getAccumulated(){    return accumulated;  }
+
+        @Override
+        public boolean equals(Object o){
+            OpValues opv = (OpValues)o;
+            return (opv.accumulated == accumulated);
+        }
+    }
+
+
+    static class Updater{
+        public volatile OpValues accumulation;
+    }
+
+    public static UnaryOperator<OpValues> opUnaryOperator(boolean isPlus, int value) {
+        return t -> t.operate(isPlus, value);
+    }
+
+    public static BinaryOperator<OpValues> opBinaryOperator(boolean isPlus) {
+        return (t1, t2) -> t1.operate(isPlus, t2.getAccumulated());
+    }
+}
\ No newline at end of file
--- a/test/java/util/concurrent/CompletableFuture/Basic.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/java/util/concurrent/CompletableFuture/Basic.java	Mon Nov 11 23:17:30 2013 -0800
@@ -66,6 +66,7 @@
         try { equalAnyOf(cf.get(), values); } catch (Throwable x) { unexpected(x); }
         try { equalAnyOf(cf.get(0L, SECONDS), values); } catch (Throwable x) { unexpected(x); }
         check(cf.isDone(), "Expected isDone to be true, got:" + cf);
+        check(!cf.isCompletedExceptionally(), "Expected isCompletedExceptionally to return false");
         check(!cf.isCancelled(), "Expected isCancelled to be false");
         check(!cf.cancel(true), "Expected cancel to return false");
         check(cf.toString().contains("[Completed normally]"));
@@ -97,6 +98,7 @@
         catch (CancellationException x) { if (cancelled) pass(); else fail(); }
         catch (ExecutionException x) { if (cancelled) check(x.getCause() instanceof CancellationException); else pass(); }
         check(cf.isDone(), "Expected isDone to be true, got:" + cf);
+        check(cf.isCompletedExceptionally(), "Expected isCompletedExceptionally");
         check(cf.isCancelled() == cancelled, "Expected isCancelled: " + cancelled + ", got:"  + cf.isCancelled());
         check(cf.cancel(true) == cancelled, "Expected cancel: " + cancelled + ", got:"  + cf.cancel(true));
         check(cf.toString().contains("[Completed exceptionally]"));  // ## TODO: 'E'xceptionally
@@ -805,6 +807,49 @@
             cf2 = cf1.handle((x,t) -> { check(t.getCause() == ex); return 2;});
             checkCompletedExceptionally(cf1);
             checkCompletedNormally(cf2, 2);
+
+            cf1 = supplyAsync(() -> 1);
+            cf2 = cf1.handleAsync((x,t) -> x+1);
+            checkCompletedNormally(cf1, 1);
+            checkCompletedNormally(cf2, 2);
+
+            cf1 = supplyAsync(() -> { throw ex; });
+            cf2 = cf1.handleAsync((x,t) -> { check(t.getCause() == ex); return 2;});
+            checkCompletedExceptionally(cf1);
+            checkCompletedNormally(cf2, 2);
+        } catch (Throwable t) { unexpected(t); }
+
+        //----------------------------------------------------------------
+        // whenComplete tests
+        //----------------------------------------------------------------
+        try {
+            AtomicInteger count = new AtomicInteger();
+            CompletableFuture<Integer> cf2;
+            CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
+            cf2 = cf1.whenComplete((x,t) -> count.getAndIncrement());
+            checkCompletedNormally(cf1, 1);
+            checkCompletedNormally(cf2, 1);
+            check(count.get() == 1, "action count should be incremented");
+
+            final RuntimeException ex = new RuntimeException();
+            cf1 = supplyAsync(() -> { throw ex; });
+            cf2 = cf1.whenComplete((x,t) -> count.getAndIncrement());
+            checkCompletedExceptionally(cf1);
+            checkCompletedExceptionally(cf2);
+            check(count.get() == 2, "action count should be incremented");
+
+            cf1 = supplyAsync(() -> 1);
+            cf2 = cf1.whenCompleteAsync((x,t) -> count.getAndIncrement());
+            checkCompletedNormally(cf1, 1);
+            checkCompletedNormally(cf2, 1);
+            check(count.get() == 3, "action count should be incremented");
+
+            cf1 = supplyAsync(() -> { throw ex; });
+            cf2 = cf1.whenCompleteAsync((x,t) -> count.getAndIncrement());
+            checkCompletedExceptionally(cf1);
+            checkCompletedExceptionally(cf2);
+            check(count.get() == 4, "action count should be incremented");
+
         } catch (Throwable t) { unexpected(t); }
 
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/concurrent/forkjoin/ParallelSorting.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,2069 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* Adapted from test/java/util/Arrays/Sorting.java
+ *
+ * Where that test checks Arrays.sort against manual quicksort routines,
+ * this test checks parallelSort against either Arrays.sort or manual
+ * quicksort routines.
+ */
+
+/*
+/*
+ * @test
+ * @summary Exercise ForkJoinUtils.parallelSort (adapted from test Sorting)
+ * @build ParallelSorting
+ * @run main ParallelSorting -shortrun
+ *
+ * @author Vladimir Yaroslavskiy
+ * @author Jon Bentley
+ * @author Josh Bloch
+ *
+ */
+
+import java.util.Arrays;
+import java.util.Random;
+import java.io.PrintStream;
+import java.util.Comparator;
+
+public class ParallelSorting {
+    private static final PrintStream out = System.out;
+    private static final PrintStream err = System.err;
+
+    // Array lengths used in a long run (default)
+    private static final int[] LONG_RUN_LENGTHS = {
+        1, 2, 3, 5, 8, 13, 21, 34, 55, 100, 1000, 10000, 100000, 1000000 };
+
+    // Array lengths used in a short run
+    private static final int[] SHORT_RUN_LENGTHS = {
+        1, 2, 3, 21, 55, 1000, 10000 };
+
+    // Random initial values used in a long run (default)
+    private static final long[] LONG_RUN_RANDOMS = { 666, 0xC0FFEE, 999 };
+
+    // Random initial values used in a short run
+    private static final long[] SHORT_RUN_RANDOMS = { 666 };
+
+    public static void main(String[] args) {
+        boolean shortRun = args.length > 0 && args[0].equals("-shortrun");
+        long start = System.currentTimeMillis();
+
+        if (shortRun) {
+            testAndCheck(SHORT_RUN_LENGTHS, SHORT_RUN_RANDOMS);
+        } else {
+            testAndCheck(LONG_RUN_LENGTHS, LONG_RUN_RANDOMS);
+        }
+        long end = System.currentTimeMillis();
+
+        out.format("PASSED in %d sec.\n", Math.round((end - start) / 1E3));
+    }
+
+    private static void testAndCheck(int[] lengths, long[] randoms) {
+        testEmptyAndNullIntArray();
+	testEmptyAndNullLongArray();
+        testEmptyAndNullShortArray();
+        testEmptyAndNullCharArray();
+        testEmptyAndNullByteArray();
+	testEmptyAndNullFloatArray();
+	testEmptyAndNullDoubleArray();
+
+        for (int length : lengths) {
+            testMergeSort(length);
+            testAndCheckRange(length);
+            testAndCheckSubArray(length);
+        }
+        for (long seed : randoms) {
+            for (int length : lengths) {
+                testAndCheckWithInsertionSort(length, new MyRandom(seed));
+                testAndCheckWithCheckSum(length, new MyRandom(seed));
+                testAndCheckWithScrambling(length, new MyRandom(seed));
+		testAndCheckFloat(length, new MyRandom(seed));
+		testAndCheckDouble(length, new MyRandom(seed));
+                testStable(length, new MyRandom(seed));
+            }
+        }
+    }
+
+    private static void testEmptyAndNullIntArray() {
+        ourDescription = "Check empty and null array";
+        Arrays.parallelSort(new int[]{});
+        Arrays.parallelSort(new int[]{}, 0, 0);
+
+        try {
+            Arrays.parallelSort((int[]) null);
+        } catch (NullPointerException expected) {
+            try {
+                Arrays.parallelSort((int[]) null, 0, 0);
+            } catch (NullPointerException expected2) {
+                return;
+            }
+            failed("ForkJoinUtils.parallelSort(int[],fromIndex,toIndex) shouldn't " +
+                "catch null array");
+        }
+        failed("ForkJoinUtils.parallelSort(int[]) shouldn't catch null array");
+    }
+
+    private static void testEmptyAndNullLongArray() {
+        ourDescription = "Check empty and null array";
+        Arrays.parallelSort(new long[]{});
+        Arrays.parallelSort(new long[]{}, 0, 0);
+
+        try {
+            Arrays.parallelSort((long[]) null);
+        } catch (NullPointerException expected) {
+            try {
+                Arrays.parallelSort((long[]) null, 0, 0);
+            } catch (NullPointerException expected2) {
+                return;
+            }
+            failed("ForkJoinUtils.parallelSort(long[],fromIndex,toIndex) shouldn't " +
+                "catch null array");
+        }
+        failed("ForkJoinUtils.parallelSort(long[]) shouldn't catch null array");
+    }
+
+    private static void testEmptyAndNullShortArray() {
+        ourDescription = "Check empty and null array";
+        Arrays.parallelSort(new short[]{});
+        Arrays.parallelSort(new short[]{}, 0, 0);
+
+        try {
+            Arrays.parallelSort((short[]) null);
+        } catch (NullPointerException expected) {
+            try {
+                Arrays.parallelSort((short[]) null, 0, 0);
+            } catch (NullPointerException expected2) {
+                return;
+            }
+            failed("ForkJoinUtils.parallelSort(short[],fromIndex,toIndex) shouldn't " +
+                "catch null array");
+        }
+        failed("ForkJoinUtils.parallelSort(short[]) shouldn't catch null array");
+    }
+
+    private static void testEmptyAndNullCharArray() {
+        ourDescription = "Check empty and null array";
+        Arrays.parallelSort(new char[]{});
+        Arrays.parallelSort(new char[]{}, 0, 0);
+
+        try {
+            Arrays.parallelSort((char[]) null);
+        } catch (NullPointerException expected) {
+            try {
+                Arrays.parallelSort((char[]) null, 0, 0);
+            } catch (NullPointerException expected2) {
+                return;
+            }
+            failed("ForkJoinUtils.parallelSort(char[],fromIndex,toIndex) shouldn't " +
+                "catch null array");
+        }
+        failed("ForkJoinUtils.parallelSort(char[]) shouldn't catch null array");
+    }
+
+    private static void testEmptyAndNullByteArray() {
+        ourDescription = "Check empty and null array";
+        Arrays.parallelSort(new byte[]{});
+        Arrays.parallelSort(new byte[]{}, 0, 0);
+
+        try {
+            Arrays.parallelSort((byte[]) null);
+        } catch (NullPointerException expected) {
+            try {
+                Arrays.parallelSort((byte[]) null, 0, 0);
+            } catch (NullPointerException expected2) {
+                return;
+            }
+            failed("ForkJoinUtils.parallelSort(byte[],fromIndex,toIndex) shouldn't " +
+                "catch null array");
+        }
+        failed("ForkJoinUtils.parallelSort(byte[]) shouldn't catch null array");
+    }
+
+    private static void testEmptyAndNullFloatArray() {
+        ourDescription = "Check empty and null array";
+        Arrays.parallelSort(new float[]{});
+        Arrays.parallelSort(new float[]{}, 0, 0);
+
+        try {
+            Arrays.parallelSort((float[]) null);
+        } catch (NullPointerException expected) {
+            try {
+                Arrays.parallelSort((float[]) null, 0, 0);
+            } catch (NullPointerException expected2) {
+                return;
+            }
+            failed("ForkJoinUtils.parallelSort(float[],fromIndex,toIndex) shouldn't " +
+                "catch null array");
+        }
+        failed("ForkJoinUtils.parallelSort(float[]) shouldn't catch null array");
+    }
+
+    private static void testEmptyAndNullDoubleArray() {
+        ourDescription = "Check empty and null array";
+        Arrays.parallelSort(new double[]{});
+        Arrays.parallelSort(new double[]{}, 0, 0);
+
+        try {
+            Arrays.parallelSort((double[]) null);
+        } catch (NullPointerException expected) {
+            try {
+                Arrays.parallelSort((double[]) null, 0, 0);
+            } catch (NullPointerException expected2) {
+                return;
+            }
+            failed("ForkJoinUtils.parallelSort(double[],fromIndex,toIndex) shouldn't " +
+                "catch null array");
+        }
+        failed("ForkJoinUtils.parallelSort(double[]) shouldn't catch null array");
+    }
+
+    private static void testAndCheckSubArray(int length) {
+        ourDescription = "Check sorting of subarray";
+        int[] golden = new int[length];
+        boolean newLine = false;
+
+        for (int m = 1; m < length / 2; m *= 2) {
+            newLine = true;
+            int fromIndex = m;
+            int toIndex = length - m;
+
+            prepareSubArray(golden, fromIndex, toIndex, m);
+            int[] test = golden.clone();
+
+            for (TypeConverter converter : TypeConverter.values()) {
+                out.println("Test 'subarray': " + converter +
+                   " length = " + length + ", m = " + m);
+                Object convertedGolden = converter.convert(golden);
+                Object convertedTest = converter.convert(test);
+                sortSubArray(convertedTest, fromIndex, toIndex);
+                checkSubArray(convertedTest, fromIndex, toIndex, m);
+            }
+        }
+        if (newLine) {
+            out.println();
+        }
+    }
+
+    private static void testAndCheckRange(int length) {
+        ourDescription = "Check range check";
+        int[] golden = new int[length];
+
+        for (int m = 1; m < 2 * length; m *= 2) {
+            for (int i = 1; i <= length; i++) {
+                golden[i - 1] = i % m + m % i;
+            }
+            for (TypeConverter converter : TypeConverter.values()) {
+                out.println("Test 'range': " + converter +
+                   ", length = " + length + ", m = " + m);
+                Object convertedGolden = converter.convert(golden);
+                checkRange(convertedGolden, m);
+            }
+        }
+        out.println();
+    }
+
+    private static void testStable(int length, MyRandom random) {
+        ourDescription = "Check if sorting is stable";
+        Pair[] a = build(length, random);
+
+        out.println("Test 'stable': " + "random = " + random.getSeed() +
+            ", length = " + length);
+        Arrays.parallelSort(a);
+        checkSorted(a);
+        checkStable(a);
+        out.println();
+
+	a = build(length, random);
+
+        out.println("Test 'stable' comparator: " + "random = " + random.getSeed() +
+            ", length = " + length);
+        Arrays.parallelSort(a, pairCmp);
+        checkSorted(a);
+        checkStable(a);
+        out.println();
+
+    }
+
+    private static void checkSorted(Pair[] a) {
+        for (int i = 0; i < a.length - 1; i++) {
+            if (a[i].getKey() > a[i + 1].getKey()) {
+                failedSort(i, "" + a[i].getKey(), "" + a[i + 1].getKey());
+            }
+        }
+    }
+
+    private static void checkStable(Pair[] a) {
+        for (int i = 0; i < a.length / 4; ) {
+            int key1 = a[i].getKey();
+            int value1 = a[i++].getValue();
+            int key2 = a[i].getKey();
+            int value2 = a[i++].getValue();
+            int key3 = a[i].getKey();
+            int value3 = a[i++].getValue();
+            int key4 = a[i].getKey();
+            int value4 = a[i++].getValue();
+
+            if (!(key1 == key2 && key2 == key3 && key3 == key4)) {
+                failed("On position " + i + " keys are different " +
+                    key1 + ", " + key2 + ", " + key3 + ", " + key4);
+            }
+            if (!(value1 < value2 && value2 < value3 && value3 < value4)) {
+                failed("Sorting is not stable at position " + i +
+                    ". Second values have been changed: " +  value1 + ", " +
+                    value2 + ", " + value3 + ", " + value4);
+            }
+        }
+    }
+
+    private static Pair[] build(int length, Random random) {
+        Pair[] a = new Pair[length * 4];
+
+        for (int i = 0; i < a.length; ) {
+            int key = random.nextInt();
+            a[i++] = new Pair(key, 1);
+            a[i++] = new Pair(key, 2);
+            a[i++] = new Pair(key, 3);
+            a[i++] = new Pair(key, 4);
+        }
+        return a;
+    }
+
+    private static Comparator<Pair> pairCmp = new Comparator<Pair>() {
+	public int compare(Pair p1, Pair p2) {
+	    return p1.compareTo(p2);
+	}
+    };
+
+    private static final class Pair implements Comparable<Pair> {
+        Pair(int key, int value) {
+            myKey = key;
+            myValue = value;
+        }
+
+        int getKey() {
+            return myKey;
+        }
+
+        int getValue() {
+            return myValue;
+        }
+
+        public int compareTo(Pair pair) {
+            if (myKey < pair.myKey) {
+                return -1;
+            }
+            if (myKey > pair.myKey) {
+                return 1;
+            }
+            return 0;
+        }
+
+        @Override
+        public String toString() {
+            return "(" + myKey + ", " + myValue + ")";
+        }
+
+        private int myKey;
+        private int myValue;
+    }
+
+
+    private static void testAndCheckWithInsertionSort(int length, MyRandom random) {
+        if (length > 1000) {
+            return;
+        }
+        ourDescription = "Check sorting with insertion sort";
+        int[] golden = new int[length];
+
+        for (int m = 1; m < 2 * length; m *= 2) {
+            for (UnsortedBuilder builder : UnsortedBuilder.values()) {
+                builder.build(golden, m, random);
+                int[] test = golden.clone();
+
+                for (TypeConverter converter : TypeConverter.values()) {
+                    out.println("Test 'insertion sort': " + converter +
+                        " " + builder + "random = " + random.getSeed() +
+                        ", length = " + length + ", m = " + m);
+                    Object convertedGolden = converter.convert(golden);
+                    Object convertedTest1 = converter.convert(test);
+                    Object convertedTest2 = converter.convert(test);
+                    sort(convertedTest1);
+                    sortByInsertionSort(convertedTest2);
+                    compare(convertedTest1, convertedTest2);
+                }
+            }
+        }
+        out.println();
+    }
+
+    private static void testMergeSort(int length) {
+        if (length < 1000) {
+            return;
+        }
+        ourDescription = "Check merge sorting";
+        int[] golden = new int[length];
+        int period = 67; // java.util.DualPivotQuicksort.MAX_RUN_COUNT
+
+        for (int m = period - 2; m <= period + 2; m++) {
+            for (MergeBuilder builder : MergeBuilder.values()) {
+                builder.build(golden, m);
+                int[] test = golden.clone();
+
+                for (TypeConverter converter : TypeConverter.values()) {
+                    out.println("Test 'merge sort': " + converter + " " +
+                        builder + "length = " + length + ", m = " + m);
+                    Object convertedGolden = converter.convert(golden);
+                    sort(convertedGolden);
+                    checkSorted(convertedGolden);
+                }
+            }
+        }
+        out.println();
+    }
+
+    private static void testAndCheckWithCheckSum(int length, MyRandom random) {
+        ourDescription = "Check sorting with check sum";
+        int[] golden = new int[length];
+
+        for (int m = 1; m < 2 * length; m *= 2) {
+            for (UnsortedBuilder builder : UnsortedBuilder.values()) {
+                builder.build(golden, m, random);
+                int[] test = golden.clone();
+
+                for (TypeConverter converter : TypeConverter.values()) {
+                    out.println("Test 'check sum': " + converter +
+                        " " + builder + "random = " + random.getSeed() +
+                        ", length = " + length + ", m = " + m);
+                    Object convertedGolden = converter.convert(golden);
+                    Object convertedTest = converter.convert(test);
+                    sort(convertedTest);
+                    checkWithCheckSum(convertedTest, convertedGolden);
+                }
+            }
+        }
+        out.println();
+    }
+
+    private static void testAndCheckWithScrambling(int length, MyRandom random) {
+        ourDescription = "Check sorting with scrambling";
+        int[] golden = new int[length];
+
+        for (int m = 1; m <= 7; m++) {
+            if (m > length) {
+                break;
+            }
+            for (SortedBuilder builder : SortedBuilder.values()) {
+                builder.build(golden, m);
+                int[] test = golden.clone();
+                scramble(test, random);
+
+                for (TypeConverter converter : TypeConverter.values()) {
+                    out.println("Test 'scrambling': " + converter +
+                       " " + builder + "random = " + random.getSeed() +
+                       ", length = " + length + ", m = " + m);
+                    Object convertedGolden = converter.convert(golden);
+                    Object convertedTest = converter.convert(test);
+                    sort(convertedTest);
+                    compare(convertedTest, convertedGolden);
+                }
+            }
+        }
+        out.println();
+    }
+
+    private static void testAndCheckFloat(int length, MyRandom random) {
+        ourDescription = "Check float sorting";
+        float[] golden = new float[length];
+        final int MAX = 10;
+        boolean newLine = false;
+
+        for (int a = 0; a <= MAX; a++) {
+            for (int g = 0; g <= MAX; g++) {
+                for (int z = 0; z <= MAX; z++) {
+                    for (int n = 0; n <= MAX; n++) {
+                        for (int p = 0; p <= MAX; p++) {
+                            if (a + g + z + n + p > length) {
+                                continue;
+                            }
+                            if (a + g + z + n + p < length) {
+                                continue;
+                            }
+                            for (FloatBuilder builder : FloatBuilder.values()) {
+                                out.println("Test 'float': random = " + random.getSeed() +
+                                   ", length = " + length + ", a = " + a + ", g = " +
+                                   g + ", z = " + z + ", n = " + n + ", p = " + p);
+                                builder.build(golden, a, g, z, n, p, random);
+                                float[] test = golden.clone();
+                                scramble(test, random);
+                                sort(test);
+                                compare(test, golden, a, n, g);
+                            }
+                            newLine = true;
+                        }
+                    }
+                }
+            }
+        }
+        if (newLine) {
+            out.println();
+        }
+    }
+
+    private static void testAndCheckDouble(int length, MyRandom random) {
+        ourDescription = "Check double sorting";
+        double[] golden = new double[length];
+        final int MAX = 10;
+        boolean newLine = false;
+
+        for (int a = 0; a <= MAX; a++) {
+            for (int g = 0; g <= MAX; g++) {
+                for (int z = 0; z <= MAX; z++) {
+                    for (int n = 0; n <= MAX; n++) {
+                        for (int p = 0; p <= MAX; p++) {
+                            if (a + g + z + n + p > length) {
+                                continue;
+                            }
+                            if (a + g + z + n + p < length) {
+                                continue;
+                            }
+                            for (DoubleBuilder builder : DoubleBuilder.values()) {
+                                out.println("Test 'double': random = " + random.getSeed() +
+                                   ", length = " + length + ", a = " + a + ", g = " +
+                                   g + ", z = " + z + ", n = " + n + ", p = " + p);
+                                builder.build(golden, a, g, z, n, p, random);
+                                double[] test = golden.clone();
+                                scramble(test, random);
+                                sort(test);
+                                compare(test, golden, a, n, g);
+                            }
+                            newLine = true;
+                        }
+                    }
+                }
+            }
+        }
+        if (newLine) {
+            out.println();
+        }
+    }
+
+    private static void prepareSubArray(int[] a, int fromIndex, int toIndex, int m) {
+        for (int i = 0; i < fromIndex; i++) {
+            a[i] = 0xDEDA;
+        }
+        int middle = (fromIndex + toIndex) >>> 1;
+        int k = 0;
+
+        for (int i = fromIndex; i < middle; i++) {
+            a[i] = k++;
+        }
+        for (int i = middle; i < toIndex; i++) {
+            a[i] = k--;
+        }
+        for (int i = toIndex; i < a.length; i++) {
+            a[i] = 0xBABA;
+        }
+    }
+
+    private static void scramble(int[] a, Random random) {
+        for (int i = 0; i < a.length * 7; i++) {
+            swap(a, random.nextInt(a.length), random.nextInt(a.length));
+        }
+    }
+
+    private static void scramble(float[] a, Random random) {
+        for (int i = 0; i < a.length * 7; i++) {
+            swap(a, random.nextInt(a.length), random.nextInt(a.length));
+        }
+    }
+
+    private static void scramble(double[] a, Random random) {
+        for (int i = 0; i < a.length * 7; i++) {
+            swap(a, random.nextInt(a.length), random.nextInt(a.length));
+        }
+    }
+
+    private static void swap(int[] a, int i, int j) {
+        int t = a[i];
+        a[i] = a[j];
+        a[j] = t;
+    }
+
+    private static void swap(float[] a, int i, int j) {
+        float t = a[i];
+        a[i] = a[j];
+        a[j] = t;
+    }
+
+    private static void swap(double[] a, int i, int j) {
+        double t = a[i];
+        a[i] = a[j];
+        a[j] = t;
+    }
+
+    private static enum TypeConverter {
+        INT {
+            Object convert(int[] a) {
+                return a.clone();
+            }
+        },
+        LONG {
+            Object convert(int[] a) {
+                long[] b = new long[a.length];
+
+                for (int i = 0; i < a.length; i++) {
+                    b[i] = (long) a[i];
+                }
+                return b;
+            }
+        },
+        BYTE {
+            Object convert(int[] a) {
+                byte[] b = new byte[a.length];
+
+                for (int i = 0; i < a.length; i++) {
+                    b[i] = (byte) a[i];
+                }
+                return b;
+            }
+        },
+        SHORT {
+            Object convert(int[] a) {
+                short[] b = new short[a.length];
+
+                for (int i = 0; i < a.length; i++) {
+                    b[i] = (short) a[i];
+                }
+                return b;
+            }
+        },
+        CHAR {
+            Object convert(int[] a) {
+                char[] b = new char[a.length];
+
+                for (int i = 0; i < a.length; i++) {
+                    b[i] = (char) a[i];
+                }
+                return b;
+            }
+        },
+        FLOAT {
+            Object convert(int[] a) {
+                float[] b = new float[a.length];
+
+                for (int i = 0; i < a.length; i++) {
+                    b[i] = (float) a[i];
+                }
+                return b;
+            }
+        },
+        DOUBLE {
+            Object convert(int[] a) {
+                double[] b = new double[a.length];
+
+                for (int i = 0; i < a.length; i++) {
+                    b[i] = (double) a[i];
+                }
+                return b;
+            }
+        },
+        INTEGER {
+            Object convert(int[] a) {
+                Integer[] b = new Integer[a.length];
+
+                for (int i = 0; i < a.length; i++) {
+                    b[i] = new Integer(a[i]);
+                }
+                return b;
+            }
+        };
+
+        abstract Object convert(int[] a);
+
+        @Override public String toString() {
+            String name = name();
+
+            for (int i = name.length(); i < 9; i++) {
+                name += " ";
+            }
+            return name;
+        }
+    }
+
+    private static enum FloatBuilder {
+        SIMPLE {
+            void build(float[] x, int a, int g, int z, int n, int p, Random random) {
+                int fromIndex = 0;
+                float negativeValue = -random.nextFloat();
+                float positiveValue =  random.nextFloat();
+
+                writeValue(x, negativeValue, fromIndex, n);
+                fromIndex += n;
+
+                writeValue(x, -0.0f, fromIndex, g);
+                fromIndex += g;
+
+                writeValue(x, 0.0f, fromIndex, z);
+                fromIndex += z;
+
+                writeValue(x, positiveValue, fromIndex, p);
+                fromIndex += p;
+
+                writeValue(x, Float.NaN, fromIndex, a);
+            }
+        };
+
+        abstract void build(float[] x, int a, int g, int z, int n, int p, Random random);
+    }
+
+    private static enum DoubleBuilder {
+        SIMPLE {
+            void build(double[] x, int a, int g, int z, int n, int p, Random random) {
+                int fromIndex = 0;
+                double negativeValue = -random.nextFloat();
+                double positiveValue =  random.nextFloat();
+
+                writeValue(x, negativeValue, fromIndex, n);
+                fromIndex += n;
+
+                writeValue(x, -0.0d, fromIndex, g);
+                fromIndex += g;
+
+                writeValue(x, 0.0d, fromIndex, z);
+                fromIndex += z;
+
+                writeValue(x, positiveValue, fromIndex, p);
+                fromIndex += p;
+
+                writeValue(x, Double.NaN, fromIndex, a);
+            }
+        };
+
+        abstract void build(double[] x, int a, int g, int z, int n, int p, Random random);
+    }
+
+    private static void writeValue(float[] a, float value, int fromIndex, int count) {
+        for (int i = fromIndex; i < fromIndex + count; i++) {
+            a[i] = value;
+        }
+    }
+
+    private static void compare(float[] a, float[] b, int numNaN, int numNeg, int numNegZero) {
+        for (int i = a.length - numNaN; i < a.length; i++) {
+            if (a[i] == a[i]) {
+                failed("On position " + i + " must be NaN instead of " + a[i]);
+            }
+        }
+        final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f);
+
+        for (int i = numNeg; i < numNeg + numNegZero; i++) {
+            if (NEGATIVE_ZERO != Float.floatToIntBits(a[i])) {
+                failed("On position " + i + " must be -0.0 instead of " + a[i]);
+            }
+        }
+        for (int i = 0; i < a.length - numNaN; i++) {
+            if (a[i] != b[i]) {
+                failedCompare(i, "" + a[i], "" + b[i]);
+            }
+        }
+    }
+
+    private static void writeValue(double[] a, double value, int fromIndex, int count) {
+        for (int i = fromIndex; i < fromIndex + count; i++) {
+            a[i] = value;
+        }
+    }
+
+    private static void compare(double[] a, double[] b, int numNaN, int numNeg, int numNegZero) {
+        for (int i = a.length - numNaN; i < a.length; i++) {
+            if (a[i] == a[i]) {
+                failed("On position " + i + " must be NaN instead of " + a[i]);
+            }
+        }
+        final long NEGATIVE_ZERO = Double.doubleToLongBits(-0.0d);
+
+        for (int i = numNeg; i < numNeg + numNegZero; i++) {
+            if (NEGATIVE_ZERO != Double.doubleToLongBits(a[i])) {
+                failed("On position " + i + " must be -0.0 instead of " + a[i]);
+            }
+        }
+        for (int i = 0; i < a.length - numNaN; i++) {
+            if (a[i] != b[i]) {
+                failedCompare(i, "" + a[i], "" + b[i]);
+            }
+        }
+    }
+
+    private static enum SortedBuilder {
+        REPEATED {
+            void build(int[] a, int m) {
+                int period = a.length / m;
+                int i = 0;
+                int k = 0;
+
+                while (true) {
+                    for (int t = 1; t <= period; t++) {
+                        if (i >= a.length) {
+                            return;
+                        }
+                        a[i++] = k;
+                    }
+                    if (i >= a.length) {
+                        return;
+                    }
+                    k++;
+                }
+            }
+        },
+        ORGAN_PIPES {
+            void build(int[] a, int m) {
+                int i = 0;
+                int k = m;
+
+                while (true) {
+                    for (int t = 1; t <= m; t++) {
+                        if (i >= a.length) {
+                            return;
+                        }
+                        a[i++] = k;
+                    }
+                }
+            }
+        };
+
+        abstract void build(int[] a, int m);
+
+        @Override public String toString() {
+            String name = name();
+
+            for (int i = name.length(); i < 12; i++) {
+                name += " ";
+            }
+            return name;
+        }
+    }
+
+    private static enum MergeBuilder {
+        ASCENDING {
+            void build(int[] a, int m) {
+                int period = a.length / m;
+                int v = 1, i = 0;
+
+                for (int k = 0; k < m; k++) {
+                    v = 1;
+                    for (int p = 0; p < period; p++) {
+                        a[i++] = v++;
+                    }
+                }
+                for (int j = i; j < a.length - 1; j++) {
+                    a[j] = v++;
+                }
+                a[a.length - 1] = 0;
+            }
+        },
+        DESCENDING {
+            void build(int[] a, int m) {
+                int period = a.length / m;
+                int v = -1, i = 0;
+
+                for (int k = 0; k < m; k++) {
+                    v = -1;
+                    for (int p = 0; p < period; p++) {
+                        a[i++] = v--;
+                    }
+                }
+                for (int j = i; j < a.length - 1; j++) {
+                    a[j] = v--;
+                }
+                a[a.length - 1] = 0;
+            }
+        };
+
+        abstract void build(int[] a, int m);
+
+        @Override public String toString() {
+            String name = name();
+
+            for (int i = name.length(); i < 12; i++) {
+                name += " ";
+            }
+            return name;
+        }
+    }
+
+    private static enum UnsortedBuilder {
+        RANDOM {
+            void build(int[] a, int m, Random random) {
+                for (int i = 0; i < a.length; i++) {
+                    a[i] = random.nextInt();
+                }
+            }
+        },
+        ASCENDING {
+            void build(int[] a, int m, Random random) {
+                for (int i = 0; i < a.length; i++) {
+                    a[i] = m + i;
+                }
+            }
+        },
+        DESCENDING {
+            void build(int[] a, int m, Random random) {
+                for (int i = 0; i < a.length; i++) {
+                    a[i] = a.length - m - i;
+                }
+            }
+        },
+        ALL_EQUAL {
+            void build(int[] a, int m, Random random) {
+                for (int i = 0; i < a.length; i++) {
+                    a[i] = m;
+                }
+            }
+        },
+        SAW {
+            void build(int[] a, int m, Random random) {
+                int incCount = 1;
+                int decCount = a.length;
+                int i = 0;
+                int period = m--;
+
+                while (true) {
+                    for (int k = 1; k <= period; k++) {
+                        if (i >= a.length) {
+                            return;
+                        }
+                        a[i++] = incCount++;
+                    }
+                    period += m;
+
+                    for (int k = 1; k <= period; k++) {
+                        if (i >= a.length) {
+                            return;
+                        }
+                        a[i++] = decCount--;
+                    }
+                    period += m;
+                }
+            }
+        },
+        REPEATED {
+            void build(int[] a, int m, Random random) {
+                for (int i = 0; i < a.length; i++) {
+                    a[i] = i % m;
+                }
+            }
+        },
+        DUPLICATED {
+            void build(int[] a, int m, Random random) {
+                for (int i = 0; i < a.length; i++) {
+                    a[i] = random.nextInt(m);
+                }
+            }
+        },
+        ORGAN_PIPES {
+            void build(int[] a, int m, Random random) {
+                int middle = a.length / (m + 1);
+
+                for (int i = 0; i < middle; i++) {
+                    a[i] = i;
+                }
+                for (int i = middle; i < a.length; i++) {
+                    a[i] = a.length - i - 1;
+                }
+            }
+        },
+        STAGGER {
+            void build(int[] a, int m, Random random) {
+                for (int i = 0; i < a.length; i++) {
+                    a[i] = (i * m + i) % a.length;
+                }
+            }
+        },
+        PLATEAU {
+            void build(int[] a, int m, Random random) {
+                for (int i = 0; i < a.length; i++) {
+                    a[i] = Math.min(i, m);
+                }
+            }
+        },
+        SHUFFLE {
+            void build(int[] a, int m, Random random) {
+                int x = 0, y = 0;
+                for (int i = 0; i < a.length; i++) {
+                    a[i] = random.nextBoolean() ? (x += 2) : (y += 2);
+                }
+            }
+        };
+
+        abstract void build(int[] a, int m, Random random);
+
+        @Override public String toString() {
+            String name = name();
+
+            for (int i = name.length(); i < 12; i++) {
+                name += " ";
+            }
+            return name;
+        }
+    }
+
+    private static void checkWithCheckSum(Object test, Object golden) {
+        checkSorted(test);
+        checkCheckSum(test, golden);
+    }
+
+    private static void failed(String message) {
+        err.format("\n*** TEST FAILED - %s.\n\n%s.\n\n", ourDescription, message);
+        throw new RuntimeException("Test failed - see log file for details");
+    }
+
+    private static void failedSort(int index, String value1, String value2) {
+        failed("Array is not sorted at " + index + "-th position: " +
+            value1 + " and " + value2);
+    }
+
+    private static void failedCompare(int index, String value1, String value2) {
+        failed("On position " + index + " must be " + value2 + " instead of " + value1);
+    }
+
+    private static void compare(Object test, Object golden) {
+        if (test instanceof int[]) {
+            compare((int[]) test, (int[]) golden);
+        } else if (test instanceof long[]) {
+            compare((long[]) test, (long[]) golden);
+        } else if (test instanceof short[]) {
+            compare((short[]) test, (short[]) golden);
+        } else if (test instanceof byte[]) {
+            compare((byte[]) test, (byte[]) golden);
+        } else if (test instanceof char[]) {
+            compare((char[]) test, (char[]) golden);
+        } else if (test instanceof float[]) {
+            compare((float[]) test, (float[]) golden);
+        } else if (test instanceof double[]) {
+            compare((double[]) test, (double[]) golden);
+        } else if (test instanceof Integer[]) {
+            compare((Integer[]) test, (Integer[]) golden);
+        } else {
+            failed("Unknow type of array: " + test + " of class " +
+                test.getClass().getName());
+        }
+    }
+
+    private static void compare(int[] a, int[] b) {
+        for (int i = 0; i < a.length; i++) {
+            if (a[i] != b[i]) {
+                failedCompare(i, "" + a[i], "" + b[i]);
+            }
+        }
+    }
+
+    private static void compare(long[] a, long[] b) {
+        for (int i = 0; i < a.length; i++) {
+            if (a[i] != b[i]) {
+                failedCompare(i, "" + a[i], "" + b[i]);
+            }
+        }
+    }
+
+    private static void compare(short[] a, short[] b) {
+        for (int i = 0; i < a.length; i++) {
+            if (a[i] != b[i]) {
+                failedCompare(i, "" + a[i], "" + b[i]);
+            }
+        }
+    }
+
+    private static void compare(byte[] a, byte[] b) {
+        for (int i = 0; i < a.length; i++) {
+            if (a[i] != b[i]) {
+                failedCompare(i, "" + a[i], "" + b[i]);
+            }
+        }
+    }
+
+    private static void compare(char[] a, char[] b) {
+        for (int i = 0; i < a.length; i++) {
+            if (a[i] != b[i]) {
+                failedCompare(i, "" + a[i], "" + b[i]);
+            }
+        }
+    }
+
+    private static void compare(float[] a, float[] b) {
+        for (int i = 0; i < a.length; i++) {
+            if (a[i] != b[i]) {
+                failedCompare(i, "" + a[i], "" + b[i]);
+            }
+        }
+    }
+
+    private static void compare(double[] a, double[] b) {
+        for (int i = 0; i < a.length; i++) {
+            if (a[i] != b[i]) {
+                failedCompare(i, "" + a[i], "" + b[i]);
+            }
+        }
+    }
+
+    private static void compare(Integer[] a, Integer[] b) {
+        for (int i = 0; i < a.length; i++) {
+            if (a[i].compareTo(b[i]) != 0) {
+                failedCompare(i, "" + a[i], "" + b[i]);
+            }
+        }
+    }
+
+    private static void checkSorted(Object object) {
+        if (object instanceof int[]) {
+            checkSorted((int[]) object);
+        } else if (object instanceof long[]) {
+            checkSorted((long[]) object);
+        } else if (object instanceof short[]) {
+            checkSorted((short[]) object);
+        } else if (object instanceof byte[]) {
+            checkSorted((byte[]) object);
+        } else if (object instanceof char[]) {
+            checkSorted((char[]) object);
+        } else if (object instanceof float[]) {
+            checkSorted((float[]) object);
+        } else if (object instanceof double[]) {
+            checkSorted((double[]) object);
+        } else if (object instanceof Integer[]) {
+            checkSorted((Integer[]) object);
+        } else {
+            failed("Unknow type of array: " + object + " of class " +
+                object.getClass().getName());
+        }
+    }
+
+    private static void checkSorted(int[] a) {
+        for (int i = 0; i < a.length - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+    }
+
+    private static void checkSorted(long[] a) {
+        for (int i = 0; i < a.length - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+    }
+
+    private static void checkSorted(short[] a) {
+        for (int i = 0; i < a.length - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+    }
+
+    private static void checkSorted(byte[] a) {
+        for (int i = 0; i < a.length - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+    }
+
+    private static void checkSorted(char[] a) {
+        for (int i = 0; i < a.length - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+    }
+
+    private static void checkSorted(float[] a) {
+        for (int i = 0; i < a.length - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+    }
+
+    private static void checkSorted(double[] a) {
+        for (int i = 0; i < a.length - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+    }
+
+    private static void checkSorted(Integer[] a) {
+        for (int i = 0; i < a.length - 1; i++) {
+            if (a[i].intValue() > a[i + 1].intValue()) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+    }
+
+    private static void checkCheckSum(Object test, Object golden) {
+        if (checkSumXor(test) != checkSumXor(golden)) {
+            failed("Original and sorted arrays are not identical [xor]");
+        }
+        if (checkSumPlus(test) != checkSumPlus(golden)) {
+            failed("Original and sorted arrays are not identical [plus]");
+        }
+    }
+
+    private static int checkSumXor(Object object) {
+        if (object instanceof int[]) {
+            return checkSumXor((int[]) object);
+        } else if (object instanceof long[]) {
+            return checkSumXor((long[]) object);
+        } else if (object instanceof short[]) {
+            return checkSumXor((short[]) object);
+        } else if (object instanceof byte[]) {
+            return checkSumXor((byte[]) object);
+        } else if (object instanceof char[]) {
+            return checkSumXor((char[]) object);
+        } else if (object instanceof float[]) {
+            return checkSumXor((float[]) object);
+        } else if (object instanceof double[]) {
+            return checkSumXor((double[]) object);
+        } else if (object instanceof Integer[]) {
+            return checkSumXor((Integer[]) object);
+        } else {
+            failed("Unknow type of array: " + object + " of class " +
+                object.getClass().getName());
+            return -1;
+        }
+    }
+
+    private static int checkSumXor(Integer[] a) {
+        int checkSum = 0;
+
+        for (Integer e : a) {
+            checkSum ^= e.intValue();
+        }
+        return checkSum;
+    }
+
+    private static int checkSumXor(int[] a) {
+        int checkSum = 0;
+
+        for (int e : a) {
+            checkSum ^= e;
+        }
+        return checkSum;
+    }
+
+    private static int checkSumXor(long[] a) {
+        long checkSum = 0;
+
+        for (long e : a) {
+            checkSum ^= e;
+        }
+        return (int) checkSum;
+    }
+
+    private static int checkSumXor(short[] a) {
+        short checkSum = 0;
+
+        for (short e : a) {
+            checkSum ^= e;
+        }
+        return (int) checkSum;
+    }
+
+    private static int checkSumXor(byte[] a) {
+        byte checkSum = 0;
+
+        for (byte e : a) {
+            checkSum ^= e;
+        }
+        return (int) checkSum;
+    }
+
+    private static int checkSumXor(char[] a) {
+        char checkSum = 0;
+
+        for (char e : a) {
+            checkSum ^= e;
+        }
+        return (int) checkSum;
+    }
+
+    private static int checkSumXor(float[] a) {
+        int checkSum = 0;
+
+        for (float e : a) {
+            checkSum ^= (int) e;
+        }
+        return checkSum;
+    }
+
+    private static int checkSumXor(double[] a) {
+        int checkSum = 0;
+
+        for (double e : a) {
+            checkSum ^= (int) e;
+        }
+        return checkSum;
+    }
+
+    private static int checkSumPlus(Object object) {
+        if (object instanceof int[]) {
+            return checkSumPlus((int[]) object);
+        } else if (object instanceof long[]) {
+            return checkSumPlus((long[]) object);
+        } else if (object instanceof short[]) {
+            return checkSumPlus((short[]) object);
+        } else if (object instanceof byte[]) {
+            return checkSumPlus((byte[]) object);
+        } else if (object instanceof char[]) {
+            return checkSumPlus((char[]) object);
+        } else if (object instanceof float[]) {
+            return checkSumPlus((float[]) object);
+        } else if (object instanceof double[]) {
+            return checkSumPlus((double[]) object);
+        } else if (object instanceof Integer[]) {
+            return checkSumPlus((Integer[]) object);
+        } else {
+            failed("Unknow type of array: " + object + " of class " +
+                object.getClass().getName());
+            return -1;
+        }
+    }
+
+    private static int checkSumPlus(int[] a) {
+        int checkSum = 0;
+
+        for (int e : a) {
+            checkSum += e;
+        }
+        return checkSum;
+    }
+
+    private static int checkSumPlus(long[] a) {
+        long checkSum = 0;
+
+        for (long e : a) {
+            checkSum += e;
+        }
+        return (int) checkSum;
+    }
+
+    private static int checkSumPlus(short[] a) {
+        short checkSum = 0;
+
+        for (short e : a) {
+            checkSum += e;
+        }
+        return (int) checkSum;
+    }
+
+    private static int checkSumPlus(byte[] a) {
+        byte checkSum = 0;
+
+        for (byte e : a) {
+            checkSum += e;
+        }
+        return (int) checkSum;
+    }
+
+    private static int checkSumPlus(char[] a) {
+        char checkSum = 0;
+
+        for (char e : a) {
+            checkSum += e;
+        }
+        return (int) checkSum;
+    }
+
+    private static int checkSumPlus(float[] a) {
+        int checkSum = 0;
+
+        for (float e : a) {
+            checkSum += (int) e;
+        }
+        return checkSum;
+    }
+
+    private static int checkSumPlus(double[] a) {
+        int checkSum = 0;
+
+        for (double e : a) {
+            checkSum += (int) e;
+        }
+        return checkSum;
+    }
+
+    private static int checkSumPlus(Integer[] a) {
+        int checkSum = 0;
+
+        for (Integer e : a) {
+            checkSum += e.intValue();
+        }
+        return checkSum;
+    }
+
+    private static void sortByInsertionSort(Object object) {
+        if (object instanceof int[]) {
+            sortByInsertionSort((int[]) object);
+        } else if (object instanceof long[]) {
+            sortByInsertionSort((long[]) object);
+        } else if (object instanceof short[]) {
+            sortByInsertionSort((short[]) object);
+        } else if (object instanceof byte[]) {
+            sortByInsertionSort((byte[]) object);
+        } else if (object instanceof char[]) {
+            sortByInsertionSort((char[]) object);
+        } else if (object instanceof float[]) {
+            sortByInsertionSort((float[]) object);
+        } else if (object instanceof double[]) {
+            sortByInsertionSort((double[]) object);
+        } else if (object instanceof Integer[]) {
+            sortByInsertionSort((Integer[]) object);
+        } else {
+            failed("Unknow type of array: " + object + " of class " +
+                object.getClass().getName());
+        }
+    }
+
+    private static void sortByInsertionSort(int[] a) {
+        for (int j, i = 1; i < a.length; i++) {
+            int ai = a[i];
+            for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+                a[j + 1] = a[j];
+            }
+            a[j + 1] = ai;
+        }
+    }
+
+    private static void sortByInsertionSort(long[] a) {
+        for (int j, i = 1; i < a.length; i++) {
+            long ai = a[i];
+            for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+                a[j + 1] = a[j];
+            }
+            a[j + 1] = ai;
+        }
+    }
+
+    private static void sortByInsertionSort(short[] a) {
+        for (int j, i = 1; i < a.length; i++) {
+            short ai = a[i];
+            for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+                a[j + 1] = a[j];
+            }
+            a[j + 1] = ai;
+        }
+    }
+
+    private static void sortByInsertionSort(byte[] a) {
+        for (int j, i = 1; i < a.length; i++) {
+            byte ai = a[i];
+            for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+                a[j + 1] = a[j];
+            }
+            a[j + 1] = ai;
+        }
+    }
+
+    private static void sortByInsertionSort(char[] a) {
+        for (int j, i = 1; i < a.length; i++) {
+            char ai = a[i];
+            for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+                a[j + 1] = a[j];
+            }
+            a[j + 1] = ai;
+        }
+    }
+
+    private static void sortByInsertionSort(float[] a) {
+        for (int j, i = 1; i < a.length; i++) {
+            float ai = a[i];
+            for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+                a[j + 1] = a[j];
+            }
+            a[j + 1] = ai;
+        }
+    }
+
+    private static void sortByInsertionSort(double[] a) {
+        for (int j, i = 1; i < a.length; i++) {
+            double ai = a[i];
+            for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+                a[j + 1] = a[j];
+            }
+            a[j + 1] = ai;
+        }
+    }
+
+    private static void sortByInsertionSort(Integer[] a) {
+        for (int j, i = 1; i < a.length; i++) {
+            Integer ai = a[i];
+            for (j = i - 1; j >= 0 && ai < a[j]; j--) {
+                a[j + 1] = a[j];
+            }
+            a[j + 1] = ai;
+        }
+    }
+
+    private static void sort(Object object) {
+        if (object instanceof int[]) {
+            Arrays.parallelSort((int[]) object);
+        } else if (object instanceof long[]) {
+            Arrays.parallelSort((long[]) object);
+        } else if (object instanceof short[]) {
+            Arrays.parallelSort((short[]) object);
+        } else if (object instanceof byte[]) {
+            Arrays.parallelSort((byte[]) object);
+        } else if (object instanceof char[]) {
+            Arrays.parallelSort((char[]) object);
+        } else if (object instanceof float[]) {
+            Arrays.parallelSort((float[]) object);
+        } else if (object instanceof double[]) {
+            Arrays.parallelSort((double[]) object);
+        } else if (object instanceof Integer[]) {
+            Arrays.parallelSort((Integer[]) object);
+        } else {
+            failed("Unknow type of array: " + object + " of class " +
+                object.getClass().getName());
+        }
+    }
+
+    private static void sortSubArray(Object object, int fromIndex, int toIndex) {
+        if (object instanceof int[]) {
+            Arrays.parallelSort((int[]) object, fromIndex, toIndex);
+        } else if (object instanceof long[]) {
+            Arrays.parallelSort((long[]) object, fromIndex, toIndex);
+        } else if (object instanceof short[]) {
+            Arrays.parallelSort((short[]) object, fromIndex, toIndex);
+        } else if (object instanceof byte[]) {
+            Arrays.parallelSort((byte[]) object, fromIndex, toIndex);
+        } else if (object instanceof char[]) {
+            Arrays.parallelSort((char[]) object, fromIndex, toIndex);
+        } else if (object instanceof float[]) {
+            Arrays.parallelSort((float[]) object, fromIndex, toIndex);
+        } else if (object instanceof double[]) {
+            Arrays.parallelSort((double[]) object, fromIndex, toIndex);
+        } else if (object instanceof Integer[]) {
+            Arrays.parallelSort((Integer[]) object, fromIndex, toIndex);
+        } else {
+            failed("Unknow type of array: " + object + " of class " +
+                object.getClass().getName());
+        }
+    }
+
+    private static void checkSubArray(Object object, int fromIndex, int toIndex, int m) {
+        if (object instanceof int[]) {
+            checkSubArray((int[]) object, fromIndex, toIndex, m);
+        } else if (object instanceof long[]) {
+            checkSubArray((long[]) object, fromIndex, toIndex, m);
+        } else if (object instanceof short[]) {
+            checkSubArray((short[]) object, fromIndex, toIndex, m);
+        } else if (object instanceof byte[]) {
+            checkSubArray((byte[]) object, fromIndex, toIndex, m);
+        } else if (object instanceof char[]) {
+            checkSubArray((char[]) object, fromIndex, toIndex, m);
+        } else if (object instanceof float[]) {
+            checkSubArray((float[]) object, fromIndex, toIndex, m);
+        } else if (object instanceof double[]) {
+            checkSubArray((double[]) object, fromIndex, toIndex, m);
+        } else if (object instanceof Integer[]) {
+            checkSubArray((Integer[]) object, fromIndex, toIndex, m);
+        } else {
+            failed("Unknow type of array: " + object + " of class " +
+                object.getClass().getName());
+        }
+    }
+
+    private static void checkSubArray(Integer[] a, int fromIndex, int toIndex, int m) {
+        for (int i = 0; i < fromIndex; i++) {
+            if (a[i].intValue() != 0xDEDA) {
+                failed("Range sort changes left element on position " + i +
+                    ": " + a[i] + ", must be " + 0xDEDA);
+            }
+        }
+
+        for (int i = fromIndex; i < toIndex - 1; i++) {
+            if (a[i].intValue() > a[i + 1].intValue()) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+
+        for (int i = toIndex; i < a.length; i++) {
+            if (a[i].intValue() != 0xBABA) {
+                failed("Range sort changes right element on position " + i +
+                    ": " + a[i] + ", must be " + 0xBABA);
+            }
+        }
+    }
+
+    private static void checkSubArray(int[] a, int fromIndex, int toIndex, int m) {
+        for (int i = 0; i < fromIndex; i++) {
+            if (a[i] != 0xDEDA) {
+                failed("Range sort changes left element on position " + i +
+                    ": " + a[i] + ", must be " + 0xDEDA);
+            }
+        }
+
+        for (int i = fromIndex; i < toIndex - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+
+        for (int i = toIndex; i < a.length; i++) {
+            if (a[i] != 0xBABA) {
+                failed("Range sort changes right element on position " + i +
+                    ": " + a[i] + ", must be " + 0xBABA);
+            }
+        }
+    }
+
+    private static void checkSubArray(byte[] a, int fromIndex, int toIndex, int m) {
+        for (int i = 0; i < fromIndex; i++) {
+            if (a[i] != (byte) 0xDEDA) {
+                failed("Range sort changes left element on position " + i +
+                    ": " + a[i] + ", must be " + 0xDEDA);
+            }
+        }
+
+        for (int i = fromIndex; i < toIndex - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+
+        for (int i = toIndex; i < a.length; i++) {
+            if (a[i] != (byte) 0xBABA) {
+                failed("Range sort changes right element on position " + i +
+                    ": " + a[i] + ", must be " + 0xBABA);
+            }
+        }
+    }
+
+    private static void checkSubArray(long[] a, int fromIndex, int toIndex, int m) {
+        for (int i = 0; i < fromIndex; i++) {
+            if (a[i] != (long) 0xDEDA) {
+                failed("Range sort changes left element on position " + i +
+                    ": " + a[i] + ", must be " + 0xDEDA);
+            }
+        }
+
+        for (int i = fromIndex; i < toIndex - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+
+        for (int i = toIndex; i < a.length; i++) {
+            if (a[i] != (long) 0xBABA) {
+                failed("Range sort changes right element on position " + i +
+                    ": " + a[i] + ", must be " + 0xBABA);
+            }
+        }
+    }
+
+    private static void checkSubArray(char[] a, int fromIndex, int toIndex, int m) {
+        for (int i = 0; i < fromIndex; i++) {
+            if (a[i] != (char) 0xDEDA) {
+                failed("Range sort changes left element on position " + i +
+                    ": " + a[i] + ", must be " + 0xDEDA);
+            }
+        }
+
+        for (int i = fromIndex; i < toIndex - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+
+        for (int i = toIndex; i < a.length; i++) {
+            if (a[i] != (char) 0xBABA) {
+                failed("Range sort changes right element on position " + i +
+                    ": " + a[i] + ", must be " + 0xBABA);
+            }
+        }
+    }
+
+    private static void checkSubArray(short[] a, int fromIndex, int toIndex, int m) {
+        for (int i = 0; i < fromIndex; i++) {
+            if (a[i] != (short) 0xDEDA) {
+                failed("Range sort changes left element on position " + i +
+                    ": " + a[i] + ", must be " + 0xDEDA);
+            }
+        }
+
+        for (int i = fromIndex; i < toIndex - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+
+        for (int i = toIndex; i < a.length; i++) {
+            if (a[i] != (short) 0xBABA) {
+                failed("Range sort changes right element on position " + i +
+                    ": " + a[i] + ", must be " + 0xBABA);
+            }
+        }
+    }
+
+    private static void checkSubArray(float[] a, int fromIndex, int toIndex, int m) {
+        for (int i = 0; i < fromIndex; i++) {
+            if (a[i] != (float) 0xDEDA) {
+                failed("Range sort changes left element on position " + i +
+                    ": " + a[i] + ", must be " + 0xDEDA);
+            }
+        }
+
+        for (int i = fromIndex; i < toIndex - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+
+        for (int i = toIndex; i < a.length; i++) {
+            if (a[i] != (float) 0xBABA) {
+                failed("Range sort changes right element on position " + i +
+                    ": " + a[i] + ", must be " + 0xBABA);
+            }
+        }
+    }
+
+    private static void checkSubArray(double[] a, int fromIndex, int toIndex, int m) {
+        for (int i = 0; i < fromIndex; i++) {
+            if (a[i] != (double) 0xDEDA) {
+                failed("Range sort changes left element on position " + i +
+                    ": " + a[i] + ", must be " + 0xDEDA);
+            }
+        }
+
+        for (int i = fromIndex; i < toIndex - 1; i++) {
+            if (a[i] > a[i + 1]) {
+                failedSort(i, "" + a[i], "" + a[i + 1]);
+            }
+        }
+
+        for (int i = toIndex; i < a.length; i++) {
+            if (a[i] != (double) 0xBABA) {
+                failed("Range sort changes right element on position " + i +
+                    ": " + a[i] + ", must be " + 0xBABA);
+            }
+        }
+    }
+
+    private static void checkRange(Object object, int m) {
+        if (object instanceof int[]) {
+            checkRange((int[]) object, m);
+        } else if (object instanceof long[]) {
+            checkRange((long[]) object, m);
+        } else if (object instanceof short[]) {
+            checkRange((short[]) object, m);
+        } else if (object instanceof byte[]) {
+            checkRange((byte[]) object, m);
+        } else if (object instanceof char[]) {
+            checkRange((char[]) object, m);
+        } else if (object instanceof float[]) {
+            checkRange((float[]) object, m);
+        } else if (object instanceof double[]) {
+            checkRange((double[]) object, m);
+        } else if (object instanceof Integer[]) {
+            checkRange((Integer[]) object, m);
+        } else {
+            failed("Unknow type of array: " + object + " of class " +
+                object.getClass().getName());
+        }
+    }
+
+    private static void checkRange(Integer[] a, int m) {
+        try {
+            Arrays.parallelSort(a, m + 1, m);
+
+            failed("ParallelSort does not throw IllegalArgumentException " +
+                " as expected: fromIndex = " + (m + 1) +
+                " toIndex = " + m);
+        }
+        catch (IllegalArgumentException iae) {
+            try {
+                Arrays.parallelSort(a, -m, a.length);
+
+                failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                    " as expected: fromIndex = " + (-m));
+            }
+            catch (ArrayIndexOutOfBoundsException aoe) {
+                try {
+                    Arrays.parallelSort(a, 0, a.length + m);
+
+                    failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                        " as expected: toIndex = " + (a.length + m));
+                }
+                catch (ArrayIndexOutOfBoundsException aie) {
+                    return;
+                }
+            }
+        }
+    }
+
+    private static void checkRange(int[] a, int m) {
+        try {
+            Arrays.parallelSort(a, m + 1, m);
+
+            failed("ParallelSort does not throw IllegalArgumentException " +
+                " as expected: fromIndex = " + (m + 1) +
+                " toIndex = " + m);
+        }
+        catch (IllegalArgumentException iae) {
+            try {
+                Arrays.parallelSort(a, -m, a.length);
+
+                failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                    " as expected: fromIndex = " + (-m));
+            }
+            catch (ArrayIndexOutOfBoundsException aoe) {
+                try {
+                    Arrays.parallelSort(a, 0, a.length + m);
+
+                    failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                        " as expected: toIndex = " + (a.length + m));
+                }
+                catch (ArrayIndexOutOfBoundsException aie) {
+                    return;
+                }
+            }
+        }
+    }
+
+    private static void checkRange(long[] a, int m) {
+        try {
+            Arrays.parallelSort(a, m + 1, m);
+
+            failed("ParallelSort does not throw IllegalArgumentException " +
+                " as expected: fromIndex = " + (m + 1) +
+                " toIndex = " + m);
+        }
+        catch (IllegalArgumentException iae) {
+            try {
+                Arrays.parallelSort(a, -m, a.length);
+
+                failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                    " as expected: fromIndex = " + (-m));
+            }
+            catch (ArrayIndexOutOfBoundsException aoe) {
+                try {
+                    Arrays.parallelSort(a, 0, a.length + m);
+
+                    failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                        " as expected: toIndex = " + (a.length + m));
+                }
+                catch (ArrayIndexOutOfBoundsException aie) {
+                    return;
+                }
+            }
+        }
+    }
+
+    private static void checkRange(byte[] a, int m) {
+        try {
+            Arrays.parallelSort(a, m + 1, m);
+
+            failed("ParallelSort does not throw IllegalArgumentException " +
+                " as expected: fromIndex = " + (m + 1) +
+                " toIndex = " + m);
+        }
+        catch (IllegalArgumentException iae) {
+            try {
+                Arrays.parallelSort(a, -m, a.length);
+
+                failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                    " as expected: fromIndex = " + (-m));
+            }
+            catch (ArrayIndexOutOfBoundsException aoe) {
+                try {
+                    Arrays.parallelSort(a, 0, a.length + m);
+
+                    failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                        " as expected: toIndex = " + (a.length + m));
+                }
+                catch (ArrayIndexOutOfBoundsException aie) {
+                    return;
+                }
+            }
+        }
+    }
+
+    private static void checkRange(short[] a, int m) {
+        try {
+            Arrays.parallelSort(a, m + 1, m);
+
+            failed("ParallelSort does not throw IllegalArgumentException " +
+                " as expected: fromIndex = " + (m + 1) +
+                " toIndex = " + m);
+        }
+        catch (IllegalArgumentException iae) {
+            try {
+                Arrays.parallelSort(a, -m, a.length);
+
+                failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                    " as expected: fromIndex = " + (-m));
+            }
+            catch (ArrayIndexOutOfBoundsException aoe) {
+                try {
+                    Arrays.parallelSort(a, 0, a.length + m);
+
+                    failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                        " as expected: toIndex = " + (a.length + m));
+                }
+                catch (ArrayIndexOutOfBoundsException aie) {
+                    return;
+                }
+            }
+        }
+    }
+
+    private static void checkRange(char[] a, int m) {
+        try {
+            Arrays.parallelSort(a, m + 1, m);
+
+            failed("ParallelSort does not throw IllegalArgumentException " +
+                " as expected: fromIndex = " + (m + 1) +
+                " toIndex = " + m);
+        }
+        catch (IllegalArgumentException iae) {
+            try {
+                Arrays.parallelSort(a, -m, a.length);
+
+                failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                    " as expected: fromIndex = " + (-m));
+            }
+            catch (ArrayIndexOutOfBoundsException aoe) {
+                try {
+                    Arrays.parallelSort(a, 0, a.length + m);
+
+                    failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                        " as expected: toIndex = " + (a.length + m));
+                }
+                catch (ArrayIndexOutOfBoundsException aie) {
+                    return;
+                }
+            }
+        }
+    }
+
+    private static void checkRange(float[] a, int m) {
+        try {
+            Arrays.parallelSort(a, m + 1, m);
+
+            failed("ParallelSort does not throw IllegalArgumentException " +
+                " as expected: fromIndex = " + (m + 1) +
+                " toIndex = " + m);
+        }
+        catch (IllegalArgumentException iae) {
+            try {
+                Arrays.parallelSort(a, -m, a.length);
+
+                failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                    " as expected: fromIndex = " + (-m));
+            }
+            catch (ArrayIndexOutOfBoundsException aoe) {
+                try {
+                    Arrays.parallelSort(a, 0, a.length + m);
+
+                    failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                        " as expected: toIndex = " + (a.length + m));
+                }
+                catch (ArrayIndexOutOfBoundsException aie) {
+                    return;
+                }
+            }
+        }
+    }
+
+    private static void checkRange(double[] a, int m) {
+        try {
+            Arrays.parallelSort(a, m + 1, m);
+
+            failed("ParallelSort does not throw IllegalArgumentException " +
+                " as expected: fromIndex = " + (m + 1) +
+                " toIndex = " + m);
+        }
+        catch (IllegalArgumentException iae) {
+            try {
+                Arrays.parallelSort(a, -m, a.length);
+
+                failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                    " as expected: fromIndex = " + (-m));
+            }
+            catch (ArrayIndexOutOfBoundsException aoe) {
+                try {
+                    Arrays.parallelSort(a, 0, a.length + m);
+
+                    failed("ParallelSort does not throw ArrayIndexOutOfBoundsException " +
+                        " as expected: toIndex = " + (a.length + m));
+                }
+                catch (ArrayIndexOutOfBoundsException aie) {
+                    return;
+                }
+            }
+        }
+    }
+
+    private static void outArray(Object[] a) {
+        for (int i = 0; i < a.length; i++) {
+            out.print(a[i] + " ");
+        }
+        out.println();
+    }
+
+    private static void outArray(int[] a) {
+        for (int i = 0; i < a.length; i++) {
+            out.print(a[i] + " ");
+        }
+        out.println();
+    }
+
+    private static void outArray(float[] a) {
+        for (int i = 0; i < a.length; i++) {
+            out.print(a[i] + " ");
+        }
+        out.println();
+    }
+
+    private static void outArray(double[] a) {
+        for (int i = 0; i < a.length; i++) {
+            out.print(a[i] + " ");
+        }
+        out.println();
+    }
+
+    private static class MyRandom extends Random {
+        MyRandom(long seed) {
+            super(seed);
+            mySeed = seed;
+        }
+
+        long getSeed() {
+            return mySeed;
+        }
+
+        private long mySeed;
+    }
+
+    private static String ourDescription;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/function/PredicateTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8004561
+ * @run testng PredicateTest
+ */
+
+import org.testng.annotations.Test;
+
+import java.util.HashSet;
+import java.util.function.Predicate;
+import java.util.function.DoublePredicate;
+import java.util.function.IntPredicate;
+import java.util.function.LongPredicate;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
+
+/**
+ * Unit tests for helper methods in Comparators
+ */
+@Test(groups = "unit")
+public class PredicateTest {
+
+    public void testIntPredicate() {
+        IntPredicate pOdd = (t) -> 0 != (t & 1);
+        IntPredicate pEven = (t) -> 0 == (t & 1);
+
+        assertFalse(pOdd.test(0));
+        assertFalse(pOdd.test(Integer.valueOf(0)));
+        assertFalse(pOdd.test(new Integer(0)));
+        assertFalse(pOdd.test(0));
+
+        assertTrue(pOdd.test(1));
+        assertTrue(pOdd.test(Integer.valueOf(1)));
+        assertTrue(pOdd.test(new Integer(1)));
+        assertTrue(pOdd.test(1));
+
+        assertTrue(pEven.test(0));
+        assertTrue(pEven.test(Integer.valueOf(0)));
+        assertTrue(pEven.test(new Integer(0)));
+        assertTrue(pEven.test(0));
+
+        assertFalse(pEven.test(1));
+        assertFalse(pEven.test(Integer.valueOf(1)));
+        assertFalse(pEven.test(new Integer(1)));
+        assertFalse(pEven.test(1));
+
+        int magic[] = { 8675390 };
+        IntPredicate pMagic = (t) -> t == magic[0];
+
+        assertFalse(pMagic.test(3927704 ));
+        assertFalse(pMagic.test(Integer.valueOf(3927704)));
+        assertFalse(pMagic.test(new Integer(3927704)));
+        assertFalse(pMagic.test(3927704));
+
+        assertTrue(pMagic.test(8675390));
+        assertTrue(pMagic.test(Integer.valueOf(8675390)));
+        assertTrue(pMagic.test(new Integer(8675390)));
+        assertTrue(pMagic.test(8675390));
+
+        magic[0] = 3927704;
+
+        assertTrue(pMagic.test(3927704));
+        assertTrue(pMagic.test(Integer.valueOf(3927704)));
+        assertTrue(pMagic.test(new Integer(3927704)));
+        assertTrue(pMagic.test(3927704));
+
+        assertFalse(pMagic.test(8675390));
+        assertFalse(pMagic.test(Integer.valueOf(8675390)));
+        assertFalse(pMagic.test(new Integer(8675390)));
+        assertFalse(pMagic.test(8675390));
+    }
+
+    public void testLongPredicate() {
+        LongPredicate pOdd = (t) -> 0 != (t & 1);
+        LongPredicate pEven = (t) -> 0 == (t & 1);
+
+        assertFalse(pOdd.test(0L));
+        assertFalse(pOdd.test(Long.valueOf(0L)));
+        assertFalse(pOdd.test(new Long(0L)));
+        assertFalse(pOdd.test(0L));
+
+        assertTrue(pOdd.test(1L));
+        assertTrue(pOdd.test(Long.valueOf(1L)));
+        assertTrue(pOdd.test(new Long(1L)));
+        assertTrue(pOdd.test(1L));
+
+        assertTrue(pEven.test(0L));
+        assertTrue(pEven.test(Long.valueOf(0L)));
+        assertTrue(pEven.test(new Long(0L)));
+        assertTrue(pEven.test(0L));
+
+        assertFalse(pEven.test(1L));
+        assertFalse(pEven.test(Long.valueOf(1L)));
+        assertFalse(pEven.test(new Long(1L)));
+        assertFalse(pEven.test(1L));
+
+        long magic[] = { 8675390L };
+        LongPredicate pMagic = (t) -> t == magic[0];
+
+        assertFalse(pMagic.test(3927704L));
+        assertFalse(pMagic.test(Long.valueOf(3927704L)));
+        assertFalse(pMagic.test(new Long(3927704L)));
+        assertFalse(pMagic.test(3927704L));
+
+        assertTrue(pMagic.test(8675390L));
+        assertTrue(pMagic.test(Long.valueOf(8675390L)));
+        assertTrue(pMagic.test(new Long(8675390L)));
+        assertTrue(pMagic.test(8675390L));
+
+        magic[0] = 3927704L;
+
+        assertTrue(pMagic.test(3927704L));
+        assertTrue(pMagic.test(Long.valueOf(3927704L)));
+        assertTrue(pMagic.test(new Long(3927704L)));
+        assertTrue(pMagic.test(3927704L));
+
+        assertFalse(pMagic.test(8675390L));
+        assertFalse(pMagic.test(Long.valueOf(8675390L)));
+        assertFalse(pMagic.test(new Long(8675390L)));
+        assertFalse(pMagic.test(8675390L));
+    }
+
+    public void testDoublePredicate() {
+        DoublePredicate pInfinite = (t) -> Double.isInfinite(t);
+        DoublePredicate pFinite = (t) -> Double.isFinite(t);
+
+        assertFalse(pInfinite.test(0.0));
+        assertFalse(pInfinite.test(Double.valueOf(0.0)));
+        assertFalse(pInfinite.test(new Double(0.0)));
+        assertFalse(pInfinite.test(0.0));
+
+        assertTrue(pInfinite.test(Double.POSITIVE_INFINITY));
+        assertTrue(pInfinite.test(Double.valueOf(Double.POSITIVE_INFINITY)));
+        assertTrue(pInfinite.test(new Double(Double.POSITIVE_INFINITY)));
+        assertTrue(pInfinite.test(Double.POSITIVE_INFINITY));
+
+        assertTrue(pFinite.test(0.0));
+        assertTrue(pFinite.test(Double.valueOf(0.0)));
+        assertTrue(pFinite.test(new Double(0.0)));
+        assertTrue(pFinite.test(0.0));
+
+        assertFalse(pFinite.test(Double.POSITIVE_INFINITY));
+        assertFalse(pFinite.test(Double.valueOf(Double.POSITIVE_INFINITY)));
+        assertFalse(pFinite.test(new Double(Double.POSITIVE_INFINITY)));
+        assertFalse(pFinite.test(Double.POSITIVE_INFINITY));
+
+        double magic[] = { 1.8675390 };
+        DoublePredicate pMagic = (t) -> t == magic[0];
+
+        assertFalse(pMagic.test(1.3927704));
+        assertFalse(pMagic.test(Double.valueOf(1.3927704)));
+        assertFalse(pMagic.test(new Double(1.3927704)));
+        assertFalse(pMagic.test(1.3927704));
+
+        assertTrue(pMagic.test(1.8675390));
+        assertTrue(pMagic.test(Double.valueOf(1.8675390)));
+        assertTrue(pMagic.test(new Double(1.8675390)));
+        assertTrue(pMagic.test(1.8675390));
+
+        magic[0] = 1.3927704;
+
+        assertTrue(pMagic.test(1.3927704));
+        assertTrue(pMagic.test(Double.valueOf(1.3927704)));
+        assertTrue(pMagic.test(new Double(1.3927704)));
+        assertTrue(pMagic.test(1.3927704));
+
+        assertFalse(pMagic.test(1.8675390));
+        assertFalse(pMagic.test(Double.valueOf(1.8675390)));
+        assertFalse(pMagic.test(new Double(1.8675390)));
+        assertFalse(pMagic.test(1.8675390));
+    }
+
+    @Test
+    public void testIsEqual() {
+        HashSet<Long> s1 = new HashSet<>();
+        HashSet<Long> s2 = (HashSet<Long>) s1.clone();
+        assertTrue(Predicate.isEqual(null).test(null));
+        assertTrue(Predicate.isEqual(s2).test(s1));
+    }
+
+}
--- a/test/java/util/regex/RegExTest.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/java/util/regex/RegExTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -40,6 +40,7 @@
 import java.util.Random;
 import java.io.*;
 import java.util.*;
+import java.util.function.Predicate;
 import java.nio.CharBuffer;
 import java.util.function.Predicate;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/BaseStreamTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.util.Random;
+
+public abstract class BaseStreamTest {
+    public ParallelType getParallelType() {
+        return parallelType;
+    }
+    protected enum ParallelType { Parallel, Sequential, Default }
+
+    //Test data size
+    protected final static int VERY_SMALL_DATA_SIZE = 1;
+    
+    protected final static int SMALL_DATA_SIZE = 1 << 2;
+
+    //MIN_PARTITION
+    protected final static int PARTITION_DATA_SIZE = 1 << 4;
+    
+    protected final static int MEDIUM_DATA_SIZE = 1 << 7;
+   
+    protected final static int[] ALL_DATA_SIZES = {    
+  
+                MEDIUM_DATA_SIZE,
+                PARTITION_DATA_SIZE,
+                SMALL_DATA_SIZE,
+                VERY_SMALL_DATA_SIZE
+    };
+
+    protected final static int[] MEDIUM_DATA_SIZES = {    
+                MEDIUM_DATA_SIZE,
+                PARTITION_DATA_SIZE,
+                SMALL_DATA_SIZE,
+                VERY_SMALL_DATA_SIZE
+    };
+        
+      protected final static  int[] SMALL_DATA_SIZES = {    
+                SMALL_DATA_SIZE,
+                PARTITION_DATA_SIZE,
+                VERY_SMALL_DATA_SIZE
+    };
+    
+    protected final static int SIXTY_FOUR = 64;
+
+    protected final static Random rand = new Random(433494437);
+    
+    protected final ParallelType parallelType;
+    
+    BaseStreamTest(ParallelType parallelType) {
+        this.parallelType = parallelType;
+    }
+
+    @FunctionalInterface
+    public interface TripleFunction<L, M, N, I> { 
+        public I apply(L l, M m, N n);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/CollectTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+public class CollectTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public CollectTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    public void testCollectByGroupingBy(String desc, Collection<U> col, Function<U, ? extends Object> mapFunc) {
+        Map<Object, List<U>> result = streamFor(col). collect(Collectors.<U, Object>groupingBy(mapFunc));
+        result.keySet().stream().forEach((key) -> {
+            result.get(key).stream().forEach((u) -> {
+                assertEquals(key, mapFunc.apply(u));
+            });
+        });
+        assertEqualContents(result.values().stream().flatMap(l -> l.stream()).collect(Collectors.<U>toList()), col, 
+                test.getNaturalOrderComparator());
+        assertTrue(streamFor(createEmptyCollection()).
+                collect(Collectors.<U, Object>groupingBy(mapFunc)).isEmpty());
+    }
+
+    public void testCollectByPartition(String desc, Collection<U> col, Predicate<U> mapFunc) {
+        Map<Boolean, List<U>> partition = streamFor(col). collect(Collectors.<U>partitioningBy(mapFunc));
+        Map<Boolean, List<U>> emptyPartition 
+                = streamFor(createEmptyCollection()).collect(Collectors.<U>partitioningBy(mapFunc));
+        Arrays.asList(true, false).forEach(key -> {
+            partition.get(key).stream().forEach((u) -> {
+                assertEquals(mapFunc.test(u), key.booleanValue());
+            });
+           assertTrue(emptyPartition.get(false).isEmpty()); 
+        });
+    }
+
+    @Test(dataProvider="collectionKeyValueFunctionData", threadPoolSize = 3)
+    public <K, V> void testCollectToMap(String desc, Collection<U> col, Function<U, K> keyFunc, 
+            Function<U, V> valueFunc) {
+        Map<K, V> keyToValue = streamFor(col).collect(Collectors.<U, K, V>toMap(keyFunc, valueFunc));
+        assertEquals(keyToValue.size(), streamFor(col).map(keyFunc).distinct().count());
+        col.stream().forEach((u) -> {
+            assertEquals(valueFunc.apply(u), keyToValue.get(keyFunc.apply(u)));
+        });
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/CollectorsTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary function test for Collectors' static methods
+ * @(#) CollectorsTest.java
+ * @run testng CollectorsTest
+ * @author Tristan Yan
+ */
+
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.*;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class CollectorsTest {
+     private final static long COLLECTION_SIZE = 1 << 8;
+     
+     private final static Random RAND = new Random(System.nanoTime());
+
+     @Test(dataProvider="streams")
+     public void testCounting(Collection<Integer> c) {
+         assertEquals(c.stream().collect(Collectors.counting()).longValue(),
+                 COLLECTION_SIZE);
+     }
+ 
+     @Test(dataProvider="streams")
+     public void testGroupingBy(Collection<Integer> c) {
+         Map<Integer, List<Integer>> map = c.parallelStream().
+                 collect(Collectors.groupingBy(Integer::lowestOneBit));
+         map.forEach((i, l) -> {
+             for(Integer li : l) {
+                 assertEquals(Integer.lowestOneBit(li), i.intValue());
+             }
+         });
+
+         Map<Integer, List<Integer>> mapConcurrent = c.parallelStream().collect(
+                 Collectors.groupingByConcurrent(Integer::highestOneBit));
+         mapConcurrent.forEach((i, l) -> {
+             for(Integer li : l) {
+                 assertEquals(Integer.highestOneBit(li), i.intValue());
+             }
+         });
+     }
+
+     @Test(dataProvider="streams")
+     public void testGroupingByWithCollector(Collection<Integer> c) {
+         Map<Integer, Set<Integer>> map = c.parallelStream().
+            collect(Collectors.groupingBy(Integer::lowestOneBit, 
+            Collectors.mapping(Integer::lowestOneBit,
+                 Collectors.<Integer>toSet())));
+         map.forEach((i, s) -> {
+            assertEquals(s.size(), 1);
+            assertEquals(s.toArray()[0], i);
+         });
+
+        Map<Integer, Set<Integer>> mapConcurrent = c.parallelStream().
+            collect(Collectors.groupingBy(Integer::highestOneBit, 
+            Collectors.mapping(Integer::highestOneBit,
+                Collectors.<Integer>toSet())));
+         mapConcurrent.forEach((i, s) -> {
+            assertEquals(s.size(), 1);
+            assertEquals(s.toArray()[0], i);
+         });
+     }
+
+     @Test(dataProvider="streams")
+     public void testGroupingByWithCollectorFactory(Collection<Integer> c) {
+         Map<Integer, Set<Integer>> map = c.parallelStream().
+            collect(Collectors.groupingBy(Integer::lowestOneBit, TreeMap::new,
+                 Collectors.toCollection(TreeSet<Integer>::new)));
+         final AtomicInteger lowerBit = new AtomicInteger(-1);
+         map.forEach((i, s) -> {
+            assertTrue(i > lowerBit.getAndSet(i));
+            final AtomicInteger smallest = new AtomicInteger(Integer.MIN_VALUE);
+            s.forEach(v -> {
+                assertTrue(v >= smallest.getAndSet(v));
+            });
+         });
+
+         Map<Integer, Set<Integer>> mapConcurrent = c.parallelStream().
+            collect(Collectors.groupingBy(Integer::lowestOneBit, TreeMap::new,
+                 Collectors.toCollection(TreeSet<Integer>::new)));
+         final AtomicInteger higherBit = new AtomicInteger(-1);
+         mapConcurrent.forEach((i, s) -> {
+            assertTrue(i > higherBit.getAndSet(i));
+            final AtomicInteger smallest = new AtomicInteger(Integer.MIN_VALUE);
+            s.forEach(v -> {
+                assertTrue(v >= smallest.getAndSet(v));
+            });
+         });
+     }
+     
+     @Test(dataProvider="streams")
+     public void testMapping(Collection<Integer> c) {
+         Function<Integer, String> itos = String::valueOf;
+         Function<Integer,Integer> lenFunc = itos.andThen(Integer::parseInt);
+         List<Integer> l = c.stream().collect(Collectors.mapping(lenFunc,
+                 Collectors.toList()));
+         assertEquals(l.size(), c.size());
+         Iterator<Integer> iter1 = c.iterator();
+         Iterator<Integer> iter2 = l.iterator();
+         while(iter1.hasNext() && iter2.hasNext()) {
+             assertEquals(iter1.next(), iter2.next());
+         } 
+     }
+
+     @Test(dataProvider="streams")
+     public void testMaxBy(Collection<Integer> c) {
+         Function<Integer, Integer> f = Math::abs;
+         Comparator<Integer> c1 = Comparator.comparing(f);
+         Integer max = c.stream().collect(Collectors.maxBy(c1)).get();
+         int maxExpected
+                 = c.stream().mapToInt(i -> Math.abs(i)).max().getAsInt();
+         assertEquals(Math.abs(max.intValue()), maxExpected);
+     }
+
+     @Test(dataProvider="streams")
+     public void testMinBy(Collection<Integer> c) {
+         Comparator<Integer> c1  = Comparator.<Integer,Integer>comparing(i -> i * -1);
+         Integer max = c.stream().collect(Collectors.minBy(c1)).get();
+         int maxExpected  = c.stream().mapToInt(i -> i.intValue()).max().getAsInt();
+         assertEquals(max.intValue(), maxExpected);
+     }
+
+     @Test(dataProvider="streams")
+     public void testPartitionBy(Collection<Integer> c) {
+         Map<Boolean, List<Integer>> partition = c.stream().
+                 collect(Collectors.partitioningBy(i -> i > 0));
+         List<Integer> greaterThanZero = partition.get(true);
+         List<Integer> notGreaterThanZero = partition.get(false);
+         for(int i :  greaterThanZero)
+             assertTrue(i > 0);
+         for(int i :  notGreaterThanZero)
+             assertFalse(i > 0);
+     }
+
+     @Test(dataProvider="streams")
+     public void testPartitionByWithCollector(Collection<Integer> c) {
+         Map<Boolean, Set<Integer>> partition = c.stream().
+                 collect(Collectors.partitioningBy(i -> (i & 0x01) == 0x01, 
+                 Collectors.toCollection(TreeSet<Integer>::new)));
+         Set<Integer> odds = partition.get(true);
+         Set<Integer> evens = partition.get(false);
+         int smallest = Integer.MIN_VALUE;
+         for(int i :  odds) {
+             assertTrue((i & 0x01) == 0x01);
+             assertTrue( i >= smallest);
+             smallest = i;
+         }
+         
+         smallest = Integer.MIN_VALUE;
+         for(int i :  evens){
+             assertTrue((i & 0x01) == 0x0);
+             assertTrue( i >= smallest);
+             smallest = i;
+         }
+     }
+
+     @Test(dataProvider="streams")
+     public void testReducing(Collection<Integer> c) {
+         Function<Integer, Integer> absFunc = Math::abs;
+         Comparator<Integer> comp = Comparator.comparing(absFunc);
+         BinaryOperator<Integer> shortest = BinaryOperator.minBy(comp);
+         Integer smallestPositive = c.stream().collect(Collectors.reducing(shortest)).get();
+         int expected = c.stream().mapToInt(Math::abs).min().getAsInt();
+         assertEquals(Math.abs(smallestPositive.intValue()), expected);
+     }
+
+     @Test(dataProvider="streams")
+     public void testReducingWithIdentity(Collection<Integer> c) {
+         Map<Integer, Integer> map = c.stream().collect(Collectors.groupingBy(
+             Integer::lowestOneBit, Collectors.reducing(0, (i1, i2) -> i1++)));
+         Map<Integer, List<Integer>> mapCal = c.stream().
+                 map(Integer::lowestOneBit).
+                 collect(Collectors.groupingBy(Function.identity()));
+         mapCal.forEach((i, l) -> {
+             assertEquals(l.size(), map.get(i).intValue());
+         });
+     }
+
+     @Test(dataProvider="streams")
+     public void testReducingWithMapper(Collection<Integer> c) {
+         Function<Integer, String> itos = String::valueOf;
+         Function<String, Integer> lenF = String::length;
+         int totalLen = c.stream().collect(Collectors.<Integer, Integer>reducing(
+                 0, itos.andThen(lenF), Integer::sum));
+         int expected
+                 = c.stream().mapToInt(i -> String.valueOf(i).length()).sum();
+         assertEquals(totalLen, expected);
+     } 
+
+     @Test(dataProvider="streams")
+     public void testSumBy(Collection<Integer> c) {
+         Long posOverNeg = c.stream().collect(Collectors.summarizingLong( i -> new Long(Integer.signum(i)))).getSum();
+         int expected = c.stream().mapToInt(Integer::signum).sum();
+         assertEquals(posOverNeg.intValue(), expected);
+     }
+
+     @Test(dataProvider="streams")
+     public void testToCollection(Collection<Integer> c) {
+         ArrayDeque<Integer> ad = c.stream().sequential().
+                 collect(Collectors.toCollection(ArrayDeque<Integer>::new));
+         assertEquals(ad, new ArrayDeque<>(c));
+         ArrayList<Integer> al = c.stream().sequential().
+                 collect(Collectors.toCollection(ArrayList<Integer>::new));
+         assertEquals(al, new ArrayList<>(c));
+         ConcurrentLinkedDeque<Integer> cld = c.stream().sequential().collect(
+                 Collectors.toCollection(ConcurrentLinkedDeque<Integer>::new));
+         assertEquals(cld, new ConcurrentLinkedDeque<>(c));
+         ConcurrentLinkedQueue<Integer> clq = c.stream().sequential().collect(
+                 Collectors.toCollection(ConcurrentLinkedQueue<Integer>::new));
+         assertEquals(clq, new ConcurrentLinkedQueue<>(c));
+         ConcurrentSkipListSet<Integer> ckls = c.stream().sequential().collect(
+                 Collectors.toCollection(ConcurrentSkipListSet<Integer>::new));
+         assertEquals(ckls, new ConcurrentSkipListSet<>(c));
+         CopyOnWriteArrayList<Integer> cowal = c.stream().sequential().collect(
+                 Collectors.toCollection(CopyOnWriteArrayList<Integer>::new));
+         assertEquals(cowal, new CopyOnWriteArrayList<>(c));
+         HashSet<Integer> hs = c.stream().
+                 collect(Collectors.toCollection(HashSet<Integer>::new));
+         assertEquals(hs, new HashSet<>(c));
+         LinkedBlockingDeque<Integer> lbd = c.stream().sequential().collect(
+                 Collectors.toCollection(LinkedBlockingDeque<Integer>::new));
+         assertEquals(lbd, new LinkedBlockingDeque<>(c));
+         LinkedBlockingQueue<Integer> lbq = c.stream().sequential().collect(
+                 Collectors.toCollection(LinkedBlockingQueue<Integer>::new));
+         assertEquals(lbq, new LinkedBlockingQueue<>(c));
+         LinkedHashSet<Integer> lhs = c.stream().sequential().collect(
+                 Collectors.toCollection(LinkedHashSet<Integer>::new));
+         assertEquals(lhs, new LinkedHashSet<>(c));
+         LinkedList<Integer> ll = c.stream().sequential().collect(
+                 Collectors.toCollection(LinkedList<Integer>::new));
+         assertEquals(ll, new LinkedList<>(c));
+         LinkedTransferQueue<Integer> ltq = c.stream().sequential().collect(
+                 Collectors.toCollection(LinkedTransferQueue<Integer>::new));
+         assertEquals(ltq, new LinkedTransferQueue<>(c));
+
+         //PriorityQueue doesn't guarante to traverse the elements of in any 
+         //particular order, we're using Arrays.sort(pq.toArray()) verify 
+         //result
+         PriorityBlockingQueue<Integer> pbq = c.stream().sequential().collect(
+                 Collectors.toCollection(PriorityBlockingQueue<Integer>::new));
+         PriorityBlockingQueue<Integer> pbqExpected
+                 = new PriorityBlockingQueue<>(c);
+         Object[] pbqArr = pbq.toArray();
+         Object[] pbqExpectedArr = pbqExpected.toArray();
+         Arrays.sort(pbqArr);
+         Arrays.sort(pbqExpectedArr);
+         assertEquals(pbqArr, pbqExpectedArr);
+
+         PriorityQueue<Integer> pq = c.stream().sequential().collect(
+                 Collectors.toCollection(PriorityQueue<Integer>::new));
+         PriorityQueue<Integer> pqExpected = new PriorityQueue<>(c);
+         Object[] pqArr = pq.toArray();
+         Object[] pqExpectedArr = pqExpected.toArray();
+         Arrays.sort(pqArr);
+         Arrays.sort(pqExpectedArr);
+         assertEquals(pqArr, pqExpectedArr);
+
+         Stack<Integer> s = c.stream().sequential().collect(Collectors.
+                 toCollection(Stack<Integer>::new));
+         Stack<Integer> sExpected = new Stack<>();
+         sExpected.addAll(c);
+         assertEquals(s, sExpected);
+         TreeSet<Integer> ts = c.stream().sequential().collect(Collectors.
+                 toCollection(TreeSet<Integer>::new));
+         assertEquals(ts, new TreeSet<>(c));
+         Vector<Integer> v = c.stream().sequential().collect(Collectors.
+                 toCollection(Vector<Integer>::new));
+         assertEquals(v, new Vector<>(c));
+     }
+     
+     @Test(dataProvider="streams")
+     public void testToMap(Collection<Integer> c) {
+         Map<Integer, String> map = c.stream().collect(
+                 Collectors.toMap(Function.identity(), String::valueOf));
+         map.forEach((k, v) -> {
+             assertEquals(k.intValue(), Integer.parseInt(v));
+         });
+         Map<Integer, String> concurrentMap = c.stream().collect(
+                 Collectors.toConcurrentMap(Function.identity(), String::valueOf));
+         concurrentMap.forEach((k, v) -> {
+             assertEquals(k.intValue(), Integer.parseInt(v));
+         });
+     }
+     
+     @Test(dataProvider="streams")
+     public void testToMapWithOperator(Collection<Integer> c) {
+         Map<Integer, Integer> map = c.stream().collect(
+                Collectors.toMap(Integer::highestOneBit, i -> 1, Integer::sum));
+         Map<Integer, List<Integer>> hmap = c.stream().
+                 map(Integer::highestOneBit).
+                 collect(Collectors.groupingBy(Function.identity()));
+         assertEquals(map.size(), hmap.size());
+         map.forEach((k , v) -> {
+             assertEquals(v.intValue(), hmap.get(k).size());
+         });
+
+         Map<Integer, Integer> concurrentMap = c.stream().collect(
+                 Collectors.toConcurrentMap(Integer::lowestOneBit, i -> 1,
+                 Integer::sum));
+         Map<Integer, List<Integer>> lmap = c.stream().
+                 map(Integer::lowestOneBit).
+                 collect(Collectors.groupingBy(Function.identity()));
+         assertEquals(concurrentMap.size(), lmap.size());
+         concurrentMap.forEach((k , v) -> {
+             assertEquals(v.intValue(), lmap.get(k).size());
+         });
+     }
+     
+     @Test(dataProvider="streams")
+     public void testToMapWithOperatorAndSupplier(Collection<Integer> c) {
+         Map<Integer, Integer> map = c.stream().collect(
+                 Collectors.toMap(Integer::highestOneBit, i -> 1, Integer::sum,
+                 TreeMap::new));
+         Map<Integer, List<Integer>> hmap = c.stream().
+                 map(Integer::highestOneBit).
+                 collect(Collectors.groupingBy(Function.identity()));
+         assertEquals(map.size(), hmap.size());
+         
+         AtomicInteger lowerKey = new AtomicInteger(Integer.MIN_VALUE);
+         map.forEach((k , v) -> {
+             assertTrue(k >= lowerKey.getAndSet(k));
+             assertEquals(v.intValue(), hmap.get(k).size());
+         });
+
+         Map<Integer, Integer> concurrentMap = c.stream().collect(
+                 Collectors.toConcurrentMap(Integer::lowestOneBit, i -> 1,
+                 Integer::sum, ConcurrentSkipListMap::new));
+         Map<Integer, List<Integer>> lmap = c.stream().
+                 map(Integer::lowestOneBit).
+                 collect(Collectors.groupingBy(Function.identity()));
+         assertEquals(concurrentMap.size(), lmap.size());
+         lowerKey.set(Integer.MIN_VALUE);
+         concurrentMap.forEach((k , v) -> {
+             assertTrue(k >= lowerKey.getAndSet(k));
+             assertEquals(v.intValue(), lmap.get(k).size());
+         });
+     }
+        
+     @Test(dataProvider="streams")
+     public void testToDoubleSummaryStatistics(Collection<Integer> c){
+         DoubleSummaryStatistics dss = c.stream().collect(Collectors.summarizingDouble(Integer::doubleValue));
+         IntSummaryStatistics iss = c.stream().mapToInt(Integer::intValue).summaryStatistics();
+         assertEquals(dss.getAverage(), iss.getAverage());
+         assertEquals(dss.getCount(), c.size());
+         assertEquals(dss.getSum(), (double)iss.getSum());
+     }
+        
+     @Test(dataProvider="streams")
+     public void testToIntSummaryStatistics(Collection<Integer> c){
+         IntSummaryStatistics iss = c.stream().collect(Collectors.summarizingInt(Math::abs));
+         assertEquals(iss.getAverage(), 
+                 c.stream().mapToInt(Math::abs).average().getAsDouble());
+         assertEquals(iss.getCount(), c.size());
+         assertEquals(iss.getSum(),  c.stream().mapToLong(i -> Math.abs(i)).sum());
+     }
+        
+     @Test(dataProvider="streams")
+     public void testToLongSummaryStatistics(Collection<Integer> c){
+         LongSummaryStatistics lss = c.stream().collect(Collectors.summarizingLong(i -> (long)Math.pow(i, 2)));
+         assertEquals(lss.getAverage(), c.stream().mapToLong(i -> (long)Math.pow(i, 2)).average().getAsDouble());
+         assertEquals(lss.getCount(), c.size());
+         assertEquals(lss.getSum(), c.stream().mapToLong(i -> (long)Math.pow(i, 2)).sum());
+     }
+
+     @Test
+     public void testEmpty(){
+         Stream<Integer> stream = Stream.<Integer>empty();
+         assertEquals(0, Stream.<Integer>empty().collect(Collectors.counting()).intValue());
+         assertTrue(Stream.<Integer>empty().collect(Collectors.
+                 <Integer, Integer>groupingBy(Function.identity())).isEmpty());
+         assertTrue(Stream.<Integer>empty().collect(Collectors.groupingBy(
+                 Function.identity(), Collectors.<Integer>toSet())).isEmpty());
+         assertTrue(Stream.<Integer>empty().collect(Collectors.groupingBy(Function.identity(), TreeMap::new,
+                 Collectors.toCollection(TreeSet<Integer>::new))).isEmpty());
+         assertTrue(Stream.<Integer>empty().collect(Collectors.mapping(
+                 Function.identity(), Collectors.toList())).isEmpty());
+         assertFalse(Stream.<Integer>empty().collect(Collectors.maxBy(Comparator.naturalOrder())).isPresent());
+         Map<Boolean, List<Integer>> partition1 = Stream.<Integer>empty().
+                 collect(Collectors.partitioningBy(i -> i > 0));
+         assertTrue(partition1.get(true).isEmpty());
+         assertTrue(partition1.get(false).isEmpty());
+         
+         Map<Boolean, Set<Integer>> partition2 = Stream.<Integer>empty().
+                 collect(Collectors.partitioningBy(i -> (i & 0x01) == 0x01, 
+                 Collectors.toCollection(TreeSet<Integer>::new)));
+         assertTrue(partition2.get(true).isEmpty());
+         assertTrue(partition2.get(false).isEmpty());
+         
+         Comparator<Integer> comp = Comparator.comparing(Function.identity());
+         BinaryOperator<Integer> largest = BinaryOperator.maxBy(comp);
+         assertFalse(Stream.<Integer>empty().collect(Collectors.reducing(largest)).isPresent());
+     }
+
+     
+     @DataProvider
+     public static Object[][] streams() {
+         Supplier<Collection<Integer>>[] suppliers = new Supplier[]{
+             ArrayDeque<Integer>::new,
+             ArrayList<Integer>::new,
+             ConcurrentLinkedDeque<Integer>::new,
+             ConcurrentLinkedQueue<Integer>::new,
+             ConcurrentSkipListSet<Integer>::new,
+             CopyOnWriteArrayList<Integer>::new,
+             HashSet<Integer>::new,
+             LinkedBlockingDeque<Integer>::new,
+             LinkedBlockingQueue<Integer>::new,
+             LinkedHashSet<Integer>::new,
+             LinkedList<Integer>::new,
+             LinkedTransferQueue<Integer>::new,
+             PriorityBlockingQueue<Integer>::new,
+             PriorityQueue<Integer>::new,
+             Stack<Integer>::new,
+             TreeSet<Integer>::new,
+             Vector<Integer>::new,
+         };
+         Object[][] params = new Object[suppliers.length][1];
+         int index = 0;
+         for(Supplier<Collection<Integer>> s: suppliers) {
+             Collection<Integer> c = s.get();
+             for(int i = 0; i < COLLECTION_SIZE; i++) {
+                 c.add(RAND.nextInt());
+             }
+             params[index++][0] = c;
+         }
+         return params;
+     }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/ConcatTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.testng.annotations.Test;
+
+public class ConcatTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public ConcatTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="concatCollectionData")
+    public void testConcat(String desc, Collection<U> tobeConcated, Collection<U> concat) {
+        //We're using List to store expected result because Set could merge object, 
+        Collection<U> expected = new ArrayList<>(tobeConcated);
+        expected.addAll(concat);
+
+        //test concat with parallel/non-parallel Stream
+        for(BaseStreamTest.ParallelType concatType : BaseStreamTest.ParallelType.values()) {
+            Stream<U> concatStream = (concatType == BaseStreamTest.ParallelType.Parallel) ? 
+                concat.parallelStream(): (concatType == BaseStreamTest.ParallelType.Sequential)
+                ? concat.parallelStream().sequential() : concat.stream();
+            List<U> calculated = Stream.concat(streamFor(tobeConcated), concatStream)
+                    .collect(Collectors.<U>toList());
+            assertEqualContents(calculated, expected, test.getNaturalOrderComparator());
+        }
+
+        List<U> result3 = Stream.concat(tobeConcated.stream(), streamFor(createEmptyCollection()))
+                .collect(Collectors.<U>toList());
+        List<U> result4 = Stream.concat(tobeConcated.stream(), Stream.empty())
+                .collect(Collectors.<U>toList());
+        assertEqualContents(tobeConcated, result3, test.getNaturalOrderComparator());
+        assertEqualContents(tobeConcated, result4, test.getNaturalOrderComparator());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/CountTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Collection;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class CountTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public CountTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionData")
+    public void testCount(String desc, Collection<U> col) {
+        assertEquals(streamFor(col).count(), col.size());
+        assertEquals(streamFor(col).count(), streamFor(col).mapToLong(u -> 1).sum());
+        assertEquals(streamFor(createEmptyCollection()).count(), 0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/DistinctTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class DistinctTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public DistinctTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionDataWithSelection")
+    public void testDistinct(String desc, Collection<U> col, Function<U, Stream<U>> mapper)  {
+        Set<U> set = new HashSet<>(col);
+
+        List<U> expected = streamFor(col).flatMap(mapper).distinct().collect(Collectors.<U>toList());
+        if(expected.size() != 0) {
+            assertEqualContents(expected, set, test.getNaturalOrderComparator());
+        } else {
+            assertEquals(mapper.apply(streamFor(col).findAny().get()).count(), 0);
+        }       
+        assertEquals(streamFor(createEmptyCollection()).distinct().count(), 0);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/EmployeeStreamTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,319 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Basic test for Stream<Employee>
+ * @library /sqeutil
+ * @(#) EmployeeStreamTest.java
+ * @author Eric Wang/Tristan Yan
+ * @run testng/othervm -mx2g EmployeeStreamTest
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.ToIntFunction;
+import java.util.stream.IntStream;
+import org.testng.annotations.Factory;
+
+class Employee implements Comparable<Employee>, Cloneable,  java.io.Serializable {
+    private static final long serialVersionUID =  3241619007641335109L;
+
+    static final int ID_LENGTH = 6;
+    static final int MIN_BIRTHDAY = 1900;
+    static final int MAX_BIRTHDAY = 2050;
+    static final int MIN_PAY = 1000;
+    static final int MAX_PAY = 100000;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    } 
+        
+    public int getBirthday() {
+        return birthday;
+    }
+
+    public boolean isMale() {
+        return male;
+    }
+
+    public double getPay() {
+        return pay;
+    }
+
+    public void setPay(double pay) {
+        this.pay = pay;
+    }  
+
+    public Title getTitle() {
+        return title;
+    }
+
+    public void setTitle(Title title) {
+        this.title = title;
+    }
+    public Employee(String id, int birthday, boolean male, double pay, Title title) {
+        this.id = id;
+        this.birthday = birthday;
+        this.male = male;
+        this.pay = pay;
+        this.title = title;
+    }
+
+    static enum Title {
+        SE, SSE, PSE, CSE, ARCHITECT, M1, M2, M3, M4
+    }
+
+    static enum Rule {
+        ID {
+            @Override
+            Function<Employee, String> empFunc() {
+                return Employee::getId;
+            }
+            @Override
+            String funcName(){
+                return "Employee::getId";
+            }
+        },
+        BIRTHDAY {
+            @Override
+            Function<Employee, Integer> empFunc() {
+                return Employee::getBirthday;
+            }
+            @Override
+            String funcName(){
+                return "Employee::getBirthday";
+            }
+        },
+        MALE {
+            @Override
+            Function<Employee, Boolean> empFunc() {
+                return Employee::isMale;
+            }
+            @Override
+            String funcName(){
+                return "Employee::isMale";
+            }
+        },
+        PAY {
+            @Override
+            Function<Employee, Double> empFunc() {
+                return Employee::getPay;
+            }
+            @Override
+            String funcName(){
+                return "Employee::getPay";
+            }
+        },
+        TITLE {
+            @Override
+            Function<Employee, Title> empFunc(){
+                return Employee::getTitle;
+            }
+
+            @Override
+            String funcName(){
+                return "Employee::getTitle";
+            }
+        };
+
+        Comparator<Employee> getComparator() {
+            return Comparator.comparing(empFunc());
+        }
+
+        Object getValue(Employee e) { return empFunc().apply(e); }
+
+        abstract String funcName();
+        
+        abstract Function<Employee, ? extends Comparable> empFunc();
+    }
+ 
+    private String id;
+    private final int birthday;
+    private final boolean male;
+    private double pay;
+    private Title title;
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof Employee) {
+            Employee compared = (Employee) other;
+            return id.equals(compared.getId()) && birthday == compared.getBirthday()
+                    && male == compared.isMale() && pay == compared.getPay()
+                    && title == compared.getTitle();
+        } 
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(this.id);
+    }
+
+    @Override
+    public int compareTo(Employee t) {
+        return id.compareTo(t.getId());
+    }
+
+    @Override
+    public Employee clone() {
+        try {
+            return (Employee)super.clone();
+        } catch (CloneNotSupportedException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "id=" + getId() + ", birthday=" + getBirthday() + ". male=" + isMale()
+                + ", pay=" + getPay() + ", title=" + getTitle();
+    }
+}
+
+public class EmployeeStreamTest<T extends Collection<Employee>> extends
+            GenericStreamTest<Employee, Collection<Employee>> {
+    private final static HashMap<Boolean, Map<Integer, Employee[]>> cache = new HashMap<>();
+
+    static {
+        Function<String, Employee> strToEmployee = EmployeeStreamTest::createEmployee;
+        Function<Integer, String> lensToString = StringUtilities::randomNumeric;
+        Function<Integer, Employee> lensToEmployee = lensToString.andThen(strToEmployee);
+        BiFunction<Boolean, Integer, Employee> randomLenToEmployee = (random, len) ->
+             lensToEmployee.apply(random ? rand.nextInt(len) + 1 : len);
+        Function<Boolean, Function<Integer, Employee[]>> randomToEmployeesFunction = random -> 
+                (size -> IntStream.rangeClosed(1, size).mapToObj(len -> 
+                        randomLenToEmployee.apply(random, len)).toArray(Employee[]::new));
+        initCache(cache, randomToEmployeesFunction,  "EmployeeStreamTest");
+    }
+    public EmployeeStreamTest(Class clazz, 
+            ParallelType parallelType, int initSize) {
+        super(clazz, parallelType, Comparator.naturalOrder(), initSize);
+    }
+
+    public EmployeeStreamTest(Class clazz, 
+            ParallelType parallelType) {
+        super(clazz, parallelType, Comparator.naturalOrder());
+    }
+
+    @Factory
+    public static Object[] create(){
+      TripleFunction<Class,ParallelType,Integer, EmployeeStreamTest> supplierWithInitSize =
+              EmployeeStreamTest<Collection<Employee>>::<Class,ParallelType,Integer>new;
+      BiFunction<Class,ParallelType,EmployeeStreamTest> supplier =
+              EmployeeStreamTest<Collection<Employee>>::<Class,ParallelType>new;
+      return GenericStreamTest.create(supplierWithInitSize, supplier, true);
+    }
+
+    @Override
+    public String getTestName() {
+        return typeObject.getName() + "<Employee>";
+    }
+
+    @Override
+    protected Object[] predicateAndDesc(int size) {
+        Employee limit = createEmployee();
+        boolean isUp = rand.nextBoolean();
+        Employee.Rule rule = Arrays.stream(Employee.Rule.values()).findAny().get();
+        return new Object[]{ LambdaUtilities.randomGenericPredicate(isUp, limit, rule.getComparator()), 
+                String.format("emp -> Comparator.comparing(%s).compare(emp, %s) %s 0", rule.funcName(), isUp ? ">=" : "<", limit)};
+    }
+    
+    //Function<U, ? extends Comparable>, descrption for Function<? extends Comparable>
+    @Override
+    protected Object[][] functionAndDesc(){
+            return Arrays.stream(Employee.Rule.values()).map(rule -> new Object[]{rule.empFunc(), rule.funcName()})
+                    .toArray(Object[][]::new);   
+    }
+   
+    //BinaryOperator, descrption, stateless
+    @Override
+    protected Object[][] binaryOperatorAndDesc() {
+        BinaryOperator<Employee> maxOp = (e1, e2) -> getNaturalOrderComparator().compare(e1, e2) < 0 ? e2 : e1;
+        BinaryOperator<Employee> minOp =  (e1, e2) -> getNaturalOrderComparator().compare(e1, e2) > 0? e2 : e1;
+        return new Object[][]{
+            {maxOp, "(e1, e2) -> naturalOrderComparator.compare(e1, e2) < 0 ? e2 : e1", true},
+            {minOp, "(e1, e2) -> naturalOrderComparator.compare(e1, e2) > 0? e2 : e1", true},
+        }; 
+    }
+    
+    @Override
+   protected Employee[] bases(int size){
+        return new Employee[]{createEmployee()};
+    }
+    
+    private static Employee createEmployee(String id)  {
+        BiFunction<Integer, Integer, Integer> RANDOM_INT_BETWEEN
+            = (start, end) -> start + rand.nextInt(end - start);
+        int birthday = RANDOM_INT_BETWEEN.apply(Employee.MIN_BIRTHDAY, Employee.MAX_BIRTHDAY);
+        Boolean gender = rand.nextBoolean();
+        double pay = RANDOM_INT_BETWEEN.apply(Employee.MIN_PAY, Employee.MAX_PAY);
+        Employee.Title title = Employee.Title.values()[rand.nextInt(Employee.Title.values().length)];
+        return new Employee(id, birthday, gender, pay, title);
+    }
+
+    private Employee createEmployee()  {
+        return this.createEmployee(StringUtilities.randomNumeric(Employee.ID_LENGTH));
+    }
+
+    @Override
+    protected Object[] validArrayGeneratorAndDesc() {
+        return new Object[]{
+            new IntFunction[]{(IntFunction)Employee[]::new, (IntFunction)Object[]::new},
+            "{Employee[]::new, Object[]::new}"
+        };
+    }
+
+    @Override
+    protected Object[][] invalidArrayGeneratorAndDesc() {
+        return new Object[][]{
+            {(IntFunction)Employee.Rule[]::new, "Employee.Rule[]::new"},
+            {(IntFunction)String[]::new, "String[]::new"},
+        };
+    }
+
+    @Override
+    protected IntFunction<Employee> createFunction() {
+        return i -> createEmployee(String.valueOf(i));
+    }
+
+    @Override
+    protected ToIntFunction<Employee> intValueFunction() {
+        return  e -> Integer.parseInt(e.getId()) ;
+    }
+
+    @Override
+    protected Employee[] getArray(int size, boolean random) { return cache.get(random).get(size);  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/FilterTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+public class FilterTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public FilterTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+    
+    @Test(dataProvider="collectionDualPredicateData")
+    public void testFilter(String desc, Collection<U> col, Predicate<U> p1, Predicate<U> p2)  {
+        //Filter the data, check if it works as expected.
+        Collection<U> filteredColByP1 = streamFor(col).filter(p1)
+                .collect(Collectors.<U, List<U>>toCollection(LinkedList::new));
+        assertTrue(verifyMatch(filteredColByP1, p1, true));
+
+        //filter on parallel stream can cause IllegalStateException
+        Collection<U>  filteredColByAlwaysTrue = streamFor(col).filter(p1).filter(e -> true)
+                .collect(Collectors.<U, List<U>>toCollection(LinkedList::new));
+        assertTrue(verifyMatch(filteredColByAlwaysTrue, p1, true));
+
+        //filter with false will get nothing
+        Collection<U>  filteredColByAlwaysFalse = streamFor(col).filter(p1).filter(e -> false)
+                .collect(Collectors.<U, List<U>>toCollection(LinkedList::new));
+        assertTrue(filteredColByAlwaysFalse.isEmpty());
+
+        //The reason conver l to sorted is CopyOnWriteArrayList doesn't support
+        //sort, we use ArrayList sort data instead
+        Collection<U> filteredColByP2AfterP1 = streamFor(col).filter(p1).filter(p2)
+                .collect(Collectors.<U, List<U>>toCollection(ArrayList::new));
+
+        List<U> filteredColByrP1AndP2 = streamFor(col).filter(p1.and(p2))
+                .collect(Collectors.<U, List<U>>toCollection(ArrayList::new));
+        assertEqualContents(filteredColByP2AfterP1, filteredColByrP1AndP2, test.getNaturalOrderComparator());
+
+        List<U> filteredColByrP1OrP2 = streamFor(col).filter(p1.or(p2))
+                .collect(Collectors.<U, List<U>>toCollection(ArrayList::new));
+
+        List<U> filteredExpected = new ArrayList<>(filteredColByrP1AndP2);
+        filteredExpected.addAll(filteredColByrP1OrP2);
+
+        //concat stream.filter(p1) with stream.filter(p2) should be same as stream.filter(p1 && p2) combine with 
+        //stream.filter(p1 || p2) 
+        List<U> filteredColByP1CancatfilteredColByP2 = Stream.concat(streamFor(col).filter(p1), streamFor(col).filter(p2))
+                .collect(Collectors.<U, List<U>>toCollection(ArrayList::new));
+        assertEqualContents(filteredColByP1CancatfilteredColByP2, filteredExpected, test.getNaturalOrderComparator());
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/FindTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+public class FindTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public FindTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionData")
+    public void testFind(String desc, Collection<U> col) {
+        Stream<U> stream = streamFor(col);
+        Optional<U> opAny = stream.findAny();
+        Optional<U> opFirst = streamFor(col).findFirst();
+        if(!stream.isParallel())
+            assertEquals(opAny, opFirst);
+        assertTrue(opAny.isPresent());
+        assertTrue(opFirst.isPresent());
+
+        assertFalse(streamFor(createEmptyCollection()).findAny().isPresent());
+        assertFalse(streamFor(createEmptyCollection()).findFirst().isPresent());
+    }
+    
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testFindNull() {
+        Collection<U> nullCol = createEmptyCollection();
+        nullCol.add(null);
+        streamFor(nullCol).findAny();
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/FlatMapTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class FlatMapTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public FlatMapTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionDataWithSelection", threadPoolSize = 3)
+    public void testFlatMap(String desc, Collection<U> col, Function<U, Stream<U>> mapper) {
+        List<U> result = streamFor(col).flatMap(mapper).collect(Collectors.<U>toList());
+        verifyFlatMap(col, result, mapper);
+        
+        assertEquals(streamFor(createEmptyCollection()).flatMap(mapper).count(), 0);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/ForEachTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+public class ForEachTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public ForEachTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+       
+    @Test(dataProvider="collectionData")
+    public void testForEach(String desc, Collection<U> col) {
+        List<U> expected= new ArrayList<>(col);
+        //Unordered streams could play parallel executions, which we need a 
+        //thread-safe queue to check the data  
+        ConcurrentLinkedQueue<U> forEachQueue = new ConcurrentLinkedQueue<>();
+        streamFor(col).forEach(forEachQueue::add);
+        assertEqualContents(forEachQueue, expected, test.getNaturalOrderComparator());
+
+        List<U> forEachOrderedList = new ArrayList<>();
+        streamFor(col).forEachOrdered(forEachOrderedList::add); 
+        assertEquals(forEachOrderedList, expected);
+        
+        List<U> expectedEmpty = new ArrayList<>();
+        streamFor(createEmptyCollection()).forEach(expectedEmpty::add);
+        assertTrue(expectedEmpty.isEmpty());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/GenericStreamTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.Predicate;
+import java.util.function.ToIntFunction;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import org.testng.ITest;
+
+public abstract class GenericStreamTest<U, V extends Collection<U>>  
+            extends BaseStreamTest implements ITest {
+    protected final static int DEFAULT_INIT_SIZE = -1;
+
+    protected final static Class[] defaultConstructorClazz = {
+        ArrayDeque.class,
+        ArrayList.class,
+        ConcurrentLinkedDeque.class,
+        ConcurrentLinkedQueue.class,
+        CopyOnWriteArrayList.class,
+        HashSet.class,
+        LinkedBlockingDeque.class,
+        LinkedBlockingQueue.class,
+        LinkedHashSet.class,
+        LinkedList.class,
+        LinkedTransferQueue.class,
+        Stack.class,
+        Vector.class
+    };
+
+    protected final static Class[] capacityConstructorClazz = {
+        ArrayBlockingQueue.class,
+        ArrayDeque.class,
+        ArrayList.class,
+        HashSet.class,
+        LinkedBlockingDeque.class,
+        LinkedBlockingQueue.class,
+        LinkedHashSet.class,
+        Vector.class
+    };
+
+    protected final static Class[] defaultComparableConstructorClazz = {
+        //Sorted collection only supports Comparable data type    
+        PriorityBlockingQueue.class,
+        PriorityQueue.class,
+        ConcurrentSkipListSet.class,
+        TreeSet.class,
+    };
+
+    protected final static Class[] capacityComparableConstructorClazz = {
+        //Sorted collection only supports Comparable data type
+        PriorityBlockingQueue.class,
+        PriorityQueue.class,
+    };
+
+    private final HashMap<Function<U, Stream<U>>, String> flatMappers(){
+        HashMap<Function<U, Stream<U>>, String> map = new HashMap<>();
+        map.put(e -> Stream.empty(), "e -> Stream.empty()");
+        map.put(e -> Collections.singletonList(e).stream(), 
+                "e -> Collections.singletonList(e).stream()");
+        map.put(e -> Stream.generate(() -> e).limit(SIXTY_FOUR), 
+                "e -> Stream.generate(() -> e).limit(FIFTEEN)");
+        return map;
+    }
+   
+    protected final Class<V> typeObject;
+
+    private final int initSize;
+    
+    protected final Comparator<U> naturalOrderComparator;
+
+    public Stream<U> streamFor(Collection<U> c1) {
+        return (getParallelType() == ParallelType.Parallel) ? 
+            c1.parallelStream(): (getParallelType() == ParallelType.Sequential)
+            ? c1.parallelStream().sequential() : c1.stream();
+    }
+
+    public Collection<U> createEmptyCollection() {
+        try {
+            Collection<U> emptyCol = (initSize == DEFAULT_INIT_SIZE) ? 
+                LambdaUtilities.create(typeObject) : 
+                LambdaUtilities.create(typeObject, initSize);
+            return emptyCol;
+        } catch ( ReflectiveOperationException roe) {
+            throw new RuntimeException(roe);
+        }
+    }
+
+    public static Object[] create(TripleFunction<Class, ParallelType, Integer,
+        ? extends GenericStreamTest> testCreatorWithInitSize, 
+            BiFunction<Class, ParallelType, ? extends GenericStreamTest> 
+                testCreator, boolean comparable) {
+        List<OperatorTest> result = new ArrayList<>();
+        List<Function<GenericStreamTest, ? extends OperatorTest>> functions = 
+            Arrays.stream(OperatorTest.GenericOperatorType.values()).
+                map(OperatorTest.GenericOperatorType::getConstructor).
+                collect(Collectors.<Function<GenericStreamTest, ? extends OperatorTest>>toList());
+        if(comparable)
+            functions.add(SortedTestForCompable::new);
+        else
+            functions.add(SortedTestForNonCompable::new);
+        Arrays.stream(ParallelType.values()).forEach(parallelType -> {
+            functions.stream().forEach(function -> {
+                Arrays.stream(defaultConstructorClazz).forEach( clazz ->  { 
+                    result.add(function.apply(testCreator.apply(
+                        clazz, parallelType)));
+                }); 
+                Arrays.stream(capacityConstructorClazz).forEach( clazz -> { 
+                    result.add(function.apply(testCreatorWithInitSize.apply(
+                        clazz, parallelType, MEDIUM_DATA_SIZE)));
+                    });
+                if(comparable) {
+                    Arrays.stream(defaultComparableConstructorClazz).forEach(
+                        clazz -> { 
+                            result.add(function.apply(testCreator.apply(
+                                clazz, parallelType)));
+                        });
+                    Arrays.stream(capacityComparableConstructorClazz).forEach(
+                        clazz -> { 
+                            result.add(function.apply(testCreatorWithInitSize.
+                                apply(clazz, parallelType, MEDIUM_DATA_SIZE)));
+                        });
+                }
+            });
+        });
+        return result.toArray();
+    }
+
+    protected GenericStreamTest(Class<V> clazz, ParallelType parallelType,
+            Comparator<U> naturalOrderComparator, int initSize) {
+        super(parallelType);
+        this.typeObject = clazz;
+        this.naturalOrderComparator = naturalOrderComparator;
+        this.initSize = initSize;
+    }
+    
+    protected GenericStreamTest(Class<V> clazz, ParallelType parallelType,
+            Comparator<U> naturalOrderComparator) {
+        this(clazz, parallelType, naturalOrderComparator, DEFAULT_INIT_SIZE);
+    }
+
+    protected static <T> void assertEqualContents(Collection<T> result1,
+            Collection<T> result2, Comparator<T> comparator) {
+        assertEquals(result1.size(), result2.size());
+        ArrayList<T> a = new ArrayList<>(result1);
+        ArrayList<T> b = new ArrayList<>(result2);
+        Collections.sort(a, comparator);
+        Collections.sort(b, comparator);
+
+        for(int i = 0; i < result1.size(); i++)
+            assertEquals(comparator.compare(a.get(i), b.get(i)), 0);
+    }
+    
+    protected static <T> void initCache(HashMap<Boolean, Map<Integer, T[]>> 
+            cache, Function<Boolean, Function<Integer, T[]>> randomToObjecstFunc,
+            String testName){
+        Arrays.asList(true, false).forEach(isRandom -> {
+            Function<Integer, T[]> sizeToObjects = randomToObjecstFunc.apply(isRandom);
+            cache.put(isRandom, Arrays.stream(MEDIUM_DATA_SIZES).boxed().collect(Collectors.
+                <Integer, Integer, T[]>toMap(Function.identity(), sizeToObjects)));
+        });
+
+        try(ObjectOutputStream cacheOOS = new ObjectOutputStream(Files.
+            newOutputStream(FileSystems.getDefault().getPath(
+            System.getProperty("test.classes", "."), testName + ".cache")))) {
+            cacheOOS.writeObject(cache);
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    protected abstract U[] getArray(int size, boolean random);
+    
+    protected Collection<U> generate(int size, boolean random) {
+        Collection<U> col = createEmptyCollection();
+        Arrays.stream(getArray(size, random)).forEach(col::add);   
+        return col;
+    }
+    
+    //Predicate<U>, descrption for Predicate<U>
+    protected abstract  Object[] predicateAndDesc(int size);
+    
+    //BinaryOperator<U>, descrption for BinaryOperator, stateless
+    protected abstract  Object[][] binaryOperatorAndDesc();
+
+    //Function<U, ? extends Comparable>, descrption for Function
+    protected abstract  Object[][] functionAndDesc();
+    
+    //IntFunction<W>[], descrption for all IntFunction<W>
+    protected abstract  Object[] validArrayGeneratorAndDesc();
+    
+    //IntFunction<W>[], descrption for IntFunction<W>
+    protected abstract  Object[][] invalidArrayGeneratorAndDesc();
+
+    //IntFunction<U> a generator from U to int
+    protected abstract IntFunction<U> createFunction();
+ 
+    //ToIntFunction<U> a generator from int to U
+    protected abstract ToIntFunction<U> intValueFunction();
+    
+    private final Function<int[], Object[]> sizeRoBuilders = sizes -> 
+        Arrays.stream(sizes).boxed().flatMap(size -> 
+            Arrays.asList(true, false).stream().map(random -> generate(size, random))
+            ).toArray();
+    
+    //base object based on size, base object will be used when the operation like reduce
+    protected abstract U[] bases(int size);
+
+    protected Object[] builders() {
+        return sizeRoBuilders.apply(MEDIUM_DATA_SIZES);
+    }
+
+    protected Object[] smallSizeBuilders() {
+        return sizeRoBuilders.apply(SMALL_DATA_SIZES);
+    }
+
+    //Test only needs Collection<U>, test like find, count, forEach, subStream, 
+    //sorted test need this
+    protected Iterator<Object[]> collectionData() {
+        Function<Collection<U>, Object[]> objGenerator = data -> new Object[]{
+            String.format("%s(%d)", typeObject.getName(), data.size()),data};
+       return Arrays.stream(builders()).
+               map(data -> objGenerator.apply((Collection<U>)data)).iterator();
+    }
+    
+    //Test only needs Collection<U> and invalid index, test like 
+    // testSubstreamException needs this.
+    protected Iterator<Object[]> collectionStartEndData() {
+        List<Object[]> dataList= new ArrayList<>();
+        long[][] exceptionStartEnd = new long[][]{
+            {-1, 1},   //startInclusive is negative
+            {1, -1},   //endInclusive is negative
+            {1, 0}    //startInclusive is greater than endExclusive
+        };
+       TripleFunction<Collection<U>, Long, Long, Object[]> objGenerator = 
+            (data, start, end) ->  new Object[]{String.format("%s(%d), %d, %d", 
+                typeObject.getName(), data.size(), start, end),
+                    data, start, end};
+       Arrays.stream(builders()).forEach(data -> {
+           Arrays.stream(exceptionStartEnd).forEach(startEnd -> {
+               dataList.add(objGenerator.apply((Collection<U>)data, startEnd[0], 
+                       startEnd[1]));
+           });
+       });    
+       return dataList.iterator();
+    }
+
+    //Test needs Collection<U> and one Predicate, tests like collect by 
+    // partition, anyMatch, noneMatch, allMatch needs this
+    protected Iterator<Object[]> collectionPredicateData() {
+        List<Object[]> dataList= new ArrayList<>();
+        Arrays.stream(builders()).forEach(data -> {
+            Collection<U> col = (Collection<U>)data;
+            Object[] predicateAndDesc = predicateAndDesc(col.size());
+            Predicate<U> p = (Predicate<U>)predicateAndDesc[0];
+            String desc = String.format("%s(%d), %s", typeObject.getName(), 
+                    col.size(), (String)predicateAndDesc[1]);
+            dataList.add(new Object[]{desc, data, p});
+        });
+        return dataList.iterator();
+    }
+    
+    //Test needs Collection<U> and two Predicates, test like filter needs this.
+    public Iterator<Object[]> collectionDualPredicateData() {
+        List<Object[]> dataList = new ArrayList<>();
+        Arrays.stream(builders()).forEach(data -> {
+            Collection<U> col = (Collection<U>)data;
+            Object[] predicateAndDesc1 = predicateAndDesc(col.size());
+            Object[] predicateAndDesc2 = predicateAndDesc(col.size());
+            Predicate<U> p1 = (Predicate<U>)predicateAndDesc1[0];
+            Predicate<U> p2 = (Predicate<U>)predicateAndDesc2[0];
+            String desc = String.format("%s(%d), %s, %s", typeObject.getName(), 
+                col.size(),(String)predicateAndDesc1[1], 
+                (String)predicateAndDesc2[1]);
+            dataList.add(new Object[]{desc, col, p1, p2});
+        });
+        return dataList.iterator();
+    }
+    
+    //Test needs Collection<U>, U base and and BinaryOperator<U>, stateless, 
+    //test like reduce needs this.
+    protected Iterator<Object[]> collectionBinaryOpeatorData(){
+        List<Object[]> dataList = new ArrayList<>();
+        Arrays.stream(builders()).forEach(data -> {
+            Collection<U> col = (Collection<U>)data;
+            Arrays.stream(binaryOperatorAndDesc()).forEach((Object[] bpDesc) -> {
+                BinaryOperator<U> bo = (BinaryOperator<U>)bpDesc[0];
+                String boDesc = (String)bpDesc[1];
+                boolean stateless =  (Boolean)bpDesc[2];
+                Arrays.stream(bases(col.size())).forEach(base -> {
+                    dataList.add(new Object[]{String.format("%s(%d), %s, %s, %s",
+                        typeObject.getName(), col.size(), base, 
+                        boDesc, stateless), col, base, bo, stateless});
+                });
+            });
+        });
+        return dataList.iterator();
+    }
+    
+    //Test needs Collection<U>, Function<U, ? extends Object>, tests like 
+    //collect by groupingBy, max, min, sorted, peek need this
+    protected Iterator<Object[]> collectionFunctionData(){
+         List<Object[]> dataList = new ArrayList<>();
+        Arrays.stream(builders()).forEach(data -> {
+            Collection<Integer> col = (Collection<Integer>)data;
+            Arrays.stream(functionAndDesc()).forEach((Object[] funcDesc) -> {
+                Function<U, Object> func = (Function<U, Object>)funcDesc[0];
+                String desc = (String)funcDesc[1];
+                dataList.add(new Object[]{String.format("%s(%d), %s", 
+                    typeObject.getName(), col.size(), desc), col, func});
+            });
+        });
+        return dataList.iterator();
+    }
+    
+    //Test needs Collection<U>, Function<U, K> keyFunc, Function<U, V> valueFunc, 
+    //tests like collect map needs this.
+    //toMap need keep key's identical, using Function.identity()
+    protected Iterator<Object[]> collectionKeyValueFunctionData(){
+         List<Object[]> dataList = new ArrayList<>();
+        Arrays.stream(builders()).forEach(data -> {
+            Collection<Integer> col = (Collection<Integer>)data;
+            Arrays.stream(functionAndDesc()).forEach((Object[] valueFuncDesc) -> {
+                Function<U, Object> valueFunc = (Function<U, Object>)valueFuncDesc[0];
+                String valuedesc = (String)valueFuncDesc[1];
+                dataList.add(new Object[]{String.format("%s(%d), %s, %s", 
+                    typeObject.getName(), col.size(), 
+                    "Function.identity()", valuedesc), col, Function.identity(), 
+                    valueFunc});
+            });
+        });
+        return dataList.iterator();
+    }
+    
+    //testToArray needs Collection<U>, IntFunction<W>[], test like toArray needs 
+    //this.
+    protected Iterator<Object[]> collectionArrayGeneratorData(){
+         List<Object[]> dataList = new ArrayList<>();
+        Arrays.stream(builders()).forEach(data -> {
+            Collection<Integer> col = (Collection<Integer>)data;
+            Object[] validArrayGenerators =  validArrayGeneratorAndDesc();
+            IntFunction[] generators = (IntFunction[])validArrayGenerators[0];
+            String desc = (String)validArrayGenerators[1];
+            dataList.add(new Object[]{String.format("%s(%d), %s", 
+                    typeObject.getName(), col.size(), desc), col, generators});
+        });
+        return dataList.iterator();
+    }
+    
+    //testToArrayException needs Collection<U>, IntFunction<W>,  this is for 
+    //testing toArray's ArrayStoreException
+    public Iterator<Object[]> collectionArrayInvalidGeneratorData(){
+         List<Object[]> dataList = new ArrayList<>();
+        Arrays.stream(builders()).forEach(data -> {
+            Collection<Integer> col = (Collection<Integer>)data;
+            Arrays.stream(invalidArrayGeneratorAndDesc()).forEach(
+                    generatorAndDesc -> {
+                IntFunction generator = (IntFunction)generatorAndDesc[0];
+                String desc = (String)generatorAndDesc[1];
+                dataList.add(new Object[]{String.format("%s(%d), %s", 
+                        typeObject.getName(), col.size(), desc), col, generator});
+            });
+        });
+        return dataList.iterator();
+    }
+    
+    //Test needs two Collection<U>, operation like concat needs this.
+    protected Iterator<Object[]> concatCollectionData(){
+        List<Object[]> dataList = new ArrayList<>();
+        Arrays.stream(builders()).forEach(data1 ->
+            Arrays.stream(builders()).forEach(data2 -> {
+                String desc = String.format("%s(%d), %s(%d)", 
+                        typeObject.getName(), ((Collection<U>)data1).size(), 
+                        typeObject.getName(), ((Collection<U>)data2).size());
+                dataList.add(new Object[]{desc, data1, data2}); }
+            )
+         );
+        return dataList.iterator();
+    }
+   
+   //Test like test limit's exception need this
+    protected Iterator<Object[]>  exceptionTestData()  {
+        Collection<U> col = generate(SMALL_DATA_SIZE, false);
+        return Arrays.stream(new Object[][]{
+            {String.format("%s(%d)", typeObject.getName(), col.size()), col},
+        }).iterator();
+    }
+
+    //Test like distinct needs this.
+    protected Iterator<Object[]> smallSizeCollectionData() {
+        List<Object[]> dataList = new ArrayList<>();
+        Arrays.stream(smallSizeBuilders()).forEach(data -> {
+            Collection<U> col = (Collection<U>)data;
+            dataList.add(new Object[]{String.format("%s(%d)", 
+                    typeObject.getName(), col.size()), col});
+        });
+        return dataList.iterator();
+    }
+
+    protected Iterator<Object[]> collectionDataWithLimit() {
+        List<Object[]> dataList = new ArrayList<>();
+        Arrays.stream(builders()).forEach(dataCol -> { 
+            Collection<U> col = (Collection<U>)dataCol;
+            int withBoundryLimit = rand.nextInt(col.size());
+            int beyondBoundryLimit = col.size() 
+                    + rand.nextInt(Integer.MAX_VALUE - col.size());
+            dataList.add(new Object[]{String.format("%s(%d), %s", 
+                    typeObject.getName(), col.size(), withBoundryLimit, 
+                    beyondBoundryLimit), col, withBoundryLimit, beyondBoundryLimit}); 
+        });
+        return dataList.iterator();
+    }
+
+    //Test like test flatMap need this
+    protected Iterator<Object[]> collectionDataWithSelection() {
+        List<Object[]> dataList = new ArrayList<>();
+        TripleFunction<Collection<U>, String, Function<U, Stream<U>>, 
+                Object[]> objectGenerator = (col, str , mapper) -> 
+                new Object[]{String.format("<%s(%d), %s>", typeObject.getName(),
+                col.size(), str), col, mapper};
+        Arrays.stream(smallSizeBuilders()).forEach(data -> {
+            Collection<U> col = (Collection<U>)data;
+            flatMappers().forEach((func, msg) -> {
+                dataList.add(objectGenerator.apply(col, msg, func));
+            });
+        });
+        return dataList.iterator();
+    }
+
+    public Comparator<U> getNaturalOrderComparator() {
+        return naturalOrderComparator;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/IntStreamTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Basic test for IntStream
+ * @library /sqeutil
+ * @(#) IntStreamTest.java
+ * @author Tristan Yan
+ * @run testng IntStreamTest
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.OptionalInt;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.IntFunction;
+import java.util.function.IntPredicate;
+import java.util.function.IntUnaryOperator;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Factory;
+import org.testng.annotations.Test;
+
+public class IntStreamTest {
+    private final static int[] ARRAY_SIZES = {1, 1 << 2, 1 << 4, 1 << 7, 1 << 12};
+
+    protected enum Selection { EMPTY, SINGLE, TRIANGLE, COPY_64};
+
+    private final static int[] EMPTY_ARRAY = new int[0];
+
+    private IntStream streamFor(ParallelType p, int[] array) {
+        return (p == ParallelType.Parallel) ? Arrays.stream(array).parallel()
+                : (p == ParallelType.Sequential) ? Arrays.stream(array).sequential() : Arrays.stream(array);
+    }
+
+    private IntStream streamFor(ParallelType p, int[] array, int startIndex, int endIndex) {
+        return (p == ParallelType.Parallel) ? Arrays.stream(array, startIndex, endIndex).parallel()
+                : (p == ParallelType.Sequential) ? Arrays.stream(array, startIndex, endIndex).sequential() :
+                Arrays.stream(array, startIndex, endIndex);
+    }
+
+    static enum ParallelType { Parallel, Sequential, Default }
+
+    private final static Random rand = new Random(1968721);
+
+    private boolean verifyMatch(int[] array, IntPredicate predicate, boolean checkAll) {
+        for(int element : array) {
+            if(predicate.test(element) != checkAll)
+                return !checkAll;
+        }
+        return checkAll;
+    }
+
+    private final ParallelType parallelType;
+
+    private IntStreamTest(final ParallelType parallelType) {
+        this.parallelType = parallelType;
+    }
+
+    @Factory
+    public static Object[] create(){
+        return Arrays.stream(ParallelType.values()).map(p -> new IntStreamTest(p)).toArray();
+    }
+
+    final static Object[][] arrays = Arrays.stream(ARRAY_SIZES).mapToObj(size ->
+            new Object[]{IntStream.range(0, size).toArray()}).toArray(Object[][]::new);
+
+    @DataProvider
+    public static Iterator<Object[]> intArrays(){
+        ArrayList<Object[]> list = new ArrayList<>();
+        String format = "<int[%d]>";
+        Arrays.stream(arrays).forEach(data -> {
+            int[] array = (int[])data[0];
+            list.add(new Object[]{String.format(format, array.length), array});
+        });
+        return list.iterator();
+    }
+
+    @DataProvider
+    public static Iterator<Object[]> intArraysWithSkipLimit(){
+        ArrayList<Object[]> list = new ArrayList<>();
+        String format = "<int[%d], %d, %d>";
+        Arrays.stream(arrays).forEach(data -> {
+            int[] array = (int[])data[0];
+            list.add(new Object[]{String.format(format, array.length, 0, array.length), array, 0, array.length});
+            list.add(new Object[]{String.format(format, array.length, array.length / 3, array.length /2), array,  array.length / 3, array.length /2});
+            list.add(new Object[]{String.format(format, array.length,  array.length /2, array.length + 1), array, array.length /2, array.length + 1});
+        });
+        return list.iterator();
+    }
+
+    @DataProvider
+    public static Iterator<Object[]> intArraysWithLimit(){
+        ArrayList<Object[]> list = new ArrayList<>();
+        String format = "<int[%d], %d>";
+        Arrays.stream(arrays).forEach(data -> {
+            int[] array = (int[])data[0];
+            list.add(new Object[]{String.format(format, array.length, 0), array, 0});
+            list.add(new Object[]{String.format(format, array.length, array.length / 3), array, array.length / 3});
+            list.add(new Object[]{String.format(format, array.length, array.length /2), array, array.length /2});
+            list.add(new Object[]{String.format(format, array.length, array.length + 1), array, array.length + 1});
+        });
+        return list.iterator();
+    }
+
+    @DataProvider
+    public static Iterator<Object[]> intArraysWithPredicate(){
+        ArrayList<Object[]> list = new ArrayList<>();
+        String format = "<int[%d], %s>";
+        Arrays.stream(arrays).forEach(data -> {
+            int[] array = (int[])data[0];
+            list.add(new Object[]{String.format(format, array.length, "i -> i < " + array.length / 2), array, (IntPredicate) i -> i < array.length / 2});
+            list.add(new Object[]{String.format(format, array.length, "i -> i < 0"), array, (IntPredicate) i -> i < 0});
+            list.add(new Object[]{String.format(format, array.length, "i -> i >= 0"), array, (IntPredicate) i -> i >= 0});
+            list.add(new Object[]{String.format(format, array.length, "i -> i >= " + array.length), array, (IntPredicate) i -> i >= array.length});
+        });
+        return list.iterator();
+    }
+
+    @DataProvider
+    public static Iterator<Object[]> intArraysWithOperator(){
+        ArrayList<Object[]> list = new ArrayList<>();
+        String format = "<int[%d], %s>";
+        Arrays.stream(arrays).forEach(data -> {
+            int[] array = (int[])data[0];
+            list.add(new Object[]{String.format(format, array.length, "i -> i + 1"), array, (IntUnaryOperator)i -> i + 1});
+            list.add(new Object[]{String.format(format, array.length, " i -> i << 2"), array, (IntUnaryOperator) i -> i << 2});
+            list.add(new Object[]{String.format(format, array.length, "Math::abs"), array, (IntUnaryOperator)Math::abs});
+        });
+        return list.iterator();
+    }
+
+    @DataProvider
+    public static Iterator<Object[]> intArraysWithSelection(){
+        ArrayList<Object[]> list = new ArrayList<>();
+        String format = "<int[%d], %s>";
+        Arrays.stream(arrays).forEach(data -> {
+            int[] array = (int[])data[0];
+            Arrays.stream(Selection.values()).forEach(selection ->
+                    list.add(new Object[]{String.format(format, array.length, selection), array, selection}));
+        });
+        return list.iterator();
+    }
+
+    @Test(dataProvider="intArraysWithPredicate")
+    public void testXxxMatch(String desc, int[] array, IntPredicate predicate) {
+        assertEquals(streamFor(parallelType, array) .allMatch(predicate), verifyMatch(array, predicate, true));
+        assertEquals(streamFor(parallelType, array) .anyMatch(predicate),  verifyMatch(array, predicate, false));
+        assertEquals(streamFor(parallelType, array) .noneMatch(predicate), verifyMatch(array, predicate.negate(), true));
+
+        assertEquals(streamFor(parallelType, array, 0, array.length).allMatch(predicate),
+                streamFor(parallelType, array).allMatch(predicate));
+        assertEquals(streamFor(parallelType, array, 0, array.length).anyMatch(predicate),
+                streamFor(parallelType, array).anyMatch(predicate));
+        assertEquals(streamFor(parallelType, array, 0, array.length).noneMatch(predicate),
+                streamFor(parallelType, array).noneMatch(predicate));
+
+        assertTrue(streamFor(parallelType, EMPTY_ARRAY).allMatch(predicate));
+        assertFalse(streamFor(parallelType, EMPTY_ARRAY).anyMatch(predicate));
+        assertTrue(streamFor(parallelType, EMPTY_ARRAY).noneMatch(predicate));
+    }
+
+    @Test(dataProvider="intArrays")
+    public void testAveargeAndSum(String desc, int[] array) throws Exception {
+        //for calculate average, we need bigger scale data type calculate total, this could prevent int overflow
+        double total = 0;
+        int intTotal = 0;
+        for(int index = 0; index < array.length; index++) {
+            total += array[index];
+            intTotal += array[index];
+        }
+        assertEquals(streamFor(parallelType, array).average(). getAsDouble(), total / array.length);
+        assertEquals(streamFor(parallelType, array).sum(), intTotal);
+
+        assertEquals(streamFor(parallelType, array).average(), streamFor(parallelType, array, 0, array.length).average());
+        assertEquals(streamFor(parallelType, array).sum(), streamFor(parallelType, array, 0, array.length).sum());
+
+        assertFalse(streamFor(parallelType, EMPTY_ARRAY).average().isPresent());
+        assertEquals(streamFor(parallelType, EMPTY_ARRAY).sum(), 0);
+    }
+
+    @Test(dataProvider="intArrays")
+    public void testBoxed(String desc, int[] array) throws Exception {
+        Object[] boxedArr1 = streamFor(parallelType, array).boxed().toArray();
+        Object[] boxedArr2 = streamFor(parallelType, array).mapToObj(Integer::new).toArray();
+        assertEquals(boxedArr1, boxedArr2);
+
+        assertEquals(streamFor(parallelType, EMPTY_ARRAY).boxed().count(), 0);
+    }
+
+    @Test(dataProvider="intArraysWithPredicate")
+    public void testFilter(String desc, int[] array/*, int startIndex, int endIndex*/, IntPredicate predicate) throws Exception{
+        assertTrue(verifyMatch(streamFor(parallelType, array).filter(predicate).toArray(), predicate, true));
+        assertEquals(streamFor(parallelType, array, 0, array.length).filter(predicate).toArray(),
+                streamFor(parallelType, array).filter(predicate).toArray());
+
+        assertEquals(streamFor(parallelType, EMPTY_ARRAY).filter(predicate).count(), 0);
+    }
+
+    @Test(dataProvider="intArrays")
+    public void testFind(String desc, int[] array) throws Exception{
+        IntStream streamFindAny = streamFor(parallelType, array);
+        OptionalInt opAny = streamFindAny.findAny();
+        OptionalInt opFirst = streamFor(parallelType, array).findFirst();
+        assertTrue(opAny.isPresent());
+        assertTrue(opFirst.isPresent());
+        if(!streamFindAny.isParallel())
+            assertEquals(opAny, opFirst);
+
+        assertFalse(streamFor(parallelType, EMPTY_ARRAY).findAny().isPresent());
+        assertFalse(streamFor(parallelType, EMPTY_ARRAY).findFirst().isPresent());
+    }
+
+    @Test(dataProvider="intArrays")
+    public void testForEach(String desc, int[] array) throws Exception {
+        IntStream stream = streamFor(parallelType, array);
+        Arrays.parallelSort(array);
+        stream.forEach(t -> { assertTrue(Arrays.binarySearch(array, t) >= 0); });
+
+        ArrayList<Integer> touch = new ArrayList<>();
+        streamFor(parallelType, EMPTY_ARRAY).forEach(t -> { touch.add(t); });
+        assertTrue(touch.isEmpty());
+    }
+
+    @Test(dataProvider="intArraysWithLimit")
+    public void testLimit(String desc, int[] array, int limit) {
+        if(limit > array.length)
+            assertEquals(streamFor(parallelType, array).limit(limit).count(), array.length);
+        else
+            assertEquals(streamFor(parallelType, array).limit(limit).count(), limit);
+    }
+
+    @Test(dataProvider="intArraysWithSelection")
+    public void testFlatMap(String desc, int[] array, Selection selection) {
+        int[] flatArray = streamFor(parallelType, array).flatMap(genIntFlatMapper(selection)).sorted().toArray();
+        verifyMultifunction(array, flatArray, selection);
+
+        assertEquals(streamFor(parallelType, EMPTY_ARRAY).flatMap(genIntFlatMapper(selection)).toArray(),EMPTY_ARRAY);
+    }
+
+    @Test(dataProvider="intArraysWithOperator")
+    public void testMap(String desc, int[] array, IntUnaryOperator mapper)  {
+        int[] mapped = streamFor(parallelType, array).map(mapper).toArray();
+        for(int index = 0; index < array.length; index++) {
+            assertEquals(mapped[index], mapper.applyAsInt(array[index]));
+        }
+
+        IntFunction<Object> objMapper = i -> new Integer(mapper.applyAsInt(i));
+        Object[] objArray1 = streamFor(parallelType, array).map(mapper).boxed().toArray();
+        Object[] objArray2 = streamFor(parallelType, array).mapToObj(objMapper).toArray();
+        assertEquals(objArray1, objArray2);
+    }
+
+    @Test(dataProvider="intArrays")
+    public void testMaxAndMin(String desc, int[] array) {
+        boolean[] maxOrMin = {true, false};
+        for(boolean testMax : maxOrMin) {
+            OptionalInt testOpt = testMax ? streamFor(parallelType, array).max()
+                    : streamFor(parallelType, array).min();
+            assertEquals(testOpt.getAsInt(), getMaxOrMin(array, testMax));
+            assertEquals(testOpt.getAsInt(), getMaxOrMinWithReduceOp(array, testMax));
+            assertEquals(testOpt.getAsInt(), getMaxOrMinWithReduceOpAndBase(array, testMax));
+
+            assertFalse(testMax ? streamFor(parallelType, EMPTY_ARRAY).max().isPresent()
+                    : streamFor(parallelType, EMPTY_ARRAY).min().isPresent());
+        }
+    }
+
+    @Test(dataProvider="intArrays")
+    public void testSpliterator(String desc, int[] array)  {
+        int[] calArrParallel = StreamSupport.intStream(streamFor(parallelType, array).spliterator(), true).toArray();
+        int[] calArrSequential = StreamSupport.intStream(streamFor(parallelType, array).spliterator(), false).toArray();
+        for(int index = 0; index < array.length; index++) {
+            assertEquals(array[index], calArrParallel[index]);
+            assertEquals(array[index], calArrSequential[index]);
+        }
+    }
+
+    @Test(dataProvider="intArrays")
+    public void testReduceWithBase(String desc, int[] array)  {
+        if(parallelType == ParallelType.Parallel)
+            return;
+        int base = rand.nextInt();
+        int oiPlus = streamFor(parallelType, array).reduce(base,
+                LambdaUtilities.addIntBinaryOperator());
+        int total = 0;
+        for(int index = 0; index < array.length; index++)
+            total += array[index];
+        assertEquals(oiPlus, total + base);
+
+        int oiSubtract = streamFor(parallelType, array).reduce(base,
+                LambdaUtilities.subIntBinaryOperator());
+        int subTotal = base;
+        for(int index = 0; index < array.length; index++)
+            subTotal -= array[index];
+        assertEquals(oiSubtract, subTotal);
+
+        int emptyByBase = streamFor(parallelType, EMPTY_ARRAY).reduce(base, rand.nextBoolean() ?
+                LambdaUtilities.addIntBinaryOperator() :
+                LambdaUtilities.subIntBinaryOperator());
+        assertEquals(emptyByBase, base);
+    }
+
+    @Test(dataProvider="intArrays")
+    public void testReduceWithoutBase(String desc, int[] array)  {
+        OptionalInt oiPlus = streamFor(parallelType, array).reduce(Integer::sum);
+        assertTrue(oiPlus.isPresent());
+        int total = 0;
+        for(int index = 0; index < array.length; index++)
+            total += array[index];
+        assertTrue(oiPlus.getAsInt() == total);
+
+        //Can't predict Parallel Substract reduce result, give up testing on
+        //parallel substract test
+        if(parallelType == ParallelType.Parallel)
+            return;
+
+        OptionalInt oiSubtract = streamFor(parallelType, array).
+                reduce(LambdaUtilities.subIntBinaryOperator());
+        assertTrue(oiSubtract.isPresent());
+        int subTotal = array[0];
+        for(int index = 1; index < array.length; index++)
+            subTotal -= array[index];
+        assertEquals(oiSubtract.getAsInt(), subTotal);
+
+        OptionalInt emptyOp = streamFor(parallelType, EMPTY_ARRAY).
+                reduce(rand.nextBoolean() ? LambdaUtilities.addIntBinaryOperator() :
+                LambdaUtilities.subIntBinaryOperator());
+        assertFalse(emptyOp.isPresent());
+    }
+
+    @Test(dataProvider="intArraysWithSkipLimit")
+    public void testSubstream(String desc, int[] array, int skip, int limit) {
+        assert(limit >= skip);
+        int[] toArray = streamFor(parallelType, array).skip(skip).limit(limit).toArray();
+        if(skip < array.length) {
+            if(limit < array.length) {
+                verifySlice(array, toArray, skip, limit);
+            } else {
+                verifySlice(array, toArray, skip, array.length);
+            }
+        }
+        else {
+            assertEquals(toArray.length, 0);
+        }
+        assertEquals(streamFor(parallelType, EMPTY_ARRAY).skip(skip).limit(limit).count(), 0);
+
+    }
+
+    @Test(dataProvider="intArrays")
+    public void testSorted(String desc, int[] array){
+        checkSorted(streamFor(parallelType, array).sorted().toArray(), Comparator.naturalOrder());
+        assertEquals(streamFor(parallelType, array).sorted().toArray(),
+                streamFor(parallelType, array, 0, array.length).sorted().toArray());
+        assertEquals(streamFor(parallelType, EMPTY_ARRAY).sorted().toArray().length, 0);
+    }
+
+    @Test(dataProvider="intArrays")
+    public void testPeek(String desc, int[] array){
+        AtomicInteger ai1 = new AtomicInteger(0);
+        IntStream stream = streamFor(parallelType, array).peek(LambdaUtilities.addIntConsumer(ai1));
+        //Lazy operation checking
+        assertEquals(ai1.get(), 0);
+        int sum = stream.sum();
+        assertEquals(ai1.get(), sum);
+
+        assertEquals(streamFor(parallelType,EMPTY_ARRAY).peek(LambdaUtilities.addIntConsumer(ai1)).count(), 0);
+    }
+
+    @Test(dataProvider="intArrays")
+    public void testToArray(String desc, int[] array){
+        assertEquals(streamFor(parallelType, array).toArray(), array);
+        assertEquals(streamFor(parallelType, array, 0, array.length).toArray(), array);
+        assertEquals(streamFor(parallelType, EMPTY_ARRAY).toArray().length, 0);
+    }
+
+    @Test(dataProvider="intArrays")
+    public void testDistrinct(String desc, int[] array){
+        int[] toArray = streamFor(parallelType, array).flatMap(genIntFlatMapper(Selection.COPY_64)).distinct().toArray();
+        assertEquals(toArray, array);
+
+        assertEquals(streamFor(parallelType, EMPTY_ARRAY).flatMap(genIntFlatMapper(Selection.COPY_64)).
+                distinct().toArray().length, 0);
+    }
+
+    private void verifyMultifunction(int[] orig, int[] result, Selection selection) {
+        switch(selection) {
+            case EMPTY:
+                assertEquals(result.length, 0);
+                break;
+            case SINGLE:
+                assertEquals(orig, result);
+                break;
+            case TRIANGLE:
+                int expectedSize = orig.length * (orig.length + 1) / 2;
+                int[] expected = IntStream.range(0, expectedSize).toArray();
+                assertEquals(result, expected);
+                break;
+            case COPY_64:
+                Stream<Integer> sToBeConcated = Stream.empty();
+                for(int current : orig) {
+                    sToBeConcated = Stream.concat(sToBeConcated,
+                            IntStream.generate(() -> current).
+                            limit(1 << 6).boxed());
+                }
+                assertEquals(sToBeConcated.toArray(), result);
+                break;
+            default:
+                throw new RuntimeException("Invalid selection " + selection);
+        }
+    }
+
+    private int getMaxOrMin(int[] array, boolean isMax) {
+        assert(array.length > 0);
+        int pos = 0;
+        int choosen = array[pos++];
+        while(pos < array.length) {
+            int current = array[pos++];
+            if((choosen < current) == isMax) choosen = current;
+        }
+        return choosen;
+    }
+
+    private int getMaxOrMinWithReduceOp(int[] array, boolean isMax) {
+        assert(array.length > 0);
+        OptionalInt choosen = Arrays.stream(array).reduce(isMax ?
+                LambdaUtilities.maxIntBinaryOperator() :
+                LambdaUtilities.minIntBinaryOperator());
+        return choosen.getAsInt();
+    }
+
+    private int getMaxOrMinWithReduceOpAndBase(int[] array, boolean isMax) {
+        assert(array.length > 0);
+        int choosen = Arrays.stream(array).reduce(array[0], isMax ?
+                LambdaUtilities.maxIntBinaryOperator() :
+                LambdaUtilities.minIntBinaryOperator());
+        return choosen;
+    }
+
+    private void verifySlice(int[] array, int[] toArray, int skip, int limit){
+        for(int index = skip; index < array.length && index < limit; index++)
+            assertTrue(array[index] <= toArray[index - skip]);
+    }
+
+    private void checkSorted(int[] array, Comparator<Integer> comp){
+        assert(array.length > 0);
+        for(int index = 0; index < array.length - 1; index++)
+            assertTrue(comp.compare(array[index] , array[index + 1]) <= 0);
+    }
+
+    private static IntFunction<IntStream> genIntFlatMapper(Selection selection) {
+        switch (selection) {
+            case EMPTY:
+                //Generate a empty collection
+                return e -> IntStream.empty();
+            case SINGLE:
+                return e -> Arrays.stream(new int[]{ e });
+            case TRIANGLE:
+                //Generate a triangle has different value
+                return e -> IntStream.range(0, e + 1).map(i -> e * (e + 1) / 2 + i);
+            case COPY_64:
+                //Generate 64 folded flat map
+                return e -> IntStream.range(0, 1 << 6).map(i -> e);
+            default:
+                throw new RuntimeException("Invalid selection " + selection);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/IntegerReduceTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.IntSummaryStatistics;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class IntegerReduceTest<V extends Collection<Integer>> extends
+            OperatorTest<Integer, V> {
+    public IntegerReduceTest(GenericStreamTest<Integer, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionFunctionData")
+    public void testCollectSummarizingInt(String desc, Collection<Integer> col,
+        Function<Integer, ? extends Object> mapFunc) {
+        //test summarizingInt
+        IntSummaryStatistics iss = streamFor(col).collect(
+                Collectors.<Integer>summarizingInt(Integer::intValue));
+        assertEquals(iss.getCount(), col.size());
+        assertEquals(iss.getMax(), streamFor(col).
+                max(test.getNaturalOrderComparator()).get().intValue());
+        assertEquals(iss.getMin(), streamFor(col).
+                min(test.getNaturalOrderComparator()).get().intValue());
+        assertEquals(iss.getSum(), streamFor(col).
+                mapToLong(Integer::longValue).sum());
+    }
+
+
+    @Test(dataProvider="collectionData")
+    public void testReduceIdentitiyWithoutBase(String desc, 
+            Collection<Integer> col) {
+        Optional<Integer> total = streamFor(col).reduce(
+                LambdaUtilities.addIntegerBinaryOperator());
+        double avg = (double) total.get().intValue() / col.size();
+        BigDecimal deviationSquare = streamFor(col).reduce(new BigDecimal(0.0),
+                LambdaUtilities.deviationSequareFunction(avg),  
+                LambdaUtilities.addBigDecimalBinaryOperator());
+        double stdev = deviationSquare.doubleValue() / col.size();
+
+        int totalExpected = 0;
+        for (Integer aCol : col)
+            totalExpected +=  aCol;
+        assertEquals(totalExpected, total.get().intValue());
+        double avgExpected = (double)totalExpected / col.size();
+        assertEquals(avgExpected, avg);
+
+        BigDecimal deviationSquareExpected = new BigDecimal(0.0);
+        for (Integer aCol : col)
+            deviationSquareExpected = deviationSquareExpected
+                    .add(new BigDecimal(avg - aCol).pow(2));
+        assertEquals(deviationSquare, deviationSquareExpected);
+
+        double stddvExpected 
+                = deviationSquareExpected.doubleValue() / col.size();
+        assertEquals(stddvExpected, stdev);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/IntegerStreamTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Basic test for Stream<Integer>
+ * @library /sqeutil
+ * @(#) IntegerStreamTest.java
+ * @author Tristan Yan
+ * @run testng IntegerStreamTest
+ */
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.IntSummaryStatistics;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.ToIntFunction;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Factory;
+import org.testng.annotations.Test;
+
+public class IntegerStreamTest<T extends Collection<Integer>> extends 
+        GenericStreamTest<Integer, Collection<Integer>> {
+    private static HashMap<Boolean, Map<Integer, Integer[]>> cache = new HashMap<>();
+    
+    static {
+        Function<Boolean, Function<Integer, Integer[]>> randomToArrays = random ->
+            random ? ( i -> rand.ints().limit(i).boxed().toArray(Integer[]::new)) : 
+            (i -> IntStream.rangeClosed(1, i).boxed().toArray(Integer[]::new));
+        initCache(cache, randomToArrays,  "IntegerStreamTest");
+    }
+    
+    @Factory
+    public static Object[] create(){
+        TripleFunction<Class,ParallelType,Integer, IntegerStreamTest> 
+            supplierWithInitSize = 
+            IntegerStreamTest<Collection<Integer>>::<Class,ParallelType,Integer>new;
+        BiFunction<Class,ParallelType, IntegerStreamTest> supplier =
+              IntegerStreamTest<Collection<Integer>>::<Class,ParallelType>new;
+        List tests = new ArrayList();
+        Arrays.stream(ParallelType.values()).forEach(parallelType -> {
+            Arrays.stream(defaultConstructorClazz).forEach( clazz -> 
+                tests.add(new IntegerReduceTest(supplier.apply(
+                    clazz, parallelType)))); 
+            Arrays.stream(capacityConstructorClazz).forEach( clazz ->
+                tests.add(new IntegerReduceTest(supplierWithInitSize.apply(
+                        clazz, parallelType,MEDIUM_DATA_SIZE))));
+            Arrays.stream(defaultComparableConstructorClazz).forEach(clazz -> { 
+                tests.add(new IntegerReduceTest(supplier.apply(clazz, 
+                        parallelType)));});
+            Arrays.stream(capacityComparableConstructorClazz).forEach(clazz -> { 
+                tests.add(new IntegerReduceTest(supplierWithInitSize.apply(clazz, 
+                        parallelType, MEDIUM_DATA_SIZE)));});
+        });
+        tests.addAll(Arrays.asList(GenericStreamTest.create(
+                supplierWithInitSize, supplier, true)));
+        return tests.toArray();
+    }
+
+    private IntegerStreamTest(Class clazz,
+            ParallelType parallelType, int initSize) {
+        super(clazz, parallelType, Comparator.naturalOrder(), initSize);
+    }
+
+   private IntegerStreamTest(Class clazz,
+            ParallelType parallelType) {
+        super(clazz, parallelType, Comparator.naturalOrder());
+    }
+
+    @Override
+    public String getTestName() {
+        return typeObject.getName() + "<Integer>";
+    }
+
+    @Override
+    protected Integer[] getArray(int size, boolean random){   
+        return cache.get(random).get(size);  
+    }
+
+    @Override
+    protected Object[] predicateAndDesc(int size){
+        boolean isUp = rand.nextBoolean();
+        int limit = rand.nextInt(size);
+        return new Object[]{ LambdaUtilities.randomIntegerPredicate(isUp, limit), 
+                String.format("i -> i %s %d", isUp ? ">=" : "<", limit)};
+    }
+
+    //BinaryOperator, descrption, stateless
+    @Override
+    protected Object[][] binaryOperatorAndDesc() {
+        return new Object[][]{
+            {(BinaryOperator<Integer>)Integer::sum, "Integer::sum", false},
+            {(BinaryOperator<Integer>)Integer::max, "Integer::max", true},
+            {(BinaryOperator<Integer>)Integer::min, "Integer::min", true},
+        }; 
+    }
+    
+    //Function<U, ? extends Comparable> and descrption for Function
+    @Override
+    protected Object[][] functionAndDesc(){
+        Function<Integer, String> toStr = String::valueOf;
+        return new Object[][]{
+            {(Function<Integer, Integer>)i -> i++, "i -> i++"},
+            {toStr, "String::valueOf"},
+        };
+    }
+    
+    @Override
+    protected Integer[] bases(int size){
+        return new Integer[]{-1, 0, 1, size /2, size - 1, size, size + 1};
+    }
+
+    @Override
+    protected Object[] validArrayGeneratorAndDesc() {
+        return new Object[]{
+            new IntFunction[]{
+                (IntFunction)Integer[]::new, 
+                (IntFunction)Number[]::new},
+            "{Integer[]::new, Number[]::new}"
+        };
+    }
+
+    @Override
+    protected Object[][] invalidArrayGeneratorAndDesc() {
+        return new Object[][]{
+            {(IntFunction)Double[]::new, "Double[]::new"},
+            {(IntFunction)String[]::new, "String[]::new"},
+        };
+    }
+
+    @Override
+    protected IntFunction<Integer> createFunction() {
+        return Integer::valueOf;
+    }
+
+    @Override
+    protected ToIntFunction<Integer> intValueFunction() {
+        return Integer::intValue;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/LimitTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class LimitTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public LimitTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionDataWithLimit")
+    public void testLimit(String desc, Collection<U> col, int withBoundryLimit, int beyondBoundryLimit) {
+        Collection<U> resultWithBoundary = streamFor(col).limit(withBoundryLimit)
+                .collect(Collectors.<U,List<U>>toCollection(LinkedList::new));
+        assertEquals(resultWithBoundary.size(), withBoundryLimit);
+
+        Collection<U> resultBeyondBoundary = streamFor(col).limit(beyondBoundryLimit)
+                .collect(Collectors.<U,List<U>>toCollection(LinkedList::new));
+        assertEquals(col.size(), resultBeyondBoundary.size());
+
+        assertEquals(streamFor(createEmptyCollection()).limit(withBoundryLimit).count(), 0);
+        assertEquals(streamFor(createEmptyCollection()).limit(beyondBoundryLimit).count(), 0);
+    }
+    
+    @Test(dataProvider="exceptionTestData",expectedExceptions = IllegalArgumentException.class)
+    public void testLimitException(String desc, Collection<U> col){
+        streamFor(col).limit(-1).toArray();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/MatchTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Collection;
+import java.util.function.Predicate;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+public class MatchTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public MatchTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionPredicateData")
+    public void testXxxMatch(String desc, Collection<U> col, Predicate<U> predicate) {
+        assertEquals(streamFor(col).allMatch(predicate),
+                verifyMatch(col, predicate, true));
+        assertEquals(streamFor(col).anyMatch(predicate),
+                verifyMatch(col, predicate, false));
+        assertEquals(streamFor(col).noneMatch(predicate),
+                verifyMatch(col, predicate.negate(), true)); 
+
+        assertTrue(streamFor(createEmptyCollection()).allMatch(predicate));
+        assertFalse(streamFor(createEmptyCollection()).anyMatch(predicate));
+        assertTrue(streamFor(createEmptyCollection()).noneMatch(predicate));
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/MaxAndMinTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+public class MaxAndMinTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public MaxAndMinTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    TripleFunction<Collection<U>,Comparator<U>,Boolean,U> maxMinFunctions[] = new TripleFunction[] {
+           (TripleFunction<Collection<U>,Comparator<U>,Boolean,U>) (
+            (col, c, isMax) -> {
+                assert(!col.isEmpty());
+                Iterator<U> it = col.iterator();
+                U choosen = it.next();
+                while(it.hasNext()) {
+                    U next = it.next();
+                    if (!(c.compare(choosen, next) < 0 ^ isMax)) choosen = next;
+                }
+                return choosen;
+             }),
+           (TripleFunction<Collection<U>,Comparator<U>,Boolean,U>) (
+            (col, c, isMax) -> {
+                assert(!col.isEmpty());
+                U choosen = isMax ? streamFor(col).collect(Collectors.<U>maxBy(c)).get() :
+                        streamFor(col).collect(Collectors.<U>minBy(c)).get();
+                return choosen;
+             }),
+           (TripleFunction<Collection<U>,Comparator<U>,Boolean,U>) (
+            (col, c, isMax) -> {
+                assert (!col.isEmpty());
+                Optional<U> choosen = col.stream().reduce(isMax ? 
+                        LambdaUtilities.maxGenericBinaryOperator(c) :
+                        LambdaUtilities.minGenericBinaryOperator(c) );
+                assert(choosen.isPresent());
+                return choosen.get();
+             }),
+           (TripleFunction<Collection<U>,Comparator<U>,Boolean,U>) (
+            (col, c, isMax) -> {
+                assert (!col.isEmpty());
+                U any = col.iterator().next();
+                U choosen = col.stream().reduce(any, 
+                        isMax ? LambdaUtilities.maxGenericFunction(c) : LambdaUtilities.minGenericFunction(c),
+                        isMax ? LambdaUtilities.maxGenericBinaryOperator(c) : LambdaUtilities.minGenericBinaryOperator(c));
+                return choosen;
+             }),
+           (TripleFunction<Collection<U>,Comparator<U>,Boolean,U>) (
+            (col, c, isMax) -> {
+                assert (!col.isEmpty());
+                U choosen = col.stream().collect(Collectors.<U>reducing(isMax ? 
+                        LambdaUtilities.maxGenericBinaryOperator(c) :
+                        LambdaUtilities.minGenericBinaryOperator(c))).get();
+                return choosen;
+             }),
+    };
+
+    @Test(dataProvider="collectionFunctionData")
+    public void testMaxAndMin(String desc, Collection<U> col, Function<U, ? extends Comparable> mapFunc) {
+        Comparator<U> comp = Comparator.comparing(mapFunc);
+        Arrays.asList(true, false).stream().peek((testMax) -> {
+            Optional<U> optional = testMax ? streamFor(col).max(comp) : streamFor(col).min(comp);
+            assertTrue(optional.isPresent());
+            for(BaseStreamTest.TripleFunction<Collection<U>,Comparator<U>,Boolean,U> func : maxMinFunctions) {
+                assertEquals(comp.compare(optional.get(), func.apply(col, comp, testMax)), 0);
+            }
+        }).forEach((testMax) -> {
+            if(testMax)
+                assertFalse(streamFor(createEmptyCollection()).max(comp).isPresent());
+            else
+                assertFalse(streamFor(createEmptyCollection()).min(comp).isPresent());
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/OperatorTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.DataProvider;
+
+public class OperatorTest<U, V extends Collection<U>> extends BaseStreamTest {
+    protected final GenericStreamTest<U, V> test;
+ 
+    public OperatorTest(GenericStreamTest<U, V> test) {
+        super(test.parallelType);
+        this.test = test;
+    }
+    
+    protected Stream<U> streamFor(Collection<U> c1) {
+        return (test.getParallelType() == BaseStreamTest.ParallelType.Parallel) ? 
+                c1.parallelStream(): (test.getParallelType() == BaseStreamTest.ParallelType.Sequential)
+                ? c1.parallelStream().sequential() : c1.stream();
+    }
+
+    @DataProvider
+    protected Iterator<Object[]> collectionArrayGeneratorData(){
+        return test.collectionArrayGeneratorData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionArrayInvalidGeneratorData(){
+        return test.collectionArrayInvalidGeneratorData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionBinaryOpeatorData(){
+        return test.collectionBinaryOpeatorData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionData() {
+        return test.collectionData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionDataWithLimit() {
+        return test.collectionDataWithLimit();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionDataWithSelection() {
+        return test.collectionDataWithSelection();
+    }
+    @DataProvider
+    public Iterator<Object[]> collectionDualPredicateData() {
+         return test.collectionDualPredicateData();
+     }
+    @DataProvider
+    protected Iterator<Object[]> collectionFunctionData(){
+        return test.collectionFunctionData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionKeyValueFunctionData(){
+        return test.collectionKeyValueFunctionData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionPredicateData() {
+        return test.collectionPredicateData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> collectionStartEndData() {
+        return test.collectionStartEndData();
+    }
+    @DataProvider
+    protected Iterator<Object[]> concatCollectionData(){
+        return test.concatCollectionData();
+    }
+    @DataProvider
+    protected Iterator<Object[]>  exceptionTestData() {
+        return test.exceptionTestData();
+    }
+        
+    protected static <T> void assertEqualContents(Collection<T> result1,
+            Collection<T> result2, Comparator<T> comparator) {
+        assertEquals(result1.size(), result2.size());
+        ArrayList<T> a = new ArrayList<>(result1);
+        ArrayList<T> b = new ArrayList<>(result2);
+        Collections.sort(a, comparator);
+        Collections.sort(b, comparator);
+
+        for(int i = 0; i < result1.size(); i++)
+            assertEquals(comparator.compare(a.get(i), b.get(i)), 0);
+    }
+
+    public Collection<U> createEmptyCollection(){
+        return test.createEmptyCollection();
+    }
+
+    protected void verifySlice(Collection<U> col, Collection<U> subL, int skip, int limit, boolean ordered) {
+        int toIndex = skip + limit < col.size() ? skip + limit : col.size();
+        if (ordered) {
+            assertEquals(new ArrayList(col).subList(skip, toIndex), subL);
+        } else {
+            // Unordered: verify that all items from the slice are
+            // present in the original collection
+            assertTrue(col.containsAll(subL));
+            assertEquals(subL.size(), toIndex - skip); 
+        }
+    }
+   
+    protected void verifyFlatMap(Collection<U> orig, Collection<U> result, Function<U, Stream<U>> mapper) {
+        Collection<U> expected = orig.stream().map(mapper::apply).reduce(Stream::concat).
+                get().collect(Collectors.<U>toList());
+        assertEqualContents(result, expected, test.getNaturalOrderComparator());
+    }
+
+    protected boolean verifyMatch(Collection<U> col, Predicate<U> predicate, boolean checkAll) {
+        for(U current : col) {
+            if (checkAll ^ predicate.test(current) )
+                    return !checkAll;
+        }
+        return checkAll;
+    }
+
+    protected void verifyAfterMap(Collection<U> origCol, Object[] result, Function<U, ? extends Object> mapFunc) {
+        int index = 0;
+        assertEquals(origCol.size(), result.length);
+        for(U element : origCol) 
+            assertEquals(mapFunc.apply(element), result[index++]);
+    }
+    static enum GenericOperatorType{
+        CONCATENATE{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return ConcatTest::new;
+            }
+        },
+        COLLECT{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return CollectTest::new;
+            }
+        },
+        COUNT{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return CountTest::new;
+            }
+        },
+        DISTINCT{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return DistinctTest::new;
+            }
+        },
+        FILTER {
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return FilterTest::new;
+            }
+        },
+        FIND{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return FindTest::new;
+            }
+        },
+        FOREACH{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return ForEachTest::new;
+            }
+        },
+        FLATMAP{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return FlatMapTest::new;
+            }
+        },
+        LIMIT{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return LimitTest::new;
+            }
+        },
+        MAX_MIN{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return MaxAndMinTest::new;
+            }
+        },
+        MATCH{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return MatchTest::new;
+            }
+        },
+        PEEK{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return PeekTest::new;
+            }
+        },
+        REDUCE{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return ReduceTest::new;
+            }
+        },
+        SORTED{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return SortedTest::new;
+            }
+        },
+        SUBSTREAM{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return SubstreamTest::new;
+            }
+        },
+        TOARRAY{
+            @Override
+            Function<GenericStreamTest, ? extends OperatorTest> getConstructor() {
+                return ToArrayTest::new;
+            }
+        };
+
+        abstract Function<GenericStreamTest, ? extends OperatorTest> getConstructor();
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/PeekTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+
+public class PeekTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public PeekTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionFunctionData")
+    public void testPeek(String desc, Collection<U> col, Function<U, ? extends Object> mapFunc) {
+        //Note ArrayList is not a concurrent data type, if we don't set initial
+        //size, we could get AIOOBE
+        List<U> peekList = new ArrayList<>(col.size());
+        Stream<U> peekedStream = streamFor(col).peek(peekList::add);
+        //Lasiness check for peek
+        assertTrue(peekList.isEmpty());
+        Object[] result = peekedStream.map(mapFunc).toArray();
+        verifyAfterMap(col, result, mapFunc);
+        
+        List<U> emptyList = new ArrayList<>();
+        assertEquals(streamFor(createEmptyCollection()).peek(emptyList::add).count(), 0);
+        assertTrue(emptyList.isEmpty());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/ReduceTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.function.BinaryOperator;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+public class ReduceTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public ReduceTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionBinaryOpeatorData")
+    public void testReduce(String desc, Collection<U> col, U base, 
+            BinaryOperator<U> op, boolean stateless)  {
+        Optional<U> reduceResult = streamFor(col).reduce( op);
+        assertTrue(reduceResult.isPresent());
+        Iterator<U> iter = col.iterator();
+        U expected = iter.next();
+        while(iter.hasNext())
+            expected = op.apply(expected, iter.next());
+        assertEquals(reduceResult.get(), expected);
+
+        assertEquals(streamFor(createEmptyCollection()).reduce(base,op), base);
+        assertFalse(streamFor(createEmptyCollection()).reduce(op).isPresent());
+
+        if(stateless || !streamFor(col).isParallel()) {
+            U reduceWithBaseResult = streamFor(col).reduce(base, op);
+            U expectedWithBase = base;
+            for(U aCol : col)
+                expectedWithBase = op.apply(expectedWithBase, aCol);
+            assertEquals(reduceWithBaseResult, expectedWithBase);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/SortedTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class SortedTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public SortedTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionFunctionData")
+    public void testSorted(String desc, Collection<U> col, 
+            Function<U, ? extends Comparable> mapFunc) {
+        //SortedSet instance's stream can't be reordered, we use ArrayList to do
+        //reorder
+        Comparator<U> comp = Comparator.comparing(mapFunc);
+        List<U> sorted = new ArrayList<>(col);
+        List<U> reversed = streamFor(col).sorted(comp).collect(Collectors.<U>toList());
+        Collections.sort(sorted, comp);
+        assertEquals(sorted, reversed);
+
+        assertEquals(streamFor(createEmptyCollection()).sorted(comp).count(), 0);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/SortedTestForCompable.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class SortedTestForCompable<U, V extends Collection<U>> 
+        extends OperatorTest<U, V>{
+    public SortedTestForCompable(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    //Note non-Comparable U need override this method
+    @Test(dataProvider="collectionData")
+    public void testSortedSpecial(String desc, Collection<U> col) {
+        // SortedSet instance's stream can't be reordered, we use ArrayList to do reorder
+        List<U> sorted = new ArrayList<>(col);
+        List<U> reversed = streamFor(col).sorted().collect(Collectors.<U>toList());
+        Collections.sort(sorted, test.getNaturalOrderComparator());
+        assertEquals(sorted, reversed);
+
+        assertEquals(streamFor(createEmptyCollection()).sorted().count(), 0);
+    } 
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/SortedTestForNonCompable.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Collection;
+import org.testng.annotations.Test;
+
+public class SortedTestForNonCompable<U, V extends Collection<U>> 
+        extends OperatorTest<U, V>{
+    public SortedTestForNonCompable(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    //StringBuilder is not Comparable
+    //Not single element stream won't throw ClassCastException
+    @Test(dataProvider="exceptionTestData", expectedExceptions = ClassCastException.class)
+    public void testSortedSpecial(String desc, Collection<U> col) {
+        streamFor(col).sorted().findFirst();
+        System.out.println(col.size());
+    }  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/StringBuilderSpecialTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Collection;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class StringBuilderSpecialTest<V extends Collection<StringBuilder>> 
+    extends OperatorTest<StringBuilder, V> {
+    public StringBuilderSpecialTest(GenericStreamTest<StringBuilder, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionFunctionData")
+    public void testCollectJoining(String desc, Collection<StringBuilder> col, 
+            Function<StringBuilder, ? extends Object> mapFunc) {
+        //test joining
+        String joined = streamFor(col).collect(Collectors.joining());
+        int pos = 0;
+        for(StringBuilder sb : col) {
+            String toString = sb.toString();
+            assertEquals(joined.substring(pos, pos + toString.length()), toString);
+            pos += toString.length();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/StringBuilderStreamTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Basic test for Stream<StringBuilder>
+ * @library /sqeutil
+ * @(#) StringBuilderStreamTest.java
+ * @author Eric Wang/Tristan Yan
+ * @run testng/othervm -mx2g StringBuilderStreamTest
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.Predicate;
+import java.util.function.ToIntFunction;
+import java.util.stream.IntStream;
+import org.testng.annotations.Factory;
+
+public class StringBuilderStreamTest<T extends Collection<StringBuilder>> extends
+            GenericStreamTest<StringBuilder, Collection<StringBuilder>> {
+    private final static HashMap<Boolean, Map<Integer, StringBuilder[]>> cache 
+            = new HashMap<>();
+    
+    private final static int MAX_STRING_LEN = 1 << 3;
+
+    static {
+        Function<String, StringBuilder> strToBuilder = StringBuilder::new;
+        BiFunction<Integer, Integer, String> lensToString 
+                = StringUtilities::randomString;
+        BiFunction<Integer, Integer, StringBuilder> lensToBuilder 
+                = lensToString.andThen(strToBuilder);
+        Function<Integer, StringBuilder> randomLenToBuilder = len ->
+             lensToBuilder.apply(MAX_STRING_LEN  + 1, 1);
+        Function<Integer, String> valueToString = String::valueOf;
+        Function<Integer, StringBuilder> valueToStringBuilder 
+                = valueToString.andThen(strToBuilder);
+        BiFunction<Boolean, Integer,StringBuilder> randomnessLenToStringBuilder 
+            = (random, len) -> {   
+                if(random) 
+                    return randomLenToBuilder.apply(len); 
+                else 
+                    return valueToStringBuilder.apply(len); 
+            };
+        Function<Boolean, Function<Integer, StringBuilder[]>> 
+                randomToBuildersFunction = random -> 
+                (size -> IntStream.rangeClosed(1, size).mapToObj(len -> 
+                        randomnessLenToStringBuilder.apply(random, len)).
+                        toArray(StringBuilder[]::new));
+        initCache(cache, randomToBuildersFunction,  "StringBuilderStreamTest");
+    }
+
+    public StringBuilderStreamTest(Class clazz, 
+            ParallelType parallelType, int initSize) {
+        super(clazz, parallelType, Comparator.comparing((Function<StringBuilder,
+                String>)StringBuilder::toString), initSize);
+    }
+
+    public StringBuilderStreamTest(Class clazz, 
+            ParallelType parallelType) {
+        super(clazz, parallelType, Comparator.comparing((Function<StringBuilder,
+                String>)StringBuilder::toString));
+    }
+
+    @Factory
+    public static Object[] create(){
+        TripleFunction<Class,ParallelType,Integer,StringBuilderStreamTest> 
+            supplierWithInitSize =
+            StringBuilderStreamTest<Collection<StringBuilder>>::<Class,ParallelType,Integer>new;
+        BiFunction<Class,ParallelType,StringBuilderStreamTest> supplier =
+            StringBuilderStreamTest<Collection<StringBuilder>>::<Class,ParallelType>new;
+        List tests = new ArrayList();
+        Arrays.stream(ParallelType.values()).forEach(parallelType -> {
+            Arrays.stream(defaultConstructorClazz).forEach( clazz -> 
+                tests.add(new StringBuilderSpecialTest(supplier.apply(
+                    clazz, parallelType)))); 
+            Arrays.stream(capacityConstructorClazz).forEach( clazz ->
+                tests.add(new StringBuilderSpecialTest(supplierWithInitSize.apply(
+                        clazz, parallelType,MEDIUM_DATA_SIZE))));
+        });
+        tests.addAll(Arrays.asList(GenericStreamTest.create(
+                supplierWithInitSize, supplier, false)));
+      return tests.toArray();
+    }
+
+    @Override
+    public String getTestName() {
+        return typeObject.getName() + "<StringBuilder>";
+    }
+  
+    @Override
+    protected Object[] predicateAndDesc(int size){
+        LambdaUtilities.CharType charType = Arrays.stream(LambdaUtilities.CharType.values()).findAny().get();
+        Boolean isFirst = rand.nextBoolean();
+       Predicate<StringBuilder> p = (Predicate<StringBuilder>)
+               LambdaUtilities.randomSBPredicate(charType, isFirst);
+       String funcName;
+        switch (charType) {
+            case DIGIT: funcName = "isDigit"; break;
+            case LOWERCASE: funcName = "isLowerCase"; break;
+            case UPPERCASE: funcName = "isUpperCase"; break;
+            default: funcName = "isLetterOrDigit"; break;
+        }
+        return new Object[]{ p , String.format("sb -> Character.%s(%s)", 
+            funcName, isFirst ? "0" : "sb.toString().length() - 1")};         
+    }
+
+    //BinaryOperator, descrption, stateless
+    @Override
+    protected Object[][] binaryOperatorAndDesc() {
+        return new Object[][]{
+//            {(BinaryOperator<StringBuilder>)StringBuilder::append, "StringBuilder::append", false},
+            {LambdaUtilities.maxGenericBinaryOperator(getNaturalOrderComparator()), 
+                "(t1, t2) -> t1 < t2 ? t2 : t1", true},
+            {LambdaUtilities.minGenericBinaryOperator(getNaturalOrderComparator()), 
+                " (t1, t2) -> t1 < t2 ? t1 : t2", true},
+        }; 
+    }
+
+    //Function<U, ? extends Comparable>, descrption for Function
+    @Override
+    protected Object[][] functionAndDesc(){
+        return new Object[][]{
+            {(Function<StringBuilder, String>)StringBuilder::toString, 
+                "StringBuilder::toString"},
+        };
+    }
+   
+    @Override
+    protected StringBuilder[] getArray(int size, boolean random){   
+        return cache.get(random).get(size);  
+    }
+    
+    @Override
+    protected StringBuilder[] bases(int size){
+        return new StringBuilder[]{new StringBuilder(), 
+            new StringBuilder(rand.nextInt(size)), new StringBuilder(size)};
+    }
+
+    //StringBuilder[] can be converted into StringBuilder[]::new,
+    //CharSequence[]::new, Object[]::new
+    @Override
+    protected Object[] validArrayGeneratorAndDesc() {
+        return new Object[]{
+            new IntFunction[]{
+                (IntFunction)StringBuilder[]::new, 
+                (IntFunction)CharSequence[]::new, 
+                (IntFunction)Object[]::new
+            },
+            "{StringBuilder[]::new, CharSequence[]::new}, Object[]::new}"
+        };
+    }
+
+    //StringBuilder[] can't be converted into StringBuffer[]::new,Integer[]::new
+    @Override
+    protected Object[][] invalidArrayGeneratorAndDesc() {
+        return new Object[][]{
+            {(IntFunction)StringBuffer[]::new, "StringBuffer[]::new"},
+            {(IntFunction)Integer[]::new, "Integer[]::new"},
+        };
+    }
+
+    @Override
+    protected IntFunction<StringBuilder> createFunction() {
+        return  i -> new StringBuilder().append(i);
+    }
+
+    @Override
+    protected ToIntFunction<StringBuilder> intValueFunction() {
+        return sb -> Integer.parseInt(sb.toString()) ;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/SubstreamTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.function.BiFunction;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class SubstreamTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public SubstreamTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionData")
+    public void testSubstream(String desc, Collection<U> col) {
+        BiFunction<Integer,Integer,Integer> bf = LambdaUtilities.randBetweenIntegerFunction();
+        int skip = new Random().nextInt(col.size());
+        int limit1 = bf.apply(0, col.size() - skip);
+        Collection<U> sliceCol = streamFor(col).skip(skip).limit(limit1).
+                collect(Collectors.<U>toList());
+        verifySlice(col, sliceCol, skip, limit1, !col.getClass().equals(HashSet.class));
+
+        int limitExceeded = bf.apply(col.size() - skip, Integer.MAX_VALUE);
+        Collection<U> sliceCol2 = streamFor(col).skip(skip).limit(limitExceeded).
+                collect(Collectors.<U>toList());
+        //We couldn't predicate unordered collection like HashSet behavior for substream, for unordered collection we
+        // only check the length and if data exists in original collection
+        verifySlice(col, sliceCol2, skip, limitExceeded, !col.getClass().equals(HashSet.class));
+
+        assertEquals(streamFor(col).skip(skip).limit(0).count(), 0);
+
+        //skip exceed collection size cause empty stream
+        Stream<U> stream3 = streamFor(col);
+        int skipExceeded = bf.apply(col.size(), Integer.MAX_VALUE);
+        assertEquals(stream3.skip(skipExceeded).limit(1).count(), 0);
+
+        assertEquals(streamFor(createEmptyCollection()).skip(skip).limit(limit1).count(), 0);
+    }
+
+    @Test(dataProvider="collectionStartEndData",expectedExceptions = IllegalArgumentException.class)
+    public void  testSubstreamException(String desc, Collection<U> col, long startInclusive, long endExclusive){
+        streamFor(col).skip(startInclusive).count();
+        streamFor(col).skip(startInclusive).limit(endExclusive-startInclusive).count();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Stream/ToArrayTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.function.IntFunction;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+public class ToArrayTest<U, V extends Collection<U>> extends OperatorTest<U, V>{
+    public ToArrayTest(GenericStreamTest<U, V> test) {
+        super(test);
+    }
+
+    @Test(dataProvider="collectionArrayGeneratorData", threadPoolSize = 3)
+    public void testToArray(String desc, Collection<U> col, IntFunction[] generators) {
+        Object[] expectedArr = col.toArray();
+        assertEquals(streamFor(col).toArray(), expectedArr);
+        assertEquals(streamFor(createEmptyCollection()).toArray().length, 0);
+        
+         Arrays.stream(generators).forEach(generator -> {
+             assertEquals(streamFor(col).toArray(generator), expectedArr);
+             assertEquals(streamFor(createEmptyCollection()).toArray(generator).length, 0);
+         });
+    }
+    
+    @Test(dataProvider="collectionArrayInvalidGeneratorData",expectedExceptions = ArrayStoreException.class)
+    public void testToArrayException(String desc, Collection<U> col, IntFunction generator){
+        streamFor(col).toArray(generator);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/Streams/BasicTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Basic test for Streams's API
+ * @library /sqeutil
+ * @(#) BasicTest.java
+ * @author Tristan Yan
+ * @run testng BasicTest
+ */
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.PrimitiveIterator;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.IntConsumer;
+import java.util.function.IntUnaryOperator;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+import java.util.Spliterators;
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+public class BasicTest {
+    private final static int ARRAY_SIZE = 1 << 12;
+
+    private final static Random rand = new Random(8675309);
+
+    private final static String HELLO_WORLD = "Hello world";
+
+    @Test
+    public void testEmpty() {
+        final AtomicInteger accumulator = new AtomicInteger(0);
+        IntConsumer ic = i -> {
+            accumulator.getAndIncrement();
+        };
+        Spliterators.emptyIntSpliterator().forEachRemaining(ic);
+        assertEquals(accumulator.get(), 0);
+
+        assertEquals(IntStream.empty().toArray().length, 0);
+
+        assertEquals(Stream.empty().toArray().length, 0);
+
+        assertEquals(Spliterators.emptyIntSpliterator().estimateSize(), 0);
+
+        assertEquals(Spliterators.<String>emptySpliterator().estimateSize(), 0);
+    }
+
+    @Test
+    public void testGenerate() {
+        final int randomValue = rand.nextInt();
+        final int randomSize= rand.nextInt(1 << 8);
+        IntStream is = IntStream.generate(() -> randomValue);
+        assertEquals(is.spliterator().getExactSizeIfKnown(), -1);
+
+        IntStream is1 = IntStream.generate(() -> randomValue);
+        IntStream is2 = IntStream.generate(() -> randomValue);
+        assertEquals(is1.limit(randomSize).max(), is2.limit(randomSize).min());
+
+        Stream<String> ss = Stream.generate(() -> HELLO_WORLD);
+        assertEquals(ss.spliterator().getExactSizeIfKnown(), -1);
+        Stream<String> ss1 = Stream.generate(() -> HELLO_WORLD);
+        Stream<String> ss2 = Stream.generate(() -> HELLO_WORLD);
+        assertEquals(ss1.limit(randomSize).findAny(), ss2.limit(randomSize).findAny());
+
+        LambdaUtilities.IntOp op = LambdaUtilities.IntOp.values()[rand.nextInt(LambdaUtilities.IntOp.values().length)];
+        final int randomInit = rand.nextInt();
+        final int randomOpnd = rand.nextInt();
+        IntUnaryOperator iuo = LambdaUtilities.opIntUnaryOperator(op, randomOpnd);
+        IntStream isi = IntStream.iterate(randomInit, iuo);
+        int limitation = rand.nextInt( 1 << 10 );
+        PrimitiveIterator.OfInt pi = isi.limit(limitation).iterator();
+
+        int next = randomInit;
+
+        while(pi.hasNext()) {
+            assertEquals(pi.nextInt(), next);
+            next = iuo.applyAsInt(next);
+        }
+
+        //below is time-consuming, need watch out if it's gonna affect our test
+        int start = rand.nextInt(1 << 12);
+        int end = rand.nextInt(1 << 12);
+
+        if(start > end) {
+            start = start ^ end;
+            end = end ^ start;
+            start = end ^ start;
+        }
+        PrimitiveIterator.OfInt it1 = IntStream.range(start, end).iterator();
+        while(it1.hasNext())
+            assertEquals(it1.nextInt(), start++);
+        assertEquals(start, end);
+    }
+
+    @Test
+    public void testIterator() {
+        int seed = rand.nextInt();
+        int opRnd = rand.nextInt();
+        int selected = rand.nextInt(LambdaUtilities.IntOp.values().length);
+        LambdaUtilities.IntOp op = LambdaUtilities.IntOp.values()[selected];
+        int limitRnd = rand.nextInt(1 << 20);
+        IntUnaryOperator iuo = LambdaUtilities.opIntUnaryOperator(op, opRnd);
+        int[] arr = IntStream.iterate(seed, iuo).limit(limitRnd).toArray();
+        assertEquals(arr.length, limitRnd);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/GenBadMHTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.tests.java.lang.invoke;
+
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Handle;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandleInfo;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+import static jdk.internal.org.objectweb.asm.Opcodes.PUTFIELD;
+import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * Regression test to ensure that the VM does not report invokevirtual method handles as invokespecial
+ */
+@Test(groups = { "serialization-hostile" })
+public class GenBadMHTest {
+    public void testMHForStringToUpper() throws IOException, ReflectiveOperationException {
+        MethodHandle mh = mhFor(Opcodes.H_INVOKEVIRTUAL, "java/lang/String", "toUpperCase", "()Ljava/lang/String;");
+        MethodHandleInfo mhi = MethodHandles.lookup().revealDirect(mh);
+        assertTrue(mhi.getReferenceKind() == MethodHandleInfo.REF_invokeVirtual);
+    }
+
+    public void testMHForAtomicLong() throws IOException, ReflectiveOperationException {
+        MethodHandle mh = mhFor(Opcodes.H_INVOKEVIRTUAL, "java/util/concurrent/atomic/AtomicLong", "addAndGet", "(J)J");
+        MethodHandleInfo mhi = MethodHandles.lookup().revealDirect(mh);
+        assertTrue(mhi.getReferenceKind() == MethodHandleInfo.REF_invokeVirtual);
+    }
+
+    private MethodHandle mhFor(int kind, String host, String method, String sig) throws IOException, ReflectiveOperationException {
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
+        cw.visit(51, ACC_SUPER + ACC_PUBLIC, "Foo", null, "java/lang/Object", new String[0]);
+
+        // Constructor
+        MethodVisitor ctor = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+        ctor.visitCode();
+        ctor.visitVarInsn(ALOAD, 0);
+        ctor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+        ctor.visitInsn(RETURN);
+        ctor.visitMaxs(-1, -1);
+        ctor.visitEnd();
+
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "foo", "()Ljava/lang/Object;", null, null);
+        mv.visitLdcInsn(new Handle(kind, host, method, sig));
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(-1, -1);
+        mv.visitEnd();
+
+        cw.visitEnd();
+
+        byte[] bytes = cw.toByteArray();
+        File f = new File("Foo.class");
+        try (FileOutputStream fos = new FileOutputStream(f)) {
+            fos.write(bytes);
+        }
+
+        List<URL> list = new ArrayList<>();
+        list.add(new URL("file:" + f.getCanonicalFile().getParent().replace("\\", "/") + "/"));
+        Class<?> clazz = Class.forName("Foo", true, new URLClassLoader(list.toArray(new URL[list.size()])));
+        Method m = clazz.getMethod("foo");
+        return (MethodHandle) m.invoke(clazz.newInstance());
+    }
+
+    public void testPrivateInnerCtorRef() {
+        Supplier<Object> ctor = new Enclosing().foo();
+        Enclosing.Inner inner = (Enclosing.Inner) ctor.get();
+        assertNotNull(inner);
+    }
+
+    static class Enclosing {
+
+        public Supplier<Object> foo() {
+            return Inner::new;
+        }
+
+        private class Inner {
+            private Inner() {}
+        }
+    }
+}
--- a/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/java/util/stream/test/org/openjdk/tests/java/lang/invoke/SerializedLambdaTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,14 +56,18 @@
  */
 @Test
 public class SerializedLambdaTest {
+    public static final int REPS = 50;
+
     @SuppressWarnings("unchecked")
     private<T> void assertSerial(T p, Consumer<T> asserter) throws IOException, ClassNotFoundException {
         asserter.accept(p);
 
-        byte[] bytes = serialize(p);
-        assertTrue(bytes.length > 0);
+        for (int i=0; i<REPS; i++) {
+            byte[] bytes = serialize(p);
+            assertTrue(bytes.length > 0);
 
-        asserter.accept((T) deserialize(bytes));
+            asserter.accept((T) deserialize(bytes));
+        }
     }
 
     private void assertNotSerial(Predicate<String> p, Consumer<Predicate<String>> asserter)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/lambda/InvokespecialMethodKindTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleInfo;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.function.Function;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * InvokespecialMethodKindTest
+ */
+@Test
+public class InvokespecialMethodKindTest {
+    public void testStringToUpper() throws ReflectiveOperationException {
+        MethodHandle mh = MethodHandles.lookup().findVirtual(String.class, "toUpperCase",
+                                                             MethodType.methodType(String.class));
+        MethodHandleInfo mhi = MethodHandles.lookup().revealDirect(mh);
+        assertEquals(mhi.getReferenceKind(), MethodHandleInfo.REF_invokeVirtual);
+    }
+
+    public void testSerializeStringToUpper() throws IOException, ClassNotFoundException {
+        Function<String, String> f = (Function<String, String> & Serializable) String::toUpperCase;
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(bos);
+        oos.writeObject(f);
+        oos.flush();
+        byte[] bs = bos.toByteArray();
+        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bs));
+        @SuppressWarnings("unchecked")
+        Function<String, String> ff = (Function<String, String>) ois.readObject();
+        assertEquals("FOO", ff.apply("fOo"));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/lambda/TestInterfaceBridges.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * TestInterfaceBridges
+ *
+ * @author Brian Goetz
+ */
+@Test
+public class TestInterfaceBridges {
+    public void testCovariantOverrideLambda() {
+        B b = () -> "Foo";
+        assertEquals("Foo", b.make());
+        assertEquals("Foo", ((A) b).make());
+    }
+
+    public void testCovariantOverrideIC() {
+        B b = new B() {
+            @Override
+            public String make() {
+                return "Foo";
+            }
+        };
+        assertEquals("Foo", b.make());
+        assertEquals("Foo", ((A) b).make());
+    }
+
+    public static interface A {
+        Object make();
+    }
+
+    public static interface B extends A {
+        String make();
+    }
+
+    public void testCovariantMerge() {
+        D d = () -> "Foo";
+        assertEquals("Foo", d.make());
+        assertEquals("Foo", ((A) d).make());
+        assertEquals("Foo", ((C) d).make());
+    }
+
+    public static interface C {
+        String make();
+    }
+
+    public static interface D extends A, C { }
+
+    public void testGenericSpecialization() {
+        F<String, String> fss = x->x;
+        assertEquals("Foo", fss.m("Foo"));
+    }
+
+    interface F<A,B> {
+        B m(A a);
+    }
+
+    public void testGenericFboundSpecialization() {
+        G<String> gs = x->x;
+        assertEquals("Foo", gs.m("Foo"));
+    }
+
+    interface G<X extends Comparable<X>> {
+       X m(X x);
+    }
+
+    public void testGenericSpecializationInSubclass() {
+        F_S_S fss = (s)->s;
+        assertEquals("Foo", fss.m("Foo"));
+        assertEquals("Foo", ((F<String,String>)fss).m("Foo"));
+    }
+
+    interface F_S_S extends F<String,String> {}
+
+    public void testCovariantMultiMerge() {
+        M1234 m1234 = ()->1;
+        assertEquals(1, (int)m1234.m());
+        assertEquals(1, (int)((M1)m1234).m());
+        assertEquals(1, (int)((M2)m1234).m());
+        assertEquals(1, (int)((M3)m1234).m());
+        assertEquals(1, (int)((M4)m1234).m());
+    }
+
+    interface M1 {Number m();}
+    interface M2 {Integer m();}
+    interface M3 {java.io.Serializable m();}
+    interface M4 {Object m();}
+
+    interface M1234 extends M1, M2, M3, M4 {}
+
+    public void testDefaultMerge() {
+        DD12<String> dds = s->1;
+        assertEquals(1, ((DD1<String>)dds).m(""));
+        assertEquals(1, ((DD2)dds).m(""));
+    }
+
+    interface DD1<T> { int m(T arg); }
+    interface DD2 { default int m(String arg) { return 42; } }
+    interface DD12<T> extends DD1<T>, DD2 {}
+
+    public void testDefaultNoMerge() {
+        DD12<Integer> dds = s->1;
+        assertEquals(1, ((DD1<Integer>)dds).m(1));
+        assertEquals(42, ((DD2)dds).m(""));
+    }
+
+    public void testRawMerge() {
+        List<String> ls = null;
+        R12 r12 = l->"Foo";
+        assertEquals("Foo", r12.m(ls));
+        assertEquals("Foo", ((R1)r12).m(ls));
+        assertEquals("Foo", ((R2)r12).m(ls));
+    }
+
+    interface R1 {
+        Object m(List<String> ls);
+    }
+
+    @SuppressWarnings("rawtypes")
+    interface R2 {
+        String m(List l);
+    }
+
+    interface R12 extends R1, R2 {}
+}
+
--- a/test/jdk/lambda/separate/Compiler.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/jdk/lambda/separate/Compiler.java	Mon Nov 11 23:17:30 2013 -0800
@@ -49,12 +49,12 @@
         USECACHE // Keeps results around for reuse.  Only use this is
                  // you're sure that each compilation name maps to the
                  // same source code
-    };
+    }
 
     private static final AtomicInteger counter = new AtomicInteger();
     private static final String targetDir =
         System.getProperty("lambda.separate.targetDirectory",
-            System.getProperty("java.io.tmpdir") + File.separator + "gen-separate");
+            "tmp" + File.separator + "gen-separate");
     private static final File root = new File(targetDir);
     private static ConcurrentHashMap<String,File> cache =
             new ConcurrentHashMap<>();
@@ -90,7 +90,7 @@
     }
 
     public void setFlags(Flags ... flags) {
-        this.flags = new HashSet<Flags>(Arrays.asList(flags));
+        this.flags = new HashSet<>(Arrays.asList(flags));
     }
 
     public void addPostprocessor(ClassFilePreprocessor cfp) {
@@ -136,17 +136,10 @@
         outputDirs.put(type.getName(), outDir);
 
         Class superClass = type.getSuperclass();
-        if (superClass != null) {
-            for( Map.Entry<String,File> each : compileHierarchy(superClass).entrySet()) {
-                outputDirs.put(each.getKey(), each.getValue());
-            }
-        }
-        for (Extends ext : type.getSupertypes()) {
-            Type iface = ext.getType();
-            for( Map.Entry<String,File> each : compileHierarchy(iface).entrySet()) {
-                outputDirs.put(each.getKey(), each.getValue());
-            }
-        }
+        if (superClass != null)
+            outputDirs.putAll(compileHierarchy(superClass));
+        for (Extends ext : type.getSupertypes())
+            outputDirs.putAll(compileHierarchy(ext.getType()));
 
         return outputDirs;
     }
@@ -161,8 +154,12 @@
         List<JavaFileObject> files = new ArrayList<>();
         SourceProcessor accum = (name, src) -> files.add(new SourceFile(name, src));
 
-        for (Type dep : type.typeDependencies()) {
-            dep.generateAsDependency(accum, type.methodDependencies());
+        Collection<Type> deps = type.typeDependencies(type.isFullCompilation());
+        for (Type dep : deps) {
+            if (type.isFullCompilation())
+                dep.generate(accum);
+            else
+                dep.generateAsDependency(accum, type.methodDependencies());
         }
 
         type.generate(accum);
@@ -189,7 +186,7 @@
                 StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir));
         } catch (IOException e) {
             throw new RuntimeException(
-                "IOException encountered during compilation");
+                "IOException encountered during compilation", e);
         }
         Boolean result = ct.call();
         if (result == Boolean.FALSE) {
--- a/test/jdk/lambda/separate/SourceModel.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/jdk/lambda/separate/SourceModel.java	Mon Nov 11 23:17:30 2013 -0800
@@ -46,7 +46,7 @@
             generate(pw);
             return sw.toString();
         }
-    };
+    }
 
     public static class AccessFlag extends Element {
         private String flag;
@@ -123,6 +123,7 @@
         // (and thus will be present in stubs)
         private Set<Method> methodDependencies;
         private List<Type> typeDependencies;
+        private boolean fullCompilation;
 
         protected Type(String name,
                 List<AccessFlag> flags, List<TypeParameter> params,
@@ -212,6 +213,14 @@
             methodDependencies.add(m);
         }
 
+        public boolean isFullCompilation() {
+            return fullCompilation;
+        }
+
+        public void setFullCompilation(boolean fullCompilation) {
+            this.fullCompilation = fullCompilation;
+        }
+
         // Convenience method for creating an Extends object using this
         // class and specified type arguments.
         public Extends with(String ... args) {
@@ -261,14 +270,23 @@
             pw.println("}");
         }
 
-        public Collection<Type> typeDependencies() {
+        public Collection<Type> typeDependencies(boolean recursive) {
             HashMap<String,Type> dependencies = new HashMap<>();
             Type superclass = getSuperclass();
             if (superclass != null) {
                 dependencies.put(superclass.getName(), superclass);
+                if (recursive) {
+                    for (Type t : superclass.typeDependencies(true))
+                        dependencies.put(t.getName(), t);
+                }
             }
-            for (Extends e : getSupertypes())
+            for (Extends e : getSupertypes()) {
                 dependencies.put(e.getType().getName(), e.getType());
+                if (recursive) {
+                    for (Type t : e.getType().typeDependencies(true))
+                        dependencies.put(t.getName(), t);
+                }
+            }
             // Do these last so that they override
             for (Type t : this.typeDependencies)
                 dependencies.put(t.getName(), t);
--- a/test/jdk/lambda/separate/TestHarness.java	Thu Oct 31 16:44:18 2013 -0700
+++ b/test/jdk/lambda/separate/TestHarness.java	Mon Nov 11 23:17:30 2013 -0800
@@ -197,7 +197,7 @@
                 assertEquals(res, value);
             }
         } catch (InvocationTargetException | IllegalAccessException e) {
-            fail("Unexpected exception thrown: " + e.getCause());
+            fail("Unexpected exception thrown: " + e.getCause(), e.getCause());
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/lambda/vm/FDSeparateCompilationTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package vm;
+
+import java.util.ArrayList;
+import java.util.Set;
+
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import separate.TestHarness;
+import separate.Compiler;
+import shapegen.ClassCase;
+import shapegen.Hierarchy;
+import shapegen.HierarchyGenerator;
+
+import static org.testng.Assert.fail;
+import static separate.SourceModel.AbstractMethod;
+import static separate.SourceModel.AccessFlag;
+import static separate.SourceModel.Class;
+import static separate.SourceModel.ConcreteMethod;
+import static separate.SourceModel.DefaultMethod;
+import static separate.SourceModel.Interface;
+import static separate.SourceModel.Method;
+import static separate.SourceModel.Type;
+
+public class FDSeparateCompilationTest extends TestHarness {
+
+    private static String EMPTY = "\"\"";
+
+    public FDSeparateCompilationTest() {
+        super(false, true);
+    }
+
+    @DataProvider(name = "allShapes", parallel = true)
+    public Object[][] hierarchyGenerator() {
+        ArrayList<Object[]> allCases = new ArrayList<>();
+
+        HierarchyGenerator hg = new HierarchyGenerator();
+        hg.getOK().stream().map(x->new Object[]{x}).forEach(allCases::add);
+        hg.getErr().stream().map(x -> new Object[] { x }).forEach(allCases::add);
+        return allCases.toArray(new Object[0][]);
+    }
+
+    // The expected value obtained when invoking the method from the specified 
+    // class.  If returns null, then an AbstractMethodError is expected.
+    private static String getExpectedResult(ClassCase cc) {
+        Set<ClassCase> provs = cc.get_mprov();
+        if (cc.get_mres() != null) {
+            return cc.get_mres().getName();
+        } else if (provs != null && provs.size() == 1) {
+            ClassCase cand = provs.iterator().next();
+            switch (cand.kind) {
+                case CCONCRETE:
+                case IDEFAULT:
+                    return cand.getName();
+                case CNONE:
+                case IVAC:
+                    return getExpectedResult(cand);
+            }
+        } 
+        return null;
+    }
+
+    private static final ConcreteMethod canonicalMethod = new ConcreteMethod(
+            "String", "m", "returns " + EMPTY + ";", AccessFlag.PUBLIC);
+
+    @Test(groups = "vm", dataProvider = "allShapes")
+    public void separateCompilationTest(Hierarchy hs) {
+        ClassCase cc = hs.root;
+        Type type = sourceTypeFrom(hs.root);
+
+        Class specimen = null;
+        if (type instanceof Class) {
+            Class ctype = (Class)type;
+            if (ctype.isAbstract()) {
+                specimen = new Class("Test" + ctype.getName(), ctype);
+            } else {
+                specimen = ctype;
+            }
+        } else {
+            specimen = new Class("Test" + type.getName(), (Interface)type);
+        }
+
+        String value = getExpectedResult(cc);
+        if (value != null) {
+            assertInvokeVirtualEquals(value, specimen, canonicalMethod, EMPTY);
+        } else {
+            assertThrows(AbstractMethodError.class, specimen, 
+                canonicalMethod, EMPTY);
+        }
+    }
+
+    @AfterMethod 
+    public void printCaseError(ITestResult result) {
+        if (result.getStatus() == ITestResult.FAILURE) {
+            Hierarchy hs = (Hierarchy)result.getParameters()[0];
+            System.out.println("Separate compilation case " + hs);
+            printCaseDetails(hs);
+        }
+    }
+
+    @AfterSuite
+    public void cleanupCompilerCache() {
+        Compiler.purgeCache();
+    }
+
+    private void printCaseDetails(Hierarchy hs) {
+        String exp = getExpectedResult(hs.root);
+        hs.getDescription().forEach(
+                x -> System.out.println("    " + x));
+        if (exp != null) { 
+            System.out.println("    Expected \"" + exp + "\"");
+        } else {
+            System.out.println("    Expected AbstractMethodError");
+        }
+    }
+
+    private Type sourceTypeFrom(ClassCase cc) {
+        Type type = null;
+
+        if (cc.isInterface()) {
+            Interface iface = new Interface(cc.getName());
+            for (ClassCase scc : cc.getInterfaces()) {
+                Interface supertype = (Interface)sourceTypeFrom(scc);
+                iface.addSuperType(supertype);
+            }
+            type = iface;
+        } else {
+            Class cls = new Class(cc.getName());
+            if (cc.hasSuperclass()) {
+                Class superc = (Class)sourceTypeFrom(cc.getSuperclass());
+                cls.setSuperClass(superc);
+            }
+            for (ClassCase scc : cc.getInterfaces()) {
+                Interface supertype = (Interface)sourceTypeFrom(scc);
+                cls.addSuperType(supertype);
+            }
+            if (cc.isAbstract()) { 
+                cls.getAccessFlags().add(AccessFlag.ABSTRACT);  
+            }
+            type = cls;
+        }
+        Method method = methodFrom(cc);
+        if (method != null) {
+            type.addMethod(method);
+        }
+        return type;
+    }
+
+    private Method methodFrom(ClassCase cc) {
+        switch (cc.kind) {
+            case IVAC: 
+            case CNONE: return null; 
+            case IPRESENT: 
+            case CABSTRACT:
+                return new AbstractMethod("String", "m", AccessFlag.PUBLIC); 
+            case IDEFAULT:
+                return new DefaultMethod(
+                    "String", "m", "return \"" + cc.getName() + "\";");
+            case CCONCRETE:
+                return new ConcreteMethod(
+                    "String", "m", "return \"" + cc.getName() + "\";", 
+                    AccessFlag.PUBLIC);
+            default:
+                fail("Unknown method type in class");
+                return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/lambda/vm/JVMBridgingTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package vm;
+
+import org.testng.annotations.Test;
+import separate.Compiler;
+import separate.TestHarness;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+import static separate.SourceModel.AbstractMethod;
+import static separate.SourceModel.AccessFlag;
+import static separate.SourceModel.Class;
+import static separate.SourceModel.ConcreteMethod;
+import static separate.SourceModel.Interface;
+import static separate.SourceModel.MethodParameter;
+import static separate.SourceModel.Type;
+import static separate.SourceModel.TypeParameter;
+
+public class JVMBridgingTest extends TestHarness {
+    public JVMBridgingTest() {
+        super(false, false);
+    }
+
+    private static final String STATIC_CLASS = "S";
+    private static final String STATIC_METHOD_NAME = "foo";
+    private static final int SUCCESS_VALUE = 99;
+
+    private boolean equalsSuccessValue(Type[] compUnits) {
+        Compiler compiler = new Compiler();
+        ClassLoader cl = compiler.compile(compUnits);
+
+        try {
+            java.lang.Class<?> S_class = 
+                java.lang.Class.forName(STATIC_CLASS, true, cl);
+            assertNotNull(S_class); 
+            java.lang.reflect.Method m = S_class.getMethod(STATIC_METHOD_NAME);
+            assertNotNull(m); 
+            Integer res = (Integer)m.invoke(null);
+            return res.intValue() == SUCCESS_VALUE;
+        } catch (ClassNotFoundException e) {
+            fail("Could not find class");
+        } catch (NoSuchMethodException e) {
+            fail("Could not find method");
+        } catch (IllegalAccessException e) {
+            fail("Unexpected IllegalAccessException");
+        } catch (java.lang.reflect.InvocationTargetException e) {
+            return false; /* A valid situation: the method may not exist */
+        } finally {
+            compiler.cleanup();
+        }
+        fail("Unexpected result");
+        return false; // unreachable
+    }
+
+    @Test(groups = "vm")
+    public void testTraditionalBridge() {
+        Interface I = new Interface("I", new TypeParameter("T"),
+            new AbstractMethod("int", "m", new MethodParameter("T", "t")));
+        Class C = new Class("C", I.with("String"), new ConcreteMethod(
+            "int", "m", "return " + SUCCESS_VALUE + ";", AccessFlag.PUBLIC,
+            new MethodParameter("String", "s")));
+        ConcreteMethod mStub = new ConcreteMethod(
+            "int", "m", "return 0;", AccessFlag.PUBLIC,
+            new MethodParameter("Object", "o"));
+        Class Cstub = new Class("C", mStub);
+        Class S = new Class(STATIC_CLASS, new ConcreteMethod(
+            "int", STATIC_METHOD_NAME, "return (new C()).m(\"\");",
+            AccessFlag.PUBLIC, AccessFlag.STATIC));
+        S.addCompilationDependency(Cstub);
+        S.addCompilationDependency(mStub);
+
+        Type[] compUnits = new Type[] {S, C, I};
+        assertFalse(equalsSuccessValue(compUnits));
+        for (Type t : compUnits)
+            t.setFullCompilation(true);
+        assertTrue(equalsSuccessValue(compUnits));
+    }
+
+    @Test(groups = "vm")
+    public void testCovarReturn() {
+        ConcreteMethod numberRet = new ConcreteMethod(
+            "Number", "m", "return 0;", AccessFlag.PUBLIC);
+        Class C = new Class("C", numberRet);
+        Class D = new Class("D", C, new ConcreteMethod("Integer", "m",
+            "return " + SUCCESS_VALUE + ";", AccessFlag.PUBLIC));
+
+        Class Dstub = new Class("D", numberRet);
+        Class S = new Class(STATIC_CLASS,
+            new ConcreteMethod("Integer", STATIC_METHOD_NAME,
+                "return (Integer)(new D()).m();",
+                AccessFlag.PUBLIC, AccessFlag.STATIC));
+        S.addCompilationDependency(Dstub);
+        S.addCompilationDependency(numberRet);
+
+        Type[] compUnits = new Type[] {S, D, C};
+        assertFalse(equalsSuccessValue(compUnits));
+        for (Type t : compUnits)
+            t.setFullCompilation(true);
+        assertTrue(equalsSuccessValue(compUnits));
+    }
+
+    @Test(groups = "vm")
+    public void testNoBridgeNeeded() {
+        Interface I = new Interface("I", new TypeParameter("T"), 
+            new AbstractMethod("int", "m", new MethodParameter("T", "t")));
+
+        ConcreteMethod implementing = new ConcreteMethod("int", "m", 
+            "return 0;", AccessFlag.PUBLIC, new MethodParameter("String", "s"));
+        ConcreteMethod matching = new ConcreteMethod("int", "m", "return 99;", 
+            AccessFlag.PUBLIC, new MethodParameter("Object", "o"));
+
+        Class C = new Class("C", I.with("String"), implementing, matching);
+
+        Class S = new Class(STATIC_CLASS, new ConcreteMethod(
+            "int", STATIC_METHOD_NAME, "return (new C()).m(new Object());",
+            AccessFlag.PUBLIC, AccessFlag.STATIC));
+        S.addCompilationDependency(C);
+        S.addCompilationDependency(matching);
+        
+        Type[] compUnits = new Type[] { S, C, I };
+        assertTrue(equalsSuccessValue(compUnits));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sqeutil/LambdaUtilities.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,674 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @summary This class provide basic support for lambda syntax
+ * @(#) LambdaUtilities.java
+ * @author Tristan Yan
+ */
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.math.BigDecimal;
+import java.nio.file.Path;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.*;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+public class LambdaUtilities {
+
+    public static enum CharType {
+        DIGIT, LOWERCASE, UPPERCASE, SPECIAL
+    }
+
+    public static enum StringPredicateType {
+        START_WTIH, NOT_START_WITH, MORE_THAN_LEN, LESS_THAN_LEN
+    }
+
+    public static enum IntOp {
+        ADD, SUBTRACT, MULTIPLY, DIVIDE, MOD
+    }
+
+    public static IntPredicate randomIntPredicate(boolean isUP, int limit) {
+        if (isUP) {
+            return i -> i >= limit;
+        } else {
+            return i -> i < limit;
+        }
+    }
+
+    public static Predicate<Integer> randomIntegerPredicate(boolean isUP, int limit) {
+        if (isUP) {
+            return i -> i >= limit;
+        } else {
+            return i -> i < limit;
+        }
+    }
+
+    public static LongPredicate randomLongPredicate(boolean isUP, long limit) {
+        if (isUP) {
+            return i -> i >= limit;
+        } else {
+            return i -> i < limit;
+        }
+    }
+
+    public static Predicate<Path> startPathPredicate(Path start) {
+        return p -> p.startsWith(start);
+    }
+
+    public static <T> Predicate<T> randomGenericPredicate(boolean isUp, T value, Comparator<T> c) {
+        if (isUp) {
+            return emp -> c.compare(emp, value) >= 0;
+        }else {
+            return emp -> c.compare(emp, value) < 0;
+        }
+    }
+
+    public static Predicate<StringBuilder> randomSBPredicate(StringPredicateType type, String value) {
+        switch (type) {
+            case START_WTIH:
+                return sb -> Character.isDigit(sb.charAt(0));
+            case NOT_START_WITH:
+                return sb -> Character.isLowerCase(sb.charAt(0));
+            case MORE_THAN_LEN:
+                return sb -> Character.isUpperCase(sb.charAt(0));
+            default:
+                return sb -> !Character.isLetterOrDigit(sb.charAt(0));
+        }
+    }
+
+    public static Predicate<? extends CharSequence> randomSBPredicate(CharType startType,
+            boolean first) {
+        switch (startType) {
+            case DIGIT:
+                return sb -> Character.isDigit(sb.charAt(first ? 0 : sb.toString().length() - 1));
+            case LOWERCASE:
+                return sb -> Character.isLowerCase(sb.charAt(first ? 0 : sb.toString().length() - 1));
+            case UPPERCASE:
+                return sb -> Character.isUpperCase(sb.charAt(first ? 0 : sb.toString().length() - 1));
+            default:
+                return sb -> !Character.isLetterOrDigit(sb.charAt(first ? 0 : sb.toString().length() - 1));
+        }
+    }
+
+    public static Predicate<Character> isDigitCharacterPredicate() {
+        return c -> Character.isDigit(c);
+    }
+
+    public static Function<Integer, Integer> posIntegerFunction(boolean isHighest) {
+        if (isHighest) {
+            return i -> Integer.valueOf(new StringBuilder().append(i < 0 ? -i : i).reverse().toString()) % 10;
+        } else {
+            return i -> i % 10 < 0 ? -i % 10 : i % 10;
+        }
+    }
+
+    public static Function<StringBuilder, CharType> sbGenericFunction(boolean isFirst) {
+        if (isFirst)
+            return i -> Character.isAlphabetic(i.charAt(0)) ? (Character.isUpperCase(i.charAt(0)) ? CharType.UPPERCASE : CharType.LOWERCASE) : (Character.isDigit(i.charAt(0)) ? CharType.DIGIT : CharType.SPECIAL);
+            else
+            return i -> Character.isAlphabetic(i.charAt(i.length() - 1)) ? (Character.isUpperCase(i.charAt(i.length() - 1)) ? CharType.UPPERCASE : CharType.LOWERCASE) : (Character.isDigit(i.charAt(i.length() - 1)) ? CharType.DIGIT : CharType.SPECIAL);
+    }
+
+    public static Function<String, Integer> mappingFunction(Map<String, Integer> m, IntOp op, int value) {
+        switch (op) {
+            case ADD:
+                return k -> (value != 0) ? m.get(k) + value : m.get(k);
+            case SUBTRACT:
+                return k -> (value != 0) ? m.get(k) - value : m.get(k);
+            case MULTIPLY:
+                return k -> (value != 0) ? m.get(k) * value : m.get(k);
+            case DIVIDE:
+                return k -> (value != 0) ? m.get(k) / value : m.get(k);
+            default:
+                return k -> (value != 0) ? m.get(k) % value : m.get(k);
+        }
+    }
+
+    public static IntFunction<Integer> posIntFunction(boolean isHighest) {
+        if (isHighest) {
+            return i -> Integer.valueOf(new StringBuilder().append(i < 0 ? -i : i).reverse().toString()) % 10;
+        } else {
+            return i -> i % 10 < 0 ? -i % 10 : i % 10;
+        }
+    }
+
+    public static BiFunction<Integer, Integer, Integer> randBetweenIntegerFunction() {
+        return (t1, t2) -> randBetween(t1, t2);
+    }
+
+    public static int randBetween(int low, int up) {
+        assert (low < up && low >= 0);
+        Random rand = new Random();
+        int i = rand.nextInt(up);
+        while (i < low) {
+            i = rand.nextInt();
+        }
+        return i;
+    }
+
+    public static ToIntFunction<Integer> highestPosValueIntFunction() {
+        return i -> Integer.valueOf(new StringBuilder().append(i < 0 ? -i : i).reverse().toString()) % 10;
+    }
+
+    public static ToIntFunction<Integer> lowestPosValueIntFunction() {
+        return i -> i % 10 < 0 ? -i % 10 : i % 10;
+    }
+
+    public static <T> Consumer<T> reverseConsumer(Set<T> set) {
+        return t -> {
+            set.add(t);
+        };
+    }
+
+    public static Consumer<Integer> addIntegerConsumer(AtomicInteger ai) {
+        return t -> {
+            ai.updateAndGet(t1 -> t1 + t);
+        };
+    }
+
+    public static Consumer<StringBuilder> appendSBConsumer(StringBuilder sb) {
+        return t -> {
+            sb.append(t);
+        };
+    }
+
+    public static IntConsumer addIntConsumer(AtomicInteger ai) {
+        return t -> {
+            ai.updateAndGet(t1 -> t1 + t);
+        };
+    }
+
+    public static IntConsumer addLongConsumer(AtomicLong ai) {
+        return t -> {
+            ai.updateAndGet(t1 -> t1 + t);
+        };
+    }
+
+    public static <T> Consumer<T> copyConsumer(List<T> list) {
+        return t -> {
+            list.add(t);
+        };
+    }
+
+    public static <T> Consumer<T> existsConsumer(Collection<T> in, Collection<T> out) {
+        return t -> {
+            if (in.contains(t)) {
+                out.add(t);
+            }
+        };
+    }
+
+    public static Supplier<StringBuilder> sbSupplier(StringBuilder value) {
+        return () -> value;
+    }
+
+    public static Supplier<Integer> integerSupplier(int value) {
+        return () -> value;
+    }
+
+    public static <T> Supplier<T> genericSuppiler(T value) {
+        return () -> value;
+    }
+
+    public static IntSupplier intSupplier(int value) {
+        return () -> value;
+    }
+
+    public static Supplier<Long> longSupplier(long value) {
+        return () -> value;
+    }
+
+    public static Supplier<AtomicInteger> atomicIntegerSupplier(int value) {
+        return () -> new AtomicInteger(value);
+    }
+
+    public static <T> Supplier<AtomicReference<T>> atomicGenericSupplier(T value) {
+        return () -> new AtomicReference<>(value);
+    }
+
+    public static Supplier<AtomicReference<StringBuilder>> atomicSBSupplier(StringBuilder value) {
+        return () -> new AtomicReference<>(value);
+    }
+
+    public static UnaryOperator<Integer> opIntegerUnaryOperator(IntOp op, int value) {
+        switch (op) {
+            case ADD:
+                return t -> t + value;
+            case SUBTRACT:
+                return t -> t - value;
+            case MULTIPLY:
+                return t -> t * value;
+            case DIVIDE:
+                return t -> t / value;
+            default:
+                return t -> t % value;
+        }
+    }
+
+    public static IntUnaryOperator opIntUnaryOperator(IntOp op, int value) {
+        if(value == 0)
+            return t -> t;
+        switch (op) {
+            case ADD:
+                return t -> t + value;
+            case SUBTRACT:
+                return t -> t - value;
+            case MULTIPLY:
+                return t -> t * value;
+            case DIVIDE:
+                return t -> t / value;
+            default:
+                return t -> t % value;
+        }
+    }
+
+    public static Function<Integer, Integer> opIntegerFunction(IntOp op, int value) {
+        if(value == 0)
+            return t -> t;
+        switch (op) {
+            case ADD:
+                return t -> Integer.valueOf(t + value);
+            case SUBTRACT:
+                return t -> Integer.valueOf(t - value);
+            case MULTIPLY:
+                return t -> Integer.valueOf(t * value);
+            case DIVIDE:
+                return t -> Integer.valueOf(t / value);
+            default:
+                return t -> Integer.valueOf(t % value);
+        }
+    }
+
+    public static ToIntFunction<Integer> opToIntFunction(IntOp op, int value) {
+        if(value == 0)
+            return t -> t.intValue();
+        switch (op) {
+            case ADD:
+                return t -> t.intValue() + value;
+            case SUBTRACT:
+                return t -> t.intValue() - value;
+            case MULTIPLY:
+                return t -> t.intValue() * value;
+            case DIVIDE:
+                return t -> t.intValue() / value;
+            default:
+                return t -> t.intValue() % value;
+        }
+    }
+
+    public static IntFunction<Integer> opIntFunction(IntOp op, int value) {
+        if(value == 0)
+            return t -> t;
+        switch (op) {
+            case ADD:
+                return t -> t + value;
+            case SUBTRACT:
+                return t -> t - value;
+            case MULTIPLY:
+                return t -> t * value;
+            case DIVIDE:
+                return t -> t / value;
+            default:
+                return t -> t % value;
+        }
+    }
+
+    public static IntUnaryOperator addIntUnaryOperator(int value) {
+        return t -> t + value;
+    }
+
+    public static IntUnaryOperator subIntUnaryOperator(int value) {
+        return t -> t - value;
+    }
+
+    public static IntUnaryOperator mulIntUnaryOperator(int value) {
+        return t -> t * value;
+    }
+
+    public static IntUnaryOperator divIntUnaryOperator(int value) {
+        return t -> t / value;
+    }
+
+    public static IntBinaryOperator minIntBinaryOperator() {
+        return (t1, t2) -> t1< t2 ? t1 : t2;
+    }
+
+    public static BinaryOperator<Integer> minIntegerBinaryOperator(Comparator<Integer> c) {
+        return (t1, t2) -> c.compare(t1, t2) < 0 ? t1 : t2;
+    }
+
+    public static <T>BinaryOperator<T> minGenericBinaryOperator(Comparator<T> c) {
+        return (t1, t2) -> c.compare(t1, t2) < 0 ? t1 : t2;
+    }
+
+    public static BinaryOperator<StringBuilder> minSBBinaryOperator(Comparator<StringBuilder>  c) {
+        return ( t1, t2 ) -> c.compare(t1, t2) < 0 ? t1 : t2;
+    }
+
+    public static IntBinaryOperator maxIntBinaryOperator() {
+        return ( t1, t2 ) -> (t1< t2) ? t2: t1;
+    }
+
+    public static BinaryOperator<Integer> maxIntegerBinaryOperator(Comparator<Integer>  c) {
+        return (t1, t2) -> c.compare(t1, t2) < 0 ? t2 : t1;
+    }
+
+    public static <T> BinaryOperator<T> maxGenericBinaryOperator(Comparator<T>  c) {
+        return (t1, t2) -> c.compare(t1, t2) < 0 ? t2 : t1;
+    }
+
+    public static IntBinaryOperator maxIntBinaryOperator(Comparator<Integer>  c) {
+        return ( t1, t2 ) -> c.compare(t1, t2) < 0 ? t2 : t1;
+    }
+
+    public static BinaryOperator<StringBuilder> maxSBBinaryOperator(Comparator<StringBuilder>  c) {
+        return ( t1, t2 ) -> c.compare(t1, t2) < 0 ? t2 : t1;
+    }
+
+    public static BinaryOperator<Integer> addIntegerBinaryOperator() {
+        return ( t1 , t2 ) -> t1 + t2;
+    }
+
+    public static IntBinaryOperator addIntBinaryOperator() {
+        return ( t1 , t2 ) -> t1 + t2;
+    }
+
+    public static BinaryOperator<BigDecimal> addBigDecimalBinaryOperator() {
+        return ( t1 , t2 ) -> t1.add(t2);
+    }
+
+    public static DoubleBinaryOperator addDoubleBinaryOperator() {
+        return ( t1 , t2 ) -> t1 + t2;
+    }
+
+    public static BinaryOperator<StringBuilder> appendSBBinaryOperator() {
+        return (t1 , t2) -> new StringBuilder().append(t1).append(t2);
+    }
+
+    public static BinaryOperator<Integer> subIntegerBinaryOperator() {
+        return (t1, t2) -> t1 - t2;
+    }
+
+    public static IntBinaryOperator subIntBinaryOperator() {
+        return (t1, t2) -> t1 - t2;
+    }
+
+    public static BinaryOperator<StringBuilder> deleteSBBinaryOperator() {
+        return (t1, t2) -> {if (t1.length() >= t2.length()) {
+                                int i1 = t1.indexOf(t2.toString());
+                                int i2 = i1 + t2.length();
+                                return new StringBuilder(t1).delete(i1, i2);
+                            }else {
+                                int i1 = t2.indexOf(t1.toString());
+                                int i2 = i1 + t1.length();
+                                return new StringBuilder(t2).delete(i1, i2);
+                            }
+        };
+
+    }
+
+    public static IntBinaryOperator mulIntBinaryOperator() {
+        return (t1, t2) -> t1 * t2;
+    }
+
+    public static IntBinaryOperator divIntBinaryOperator() {
+        return (t1, t2) -> t1 / t2;
+    }
+
+    public static LongUnaryOperator addLongUnaryOperator(long value) {
+        return t -> t + value;
+    }
+
+    public static UnaryOperator<StringBuilder> appendSBUnaryOperator(StringBuilder value) {
+        return t -> t.append(value);
+    }
+
+    public static LongUnaryOperator subLongUnaryOperator(long value) {
+        return t -> t - value;
+    }
+
+    public static LongUnaryOperator mulLongUnaryOperator(long value) {
+        return t -> t * value;
+    }
+
+    public static LongUnaryOperator divLongUnaryOperator(long value) {
+        return t -> t / value;
+    }
+
+    public static LongBinaryOperator addLongBinaryOperator() {
+        return (t1, t2) -> t1 + t2;
+    }
+
+    public static LongBinaryOperator subLongBinaryOperator() {
+        return (t1, t2) -> t1 - t2;
+    }
+
+    public static LongBinaryOperator mulLongBinaryOperator() {
+        return (t1, t2) -> t1 * t2;
+    }
+
+    public static LongBinaryOperator divLongBinaryOperator() {
+        return (t1, t2) -> t1 / t2;
+    }
+
+    public static BiConsumer<AtomicInteger, Integer> addIntegerBiConsumer() {
+        return (t1 , t2 ) -> {  t1.addAndGet(t2); };
+    }
+
+    public static BiConsumer<AtomicInteger, AtomicInteger> addAtomicIntegerBiConsumer() {
+        return (t1 , t2) -> {  t1.addAndGet(t2.get()); };
+    }
+
+    public static BiConsumer<AtomicReference<StringBuilder>, StringBuilder> appendSBBiConsumer() {
+        return (t1, t2) -> {t1.updateAndGet(appendSBUnaryOperator(t2));};
+    }
+
+    public static BiConsumer<AtomicReference<StringBuilder>, AtomicReference<StringBuilder>> appendAtomicSBBiConsumer() {
+        return (t1, t2) -> {t1.updateAndGet(appendSBUnaryOperator(t2.get()));};
+    }
+
+    public static BiConsumer<AtomicInteger, Integer> maxIntegerBiConsumer(Comparator<Integer> c) {
+        return (t1 , t2 ) -> {  t1.getAndUpdate(t -> max(t, t2, c)); };
+    }
+
+    public static <T> BiConsumer<AtomicReference<T>, T> maxGenericBiConsumer(Comparator<T> c) {
+        return (t1 , t2 ) -> {  t1.getAndUpdate(t -> max(t, t2, c)); };
+    }
+
+    public static BiConsumer<AtomicInteger, AtomicInteger> maxAtomicIntegerBiConsumer(Comparator<Integer> c) {
+        return (t1 , t2) -> {  t1.getAndUpdate(t -> max(t, t2.get(), c)); };
+    }
+
+    public static <T> BiConsumer<AtomicReference<T>, AtomicReference<T>> maxAtomicGenericBiConsumer(Comparator<T> c) {
+        return (t1 , t2) -> {  t1.getAndUpdate(t -> max(t, t2.get(), c)); };
+    }
+
+    public static BiConsumer<AtomicInteger, Integer> minIntegerBiConsumer(Comparator<Integer> c) {
+        return (t1 , t2) -> {  t1.getAndUpdate(t -> min(t, t2, c)); };
+    }
+
+    public static <T> BiConsumer<AtomicReference<T>, T> minGenericBiConsumer(Comparator<T> c) {
+        return (t1 , t2) -> {  t1.getAndUpdate(t -> min(t, t2, c)); };
+    }
+
+    public static BiConsumer<AtomicInteger, AtomicInteger> minAtomicIntegerBiConsumer(Comparator<Integer> c) {
+        return (t1, t2) -> {  t1.getAndUpdate(t -> min(t, t2.get(), c)); };
+    }
+
+    public static <T> BiConsumer<AtomicReference<T>, AtomicReference<T>> minAtomicGenericBiConsumer(Comparator<T> c) {
+        return (t1, t2) -> {  t1.getAndUpdate(t -> min(t, t2.get(), c)); };
+    }
+
+    public static BiFunction<Integer, Integer, Integer> maxIntegerFunction(Comparator<Integer> c) {
+        return (t1, t2) -> max(t1, t2, c);
+    }
+
+    public static BiFunction<BigDecimal, Integer, BigDecimal> deviationSequareFunction(double avg) {
+        return (bd, t) -> bd.add(new BigDecimal(avg - t).pow(2));
+    }
+
+    public static <T> BiFunction<T, T, T> maxGenericFunction(Comparator<T> c) {
+        return (t1, t2) -> max(t1, t2, c);
+    }
+
+    public static BiFunction<StringBuilder, StringBuilder, StringBuilder> maxStringBuilderFunction(Comparator<StringBuilder> c) {
+        return (t1, t2) -> max(t1, t2, c);
+    }
+
+    public static BiFunction<Integer, Integer, Integer> minIntegerFunction(Comparator<Integer> c) {
+        return (t1, t2) -> min(t1, t2, c);
+    }
+
+    public static <T> BiFunction<T, T, T> minGenericFunction(Comparator<T> c) {
+        return (t1, t2) -> min(t1, t2, c);
+    }
+
+    public static BiFunction<StringBuilder, StringBuilder, StringBuilder> minStringBuilderFunction(Comparator<StringBuilder> c) {
+        return (t1, t2) -> min(t1, t2, c);
+    }
+
+    public static BiFunction<String, Integer, Integer> opBiFunction(IntOp op, int value) {
+        switch (op) {
+            case ADD:
+                return (k, v) -> (value != 0) ? v + value : v;
+            case SUBTRACT:
+                return (k, v) -> (value != 0) ? v - value : v;
+            case MULTIPLY:
+                return (k, v) -> (value != 0) ? v * value : v;
+            case DIVIDE:
+                return (k, v) -> (value != 0) ? v / value : v;
+            default:
+                return (k, v) -> (value != 0) ? v % value : v;
+        }
+    }
+
+
+    public static BiFunction<Integer, Integer, Integer> opBiFunction(IntOp op) {
+        switch (op) {
+            case ADD:
+                return (oldv, v) -> (v != 0) ? oldv + v : oldv;
+            case SUBTRACT:
+                return (oldv, v) -> (v != 0) ? oldv - v : oldv;
+            case MULTIPLY:
+                return (oldv, v) -> (v != 0) ? oldv * v : oldv;
+            case DIVIDE:
+                return (oldv, v) -> (v != 0) ? oldv / v : oldv;
+            default:
+                return (oldv, v) -> (v != 0) ? oldv % v : oldv;
+        }
+    }
+
+    private static Integer min(Integer i1, Integer i2, Comparator<Integer> c) {
+        return c.compare(i1, i2) < 0 ? i1 : i2;
+    }
+
+    private static <T> T min(T i1, T i2, Comparator<T> c) {
+        return c.compare(i1, i2) < 0 ? i1 : i2;
+    }
+
+    private static StringBuilder min(StringBuilder sb1, StringBuilder sb2, Comparator<StringBuilder> c) {
+        return c.compare(sb1, sb2) < 0 ? sb1 : sb2;
+    }
+
+    private static Integer max(Integer i1, Integer i2, Comparator<Integer> c) {
+        return c.compare(i1, i2) < 0 ? i2 : i1;
+    }
+
+    private static <T> T max(T i1, T i2, Comparator<T> c) {
+        return c.compare(i1, i2) < 0 ? i2 : i1;
+    }
+
+    private static StringBuilder max(StringBuilder sb1, StringBuilder sb2, Comparator<StringBuilder> c) {
+        return c.compare(sb1, sb2) < 0 ? sb2 : sb1;
+    }
+    /*
+     * Construct a Collection C object based on a C object, using generic type
+     * instead of Class type can help preventing type error in compilation
+     */
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static <E, C extends Collection<E>>  C create(C c, int... initSize)
+            throws InstantiationException, IllegalAccessException,
+            NoSuchMethodException, IllegalArgumentException,
+            InvocationTargetException {
+        return create((Class<C>) c.getClass(), initSize);
+    }
+
+    /*
+     * Construct a Collection C object based on a C's type, using generic type
+     * instead of Class type can help preventing type error in compilation
+     */
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static <E, T extends Collection<E>>  T create(
+            Class<? extends Collection<E>> cls, int... initSize)
+            throws InstantiationException, IllegalAccessException,
+            NoSuchMethodException, IllegalArgumentException,
+            InvocationTargetException {
+        assert (initSize.length <= 1);
+        Collection<E> c;
+        if (initSize.length == 0) {
+            c = cls.newInstance();
+        } else {
+            Constructor con = cls.getConstructor(int.class);
+            c = (Collection<E>) con.newInstance(initSize[0]);
+        }
+        return (T) c;
+    }
+
+    /*
+     * Construct a T object based on T's type, using generic type instead of
+     * Class type can help preventing type error in compilation
+     */
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static <K, V, M extends Map<K, V>>  M createMap(M m, int... initSize)
+            throws InstantiationException, IllegalAccessException,
+            NoSuchMethodException, IllegalArgumentException,
+            InvocationTargetException {
+        return createMap((Class<M>) m.getClass(), initSize);
+    }
+
+    /*
+     * Construct a Map M object based on M's type, using generic type instead of
+     * Class type can help preventing type error in compilation
+     */
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static <K, V, M extends Map<K, V>>  M createMap(Class<? extends Map<K, V>> cls,
+            int... initSize) throws InstantiationException,
+            IllegalAccessException, NoSuchMethodException,
+            IllegalArgumentException, InvocationTargetException {
+        assert (initSize.length <= 1);
+        Map<K, V> map;
+        if (initSize.length == 0) {
+            map = cls.newInstance();
+        } else {
+            Constructor con = cls.getConstructor(int.class);
+            map = (Map<K, V>) con.newInstance(initSize[0]);
+        }
+        return (M) map;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sqeutil/StringUtilities.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ *
+ * @summary utilities class supporting common operation for tests.
+ * @(#)StringUtilities.java
+ * @author Tristan Yan
+ * @version 1.0
+ */
+
+import java.util.Random;
+
+public class StringUtilities {
+    private final static Random RANDOM =  new Random(System.currentTimeMillis());
+
+    public static String randomString(int max_length, int min_length){
+        return randomAscii(min_length + RANDOM.nextInt(max_length - min_length));
+    }
+
+    public static String random(int count, int start, int end, boolean letters,
+            boolean numbers, char[] chars, Random rnd) {
+        if (count == 0) {
+            return "";
+        } else if (count < 0) {
+            throw new IllegalArgumentException("Requested random string length " + count + " is less than 0.");
+        }
+        if ((start == 0) && (end == 0)) {
+            end = 'z' + 1;
+            start = ' ';
+            if (!letters && !numbers) {
+                start = 0;
+                end = Integer.MAX_VALUE;
+            }
+        }
+
+        char[] buffer = new char[count];
+        int gap = end - start;
+
+        while (count-- != 0) {
+            char ch;
+            if (chars == null) {
+                ch = (char) (rnd.nextInt(gap) + start);
+            } else {
+                ch = chars[rnd.nextInt(gap) + start];
+            }
+            if ((letters && Character.isLetter(ch))
+                || (numbers && Character.isDigit(ch))
+                || (!letters && !numbers))
+            {
+                if(ch >= 56320 && ch <= 57343) {
+                    if(count == 0) {
+                        count++;
+                    } else {
+                        // low surrogate, insert high surrogate after putting it in
+                        buffer[count] = ch;
+                        count--;
+                        buffer[count] = (char) (55296 + rnd.nextInt(128));
+                    }
+                } else if(ch >= 55296 && ch <= 56191) {
+                    if(count == 0) {
+                        count++;
+                    } else {
+                        // high surrogate, insert low surrogate before putting it in
+                        buffer[count] = (char) (56320 + rnd.nextInt(128));
+                        count--;
+                        buffer[count] = ch;
+                    }
+                } else if(ch >= 56192 && ch <= 56319) {
+                    // private high surrogate, no effing clue, so skip it
+                    count++;
+                } else {
+                    buffer[count] = ch;
+                }
+            } else {
+                count++;
+            }
+        }
+        return new String(buffer);
+    }
+    public static String random(int count) {
+        return random(count, false, false);
+    }
+
+    public static String randomAscii(int count) {
+        return random(count, 32, 127, false, false);
+    }
+
+    public static String randomAlphabetic(int count) {
+        return random(count, true, false);
+    }
+
+    public static String randomAlphanumeric(int count) {
+        return random(count, true, true);
+    }
+
+    public static String randomNumeric(int count) {
+        return random(count, false, true);
+    }
+
+    public static String random(int count, boolean letters, boolean numbers) {
+        return random(count, 0, 0, letters, numbers);
+    }
+
+    public static String random(int count, int start, int end, boolean letters, boolean numbers) {
+        return random(count, start, end, letters, numbers, null, RANDOM);
+    }
+
+    public static String random(int count, int start, int end, boolean letters, boolean numbers, char[] chars) {
+        return random(count, start, end, letters, numbers, chars, RANDOM);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/reflect/AnonymousNewInstance/ManyNewInstanceAnonTest.java	Mon Nov 11 23:17:30 2013 -0800
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7194897
+ * @summary JSR 292: Cannot create more than 16 instances of an anonymous class
+ * @author  Robert Field
+ * @library /lib/testlibrary
+ * @compile -XDignore.symbol.file ManyNewInstanceAnonTest.java
+ * @run main ClassFileInstaller ManyNewInstanceAnonTest
+ * @run main/othervm -Xbootclasspath/a:. -Xverify:all ManyNewInstanceAnonTest
+ */
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import sun.misc.Unsafe;
+
+public class ManyNewInstanceAnonTest {
+
+    static final int REPS = 20;
+    static final Class<?> klass = ManyNewInstanceAnonTest.class;
+
+    public static void main(String[] args) throws Exception {
+        Class<?> c = Unsafe.getUnsafe().defineAnonymousClass(klass, readClassFile(), null);
+        for (int i = 0; i < REPS; ++i) {
+            System.out.printf("%d: %s\n", i, c.newInstance());
+        }
+        System.out.println("Passed.");
+    }
+
+    private static byte[] readClassFile() throws Exception {
+        try (InputStream in = klass.getResourceAsStream(klass.getSimpleName() + ".class");
+             ByteArrayOutputStream out = new ByteArrayOutputStream())
+        {
+            int b;
+            while ((b = in.read()) != -1) {
+                out.write(b);
+            }
+            return out.toByteArray();
+        }
+    }
+}