Merge
authorlana
Mon, 10 Dec 2012 20:59:38 -0800
changeset 14728 36e1566efb55
parent 14716 0ee6d44c5714 (current diff)
parent 14727 60b1eac3a6c9 (diff)
child 14729 843573fa3f74
Merge
langtools/test/tools/javac/defaultMethodExecution/DefaultMethodRegressionTests.java
langtools/test/tools/javac/diags/examples/InvalidGenericDescInFunctionalInterface.java
langtools/test/tools/javac/lambda/LambdaConversionTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/source/tree/IntersectionTypeTree.java	Mon Dec 10 20:59:38 2012 -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 com.sun.source.tree;
+
+import java.util.List;
+
+/**
+ * A tree node for an intersection type in a cast expression.
+ *
+ * @author Maurizio Cimadamore
+ *
+ * @since 1.8
+ */
+public interface IntersectionTypeTree extends Tree {
+    List<? extends Tree> getBounds();
+}
--- a/langtools/src/share/classes/com/sun/source/tree/Tree.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/source/tree/Tree.java	Mon Dec 10 20:59:38 2012 -0800
@@ -247,6 +247,11 @@
         UNION_TYPE(UnionTypeTree.class),
 
         /**
+         * Used for instances of {@link IntersectionTypeTree}.
+         */
+        INTERSECTION_TYPE(IntersectionTypeTree.class),
+
+        /**
          * Used for instances of {@link TypeCastTree}.
          */
         TYPE_CAST(TypeCastTree.class),
--- a/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/source/tree/TreeVisitor.java	Mon Dec 10 20:59:38 2012 -0800
@@ -98,6 +98,7 @@
     R visitTry(TryTree node, P p);
     R visitParameterizedType(ParameterizedTypeTree node, P p);
     R visitUnionType(UnionTypeTree node, P p);
+    R visitIntersectionType(IntersectionTypeTree node, P p);
     R visitArrayType(ArrayTypeTree node, P p);
     R visitTypeCast(TypeCastTree node, P p);
     R visitPrimitiveType(PrimitiveTypeTree node, P p);
--- a/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java	Mon Dec 10 20:59:38 2012 -0800
@@ -240,6 +240,10 @@
         return defaultAction(node, p);
     }
 
+    public R visitIntersectionType(IntersectionTypeTree node, P p) {
+        return defaultAction(node, p);
+    }
+
     public R visitTypeParameter(TypeParameterTree node, P p) {
         return defaultAction(node, p);
     }
--- a/langtools/src/share/classes/com/sun/source/util/TreeScanner.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/source/util/TreeScanner.java	Mon Dec 10 20:59:38 2012 -0800
@@ -371,6 +371,10 @@
         return scan(node.getTypeAlternatives(), p);
     }
 
+    public R visitIntersectionType(IntersectionTypeTree node, P p) {
+        return scan(node.getBounds(), p);
+    }
+
     public R visitTypeParameter(TypeParameterTree node, P p) {
         R r = scan(node.getBounds(), p);
         return r;
--- a/langtools/src/share/classes/com/sun/tools/classfile/Instruction.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/classfile/Instruction.java	Mon Dec 10 20:59:38 2012 -0800
@@ -71,11 +71,16 @@
         SHORT(3),
         /** Wide opcode is not followed by any operands. */
         WIDE_NO_OPERANDS(2),
+        /** Wide opcode is followed by a 2-byte index into the local variables array. */
+        WIDE_LOCAL(4),
         /** Wide opcode is followed by a 2-byte index into the constant pool. */
         WIDE_CPREF_W(4),
         /** Wide opcode is followed by a 2-byte index into the constant pool,
          *  and a signed short value. */
         WIDE_CPREF_W_SHORT(6),
+        /** Wide opcode is followed by a 2-byte reference to a local variable,
+         *  and a signed short value. */
+        WIDE_LOCAL_SHORT(6),
         /** Opcode was not recognized. */
         UNKNOWN(1);
 
@@ -101,7 +106,7 @@
         R visitConstantPoolRef(Instruction instr, int index, P p);
         /** See {@link Kind#CPREF_W_UBYTE}, {@link Kind#CPREF_W_UBYTE_ZERO}, {@link Kind#WIDE_CPREF_W_SHORT}. */
         R visitConstantPoolRefAndValue(Instruction instr, int index, int value, P p);
-        /** See {@link Kind#LOCAL}. */
+        /** See {@link Kind#LOCAL}, {@link Kind#WIDE_LOCAL}. */
         R visitLocal(Instruction instr, int index, P p);
         /** See {@link Kind#LOCAL_BYTE}. */
         R visitLocalAndValue(Instruction instr, int index, int value, P p);
@@ -315,6 +320,9 @@
             case WIDE_NO_OPERANDS:
                 return visitor.visitNoOperands(this, p);
 
+            case WIDE_LOCAL:
+                return visitor.visitLocal(this, getUnsignedShort(2), p);
+
             case WIDE_CPREF_W:
                 return visitor.visitConstantPoolRef(this, getUnsignedShort(2), p);
 
@@ -322,6 +330,10 @@
                 return visitor.visitConstantPoolRefAndValue(
                         this, getUnsignedShort(2), getUnsignedByte(4), p);
 
+            case WIDE_LOCAL_SHORT:
+                return visitor.visitLocalAndValue(
+                        this, getUnsignedShort(2), getShort(4), p);
+
             case UNKNOWN:
                 return visitor.visitUnknown(this, p);
 
--- a/langtools/src/share/classes/com/sun/tools/classfile/Opcode.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/classfile/Opcode.java	Mon Dec 10 20:59:38 2012 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -246,18 +246,18 @@
     // impdep 0xff: Picojava priv
 
     // wide opcodes
-    ILOAD_W(0xc415, WIDE_CPREF_W),
-    LLOAD_W(0xc416, WIDE_CPREF_W),
-    FLOAD_W(0xc417, WIDE_CPREF_W),
-    DLOAD_W(0xc418, WIDE_CPREF_W),
-    ALOAD_W(0xc419, WIDE_CPREF_W),
-    ISTORE_W(0xc436, WIDE_CPREF_W),
-    LSTORE_W(0xc437, WIDE_CPREF_W),
-    FSTORE_W(0xc438, WIDE_CPREF_W),
-    DSTORE_W(0xc439, WIDE_CPREF_W),
-    ASTORE_W(0xc43a, WIDE_CPREF_W),
-    IINC_W(0xc484, WIDE_CPREF_W_SHORT),
-    RET_W(0xc4a9, WIDE_CPREF_W),
+    ILOAD_W(0xc415, WIDE_LOCAL),
+    LLOAD_W(0xc416, WIDE_LOCAL),
+    FLOAD_W(0xc417, WIDE_LOCAL),
+    DLOAD_W(0xc418, WIDE_LOCAL),
+    ALOAD_W(0xc419, WIDE_LOCAL),
+    ISTORE_W(0xc436, WIDE_LOCAL),
+    LSTORE_W(0xc437, WIDE_LOCAL),
+    FSTORE_W(0xc438, WIDE_LOCAL),
+    DSTORE_W(0xc439, WIDE_LOCAL),
+    ASTORE_W(0xc43a, WIDE_LOCAL),
+    IINC_W(0xc484, WIDE_LOCAL_SHORT),
+    RET_W(0xc4a9, WIDE_LOCAL),
 
     // PicoJava nonpriv instructions
     LOAD_UBYTE(PICOJAVA, 0xfe00),
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Dec 10 20:59:38 2012 -0800
@@ -215,6 +215,9 @@
     public boolean allowRepeatedAnnotations() {
         return compareTo(JDK1_8) >= 0;
     }
+    public boolean allowIntersectionTypesInCast() {
+        return compareTo(JDK1_8) >= 0;
+    }
     public static SourceVersion toSourceVersion(Source source) {
         switch(source) {
         case JDK1_2:
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java	Mon Dec 10 20:59:38 2012 -0800
@@ -839,6 +839,49 @@
         }
     }
 
+    // a clone of a ClassType that knows about the bounds of an intersection type.
+    public static class IntersectionClassType extends ClassType implements IntersectionType {
+
+        public boolean allInterfaces;
+
+        public enum IntersectionKind {
+            EXPLICIT,
+            IMPLICT;
+        }
+
+        public IntersectionKind intersectionKind;
+
+        public IntersectionClassType(List<Type> bounds, ClassSymbol csym, boolean allInterfaces) {
+            super(Type.noType, List.<Type>nil(), csym);
+            this.allInterfaces = allInterfaces;
+            Assert.check((csym.flags() & COMPOUND) != 0);
+            supertype_field = bounds.head;
+            interfaces_field = bounds.tail;
+            Assert.check(supertype_field.tsym.completer != null ||
+                    !supertype_field.isInterface(), supertype_field);
+        }
+
+        public java.util.List<? extends TypeMirror> getBounds() {
+            return Collections.unmodifiableList(getComponents());
+        }
+
+        public List<Type> getComponents() {
+            return interfaces_field.prepend(supertype_field);
+        }
+
+        @Override
+        public TypeKind getKind() {
+            return TypeKind.INTERSECTION;
+        }
+
+        @Override
+        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
+            return intersectionKind == IntersectionKind.EXPLICIT ?
+                v.visitIntersection(this, p) :
+                v.visitDeclared(this, p);
+        }
+    }
+
     public static class ArrayType extends Type
             implements javax.lang.model.type.ArrayType {
 
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Dec 10 20:59:38 2012 -0800
@@ -26,7 +26,13 @@
 package com.sun.tools.javac.code;
 
 import java.lang.ref.SoftReference;
-import java.util.*;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
 
 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
 import com.sun.tools.javac.code.Lint.LintCategory;
@@ -383,28 +389,6 @@
         }
 
         /**
-         * Scope filter used to skip methods that should be ignored during
-         * function interface conversion (such as methods overridden by
-         * j.l.Object)
-         */
-        class DescriptorFilter implements Filter<Symbol> {
-
-            TypeSymbol origin;
-
-            DescriptorFilter(TypeSymbol origin) {
-                this.origin = origin;
-            }
-
-            @Override
-            public boolean accepts(Symbol sym) {
-                return sym.kind == Kinds.MTH &&
-                        (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT &&
-                        !overridesObjectMethod(origin, sym) &&
-                        (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0;
-            }
-        };
-
-        /**
          * Compute the function descriptor associated with a given functional interface
          */
         public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError {
@@ -431,23 +415,8 @@
                 throw failure("not.a.functional.intf.1",
                             diags.fragment("no.abstracts", Kinds.kindName(origin), origin));
             } else if (abstracts.size() == 1) {
-                if (abstracts.first().type.tag == FORALL) {
-                    throw failure("invalid.generic.desc.in.functional.intf",
-                            abstracts.first(),
-                            Kinds.kindName(origin),
-                            origin);
-                } else {
-                    return new FunctionDescriptor(abstracts.first());
-                }
+                return new FunctionDescriptor(abstracts.first());
             } else { // size > 1
-                for (Symbol msym : abstracts) {
-                    if (msym.type.tag == FORALL) {
-                        throw failure("invalid.generic.desc.in.functional.intf",
-                                abstracts.first(),
-                                Kinds.kindName(origin),
-                                origin);
-                    }
-                }
                 FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList());
                 if (descRes == null) {
                     //we can get here if the functional interface is ill-formed
@@ -586,6 +555,85 @@
     }
     // </editor-fold>
 
+   /**
+    * Scope filter used to skip methods that should be ignored (such as methods
+    * overridden by j.l.Object) during function interface conversion/marker interface checks
+    */
+    class DescriptorFilter implements Filter<Symbol> {
+
+       TypeSymbol origin;
+
+       DescriptorFilter(TypeSymbol origin) {
+           this.origin = origin;
+       }
+
+       @Override
+       public boolean accepts(Symbol sym) {
+           return sym.kind == Kinds.MTH &&
+                   (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT &&
+                   !overridesObjectMethod(origin, sym) &&
+                   (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0;
+       }
+    };
+
+    // <editor-fold defaultstate="collapsed" desc="isMarker">
+
+    /**
+     * A cache that keeps track of marker interfaces
+     */
+    class MarkerCache {
+
+        private WeakHashMap<TypeSymbol, Entry> _map = new WeakHashMap<TypeSymbol, Entry>();
+
+        class Entry {
+            final boolean isMarkerIntf;
+            final int prevMark;
+
+            public Entry(boolean isMarkerIntf,
+                    int prevMark) {
+                this.isMarkerIntf = isMarkerIntf;
+                this.prevMark = prevMark;
+            }
+
+            boolean matches(int mark) {
+                return  this.prevMark == mark;
+            }
+        }
+
+        boolean get(TypeSymbol origin) throws FunctionDescriptorLookupError {
+            Entry e = _map.get(origin);
+            CompoundScope members = membersClosure(origin.type, false);
+            if (e == null ||
+                    !e.matches(members.getMark())) {
+                boolean isMarkerIntf = isMarkerInterfaceInternal(origin, members);
+                _map.put(origin, new Entry(isMarkerIntf, members.getMark()));
+                return isMarkerIntf;
+            }
+            else {
+                return e.isMarkerIntf;
+            }
+        }
+
+        /**
+         * Is given symbol a marker interface
+         */
+        public boolean isMarkerInterfaceInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError {
+            return !origin.isInterface() ?
+                    false :
+                    !membersCache.getElements(new DescriptorFilter(origin)).iterator().hasNext();
+        }
+    }
+
+    private MarkerCache markerCache = new MarkerCache();
+
+    /**
+     * Is given type a marker interface?
+     */
+    public boolean isMarkerInterface(Type site) {
+        return markerCache.get(site.tsym);
+    }
+    // </editor-fold>
+
     // <editor-fold defaultstate="collapsed" desc="isSubtype">
     /**
      * Is t an unchecked subtype of s?
@@ -1964,45 +2012,28 @@
      * @param supertype         is objectType if all bounds are interfaces,
      *                          null otherwise.
      */
-    public Type makeCompoundType(List<Type> bounds,
-                                 Type supertype) {
+    public Type makeCompoundType(List<Type> bounds) {
+        return makeCompoundType(bounds, bounds.head.tsym.isInterface());
+    }
+    public Type makeCompoundType(List<Type> bounds, boolean allInterfaces) {
+        Assert.check(bounds.nonEmpty());
+        Type firstExplicitBound = bounds.head;
+        if (allInterfaces) {
+            bounds = bounds.prepend(syms.objectType);
+        }
         ClassSymbol bc =
             new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,
                             Type.moreInfo
                                 ? names.fromString(bounds.toString())
                                 : names.empty,
+                            null,
                             syms.noSymbol);
-        if (bounds.head.tag == TYPEVAR)
-            // error condition, recover
-                bc.erasure_field = syms.objectType;
-            else
-                bc.erasure_field = erasure(bounds.head);
-            bc.members_field = new Scope(bc);
-        ClassType bt = (ClassType)bc.type;
-        bt.allparams_field = List.nil();
-        if (supertype != null) {
-            bt.supertype_field = supertype;
-            bt.interfaces_field = bounds;
-        } else {
-            bt.supertype_field = bounds.head;
-            bt.interfaces_field = bounds.tail;
-        }
-        Assert.check(bt.supertype_field.tsym.completer != null
-                || !bt.supertype_field.isInterface(),
-            bt.supertype_field);
-        return bt;
-    }
-
-    /**
-     * Same as {@link #makeCompoundType(List,Type)}, except that the
-     * second parameter is computed directly. Note that this might
-     * cause a symbol completion.  Hence, this version of
-     * makeCompoundType may not be called during a classfile read.
-     */
-    public Type makeCompoundType(List<Type> bounds) {
-        Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
-            supertype(bounds.head) : null;
-        return makeCompoundType(bounds, supertype);
+        bc.type = new IntersectionClassType(bounds, bc, allInterfaces);
+        bc.erasure_field = (bounds.head.tag == TYPEVAR) ?
+                syms.objectType : // error condition, recover
+                erasure(firstExplicitBound);
+        bc.members_field = new Scope(bc);
+        return bc.type;
     }
 
     /**
@@ -2192,12 +2223,8 @@
      * @param supertype         is objectType if all bounds are interfaces,
      *                          null otherwise.
      */
-    public void setBounds(TypeVar t, List<Type> bounds, Type supertype) {
-        if (bounds.tail.isEmpty())
-            t.bound = bounds.head;
-        else
-            t.bound = makeCompoundType(bounds, supertype);
-        t.rank_field = -1;
+    public void setBounds(TypeVar t, List<Type> bounds) {
+        setBounds(t, bounds, bounds.head.tsym.isInterface());
     }
 
     /**
@@ -2209,10 +2236,10 @@
      * Note that this check might cause a symbol completion. Hence, this version of
      * setBounds may not be called during a classfile read.
      */
-    public void setBounds(TypeVar t, List<Type> bounds) {
-        Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
-            syms.objectType : null;
-        setBounds(t, bounds, supertype);
+    public void setBounds(TypeVar t, List<Type> bounds, boolean allInterfaces) {
+        t.bound = bounds.tail.isEmpty() ?
+                bounds.head :
+                makeCompoundType(bounds, allInterfaces);
         t.rank_field = -1;
     }
     // </editor-fold>
@@ -2222,7 +2249,7 @@
      * Return list of bounds of the given type variable.
      */
     public List<Type> getBounds(TypeVar t) {
-                if (t.bound.hasTag(NONE))
+        if (t.bound.hasTag(NONE))
             return List.nil();
         else if (t.bound.isErroneous() || !t.bound.isCompound())
             return List.of(t.bound);
@@ -3321,8 +3348,7 @@
                     if (arraySuperType == null) {
                         // JLS 10.8: all arrays implement Cloneable and Serializable.
                         arraySuperType = makeCompoundType(List.of(syms.serializableType,
-                                                                  syms.cloneableType),
-                                                          syms.objectType);
+                                                                  syms.cloneableType), true);
                     }
                 }
             }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Dec 10 20:59:38 2012 -0800
@@ -716,21 +716,8 @@
             }
             a.tsym.flags_field &= ~UNATTRIBUTED;
         }
-        for (JCTypeParameter tvar : typarams)
+        for (JCTypeParameter tvar : typarams) {
             chk.checkNonCyclic(tvar.pos(), (TypeVar)tvar.type);
-        attribStats(typarams, env);
-    }
-
-    void attribBounds(List<JCTypeParameter> typarams) {
-        for (JCTypeParameter typaram : typarams) {
-            Type bound = typaram.type.getUpperBound();
-            if (bound != null && bound.tsym instanceof ClassSymbol) {
-                ClassSymbol c = (ClassSymbol)bound.tsym;
-                if ((c.flags_field & COMPOUND) != 0) {
-                    Assert.check((c.flags_field & UNATTRIBUTED) != 0, c);
-                    attribClass(typaram.pos(), c);
-                }
-            }
         }
     }
 
@@ -892,7 +879,12 @@
             deferredLintHandler.flush(tree.pos());
             chk.checkDeprecatedAnnotation(tree.pos(), m);
 
-            attribBounds(tree.typarams);
+            // Create a new environment with local scope
+            // for attributing the method.
+            Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env);
+            localEnv.info.lint = lint;
+
+            attribStats(tree.typarams, localEnv);
 
             // If we override any other methods, check that we do so properly.
             // JLS ???
@@ -903,12 +895,6 @@
             }
             chk.checkOverride(tree, m);
 
-            // Create a new environment with local scope
-            // for attributing the method.
-            Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env);
-
-            localEnv.info.lint = lint;
-
             if (isDefaultMethod && types.overridesObjectMethod(m.enclClass(), m)) {
                 log.error(tree, "default.overrides.object.member", m.name, Kinds.kindName(m.location()), m.location());
             }
@@ -2196,7 +2182,7 @@
             Type target;
             Type lambdaType;
             if (pt() != Type.recoveryType) {
-                target = infer.instantiateFunctionalInterface(that, pt(), explicitParamTypes, resultInfo.checkContext);
+                target = infer.instantiateFunctionalInterface(that, checkIntersectionTarget(that, resultInfo), explicitParamTypes, resultInfo.checkContext);
                 lambdaType = types.findDescriptorType(target);
                 chk.checkFunctionalInterface(that, target);
             } else {
@@ -2204,6 +2190,14 @@
                 lambdaType = fallbackDescriptorType(that);
             }
 
+            if (lambdaType.hasTag(FORALL)) {
+                //lambda expression target desc cannot be a generic method
+                resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
+                        lambdaType, kindName(target.tsym), target.tsym));
+                result = that.type = types.createErrorType(pt());
+                return;
+            }
+
             if (!TreeInfo.isExplicitLambda(that)) {
                 //add param type info in the AST
                 List<Type> actuals = lambdaType.getParameterTypes();
@@ -2244,9 +2238,13 @@
             //with the target-type, it will be recovered anyway in Attr.checkId
             needsRecovery = false;
 
+            FunctionalReturnContext funcContext = that.getBodyKind() == JCLambda.BodyKind.EXPRESSION ?
+                    new ExpressionLambdaReturnContext((JCExpression)that.getBody(), resultInfo.checkContext) :
+                    new FunctionalReturnContext(resultInfo.checkContext);
+
             ResultInfo bodyResultInfo = lambdaType.getReturnType() == Type.recoveryType ?
                 recoveryInfo :
-                new ResultInfo(VAL, lambdaType.getReturnType(), new LambdaReturnContext(resultInfo.checkContext));
+                new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
             localEnv.info.returnResult = bodyResultInfo;
 
             if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
@@ -2282,6 +2280,26 @@
             }
         }
     }
+
+    private Type checkIntersectionTarget(DiagnosticPosition pos, ResultInfo resultInfo) {
+        Type pt = resultInfo.pt;
+        if (pt != Type.recoveryType && pt.isCompound()) {
+            IntersectionClassType ict = (IntersectionClassType)pt;
+            List<Type> bounds = ict.allInterfaces ?
+                    ict.getComponents().tail :
+                    ict.getComponents();
+            types.findDescriptorType(bounds.head); //propagate exception outwards!
+            for (Type bound : bounds.tail) {
+                if (!types.isMarkerInterface(bound)) {
+                    resultInfo.checkContext.report(pos, diags.fragment("secondary.bound.must.be.marker.intf", bound));
+                }
+            }
+            //for now (translation doesn't support intersection types)
+            return bounds.head;
+        } else {
+            return pt;
+        }
+    }
     //where
         private Type fallbackDescriptorType(JCExpression tree) {
             switch (tree.getTag()) {
@@ -2327,8 +2345,9 @@
          * type according to both the inherited context and the assignment
          * context.
          */
-        class LambdaReturnContext extends Check.NestedCheckContext {
-            public LambdaReturnContext(CheckContext enclosingContext) {
+        class FunctionalReturnContext extends Check.NestedCheckContext {
+
+            FunctionalReturnContext(CheckContext enclosingContext) {
                 super(enclosingContext);
             }
 
@@ -2344,6 +2363,23 @@
             }
         }
 
+        class ExpressionLambdaReturnContext extends FunctionalReturnContext {
+
+            JCExpression expr;
+
+            ExpressionLambdaReturnContext(JCExpression expr, CheckContext enclosingContext) {
+                super(enclosingContext);
+                this.expr = expr;
+            }
+
+            @Override
+            public boolean compatible(Type found, Type req, Warner warn) {
+                //a void return is compatible with an expression statement lambda
+                return TreeInfo.isExpressionStatement(expr) && req.hasTag(VOID) ||
+                        super.compatible(found, req, warn);
+            }
+        }
+
         /**
         * Lambda compatibility. Check that given return types, thrown types, parameter types
         * are compatible with the expected functional interface descriptor. This means that:
@@ -2428,7 +2464,7 @@
             }
 
             //attrib type-arguments
-            List<Type> typeargtypes = null;
+            List<Type> typeargtypes = List.nil();
             if (that.typeargs != null) {
                 typeargtypes = attribTypes(that.typeargs, localEnv);
             }
@@ -2436,7 +2472,7 @@
             Type target;
             Type desc;
             if (pt() != Type.recoveryType) {
-                target = infer.instantiateFunctionalInterface(that, pt(), null, resultInfo.checkContext);
+                target = infer.instantiateFunctionalInterface(that, checkIntersectionTarget(that, resultInfo), null, resultInfo.checkContext);
                 desc = types.findDescriptorType(target);
                 chk.checkFunctionalInterface(that, target);
             } else {
@@ -2498,6 +2534,26 @@
                 }
             }
 
+            if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) {
+                if (refSym.isStatic() && TreeInfo.isStaticSelector(that.expr, names) &&
+                        exprType.getTypeArguments().nonEmpty()) {
+                    //static ref with class type-args
+                    log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
+                            diags.fragment("static.mref.with.targs"));
+                    result = that.type = types.createErrorType(target);
+                    return;
+                }
+
+                if (refSym.isStatic() && !TreeInfo.isStaticSelector(that.expr, names) &&
+                        !lookupHelper.referenceKind(refSym).isUnbound()) {
+                    //no static bound mrefs
+                    log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
+                            diags.fragment("static.bound.mref"));
+                    result = that.type = types.createErrorType(target);
+                    return;
+                }
+            }
+
             if (desc.getReturnType() == Type.recoveryType) {
                 // stop here
                 result = that.type = target;
@@ -2560,7 +2616,7 @@
 
         if (!returnType.hasTag(VOID) && !resType.hasTag(VOID)) {
             if (resType.isErroneous() ||
-                    new LambdaReturnContext(checkContext).compatible(resType, returnType, types.noWarnings)) {
+                    new FunctionalReturnContext(checkContext).compatible(resType, returnType, types.noWarnings)) {
                 incompatibleReturnType = null;
             }
         }
@@ -3525,63 +3581,79 @@
         tree.type = result = t;
     }
 
-    public void visitTypeParameter(JCTypeParameter tree) {
-        TypeVar a = (TypeVar)tree.type;
+    public void visitTypeIntersection(JCTypeIntersection tree) {
+        attribTypes(tree.bounds, env);
+        tree.type = result = checkIntersection(tree, tree.bounds);
+    }
+
+     public void visitTypeParameter(JCTypeParameter tree) {
+        TypeVar typeVar = (TypeVar)tree.type;
+        if (!typeVar.bound.isErroneous()) {
+            //fixup type-parameter bound computed in 'attribTypeVariables'
+            typeVar.bound = checkIntersection(tree, tree.bounds);
+        }
+    }
+
+    Type checkIntersection(JCTree tree, List<JCExpression> bounds) {
         Set<Type> boundSet = new HashSet<Type>();
-        if (a.bound.isErroneous())
-            return;
-        List<Type> bs = types.getBounds(a);
-        if (tree.bounds.nonEmpty()) {
+        if (bounds.nonEmpty()) {
             // accept class or interface or typevar as first bound.
-            Type b = checkBase(bs.head, tree.bounds.head, env, false, false, false);
-            boundSet.add(types.erasure(b));
-            if (b.isErroneous()) {
-                a.bound = b;
+            bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false);
+            boundSet.add(types.erasure(bounds.head.type));
+            if (bounds.head.type.isErroneous()) {
+                return bounds.head.type;
             }
-            else if (b.hasTag(TYPEVAR)) {
+            else if (bounds.head.type.hasTag(TYPEVAR)) {
                 // if first bound was a typevar, do not accept further bounds.
-                if (tree.bounds.tail.nonEmpty()) {
-                    log.error(tree.bounds.tail.head.pos(),
+                if (bounds.tail.nonEmpty()) {
+                    log.error(bounds.tail.head.pos(),
                               "type.var.may.not.be.followed.by.other.bounds");
-                    tree.bounds = List.of(tree.bounds.head);
-                    a.bound = bs.head;
+                    return bounds.head.type;
                 }
             } else {
                 // if first bound was a class or interface, accept only interfaces
                 // as further bounds.
-                for (JCExpression bound : tree.bounds.tail) {
-                    bs = bs.tail;
-                    Type i = checkBase(bs.head, bound, env, false, true, false);
-                    if (i.isErroneous())
-                        a.bound = i;
-                    else if (i.hasTag(CLASS))
-                        chk.checkNotRepeated(bound.pos(), types.erasure(i), boundSet);
+                for (JCExpression bound : bounds.tail) {
+                    bound.type = checkBase(bound.type, bound, env, false, true, false);
+                    if (bound.type.isErroneous()) {
+                        bounds = List.of(bound);
+                    }
+                    else if (bound.type.hasTag(CLASS)) {
+                        chk.checkNotRepeated(bound.pos(), types.erasure(bound.type), boundSet);
+                    }
                 }
             }
         }
-        bs = types.getBounds(a);
-
-        // in case of multiple bounds ...
-        if (bs.length() > 1) {
+
+        if (bounds.length() == 0) {
+            return syms.objectType;
+        } else if (bounds.length() == 1) {
+            return bounds.head.type;
+        } else {
+            Type owntype = types.makeCompoundType(TreeInfo.types(bounds));
+            if (tree.hasTag(TYPEINTERSECTION)) {
+                ((IntersectionClassType)owntype).intersectionKind =
+                        IntersectionClassType.IntersectionKind.EXPLICIT;
+            }
             // ... the variable's bound is a class type flagged COMPOUND
             // (see comment for TypeVar.bound).
             // In this case, generate a class tree that represents the
             // bound class, ...
             JCExpression extending;
             List<JCExpression> implementing;
-            if ((bs.head.tsym.flags() & INTERFACE) == 0) {
-                extending = tree.bounds.head;
-                implementing = tree.bounds.tail;
+            if (!bounds.head.type.isInterface()) {
+                extending = bounds.head;
+                implementing = bounds.tail;
             } else {
                 extending = null;
-                implementing = tree.bounds;
+                implementing = bounds;
             }
-            JCClassDecl cd = make.at(tree.pos).ClassDef(
+            JCClassDecl cd = make.at(tree).ClassDef(
                 make.Modifiers(PUBLIC | ABSTRACT),
-                tree.name, List.<JCTypeParameter>nil(),
+                names.empty, List.<JCTypeParameter>nil(),
                 extending, implementing, List.<JCTree>nil());
 
-            ClassSymbol c = (ClassSymbol)a.getUpperBound().tsym;
+            ClassSymbol c = (ClassSymbol)owntype.tsym;
             Assert.check((c.flags() & COMPOUND) != 0);
             cd.sym = c;
             c.sourcefile = env.toplevel.sourcefile;
@@ -3590,10 +3662,11 @@
             c.flags_field |= UNATTRIBUTED;
             Env<AttrContext> cenv = enter.classEnv(cd, env);
             enter.typeEnvs.put(c, cenv);
+            attribClass(c);
+            return owntype;
         }
     }
 
-
     public void visitWildcard(JCWildcard tree) {
         //- System.err.println("visitWildcard("+tree+");");//DEBUG
         Type type = (tree.kind.kind == BoundKind.UNBOUND)
@@ -3747,7 +3820,7 @@
         chk.validateAnnotations(tree.mods.annotations, c);
 
         // Validate type parameters, supertype and interfaces.
-        attribBounds(tree.typarams);
+        attribStats(tree.typarams, env);
         if (!c.isAnonymous()) {
             //already checked if anonymous
             chk.validate(tree.typarams, env);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Mon Dec 10 20:59:38 2012 -0800
@@ -288,21 +288,20 @@
         JCExpression init;
         switch(tree.kind) {
 
-            case IMPLICIT_INNER:    /** Inner # new */
-            case SUPER:             /** super # instMethod */
+            case IMPLICIT_INNER:    /** Inner :: new */
+            case SUPER:             /** super :: instMethod */
                 init = makeThis(
                     localContext.owner.owner.asType(),
                     localContext.owner);
                 break;
 
-            case BOUND:             /** Expr # instMethod */
+            case BOUND:             /** Expr :: instMethod */
                 init = tree.getQualifierExpression();
                 break;
 
-            case STATIC_EVAL:       /** Expr # staticMethod */
-            case UNBOUND:           /** Type # instMethod */
-            case STATIC:            /** Type # staticMethod */
-            case TOPLEVEL:          /** Top level # new */
+            case UNBOUND:           /** Type :: instMethod */
+            case STATIC:            /** Type :: staticMethod */
+            case TOPLEVEL:          /** Top level :: new */
                 init = null;
                 break;
 
@@ -315,14 +314,6 @@
 
         //build a sam instance using an indy call to the meta-factory
         result = makeMetaFactoryIndyCall(tree, tree.targetType, localContext.referenceKind(), refSym, indy_args);
-
-        //if we had a static reference with non-static qualifier, add a let
-        //expression to force the evaluation of the qualifier expr
-        if (tree.hasKind(ReferenceKind.STATIC_EVAL)) {
-            VarSymbol rec = new VarSymbol(0, names.fromString("rec$"), tree.getQualifierExpression().type, localContext.owner);
-            JCVariableDecl recDef = make.VarDef(rec, tree.getQualifierExpression());
-            result = make.LetExpr(recDef, result).setType(tree.type);
-        }
     }
 
     /**
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Mon Dec 10 20:59:38 2012 -0800
@@ -138,6 +138,10 @@
      */
     Map<ClassSymbol, JCClassDecl> classdefs;
 
+    /** A hash table mapping local classes to a list of pruned trees.
+     */
+    public Map<ClassSymbol, List<JCTree>> prunedTree = new WeakHashMap<ClassSymbol, List<JCTree>>();
+
     /** A hash table mapping virtual accessed symbols in outer subclasses
      *  to the actually referred symbol in superclasses.
      */
@@ -1039,6 +1043,12 @@
         }
     }
 
+    private void addPrunedInfo(JCTree tree) {
+        List<JCTree> infoList = prunedTree.get(currentClass);
+        infoList = (infoList == null) ? List.of(tree) : infoList.prepend(tree);
+        prunedTree.put(currentClass, infoList);
+    }
+
     /** Ensure that identifier is accessible, return tree accessing the identifier.
      *  @param sym      The accessed symbol.
      *  @param tree     The tree referring to the symbol.
@@ -1111,7 +1121,10 @@
                     // Constants are replaced by their constant value.
                     if (sym.kind == VAR) {
                         Object cv = ((VarSymbol)sym).getConstValue();
-                        if (cv != null) return makeLit(sym.type, cv);
+                        if (cv != null) {
+                            addPrunedInfo(tree);
+                            return makeLit(sym.type, cv);
+                        }
                     }
 
                     // Private variables and methods are replaced by calls
@@ -2746,12 +2759,15 @@
 
     /** Visitor method for conditional expressions.
      */
+    @Override
     public void visitConditional(JCConditional tree) {
         JCTree cond = tree.cond = translate(tree.cond, syms.booleanType);
         if (cond.type.isTrue()) {
             result = convert(translate(tree.truepart, tree.type), tree.type);
+            addPrunedInfo(cond);
         } else if (cond.type.isFalse()) {
             result = convert(translate(tree.falsepart, tree.type), tree.type);
+            addPrunedInfo(cond);
         } else {
             // Condition is not a compile-time constant.
             tree.truepart = translate(tree.truepart, tree.type);
@@ -2760,14 +2776,14 @@
         }
     }
 //where
-        private JCTree convert(JCTree tree, Type pt) {
-            if (tree.type == pt || tree.type.hasTag(BOT))
-                return tree;
-            JCTree result = make_at(tree.pos()).TypeCast(make.Type(pt), (JCExpression)tree);
-            result.type = (tree.type.constValue() != null) ? cfolder.coerce(tree.type, pt)
-                                                           : pt;
-            return result;
-        }
+    private JCTree convert(JCTree tree, Type pt) {
+        if (tree.type == pt || tree.type.hasTag(BOT))
+            return tree;
+        JCTree result = make_at(tree.pos()).TypeCast(make.Type(pt), (JCExpression)tree);
+        result.type = (tree.type.constValue() != null) ? cfolder.coerce(tree.type, pt)
+                                                       : pt;
+        return result;
+    }
 
     /** Visitor method for if statements.
      */
@@ -2775,12 +2791,14 @@
         JCTree cond = tree.cond = translate(tree.cond, syms.booleanType);
         if (cond.type.isTrue()) {
             result = translate(tree.thenpart);
+            addPrunedInfo(cond);
         } else if (cond.type.isFalse()) {
             if (tree.elsepart != null) {
                 result = translate(tree.elsepart);
             } else {
                 result = make.Skip();
             }
+            addPrunedInfo(cond);
         } else {
             // Condition is not a compile-time constant.
             tree.thenpart = translate(tree.thenpart);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Dec 10 20:59:38 2012 -0800
@@ -2617,8 +2617,7 @@
         @Override
         ReferenceKind referenceKind(Symbol sym) {
             if (sym.isStatic()) {
-                return TreeInfo.isStaticSelector(referenceTree.expr, names) ?
-                        ReferenceKind.STATIC : ReferenceKind.STATIC_EVAL;
+                return ReferenceKind.STATIC;
             } else {
                 Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
                 return selName != null && selName == names._super ?
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Mon Dec 10 20:59:38 2012 -0800
@@ -551,6 +551,7 @@
             tree.body = translate(tree.body, null);
             //save non-erased target
             tree.targetType = tree.type;
+            Assert.check(!tree.targetType.isCompound(), "Intersection-type targets not supported yet!");
             tree.type = erasure(tree.type);
             result = tree;
         }
@@ -786,6 +787,7 @@
         tree.expr = translate(tree.expr, null);
         //save non-erased target
         tree.targetType = tree.type;
+        Assert.check(!tree.targetType.isCompound(), "Intersection-type targets not supported yet!");
         tree.type = erasure(tree.type);
         result = tree;
     }
@@ -803,6 +805,12 @@
         result = clazz;
     }
 
+    public void visitTypeIntersection(JCTypeIntersection tree) {
+        tree.bounds = translate(tree.bounds, null);
+        tree.type = erasure(tree.type);
+        result = tree;
+    }
+
 /**************************************************************************
  * utility methods
  *************************************************************************/
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Dec 10 20:59:38 2012 -0800
@@ -846,17 +846,17 @@
             tvar = (TypeVar)findTypeVar(name);
         }
         List<Type> bounds = List.nil();
-        Type st = null;
+        boolean allInterfaces = false;
         if (signature[sigp] == ':' && signature[sigp+1] == ':') {
             sigp++;
-            st = syms.objectType;
+            allInterfaces = true;
         }
         while (signature[sigp] == ':') {
             sigp++;
             bounds = bounds.prepend(sigToType());
         }
         if (!sigEnterPhase) {
-            types.setBounds(tvar, bounds.reverse(), st);
+            types.setBounds(tvar, bounds.reverse(), allInterfaces);
         }
         return tvar;
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Mon Dec 10 20:59:38 2012 -0800
@@ -71,6 +71,7 @@
     private final Map<Type,Symbol> stringBufferAppend;
     private Name accessDollar;
     private final Types types;
+    private final Lower lower;
 
     /** Switch: GJ mode?
      */
@@ -112,6 +113,7 @@
         stringBufferAppend = new HashMap<Type,Symbol>();
         accessDollar = names.
             fromString("access" + target.syntheticNameChar());
+        lower = Lower.instance(context);
 
         Options options = Options.instance(context);
         lineDebugInfo =
@@ -816,6 +818,62 @@
         }
     }
 
+    /** Visitor class for expressions which might be constant expressions.
+     *  This class is a subset of TreeScanner. Intended to visit trees pruned by
+     *  Lower as long as constant expressions looking for references to any
+     *  ClassSymbol. Any such reference will be added to the constant pool so
+     *  automated tools can detect class dependencies better.
+     */
+    class ClassReferenceVisitor extends JCTree.Visitor {
+
+        @Override
+        public void visitTree(JCTree tree) {}
+
+        @Override
+        public void visitBinary(JCBinary tree) {
+            tree.lhs.accept(this);
+            tree.rhs.accept(this);
+        }
+
+        @Override
+        public void visitSelect(JCFieldAccess tree) {
+            if (tree.selected.type.hasTag(CLASS)) {
+                makeRef(tree.selected.pos(), tree.selected.type);
+            }
+        }
+
+        @Override
+        public void visitIdent(JCIdent tree) {
+            if (tree.sym.owner instanceof ClassSymbol) {
+                pool.put(tree.sym.owner);
+            }
+        }
+
+        @Override
+        public void visitConditional(JCConditional tree) {
+            tree.cond.accept(this);
+            tree.truepart.accept(this);
+            tree.falsepart.accept(this);
+        }
+
+        @Override
+        public void visitUnary(JCUnary tree) {
+            tree.arg.accept(this);
+        }
+
+        @Override
+        public void visitParens(JCParens tree) {
+            tree.expr.accept(this);
+        }
+
+        @Override
+        public void visitTypeCast(JCTypeCast tree) {
+            tree.expr.accept(this);
+        }
+    }
+
+    private ClassReferenceVisitor classReferenceVisitor = new ClassReferenceVisitor();
+
     /** Visitor method: generate code for an expression, catching and reporting
      *  any completion failures.
      *  @param tree    The expression to be visited.
@@ -826,6 +884,7 @@
         try {
             if (tree.type.constValue() != null) {
                 // Short circuit any expressions which are constants
+                tree.accept(classReferenceVisitor);
                 checkStringConstant(tree.pos(), tree.type.constValue());
                 result = items.makeImmediateItem(tree.type, tree.type.constValue());
             } else {
@@ -2205,6 +2264,15 @@
         code.endScopes(limit);
     }
 
+    private void generateReferencesToPrunedTree(ClassSymbol classSymbol, Pool pool) {
+        List<JCTree> prunedInfo = lower.prunedTree.get(classSymbol);
+        if (prunedInfo != null) {
+            for (JCTree prunedTree: prunedInfo) {
+                prunedTree.accept(classReferenceVisitor);
+            }
+        }
+    }
+
 /* ************************************************************************
  * main method
  *************************************************************************/
@@ -2232,6 +2300,7 @@
             cdef.defs = normalizeDefs(cdef.defs, c);
             c.pool = pool;
             pool.reset();
+            generateReferencesToPrunedTree(c, pool);
             Env<GenContext> localEnv =
                 new Env<GenContext>(cdef, new GenContext());
             localEnv.toplevel = env.toplevel;
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java	Mon Dec 10 20:59:38 2012 -0800
@@ -74,6 +74,7 @@
     public Element asElement(TypeMirror t) {
         switch (t.getKind()) {
             case DECLARED:
+            case INTERSECTION:
             case ERROR:
             case TYPEVAR:
                 Type type = cast(Type.class, t);
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java	Mon Dec 10 20:59:38 2012 -0800
@@ -348,8 +348,8 @@
     private void scanIdent() {
         boolean isJavaIdentifierPart;
         char high;
+        reader.putChar(true);
         do {
-            reader.putChar(true);
             switch (reader.ch) {
             case 'A': case 'B': case 'C': case 'D': case 'E':
             case 'F': case 'G': case 'H': case 'I': case 'J':
@@ -366,6 +366,7 @@
             case '$': case '_':
             case '0': case '1': case '2': case '3': case '4':
             case '5': case '6': case '7': case '8': case '9':
+                break;
             case '\u0000': case '\u0001': case '\u0002': case '\u0003':
             case '\u0004': case '\u0005': case '\u0006': case '\u0007':
             case '\u0008': case '\u000E': case '\u000F': case '\u0010':
@@ -373,26 +374,33 @@
             case '\u0015': case '\u0016': case '\u0017':
             case '\u0018': case '\u0019': case '\u001B':
             case '\u007F':
-                break;
+                reader.scanChar();
+                continue;
             case '\u001A': // EOI is also a legal identifier part
                 if (reader.bp >= reader.buflen) {
                     name = reader.name();
                     tk = tokens.lookupKind(name);
                     return;
                 }
-                break;
+                reader.scanChar();
+                continue;
             default:
                 if (reader.ch < '\u0080') {
                     // all ASCII range chars already handled, above
                     isJavaIdentifierPart = false;
                 } else {
-                    high = reader.scanSurrogates();
-                    if (high != 0) {
-                        reader.putChar(high);
-                        isJavaIdentifierPart = Character.isJavaIdentifierPart(
-                            Character.toCodePoint(high, reader.ch));
+                    if (Character.isIdentifierIgnorable(reader.ch)) {
+                        reader.scanChar();
+                        continue;
                     } else {
-                        isJavaIdentifierPart = Character.isJavaIdentifierPart(reader.ch);
+                        high = reader.scanSurrogates();
+                        if (high != 0) {
+                            reader.putChar(high);
+                            isJavaIdentifierPart = Character.isJavaIdentifierPart(
+                                Character.toCodePoint(high, reader.ch));
+                        } else {
+                            isJavaIdentifierPart = Character.isJavaIdentifierPart(reader.ch);
+                        }
                     }
                 }
                 if (!isJavaIdentifierPart) {
@@ -401,6 +409,7 @@
                     return;
                 }
             }
+            reader.putChar(true);
         } while (true);
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Mon Dec 10 20:59:38 2012 -0800
@@ -124,6 +124,9 @@
         this.allowLambda = source.allowLambda();
         this.allowMethodReferences = source.allowMethodReferences();
         this.allowDefaultMethods = source.allowDefaultMethods();
+        this.allowIntersectionTypesInCast =
+                source.allowIntersectionTypesInCast() &&
+                fac.options.isSet("allowIntersectionTypes");
         this.keepDocComments = keepDocComments;
         docComments = newDocCommentTable(keepDocComments, fac);
         this.keepLineMap = keepLineMap;
@@ -197,6 +200,10 @@
      */
     boolean allowDefaultMethods;
 
+    /** Switch: should we allow intersection types in cast?
+     */
+    boolean allowIntersectionTypesInCast;
+
     /** Switch: should we keep docComments?
      */
     boolean keepDocComments;
@@ -239,22 +246,38 @@
     }
 
     protected boolean peekToken(TokenKind tk) {
-        return S.token(1).kind == tk;
+        return peekToken(0, tk);
+    }
+
+    protected boolean peekToken(int lookahead, TokenKind tk) {
+        return S.token(lookahead + 1).kind == tk;
     }
 
     protected boolean peekToken(TokenKind tk1, TokenKind tk2) {
-        return S.token(1).kind == tk1 &&
-                S.token(2).kind == tk2;
+        return peekToken(0, tk1, tk2);
+    }
+
+    protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2) {
+        return S.token(lookahead + 1).kind == tk1 &&
+                S.token(lookahead + 2).kind == tk2;
     }
 
     protected boolean peekToken(TokenKind tk1, TokenKind tk2, TokenKind tk3) {
-        return S.token(1).kind == tk1 &&
-                S.token(2).kind == tk2 &&
-                S.token(3).kind == tk3;
+        return peekToken(0, tk1, tk2, tk3);
+    }
+
+    protected boolean peekToken(int lookahead, TokenKind tk1, TokenKind tk2, TokenKind tk3) {
+        return S.token(lookahead + 1).kind == tk1 &&
+                S.token(lookahead + 2).kind == tk2 &&
+                S.token(lookahead + 3).kind == tk3;
     }
 
     protected boolean peekToken(TokenKind... kinds) {
-        for (int lookahead = 0 ; lookahead < kinds.length ; lookahead++) {
+        return peekToken(0, kinds);
+    }
+
+    protected boolean peekToken(int lookahead, TokenKind... kinds) {
+        for (; lookahead < kinds.length ; lookahead++) {
             if (S.token(lookahead + 1).kind != kinds[lookahead]) {
                 return false;
             }
@@ -966,102 +989,40 @@
             break;
         case LPAREN:
             if (typeArgs == null && (mode & EXPR) != 0) {
-                if (peekToken(MONKEYS_AT) ||
-                        peekToken(FINAL) ||
-                        peekToken(RPAREN) ||
-                        peekToken(IDENTIFIER, COMMA) ||
-                        peekToken(IDENTIFIER, RPAREN, ARROW)) {
-                    //implicit n-ary lambda
-                    t = lambdaExpressionOrStatement(true, peekToken(MONKEYS_AT) || peekToken(FINAL), pos);
-                    break;
-                } else {
-                    nextToken();
-                    mode = EXPR | TYPE | NOPARAMS;
-                    t = term3();
-                    if ((mode & TYPE) != 0 && token.kind == LT) {
-                        // Could be a cast to a parameterized type
-                        JCTree.Tag op = JCTree.Tag.LT;
-                        int pos1 = token.pos;
-                        nextToken();
-                        mode &= (EXPR | TYPE);
-                        mode |= TYPEARG;
-                        JCExpression t1 = term3();
-                        if ((mode & TYPE) != 0 &&
-                            (token.kind == COMMA || token.kind == GT)) {
-                            mode = TYPE;
-                            ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
-                            args.append(t1);
-                            while (token.kind == COMMA) {
-                                nextToken();
-                                args.append(typeArgument());
-                            }
-                            accept(GT);
-                            t = toP(F.at(pos1).TypeApply(t, args.toList()));
-                            checkGenerics();
-                            mode = EXPR | TYPE; //could be a lambda or a method ref or a cast to a type
-                            t = term3Rest(t, typeArgs);
-                            if (token.kind == IDENTIFIER || token.kind == ELLIPSIS) {
-                                //explicit lambda (w/ generic type)
-                                mode = EXPR;
-                                JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
-                                if (token.kind == ELLIPSIS) {
-                                    mods.flags = Flags.VARARGS;
-                                    t = to(F.at(token.pos).TypeArray(t));
-                                    nextToken();
-                                }
-                                t = lambdaExpressionOrStatement(variableDeclaratorId(mods, t), pos);
-                                break;
-                            }
-                        } else if ((mode & EXPR) != 0) {
-                            mode = EXPR;
-                            JCExpression e = term2Rest(t1, TreeInfo.shiftPrec);
-                            t = F.at(pos1).Binary(op, t, e);
-                            t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
-                        } else {
-                            accept(GT);
-                        }
-                    } else if ((mode & TYPE) != 0 &&
-                            (token.kind == IDENTIFIER || token.kind == ELLIPSIS)) {
-                        //explicit lambda (w/ non-generic type)
+                ParensResult pres = analyzeParens();
+                switch (pres) {
+                    case CAST:
+                       accept(LPAREN);
+                       mode = TYPE;
+                       int pos1 = pos;
+                       List<JCExpression> targets = List.of(t = term3());
+                       while (token.kind == AMP) {
+                           checkIntersectionTypesInCast();
+                           accept(AMP);
+                           targets = targets.prepend(term3());
+                       }
+                       if (targets.length() > 1) {
+                           t = toP(F.at(pos1).TypeIntersection(targets.reverse()));
+                       }
+                       accept(RPAREN);
+                       mode = EXPR;
+                       JCExpression t1 = term3();
+                       return F.at(pos).TypeCast(t, t1);
+                    case IMPLICIT_LAMBDA:
+                    case EXPLICIT_LAMBDA:
+                        t = lambdaExpressionOrStatement(true, pres == ParensResult.EXPLICIT_LAMBDA, pos);
+                        break;
+                    default: //PARENS
+                        accept(LPAREN);
                         mode = EXPR;
-                        JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
-                        if (token.kind == ELLIPSIS) {
-                            mods.flags = Flags.VARARGS;
-                            t = to(F.at(token.pos).TypeArray(t));
-                            nextToken();
-                        }
-                        t = lambdaExpressionOrStatement(variableDeclaratorId(mods, t), pos);
+                        t = termRest(term1Rest(term2Rest(term3(), TreeInfo.orPrec)));
+                        accept(RPAREN);
+                        t = toP(F.at(pos).Parens(t));
                         break;
-                    } else {
-                        t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
-                    }
-                }
-
-                accept(RPAREN);
-                lastmode = mode;
-                mode = EXPR;
-                if ((lastmode & EXPR) == 0) {
-                    JCExpression t1 = term3();
-                    return F.at(pos).TypeCast(t, t1);
-                } else if ((lastmode & TYPE) != 0) {
-                    switch (token.kind) {
-                    /*case PLUSPLUS: case SUBSUB: */
-                    case BANG: case TILDE:
-                    case LPAREN: case THIS: case SUPER:
-                    case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
-                    case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
-                    case TRUE: case FALSE: case NULL:
-                        case NEW: case IDENTIFIER: case ASSERT: case ENUM:
-                    case BYTE: case SHORT: case CHAR: case INT:
-                    case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
-                        JCExpression t1 = term3();
-                        return F.at(pos).TypeCast(t, t1);
-                    }
                 }
             } else {
                 return illegal();
             }
-            t = toP(F.at(pos).Parens(t));
             break;
         case THIS:
             if ((mode & EXPR) != 0) {
@@ -1346,6 +1307,138 @@
         }
     }
 
+    /**
+     * If we see an identifier followed by a '&lt;' it could be an unbound
+     * method reference or a binary expression. To disambiguate, look for a
+     * matching '&gt;' and see if the subsequent terminal is either '.' or '#'.
+     */
+    @SuppressWarnings("fallthrough")
+    ParensResult analyzeParens() {
+        int depth = 0;
+        boolean type = false;
+        for (int lookahead = 0 ; ; lookahead++) {
+            TokenKind tk = S.token(lookahead).kind;
+            switch (tk) {
+                case EXTENDS: case SUPER: case COMMA:
+                    type = true;
+                case QUES: case DOT: case AMP:
+                    //skip
+                    break;
+                case BYTE: case SHORT: case INT: case LONG: case FLOAT:
+                case DOUBLE: case BOOLEAN: case CHAR:
+                    if (peekToken(lookahead, RPAREN)) {
+                        //Type, ')' -> cast
+                        return ParensResult.CAST;
+                    } else if (peekToken(lookahead, IDENTIFIER)) {
+                        //Type, 'Identifier -> explicit lambda
+                        return ParensResult.EXPLICIT_LAMBDA;
+                    }
+                    break;
+                case LPAREN:
+                    if (lookahead != 0) {
+                        // '(' in a non-starting position -> parens
+                        return ParensResult.PARENS;
+                    } else if (peekToken(lookahead, RPAREN)) {
+                        // '(', ')' -> explicit lambda
+                        return ParensResult.EXPLICIT_LAMBDA;
+                    }
+                    break;
+                case RPAREN:
+                    // if we have seen something that looks like a type,
+                    // then it's a cast expression
+                    if (type) return ParensResult.CAST;
+                    // otherwise, disambiguate cast vs. parenthesized expression
+                    // based on subsequent token.
+                    switch (S.token(lookahead + 1).kind) {
+                        /*case PLUSPLUS: case SUBSUB: */
+                        case BANG: case TILDE:
+                        case LPAREN: case THIS: case SUPER:
+                        case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
+                        case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
+                        case TRUE: case FALSE: case NULL:
+                            case NEW: case IDENTIFIER: case ASSERT: case ENUM:
+                        case BYTE: case SHORT: case CHAR: case INT:
+                        case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
+                            return ParensResult.CAST;
+                        default:
+                            return ParensResult.PARENS;
+                    }
+                case IDENTIFIER:
+                    if (peekToken(lookahead, IDENTIFIER)) {
+                        // Identifier, Identifier -> explicit lambda
+                        return ParensResult.EXPLICIT_LAMBDA;
+                    } else if (peekToken(lookahead, RPAREN, ARROW)) {
+                        // Identifier, ')' '->' -> implicit lambda
+                        return ParensResult.IMPLICIT_LAMBDA;
+                    }
+                    break;
+                case FINAL:
+                case ELLIPSIS:
+                case MONKEYS_AT:
+                    //those can only appear in explicit lambdas
+                    return ParensResult.EXPLICIT_LAMBDA;
+                case LBRACKET:
+                    if (peekToken(lookahead, RBRACKET, IDENTIFIER)) {
+                        // '[', ']', Identifier -> explicit lambda
+                        return ParensResult.EXPLICIT_LAMBDA;
+                    } else if (peekToken(lookahead, RBRACKET, RPAREN) ||
+                            peekToken(lookahead, RBRACKET, AMP)) {
+                        // '[', ']', ')' -> cast
+                        // '[', ']', '&' -> cast (intersection type)
+                        return ParensResult.CAST;
+                    } else if (peekToken(lookahead, RBRACKET)) {
+                        //consume the ']' and skip
+                        type = true;
+                        lookahead++;
+                        break;
+                    } else {
+                        return ParensResult.PARENS;
+                    }
+                case LT:
+                    depth++; break;
+                case GTGTGT:
+                    depth--;
+                case GTGT:
+                    depth--;
+                case GT:
+                    depth--;
+                    if (depth == 0) {
+                        if (peekToken(lookahead, RPAREN) ||
+                                peekToken(lookahead, AMP)) {
+                            // '>', ')' -> cast
+                            // '>', '&' -> cast
+                            return ParensResult.CAST;
+                        } else if (peekToken(lookahead, IDENTIFIER, COMMA) ||
+                                peekToken(lookahead, IDENTIFIER, RPAREN, ARROW) ||
+                                peekToken(lookahead, ELLIPSIS)) {
+                            // '>', Identifier, ',' -> explicit lambda
+                            // '>', Identifier, ')', '->' -> explicit lambda
+                            // '>', '...' -> explicit lambda
+                            return ParensResult.EXPLICIT_LAMBDA;
+                        }
+                        //it looks a type, but could still be (i) a cast to generic type,
+                        //(ii) an unbound method reference or (iii) an explicit lambda
+                        type = true;
+                        break;
+                    } else if (depth < 0) {
+                        //unbalanced '<', '>' - not a generic type
+                        return ParensResult.PARENS;
+                    }
+                    break;
+                default:
+                    //this includes EOF
+                    return ParensResult.PARENS;
+            }
+        }
+    }
+
+    enum ParensResult {
+        CAST,
+        EXPLICIT_LAMBDA,
+        IMPLICIT_LAMBDA,
+        PARENS;
+    }
+
     JCExpression lambdaExpressionOrStatement(JCVariableDecl firstParam, int pos) {
         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
         params.append(firstParam);
@@ -3171,21 +3264,12 @@
     /** Check that given tree is a legal expression statement.
      */
     protected JCExpression checkExprStat(JCExpression t) {
-        switch(t.getTag()) {
-        case PREINC: case PREDEC:
-        case POSTINC: case POSTDEC:
-        case ASSIGN:
-        case BITOR_ASG: case BITXOR_ASG: case BITAND_ASG:
-        case SL_ASG: case SR_ASG: case USR_ASG:
-        case PLUS_ASG: case MINUS_ASG:
-        case MUL_ASG: case DIV_ASG: case MOD_ASG:
-        case APPLY: case NEWCLASS:
-        case ERRONEOUS:
-            return t;
-        default:
+        if (!TreeInfo.isExpressionStatement(t)) {
             JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
             error(ret, "not.stmt");
             return ret;
+        } else {
+            return t;
         }
     }
 
@@ -3395,6 +3479,12 @@
             allowDefaultMethods = true;
         }
     }
+    void checkIntersectionTypesInCast() {
+        if (!allowIntersectionTypesInCast) {
+            log.error(token.pos, "intersection.types.in.cast.not.supported.in.source", source.name);
+            allowIntersectionTypesInCast = true;
+        }
+    }
 
     /*
      * a functional source tree and end position mappings
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Dec 10 20:59:38 2012 -0800
@@ -187,8 +187,9 @@
     {0}
 
 # 0: symbol, 1: symbol kind, 2: symbol
-compiler.misc.invalid.generic.desc.in.functional.intf=\
-    invalid functional descriptor: method {0} in {1} {2} is generic
+compiler.misc.invalid.generic.lambda.target=\
+    invalid functional descriptor for lambda expression\n\
+    method {0} in {1} {2} is generic
 
 # 0: symbol kind, 1: symbol
 compiler.misc.incompatible.descs.in.functional.intf=\
@@ -206,6 +207,10 @@
 compiler.misc.no.suitable.functional.intf.inst=\
     cannot infer functional interface descriptor for {0}
 
+# 0: type
+compiler.misc.secondary.bound.must.be.marker.intf=\
+    secondary bound {0} must be a marker interface
+
 # 0: symbol kind, 1: message segment
 compiler.err.invalid.mref=\
     invalid {0} reference; {1}
@@ -214,6 +219,12 @@
 compiler.misc.invalid.mref=\
     invalid {0} reference; {1}
 
+compiler.misc.static.mref.with.targs=\
+    parameterized qualifier on static method reference
+
+compiler.misc.static.bound.mref=\
+    static bound method reference
+
 # 0: symbol
 compiler.err.cant.assign.val.to.final.var=\
     cannot assign a value to final variable {0}
@@ -2196,6 +2207,11 @@
     default methods are not supported in -source {0}\n\
     (use -source 8 or higher to enable default methods)
 
+# 0: string
+compiler.err.intersection.types.in.cast.not.supported.in.source=\
+    intersection types in cast are not supported in -source {0}\n\
+    (use -source 8 or higher to enable default methods)
+
 ########################################
 # Diagnostics for verbose resolution
 # used by Resolve (debug only)
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Mon Dec 10 20:59:38 2012 -0800
@@ -254,6 +254,10 @@
          */
         TYPEUNION,
 
+        /** Intersection types, of type TypeIntersection
+         */
+        TYPEINTERSECTION,
+
         /** Formal type parameters, of type TypeParameter.
          */
         TYPEPARAMETER,
@@ -1829,8 +1833,6 @@
             STATIC(ReferenceMode.INVOKE, false),
             /** Expr # instMethod */
             BOUND(ReferenceMode.INVOKE, false),
-            /** Expr # staticMethod */
-            STATIC_EVAL(ReferenceMode.INVOKE, false),
             /** Inner # new */
             IMPLICIT_INNER(ReferenceMode.NEW, false),
             /** Toplevel # new */
@@ -2064,6 +2066,34 @@
     }
 
     /**
+     * An intersection type, T1 & T2 & ... Tn (used in cast expressions)
+     */
+    public static class JCTypeIntersection extends JCExpression implements IntersectionTypeTree {
+
+        public List<JCExpression> bounds;
+
+        protected JCTypeIntersection(List<JCExpression> bounds) {
+            this.bounds = bounds;
+        }
+        @Override
+        public void accept(Visitor v) { v.visitTypeIntersection(this); }
+
+        public Kind getKind() { return Kind.INTERSECTION_TYPE; }
+
+        public List<JCExpression> getBounds() {
+            return bounds;
+        }
+        @Override
+        public <R,D> R accept(TreeVisitor<R,D> v, D d) {
+            return v.visitIntersectionType(this, d);
+        }
+        @Override
+        public Tag getTag() {
+            return TYPEINTERSECTION;
+        }
+    }
+
+    /**
      * A formal class parameter.
      */
     public static class JCTypeParameter extends JCTree implements TypeParameterTree {
@@ -2385,6 +2415,7 @@
         public void visitTypeArray(JCArrayTypeTree that)     { visitTree(that); }
         public void visitTypeApply(JCTypeApply that)         { visitTree(that); }
         public void visitTypeUnion(JCTypeUnion that)         { visitTree(that); }
+        public void visitTypeIntersection(JCTypeIntersection that)  { visitTree(that); }
         public void visitTypeParameter(JCTypeParameter that) { visitTree(that); }
         public void visitWildcard(JCWildcard that)           { visitTree(that); }
         public void visitTypeBoundKind(TypeBoundKind that)   { visitTree(that); }
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Mon Dec 10 20:59:38 2012 -0800
@@ -1249,6 +1249,14 @@
         }
     }
 
+    public void visitTypeIntersection(JCTypeIntersection tree) {
+        try {
+            printExprs(tree.bounds, " & ");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
     public void visitTypeParameter(JCTypeParameter tree) {
         try {
             print(tree.name);
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Mon Dec 10 20:59:38 2012 -0800
@@ -358,6 +358,12 @@
         return M.at(t.pos).TypeUnion(components);
     }
 
+    public JCTree visitIntersectionType(IntersectionTypeTree node, P p) {
+        JCTypeIntersection t = (JCTypeIntersection) node;
+        List<JCExpression> bounds = copy(t.bounds, p);
+        return M.at(t.pos).TypeIntersection(bounds);
+    }
+
     public JCTree visitArrayType(ArrayTypeTree node, P p) {
         JCArrayTypeTree t = (JCArrayTypeTree) node;
         JCExpression elemtype = copy(t.elemtype, p);
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Mon Dec 10 20:59:38 2012 -0800
@@ -267,6 +267,25 @@
         return lambda.params.isEmpty() ||
                 lambda.params.head.vartype != null;
     }
+
+    /** Return true if the tree corresponds to an expression statement */
+    public static boolean isExpressionStatement(JCExpression tree) {
+        switch(tree.getTag()) {
+            case PREINC: case PREDEC:
+            case POSTINC: case POSTDEC:
+            case ASSIGN:
+            case BITOR_ASG: case BITXOR_ASG: case BITAND_ASG:
+            case SL_ASG: case SR_ASG: case USR_ASG:
+            case PLUS_ASG: case MINUS_ASG:
+            case MUL_ASG: case DIV_ASG: case MOD_ASG:
+            case APPLY: case NEWCLASS:
+            case ERRONEOUS:
+                return true;
+            default:
+                return false;
+        }
+    }
+
     /**
      * Return true if the AST corresponds to a static select of the kind A.B
      */
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Mon Dec 10 20:59:38 2012 -0800
@@ -456,6 +456,12 @@
         return tree;
     }
 
+    public JCTypeIntersection TypeIntersection(List<JCExpression> components) {
+        JCTypeIntersection tree = new JCTypeIntersection(components);
+        tree.pos = pos;
+        return tree;
+    }
+
     public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) {
         JCTypeParameter tree = new JCTypeParameter(name, bounds);
         tree.pos = pos;
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Mon Dec 10 20:59:38 2012 -0800
@@ -286,6 +286,10 @@
         scan(tree.alternatives);
     }
 
+    public void visitTypeIntersection(JCTypeIntersection tree) {
+        scan(tree.bounds);
+    }
+
     public void visitTypeParameter(JCTypeParameter tree) {
         scan(tree.bounds);
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java	Mon Dec 10 20:59:38 2012 -0800
@@ -379,6 +379,11 @@
         result = tree;
     }
 
+    public void visitTypeIntersection(JCTypeIntersection tree) {
+        tree.bounds = translate(tree.bounds);
+        result = tree;
+    }
+
     public void visitTypeParameter(JCTypeParameter tree) {
         tree.bounds = translate(tree.bounds);
         result = tree;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/javax/lang/model/type/IntersectionType.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,47 @@
+/*
+ * 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 javax.lang.model.type;
+
+import java.util.List;
+
+/**
+ * Represents an intersection type.
+ *
+ * As of the {@link javax.lang.model.SourceVersion#RELEASE_8
+ * RELEASE_8} source version, intersection types can appear as the target type
+ * of a cast expression.
+ *
+ * @since 1.8
+ */
+public interface IntersectionType extends TypeMirror {
+
+    /**
+     * Return the bounds comprising this intersection type.
+     *
+     * @return the bounds of this intersection types.
+     */
+    List<? extends TypeMirror> getBounds();
+}
--- a/langtools/src/share/classes/javax/lang/model/type/TypeKind.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/javax/lang/model/type/TypeKind.java	Mon Dec 10 20:59:38 2012 -0800
@@ -144,7 +144,14 @@
       *
       * @since 1.7
       */
-    UNION;
+    UNION,
+
+    /**
+      * An intersection type.
+      *
+      * @since 1.8
+      */
+    INTERSECTION;
 
     /**
      * Returns {@code true} if this kind corresponds to a primitive
--- a/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/javax/lang/model/type/TypeVisitor.java	Mon Dec 10 20:59:38 2012 -0800
@@ -172,4 +172,14 @@
      * @since 1.7
      */
     R visitUnion(UnionType t, P p);
+
+    /**
+     * Visits an intersection type.
+     *
+     * @param t the type to visit
+     * @param p a visitor-specified parameter
+     * @return  a visitor-specified result
+     * @since 1.8
+     */
+    R visitIntersection(IntersectionType t, P p);
 }
--- a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java	Mon Dec 10 20:59:38 2012 -0800
@@ -111,6 +111,20 @@
     }
 
     /**
+     * Visits an {@code IntersectionType} element by calling {@code
+     * visitUnknown}.
+
+     * @param t  {@inheritDoc}
+     * @param p  {@inheritDoc}
+     * @return the result of {@code visitUnknown}
+     *
+     * @since 1.8
+     */
+    public R visitIntersection(IntersectionType t, P p) {
+        return visitUnknown(t, p);
+    }
+
+    /**
      * {@inheritDoc}
      *
      * <p> The default implementation of this method in {@code
--- a/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor8.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/javax/lang/model/util/AbstractTypeVisitor8.java	Mon Dec 10 20:59:38 2012 -0800
@@ -66,4 +66,13 @@
     protected AbstractTypeVisitor8() {
         super();
     }
+
+    /**
+     * Visits an {@code IntersectionType} in a manner defined by a subclass.
+     *
+     * @param t  {@inheritDoc}
+     * @param p  {@inheritDoc}
+     * @return the result of the visit as defined by a subclass
+     */
+    public abstract R visitIntersection(IntersectionType t, P p);
 }
--- a/langtools/src/share/classes/javax/tools/JavaCompiler.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/src/share/classes/javax/tools/JavaCompiler.java	Mon Dec 10 20:59:38 2012 -0800
@@ -108,8 +108,8 @@
  *     example a recommended coding pattern:
  *
  *     <pre>
- *       Files[] files1 = ... ; // input for first compilation task
- *       Files[] files2 = ... ; // input for second compilation task
+ *       File[] files1 = ... ; // input for first compilation task
+ *       File[] files2 = ... ; // input for second compilation task
  *
  *       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
  *       StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
@@ -165,7 +165,7 @@
  *       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
  *       StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
  *       JavaFileManager fileManager = new ForwardingJavaFileManager(stdFileManager) {
- *           public void flush() {
+ *           public void flush() throws IOException {
  *               logger.entering(StandardJavaFileManager.class.getName(), "flush");
  *               super.flush();
  *               logger.exiting(StandardJavaFileManager.class.getName(), "flush");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/7144981/IgnoreIgnorableCharactersInInput.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,92 @@
+
+/*
+ * @test  /nodynamiccopyright/
+ * @bug 7144981
+ * @summary javac should ignore ignorable characters in input
+ * @run main IgnoreIgnorableCharactersInInput
+ */
+
+import com.sun.source.util.JavacTask;
+import java.io.File;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.TreeSet;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+public class IgnoreIgnorableCharactersInInput {
+
+    public static void main(String... args) throws Exception {
+        new IgnoreIgnorableCharactersInInput().run();
+    }
+
+    void run() throws Exception {
+        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+        File classesDir = new File(System.getProperty("user.dir"), "classes");
+        classesDir.mkdirs();
+        JavaSource[] sources = new JavaSource[]{
+            new JavaSource("TestOneIgnorableChar", "AA\\u0000BB"),
+            new JavaSource("TestMultipleIgnorableChar", "AA\\u0000\\u0000\\u0000BB")};
+        JavacTask ct = (JavacTask)comp.getTask(null, null, null,
+                Arrays.asList("-d", classesDir.getPath()),
+                null, Arrays.asList(sources));
+        try {
+            if (!ct.call()) {
+                throw new AssertionError("Error thrown when compiling test cases");
+            }
+        } catch (Throwable ex) {
+            throw new AssertionError("Error thrown when compiling test cases");
+        }
+        check(classesDir,
+                "TestOneIgnorableChar.class",
+                "TestOneIgnorableChar$AABB.class",
+                "TestMultipleIgnorableChar.class",
+                "TestMultipleIgnorableChar$AABB.class");
+        if (errors > 0)
+            throw new AssertionError("There are some errors in the test check the error output");
+    }
+
+    /**
+     *  Check that a directory contains the expected files.
+     */
+    void check(File dir, String... paths) {
+        Set<String> found = new TreeSet<String>(Arrays.asList(dir.list()));
+        Set<String> expect = new TreeSet<String>(Arrays.asList(paths));
+        if (found.equals(expect))
+            return;
+        for (String f: found) {
+            if (!expect.contains(f))
+                error("Unexpected file found: " + f);
+        }
+        for (String e: expect) {
+            if (!found.contains(e))
+                error("Expected file not found: " + e);
+        }
+    }
+
+    int errors;
+
+    void error(String msg) {
+        System.err.println(msg);
+        errors++;
+    }
+
+    class JavaSource extends SimpleJavaFileObject {
+
+        String internalSource =
+            "public class #O {public class #I {} }";
+        public JavaSource(String outerClassName, String innerClassName) {
+            super(URI.create(outerClassName + ".java"), JavaFileObject.Kind.SOURCE);
+            internalSource =
+                    internalSource.replace("#O", outerClassName).replace("#I", innerClassName);
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return internalSource;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/7153958/CPoolRefClassContainingInlinedCts.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,134 @@
+/*
+ * 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 7153958
+ * @summary add constant pool reference to class containing inlined constants
+ * @compile pkg/ClassToBeStaticallyImported.java
+ * @run main CPoolRefClassContainingInlinedCts
+ */
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
+import com.sun.tools.classfile.ConstantPool.CPInfo;
+import com.sun.tools.classfile.ConstantPoolException;
+import java.io.File;
+import java.io.IOException;
+
+import static pkg.ClassToBeStaticallyImported.staticField;
+
+public class CPoolRefClassContainingInlinedCts {
+
+    public static void main(String args[]) throws Exception {
+        new CPoolRefClassContainingInlinedCts().run();
+    }
+
+    void run() throws Exception {
+        checkReferences();
+    }
+
+    int numberOfReferencedClassesToBeChecked = 0;
+
+    void checkClassName(String className) {
+        switch (className) {
+            case "SimpleAssignClass" : case "BinaryExpClass":
+            case "UnaryExpClass" : case "CastClass":
+            case "ParensClass" : case "CondClass":
+            case "IfClass" : case "pkg/ClassToBeStaticallyImported":
+                numberOfReferencedClassesToBeChecked++;
+        }
+    }
+
+    void checkReferences() throws IOException, ConstantPoolException {
+        File testClasses = new File(System.getProperty("test.classes"));
+        File file = new File(testClasses,
+                CPoolRefClassContainingInlinedCts.class.getName() + ".class");
+        ClassFile classFile = ClassFile.read(file);
+        int i = 1;
+        CPInfo cpInfo;
+        while (i < classFile.constant_pool.size()) {
+            cpInfo = classFile.constant_pool.get(i);
+            if (cpInfo instanceof CONSTANT_Class_info) {
+                checkClassName(((CONSTANT_Class_info)cpInfo).getName());
+            }
+            i += cpInfo.size();
+        }
+        if (numberOfReferencedClassesToBeChecked != 8) {
+            throw new AssertionError("Class reference missing in the constant pool");
+        }
+    }
+
+    private int assign = SimpleAssignClass.x;
+    private int binary = BinaryExpClass.x + 1;
+    private int unary = -UnaryExpClass.x;
+    private int cast = (int)CastClass.x;
+    private int parens = (ParensClass.x);
+    private int cond = (CondClass.x == 1) ? 1 : 2;
+    private static int ifConstant;
+    private static int importStatic;
+    static {
+        if (IfClass.x == 1) {
+            ifConstant = 1;
+        } else {
+            ifConstant = 2;
+        }
+    }
+    static {
+        if (staticField == 1) {
+            importStatic = 1;
+        } else {
+            importStatic = 2;
+        }
+    }
+}
+
+class SimpleAssignClass {
+    public static final int x = 1;
+}
+
+class BinaryExpClass {
+    public static final int x = 1;
+}
+
+class UnaryExpClass {
+    public static final int x = 1;
+}
+
+class CastClass {
+    public static final int x = 1;
+}
+
+class ParensClass {
+    public static final int x = 1;
+}
+
+class CondClass {
+    public static final int x = 1;
+}
+
+class IfClass {
+    public static final int x = 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/7153958/pkg/ClassToBeStaticallyImported.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,29 @@
+/*
+ * 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 pkg;
+
+public class ClassToBeStaticallyImported {
+    public static final int staticField = 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/intersection/IntersectionTypeCastTest.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,330 @@
+/*
+ * 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
+ * @bug 8002099
+ * @summary Add support for intersection types in cast expression
+ */
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class IntersectionTypeCastTest {
+
+    static int checkCount = 0;
+
+    interface Type {
+        boolean subtypeOf(Type that);
+        String asString();
+        boolean isClass();
+        boolean isInterface();
+    }
+
+    enum InterfaceKind implements Type {
+        A("interface A { }\n", "A", null),
+        B("interface B { }\n", "B", null),
+        C("interface C extends A { }\n", "C", A);
+
+        String declStr;
+        String typeStr;
+        InterfaceKind superInterface;
+
+        InterfaceKind(String declStr, String typeStr, InterfaceKind superInterface) {
+            this.declStr = declStr;
+            this.typeStr = typeStr;
+            this.superInterface = superInterface;
+        }
+
+        @Override
+        public boolean subtypeOf(Type that) {
+            return this == that || superInterface == that || that == ClassKind.OBJECT;
+        }
+
+        @Override
+        public String asString() {
+            return typeStr;
+        }
+
+        @Override
+        public boolean isClass() {
+            return false;
+        }
+
+        @Override
+        public boolean isInterface() {
+            return true;
+        }
+    }
+
+    enum ClassKind implements Type {
+        OBJECT(null, "Object"),
+        CA("#M class CA implements A { }\n", "CA", InterfaceKind.A),
+        CB("#M class CB implements B { }\n", "CB", InterfaceKind.B),
+        CAB("#M class CAB implements A, B { }\n", "CAB", InterfaceKind.A, InterfaceKind.B),
+        CC("#M class CC implements C { }\n", "CC", InterfaceKind.C, InterfaceKind.A),
+        CCA("#M class CCA implements C, A { }\n", "CCA", InterfaceKind.C, InterfaceKind.A),
+        CCB("#M class CCB implements C, B { }\n", "CCB", InterfaceKind.C, InterfaceKind.A, InterfaceKind.B),
+        CCAB("#M class CCAB implements C, A, B { }\n", "CCAB", InterfaceKind.C, InterfaceKind.A, InterfaceKind.B);
+
+        String declTemplate;
+        String typeStr;
+        List<InterfaceKind> superInterfaces;
+
+        ClassKind(String declTemplate, String typeStr, InterfaceKind... superInterfaces) {
+            this.declTemplate = declTemplate;
+            this.typeStr = typeStr;
+            this.superInterfaces = List.from(superInterfaces);
+        }
+
+        String getDecl(ModifierKind mod) {
+            return declTemplate != null ?
+                    declTemplate.replaceAll("#M", mod.modStr) :
+                    "";
+        }
+
+        @Override
+        public boolean subtypeOf(Type that) {
+            return this == that || superInterfaces.contains(that) || that == OBJECT;
+        }
+
+        @Override
+        public String asString() {
+            return typeStr;
+        }
+
+        @Override
+        public boolean isClass() {
+            return true;
+        }
+
+        @Override
+        public boolean isInterface() {
+            return false;
+        }
+    }
+
+    enum ModifierKind {
+        NONE(""),
+        FINAL("final");
+
+        String modStr;
+
+        ModifierKind(String modStr) {
+            this.modStr = modStr;
+        }
+    }
+
+    enum CastKind {
+        CLASS("(#C)", 0),
+        INTERFACE("(#I0)", 1),
+        INTERSECTION2("(#C & #I0)", 1),
+        INTERSECTION3("(#C & #I0 & #I1)", 2);
+        //INTERSECTION4("(#C & #I0 & #I1 & #I2)", 3);
+
+        String castTemplate;
+        int interfaceBounds;
+
+        CastKind(String castTemplate, int interfaceBounds) {
+            this.castTemplate = castTemplate;
+            this.interfaceBounds = interfaceBounds;
+        }
+    }
+
+    static class CastInfo {
+        CastKind kind;
+        Type[] types;
+
+        CastInfo(CastKind kind, Type... types) {
+            this.kind = kind;
+            this.types = types;
+        }
+
+        String getCast() {
+            String temp = kind.castTemplate.replaceAll("#C", types[0].asString());
+            for (int i = 0; i < kind.interfaceBounds ; i++) {
+                temp = temp.replace(String.format("#I%d", i), types[i + 1].asString());
+            }
+            return temp;
+        }
+
+        boolean hasDuplicateTypes() {
+            for (int i = 0 ; i < types.length ; i++) {
+                for (int j = 0 ; j < types.length ; j++) {
+                    if (i != j && types[i] == types[j]) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        boolean compatibleWith(ModifierKind mod, CastInfo that) {
+            for (Type t1 : types) {
+                for (Type t2 : that.types) {
+                    boolean compat =
+                            t1.subtypeOf(t2) ||
+                            t2.subtypeOf(t1) ||
+                            (t1.isInterface() && t2.isInterface()) || //side-cast (1)
+                            (mod == ModifierKind.NONE && (t1.isInterface() != t2.isInterface())); //side-cast (2)
+                    if (!compat) return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        //create default shared JavaCompiler - reused across multiple compilations
+        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+        for (ModifierKind mod : ModifierKind.values()) {
+            for (CastInfo cast1 : allCastInfo()) {
+                for (CastInfo cast2 : allCastInfo()) {
+                    new IntersectionTypeCastTest(mod, cast1, cast2).run(comp, fm);
+                }
+            }
+        }
+        System.out.println("Total check executed: " + checkCount);
+    }
+
+    static List<CastInfo> allCastInfo() {
+        ListBuffer<CastInfo> buf = ListBuffer.lb();
+        for (CastKind kind : CastKind.values()) {
+            for (ClassKind clazz : ClassKind.values()) {
+                if (kind == CastKind.INTERFACE && clazz != ClassKind.OBJECT) {
+                    continue;
+                } else if (kind.interfaceBounds == 0) {
+                    buf.append(new CastInfo(kind, clazz));
+                    continue;
+                } else {
+                    for (InterfaceKind intf1 : InterfaceKind.values()) {
+                        if (kind.interfaceBounds == 1) {
+                            buf.append(new CastInfo(kind, clazz, intf1));
+                            continue;
+                        } else {
+                            for (InterfaceKind intf2 : InterfaceKind.values()) {
+                                if (kind.interfaceBounds == 2) {
+                                    buf.append(new CastInfo(kind, clazz, intf1, intf2));
+                                    continue;
+                                } else {
+                                    for (InterfaceKind intf3 : InterfaceKind.values()) {
+                                        buf.append(new CastInfo(kind, clazz, intf1, intf2, intf3));
+                                        continue;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return buf.toList();
+    }
+
+    ModifierKind mod;
+    CastInfo cast1, cast2;
+    JavaSource source;
+    DiagnosticChecker diagChecker;
+
+    IntersectionTypeCastTest(ModifierKind mod, CastInfo cast1, CastInfo cast2) {
+        this.mod = mod;
+        this.cast1 = cast1;
+        this.cast2 = cast2;
+        this.source = new JavaSource();
+        this.diagChecker = new DiagnosticChecker();
+    }
+
+    class JavaSource extends SimpleJavaFileObject {
+
+        String bodyTemplate = "class Test {\n" +
+                              "   void test() {\n" +
+                              "      Object o = #C1#C2null;\n" +
+                              "   } }";
+
+        String source = "";
+
+        public JavaSource() {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            for (ClassKind ck : ClassKind.values()) {
+                source += ck.getDecl(mod);
+            }
+            for (InterfaceKind ik : InterfaceKind.values()) {
+                source += ik.declStr;
+            }
+            source += bodyTemplate.replaceAll("#C1", cast1.getCast()).replaceAll("#C2", cast2.getCast());
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return source;
+        }
+    }
+
+    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+                Arrays.asList("-XDallowIntersectionTypes"), null, Arrays.asList(source));
+        try {
+            ct.analyze();
+        } catch (Throwable ex) {
+            throw new AssertionError("Error thrown when compiling the following code:\n" + source.getCharContent(true));
+        }
+        check();
+    }
+
+    void check() {
+        checkCount++;
+
+        boolean errorExpected = cast1.hasDuplicateTypes() || cast2.hasDuplicateTypes();
+
+        errorExpected |= !cast2.compatibleWith(mod, cast1);
+
+        if (errorExpected != diagChecker.errorFound) {
+            throw new Error("invalid diagnostics for source:\n" +
+                source.getCharContent(true) +
+                "\nFound error: " + diagChecker.errorFound +
+                "\nExpected error: " + errorExpected);
+        }
+    }
+
+    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+        boolean errorFound;
+
+        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+                errorFound = true;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/intersection/IntersectionTypeParserTest.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,191 @@
+/*
+ * 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
+ * @bug 8002099
+ * @summary Add support for intersection types in cast expression
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class IntersectionTypeParserTest {
+
+    static int checkCount = 0;
+
+    enum TypeKind {
+        SIMPLE("A"),
+        GENERIC("A<X>"),
+        WILDCARD("A<? super X, ? extends Y>");
+
+        String typeStr;
+
+        TypeKind(String typeStr) {
+            this.typeStr = typeStr;
+        }
+    }
+
+    enum ArrayKind {
+        NONE(""),
+        SINGLE("[]"),
+        DOUBLE("[][]");
+
+        String arrStr;
+
+        ArrayKind(String arrStr) {
+            this.arrStr = arrStr;
+        }
+    }
+
+    static class Type {
+        TypeKind tk;
+        ArrayKind ak;
+
+        Type(TypeKind tk, ArrayKind ak) {
+            this.tk = tk;
+            this.ak = ak;
+        }
+
+        String asString() {
+            return tk.typeStr + ak.arrStr;
+        }
+    }
+
+    enum CastKind {
+        ONE("(#T0)", 1),
+        TWO("(#T0 & T1)", 2),
+        THREE("(#T0 & #T1 & #T2)", 3);
+
+        String castTemplate;
+        int nBounds;
+
+        CastKind(String castTemplate, int nBounds) {
+            this.castTemplate = castTemplate;
+            this.nBounds = nBounds;
+        }
+
+        String asString(Type... types) {
+            String res = castTemplate;
+            for (int i = 0; i < nBounds ; i++) {
+                res = res.replaceAll(String.format("#T%d", i), types[i].asString());
+            }
+            return res;
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        //create default shared JavaCompiler - reused across multiple compilations
+        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+        for (CastKind ck : CastKind.values()) {
+            for (TypeKind t1 : TypeKind.values()) {
+                for (ArrayKind ak1 : ArrayKind.values()) {
+                    Type typ1 = new Type(t1, ak1);
+                    if (ck.nBounds == 1) {
+                        new IntersectionTypeParserTest(ck, typ1).run(comp, fm);
+                        continue;
+                    }
+                    for (TypeKind t2 : TypeKind.values()) {
+                        for (ArrayKind ak2 : ArrayKind.values()) {
+                            Type typ2 = new Type(t2, ak2);
+                            if (ck.nBounds == 2) {
+                                new IntersectionTypeParserTest(ck, typ1, typ2).run(comp, fm);
+                                continue;
+                            }
+                            for (TypeKind t3 : TypeKind.values()) {
+                                for (ArrayKind ak3 : ArrayKind.values()) {
+                                    Type typ3 = new Type(t3, ak3);
+                                    new IntersectionTypeParserTest(ck, typ1, typ2, typ3).run(comp, fm);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        System.out.println("Total check executed: " + checkCount);
+    }
+
+    CastKind ck;
+    Type[] types;
+    JavaSource source;
+    DiagnosticChecker diagChecker;
+
+    IntersectionTypeParserTest(CastKind ck, Type... types) {
+        this.ck = ck;
+        this.types = types;
+        this.source = new JavaSource();
+        this.diagChecker = new DiagnosticChecker();
+    }
+
+    class JavaSource extends SimpleJavaFileObject {
+
+        String bodyTemplate = "class Test {\n" +
+                              "   void test() {\n" +
+                              "      Object o = #Cnull;\n" +
+                              "   } }";
+
+        String source = "";
+
+        public JavaSource() {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            source += bodyTemplate.replaceAll("#C", ck.asString(types));
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return source;
+        }
+    }
+
+    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+        checkCount++;
+        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+                Arrays.asList("-XDallowIntersectionTypes"), null, Arrays.asList(source));
+        ct.parse();
+        if (diagChecker.errorFound) {
+            throw new Error("Unexpected parser error for source:\n" +
+                source.getCharContent(true));
+        }
+    }
+
+    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+        boolean errorFound;
+
+        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+                errorFound = true;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/intersection/model/Check.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+/**
+ * Annotation used by ModelChecker to mark the class whose model is to be checked
+ */
+@interface Check {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/intersection/model/IntersectionTypeInfo.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/**
+ * Used by ModelChecker to validate the modeling information of a union type.
+ */
+@interface IntersectionTypeInfo {
+    String[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/intersection/model/Member.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,31 @@
+/*
+ * 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 javax.lang.model.element.ElementKind;
+
+/**
+ * Annotation used by ModelChecker to mark a member that is to be checked
+ */
+@interface Member {
+   ElementKind value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/intersection/model/Model01.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,52 @@
+/*
+ * 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
+ * @bug 8002099
+ * @summary Add support for intersection types in cast expression
+ * @library ../../../lib
+ * @build JavacTestingAbstractProcessor ModelChecker
+ * @compile -XDallowIntersectionTypes -processor ModelChecker Model01.java
+ */
+
+import javax.lang.model.element.ElementKind;
+
+@Check
+class Test {
+
+    interface A {
+        @Member(ElementKind.METHOD)
+        public void m1();
+    }
+
+    interface B {
+        @Member(ElementKind.METHOD)
+        public void m2();
+    }
+
+    void test(){
+        @IntersectionTypeInfo({"java.lang.Object", "Test.A", "Test.B"})
+        Object o = (A & B)null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/cast/intersection/model/ModelChecker.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,153 @@
+/*
+ * 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 com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.TypeCastTree;
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.Trees;
+import com.sun.source.util.TreePath;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+
+import java.util.Set;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.IntersectionType;
+import javax.lang.model.type.UnknownTypeException;
+import javax.lang.model.util.SimpleTypeVisitor6;
+import javax.lang.model.util.SimpleTypeVisitor7;
+
+@SupportedAnnotationTypes("Check")
+public class ModelChecker extends JavacTestingAbstractProcessor {
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        if (roundEnv.processingOver())
+            return true;
+
+        Trees trees = Trees.instance(processingEnv);
+
+        TypeElement testAnno = elements.getTypeElement("Check");
+        for (Element elem: roundEnv.getElementsAnnotatedWith(testAnno)) {
+            TreePath p = trees.getPath(elem);
+            new IntersectionCastTester(trees).scan(p, null);
+        }
+        return true;
+    }
+
+    class IntersectionCastTester extends TreePathScanner<Void, Void> {
+        Trees trees;
+
+        public IntersectionCastTester(Trees trees) {
+            super();
+            this.trees = trees;
+        }
+
+        @Override
+        public Void visitVariable(VariableTree node, Void p) {
+
+            TreePath varPath = new TreePath(getCurrentPath(), node);
+            Element v = trees.getElement(varPath);
+
+            IntersectionTypeInfo it = v.getAnnotation(IntersectionTypeInfo.class);
+            assertTrue(it != null, "IntersectionType annotation must be present");
+
+            ExpressionTree varInit = node.getInitializer();
+            assertTrue(varInit != null && varInit.getKind() == Tree.Kind.TYPE_CAST,
+                    "variable must have be initialized to an expression containing an intersection type cast");
+
+            TypeMirror t = ((JCExpression)((TypeCastTree)varInit).getType()).type;
+
+            validateIntersectionTypeInfo(t, it);
+
+            for (Element e2 : types.asElement(t).getEnclosedElements()) {
+                assertTrue(false, "an intersection type has no declared members");
+            }
+
+            for (Element e2 : elements.getAllMembers((TypeElement)types.asElement(t))) {
+                Member m = e2.getAnnotation(Member.class);
+                if (m != null) {
+                    assertTrue(e2.getKind() == m.value(), "Expected " + m.value() + " - found " + e2.getKind());
+                }
+            }
+
+            assertTrue(assertionCount == 10, "Expected 10 assertions - found " + assertionCount);
+            return super.visitVariable(node, p);
+        }
+    }
+
+    private void validateIntersectionTypeInfo(TypeMirror expectedIntersectionType, IntersectionTypeInfo it) {
+
+        assertTrue(expectedIntersectionType.getKind() == TypeKind.INTERSECTION, "INTERSECTION kind expected");
+
+        try {
+            new SimpleTypeVisitor6<Void, Void>(){}.visit(expectedIntersectionType);
+            throw new RuntimeException("Expected UnknownTypeException not thrown.");
+        } catch (UnknownTypeException ute) {
+            ; // Expected
+        }
+
+        try {
+            new SimpleTypeVisitor7<Void, Void>(){}.visit(expectedIntersectionType);
+            throw new RuntimeException("Expected UnknownTypeException not thrown.");
+        } catch (UnknownTypeException ute) {
+            ; // Expected
+        }
+
+        IntersectionType intersectionType = new SimpleTypeVisitor<IntersectionType, Void>(){
+            @Override
+            protected IntersectionType defaultAction(TypeMirror e, Void p) {return null;}
+
+            @Override
+            public IntersectionType visitIntersection(IntersectionType t, Void p) {return t;}
+        }.visit(expectedIntersectionType);
+        assertTrue(intersectionType != null, "Must get a non-null intersection type.");
+
+        assertTrue(it.value().length == intersectionType.getBounds().size(), "Cardinalities do not match");
+
+        String[] typeNames = it.value();
+        for(int i = 0; i < typeNames.length; i++) {
+            TypeMirror typeFromAnnotation = nameToType(typeNames[i]);
+            assertTrue(types.isSameType(typeFromAnnotation, intersectionType.getBounds().get(i)),
+                       "Types were not equal.");
+        }
+    }
+
+    private TypeMirror nameToType(String name) {
+        return elements.getTypeElement(name).asType();
+    }
+
+    private static void assertTrue(boolean cond, String msg) {
+        assertionCount++;
+        if (!cond)
+            throw new AssertionError(msg);
+    }
+
+    static int assertionCount = 0;
+}
--- a/langtools/test/tools/javac/defaultMethodExecution/DefaultMethodRegressionTests.java	Thu Dec 06 12:04:44 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*
- * 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 8003639
- * @summary convert lambda testng tests to jtreg and add them
- * @run testng DefaultMethodRegressionTests
- */
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import org.testng.annotations.Test;
-
-import static org.testng.Assert.*;
-
-/**
- * This set of classes/interfaces (K/I/C) is specially designed to expose a
- * bug in the JVM where it did not find some overloaded methods in some
- * specific situations. (fixed by hotspot changeset ffb9316fd9ed)
- */
-interface K {
-    int bbb(Long l);
-}
-
-interface I extends K {
-    default void aaa() {}
-    default void aab() {}
-    default void aac() {}
-
-    default int bbb(Integer i) { return 22; }
-    default int bbb(Float f) { return 33; }
-    default int bbb(Long l) { return 44; }
-    default int bbb(Double d) { return 55; }
-    default int bbb(String s) { return 66; }
-
-    default void caa() {}
-    default void cab() {}
-    default void cac() {}
-}
-
-class C implements I {}
-
-public class DefaultMethodRegressionTests {
-
-    @Test(groups = "vm")
-    public void testLostOverloadedMethod() {
-        C c = new C();
-        assertEquals(c.bbb(new Integer(1)), 22);
-        assertEquals(c.bbb(new Float(1.1)), 33);
-        assertEquals(c.bbb(new Long(1L)), 44);
-        assertEquals(c.bbb(new Double(0.01)), 55);
-        assertEquals(c.bbb(new String("")), 66);
-    }
-
-    // Test to ensure that the inference verifier accepts older classfiles
-    // with classes that implement interfaces with defaults.
-    @Test(groups = "vm")
-    public void testInferenceVerifier() {
-        // interface I { int m() default { return 99; } }
-        byte I_bytes[] = {
-            (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x33,
-            0x00, 0x08, 0x07, 0x00, 0x06, 0x07, 0x00, 0x07,
-            0x01, 0x00, 0x03, 0x66, 0x6f, 0x6f, 0x01, 0x00,
-            0x03, 0x28, 0x29, 0x49, 0x01, 0x00, 0x04, 0x43,
-            0x6f, 0x64, 0x65, 0x01, 0x00, 0x01, 0x49, 0x01,
-            0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
-            0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
-            0x63, 0x74, 0x06, 0x00, 0x00, 0x01, 0x00, 0x02,
-            0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01,
-            0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05,
-            0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x01,
-            0x00, 0x00, 0x00, 0x03, 0x10, 0x63, (byte)0xac, 0x00,
-            0x00, 0x00, 0x00, 0x00, 0x00
-        };
-        // public class C implements I {}  /* -target 1.5 */
-        byte C_bytes[] = {
-            (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x31,
-            0x00, 0x0c, 0x0a, 0x00, 0x03, 0x00, 0x08, 0x07,
-            0x00, 0x09, 0x07, 0x00, 0x0a, 0x07, 0x00, 0x0b,
-            0x01, 0x00, 0x06, 0x3c, 0x69, 0x6e, 0x69, 0x74,
-            0x3e, 0x01, 0x00, 0x03, 0x28, 0x29, 0x56, 0x01,
-            0x00, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x0c, 0x00,
-            0x05, 0x00, 0x06, 0x01, 0x00, 0x01, 0x43, 0x01,
-            0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
-            0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
-            0x63, 0x74, 0x01, 0x00, 0x01, 0x49, 0x00, 0x21,
-            0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04,
-            0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x05,
-            0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00,
-            0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
-            0x00, 0x05, 0x2a, (byte)0xb7, 0x00, 0x01, (byte)0xb1, 0x00,
-            0x00, 0x00, 0x00, 0x00, 0x00
-        };
-
-        ClassLoader cl = new ClassLoader() {
-            protected Class<?> findClass(String name) {
-                if (name.equals("I")) {
-                    return defineClass("I", I_bytes, 0, I_bytes.length);
-                } else if (name.equals("C")) {
-                    return defineClass("C", C_bytes, 0, C_bytes.length);
-                } else {
-                    return null;
-                }
-            }
-        };
-        try {
-            Class.forName("C", true, cl);
-        } catch (Exception e) {
-            // unmodified verifier will throw VerifyError
-            fail("No exception should be thrown");
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/defaultMethodExecution/DefaultMethodRegressionTests.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,138 @@
+/*
+ * 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
+ * @ignore 8004360
+ * @bug 8003639
+ * @summary convert lambda testng tests to jtreg and add them
+ * @run testng DefaultMethodRegressionTests
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+/**
+ * This set of classes/interfaces (K/I/C) is specially designed to expose a
+ * bug in the JVM where it did not find some overloaded methods in some
+ * specific situations. (fixed by hotspot changeset ffb9316fd9ed)
+ */
+interface K {
+    int bbb(Long l);
+}
+
+interface I extends K {
+    default void aaa() {}
+    default void aab() {}
+    default void aac() {}
+
+    default int bbb(Integer i) { return 22; }
+    default int bbb(Float f) { return 33; }
+    default int bbb(Long l) { return 44; }
+    default int bbb(Double d) { return 55; }
+    default int bbb(String s) { return 66; }
+
+    default void caa() {}
+    default void cab() {}
+    default void cac() {}
+}
+
+class C implements I {}
+
+public class DefaultMethodRegressionTests {
+
+    @Test(groups = "vm")
+    public void testLostOverloadedMethod() {
+        C c = new C();
+        assertEquals(c.bbb(new Integer(1)), 22);
+        assertEquals(c.bbb(new Float(1.1)), 33);
+        assertEquals(c.bbb(new Long(1L)), 44);
+        assertEquals(c.bbb(new Double(0.01)), 55);
+        assertEquals(c.bbb(new String("")), 66);
+    }
+
+    // Test to ensure that the inference verifier accepts older classfiles
+    // with classes that implement interfaces with defaults.
+    @Test(groups = "vm")
+    public void testInferenceVerifier() {
+        // interface I { int m() default { return 99; } }
+        byte I_bytes[] = {
+            (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x33,
+            0x00, 0x08, 0x07, 0x00, 0x06, 0x07, 0x00, 0x07,
+            0x01, 0x00, 0x03, 0x66, 0x6f, 0x6f, 0x01, 0x00,
+            0x03, 0x28, 0x29, 0x49, 0x01, 0x00, 0x04, 0x43,
+            0x6f, 0x64, 0x65, 0x01, 0x00, 0x01, 0x49, 0x01,
+            0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
+            0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
+            0x63, 0x74, 0x06, 0x00, 0x00, 0x01, 0x00, 0x02,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01,
+            0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05,
+            0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x01,
+            0x00, 0x00, 0x00, 0x03, 0x10, 0x63, (byte)0xac, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00
+        };
+        // public class C implements I {}  /* -target 1.5 */
+        byte C_bytes[] = {
+            (byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, 0x00, 0x00, 0x00, 0x31,
+            0x00, 0x0c, 0x0a, 0x00, 0x03, 0x00, 0x08, 0x07,
+            0x00, 0x09, 0x07, 0x00, 0x0a, 0x07, 0x00, 0x0b,
+            0x01, 0x00, 0x06, 0x3c, 0x69, 0x6e, 0x69, 0x74,
+            0x3e, 0x01, 0x00, 0x03, 0x28, 0x29, 0x56, 0x01,
+            0x00, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x0c, 0x00,
+            0x05, 0x00, 0x06, 0x01, 0x00, 0x01, 0x43, 0x01,
+            0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c,
+            0x61, 0x6e, 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65,
+            0x63, 0x74, 0x01, 0x00, 0x01, 0x49, 0x00, 0x21,
+            0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04,
+            0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x05,
+            0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00,
+            0x00, 0x11, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
+            0x00, 0x05, 0x2a, (byte)0xb7, 0x00, 0x01, (byte)0xb1, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00
+        };
+
+        ClassLoader cl = new ClassLoader() {
+            protected Class<?> findClass(String name) {
+                if (name.equals("I")) {
+                    return defineClass("I", I_bytes, 0, I_bytes.length);
+                } else if (name.equals("C")) {
+                    return defineClass("C", C_bytes, 0, C_bytes.length);
+                } else {
+                    return null;
+                }
+            }
+        };
+        try {
+            Class.forName("C", true, cl);
+        } catch (Exception e) {
+            // unmodified verifier will throw VerifyError
+            fail("No exception should be thrown");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/IntersectionTypesInCastNotSupported.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.intersection.types.in.cast.not.supported.in.source
+// options: -source 7 -Xlint:-options
+
+interface IntersectionTypesInCastNotSupported {
+    Object o = (A & B)null;
+}
--- a/langtools/test/tools/javac/diags/examples/InvalidGenericDescInFunctionalInterface.java	Thu Dec 06 12:04:44 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-
-// key: compiler.err.prob.found.req
-// key: compiler.misc.invalid.generic.desc.in.functional.intf
-
-class InvalidGenericDescInFunctionalIntf {
-
-    interface SAM {
-        <Z> void m();
-    }
-
-    SAM s = x-> { };
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/InvalidGenericLambdaTarget.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.prob.found.req
+// key: compiler.misc.invalid.generic.lambda.target
+
+class InvalidGenericLambdaTarget {
+
+    interface SAM {
+        <Z> void m();
+    }
+
+    SAM s = x-> { };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/SecondaryBoundMustBeMarkerIntf.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.prob.found.req
+// key: compiler.misc.secondary.bound.must.be.marker.intf
+// options: -XDallowIntersectionTypes
+
+class SecondaryBoundMustBeMarkerInterface {
+    Runnable r = (Runnable & Comparable<?>)()->{};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/StaticBoundMref.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.mref
+// key: compiler.misc.static.bound.mref
+
+class StaticBoundMref {
+
+    Runnable r = new StaticBoundMref()::m;
+
+    static void m() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/StaticMrefWithTargs.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.mref
+// key: compiler.misc.static.mref.with.targs
+
+class StaticMrefWithTargs<X> {
+
+    Runnable r = StaticMrefWithTargs<String>::m;
+
+    static void m() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/FunctionalInterfaceConversionTest.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,280 @@
+/*
+ * 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
+ * @bug 8003280 8004102
+ * @summary Add lambda tests
+ *  perform several automated checks in lambda conversion, esp. around accessibility
+ * @author  Maurizio Cimadamore
+ * @run main FunctionalInterfaceConversionTest
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class FunctionalInterfaceConversionTest {
+
+    enum PackageKind {
+        NO_PKG(""),
+        PKG_A("a");
+
+        String pkg;
+
+        PackageKind(String pkg) {
+            this.pkg = pkg;
+        }
+
+        String getPkgDecl() {
+            return this == NO_PKG ?
+                "" :
+                "package " + pkg + ";";
+        }
+
+        String getImportStat() {
+            return this == NO_PKG ?
+                "" :
+                "import " + pkg + ".*;";
+        }
+    }
+
+    enum SamKind {
+        CLASS("public class Sam {  }"),
+        ABSTACT_CLASS("public abstract class Sam {  }"),
+        ANNOTATION("public @interface Sam {  }"),
+        ENUM("public enum Sam { }"),
+        INTERFACE("public interface Sam { \n #METH; \n }");
+
+        String sam_str;
+
+        SamKind(String sam_str) {
+            this.sam_str = sam_str;
+        }
+
+        String getSam(String methStr) {
+            return sam_str.replaceAll("#METH", methStr);
+        }
+    }
+
+    enum ModifierKind {
+        PUBLIC("public"),
+        PACKAGE("");
+
+        String modifier_str;
+
+        ModifierKind(String modifier_str) {
+            this.modifier_str = modifier_str;
+        }
+
+        boolean stricterThan(ModifierKind that) {
+            return this.ordinal() > that.ordinal();
+        }
+    }
+
+    enum TypeKind {
+        EXCEPTION("Exception"),
+        PKG_CLASS("PackageClass");
+
+        String typeStr;
+
+        private TypeKind(String typeStr) {
+            this.typeStr = typeStr;
+        }
+    }
+
+    enum ExprKind {
+        LAMBDA("x -> null"),
+        MREF("this::m");
+
+        String exprStr;
+
+        private ExprKind(String exprStr) {
+            this.exprStr = exprStr;
+        }
+    }
+
+    enum MethodKind {
+        NONE(""),
+        NON_GENERIC("public abstract #R m(#ARG s) throws #T;"),
+        GENERIC("public abstract <X> #R m(#ARG s) throws #T;");
+
+        String methodTemplate;
+
+        private MethodKind(String methodTemplate) {
+            this.methodTemplate = methodTemplate;
+        }
+
+        String getMethod(TypeKind retType, TypeKind argType, TypeKind thrownType) {
+            return methodTemplate.replaceAll("#R", retType.typeStr).
+                    replaceAll("#ARG", argType.typeStr).
+                    replaceAll("#T", thrownType.typeStr);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+        for (PackageKind samPkg : PackageKind.values()) {
+            for (ModifierKind modKind : ModifierKind.values()) {
+                for (SamKind samKind : SamKind.values()) {
+                    for (MethodKind samMeth : MethodKind.values()) {
+                        for (MethodKind clientMeth : MethodKind.values()) {
+                            for (TypeKind retType : TypeKind.values()) {
+                                for (TypeKind argType : TypeKind.values()) {
+                                    for (TypeKind thrownType : TypeKind.values()) {
+                                        for (ExprKind exprKind : ExprKind.values()) {
+                                            new FunctionalInterfaceConversionTest(samPkg, modKind, samKind,
+                                                    samMeth, clientMeth, retType, argType, thrownType, exprKind).test(comp, fm);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    PackageKind samPkg;
+    ModifierKind modKind;
+    SamKind samKind;
+    MethodKind samMeth;
+    MethodKind clientMeth;
+    TypeKind retType;
+    TypeKind argType;
+    TypeKind thrownType;
+    ExprKind exprKind;
+    DiagnosticChecker dc;
+
+    SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
+        public String toString() {
+            return template.replaceAll("#P", samPkg.getPkgDecl()).
+                    replaceAll("#C", samKind.getSam(samMeth.getMethod(retType, argType, thrownType)));
+        }
+    };
+
+    SourceFile pkgClassSourceFile = new SourceFile("PackageClass.java",
+                                                   "#P\n #M class PackageClass extends Exception { }") {
+        public String toString() {
+            return template.replaceAll("#P", samPkg.getPkgDecl()).
+                    replaceAll("#M", modKind.modifier_str);
+        }
+    };
+
+    SourceFile clientSourceFile = new SourceFile("Client.java",
+                                                 "#I\n abstract class Client { \n" +
+                                                 "  Sam s = #E;\n" +
+                                                 "  #M \n }") {
+        public String toString() {
+            return template.replaceAll("#I", samPkg.getImportStat())
+                    .replaceAll("#E", exprKind.exprStr)
+                    .replaceAll("#M", clientMeth.getMethod(retType, argType, thrownType));
+        }
+    };
+
+    FunctionalInterfaceConversionTest(PackageKind samPkg, ModifierKind modKind, SamKind samKind,
+            MethodKind samMeth, MethodKind clientMeth, TypeKind retType, TypeKind argType,
+            TypeKind thrownType, ExprKind exprKind) {
+        this.samPkg = samPkg;
+        this.modKind = modKind;
+        this.samKind = samKind;
+        this.samMeth = samMeth;
+        this.clientMeth = clientMeth;
+        this.retType = retType;
+        this.argType = argType;
+        this.thrownType = thrownType;
+        this.exprKind = exprKind;
+        this.dc = new DiagnosticChecker();
+    }
+
+    void test(JavaCompiler comp, StandardJavaFileManager fm) throws Exception {
+        JavacTask ct = (JavacTask)comp.getTask(null, fm, dc,
+                null, null, Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
+        ct.analyze();
+        if (dc.errorFound == checkSamConversion()) {
+            throw new AssertionError(samSourceFile + "\n\n" + pkgClassSourceFile + "\n\n" + clientSourceFile);
+        }
+    }
+
+    boolean checkSamConversion() {
+        if (samKind != SamKind.INTERFACE) {
+            //sam type must be an interface
+            return false;
+        } else if (samMeth == MethodKind.NONE) {
+            //interface must have at least a method
+            return false;
+        } else if (exprKind == ExprKind.LAMBDA &&
+                samMeth != MethodKind.NON_GENERIC) {
+            //target method for lambda must be non-generic
+            return false;
+        } else if (exprKind == ExprKind.MREF &&
+                clientMeth == MethodKind.NONE) {
+            return false;
+        } else if (samPkg != PackageKind.NO_PKG &&
+                modKind != ModifierKind.PUBLIC &&
+                (retType == TypeKind.PKG_CLASS ||
+                argType == TypeKind.PKG_CLASS ||
+                thrownType == TypeKind.PKG_CLASS)) {
+            //target must not contain inaccessible types
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    abstract class SourceFile extends SimpleJavaFileObject {
+
+        protected String template;
+
+        public SourceFile(String filename, String template) {
+            super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
+            this.template = template;
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return toString();
+        }
+
+        public abstract String toString();
+    }
+
+    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+        boolean errorFound = false;
+
+        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+                errorFound = true;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/Intersection01.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * @bug 8002099
+ * @summary Add support for intersection types in cast expression
+ * @compile/fail/ref=Intersection01.out -XDallowIntersectionTypes -XDrawDiagnostics Intersection01.java
+ */
+class Intersection01 {
+
+    interface SAM {
+        void m();
+    }
+
+    Object o1 = (java.io.Serializable & SAM)()->{};
+    Object o2 = (SAM & java.io.Serializable)()->{};
+    Object o3 = (java.io.Serializable & SAM)Intersection01::m;
+    Object o4 = (SAM & java.io.Serializable)Intersection01::m;
+
+    static void m() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/Intersection01.out	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,3 @@
+Intersection01.java:36:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
+Intersection01.java:38:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
+2 errors
--- a/langtools/test/tools/javac/lambda/LambdaConv21.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/test/tools/javac/lambda/LambdaConv21.java	Mon Dec 10 20:59:38 2012 -0800
@@ -23,7 +23,7 @@
     static void testExpressionLambda() {
         SAM_void s1 = ()->m_void(); //ok
         SAM_java_lang_Void s2 = ()->m_void(); //no - incompatible target
-        SAM_void s3 = ()->m_java_lang_Void(); //no - incompatible target
+        SAM_void s3 = ()->m_java_lang_Void(); //ok - expression statement lambda is compatible with void
         SAM_java_lang_Void s4 = ()->m_java_lang_Void(); //ok
     }
 
--- a/langtools/test/tools/javac/lambda/LambdaConv21.out	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/test/tools/javac/lambda/LambdaConv21.out	Mon Dec 10 20:59:38 2012 -0800
@@ -1,6 +1,5 @@
 LambdaConv21.java:25:43: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: void, java.lang.Void))
-LambdaConv21.java:26:43: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Void, void))
 LambdaConv21.java:32:33: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.Void))
 LambdaConv21.java:33:53: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val))
 LambdaConv21.java:36:33: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.Void))
-5 errors
+4 errors
--- a/langtools/test/tools/javac/lambda/LambdaConversionTest.java	Thu Dec 06 12:04:44 2012 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,246 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * @test
- * @bug 8003280
- * @summary Add lambda tests
- *  perform several automated checks in lambda conversion, esp. around accessibility
- * @author  Maurizio Cimadamore
- * @run main LambdaConversionTest
- */
-
-import com.sun.source.util.JavacTask;
-import java.net.URI;
-import java.util.Arrays;
-import javax.tools.Diagnostic;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.ToolProvider;
-
-public class LambdaConversionTest {
-
-    enum PackageKind {
-        NO_PKG(""),
-        PKG_A("a");
-
-        String pkg;
-
-        PackageKind(String pkg) {
-            this.pkg = pkg;
-        }
-
-        String getPkgDecl() {
-            return this == NO_PKG ?
-                "" :
-                "package " + pkg + ";";
-        }
-
-        String getImportStat() {
-            return this == NO_PKG ?
-                "" :
-                "import " + pkg + ".*;";
-        }
-    }
-
-    enum SamKind {
-        CLASS("public class Sam {  }"),
-        ABSTACT_CLASS("public abstract class Sam {  }"),
-        ANNOTATION("public @interface Sam {  }"),
-        ENUM("public enum Sam { }"),
-        INTERFACE("public interface Sam { \n #METH; \n }");
-
-        String sam_str;
-
-        SamKind(String sam_str) {
-            this.sam_str = sam_str;
-        }
-
-        String getSam(String methStr) {
-            return sam_str.replaceAll("#METH", methStr);
-        }
-    }
-
-    enum ModifierKind {
-        PUBLIC("public"),
-        PACKAGE("");
-
-        String modifier_str;
-
-        ModifierKind(String modifier_str) {
-            this.modifier_str = modifier_str;
-        }
-
-        boolean stricterThan(ModifierKind that) {
-            return this.ordinal() > that.ordinal();
-        }
-    }
-
-    enum TypeKind {
-        EXCEPTION("Exception"),
-        PKG_CLASS("PackageClass");
-
-        String typeStr;
-
-        private TypeKind(String typeStr) {
-            this.typeStr = typeStr;
-        }
-    }
-
-    enum MethodKind {
-        NONE(""),
-        NON_GENERIC("public #R m(#ARG s) throws #T;"),
-        GENERIC("public <X> #R m(#ARG s) throws #T;");
-
-        String methodTemplate;
-
-        private MethodKind(String methodTemplate) {
-            this.methodTemplate = methodTemplate;
-        }
-
-        String getMethod(TypeKind retType, TypeKind argType, TypeKind thrownType) {
-            return methodTemplate.replaceAll("#R", retType.typeStr).
-                    replaceAll("#ARG", argType.typeStr).
-                    replaceAll("#T", thrownType.typeStr);
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        for (PackageKind samPkg : PackageKind.values()) {
-            for (ModifierKind modKind : ModifierKind.values()) {
-                for (SamKind samKind : SamKind.values()) {
-                    for (MethodKind meth : MethodKind.values()) {
-                        for (TypeKind retType : TypeKind.values()) {
-                            for (TypeKind argType : TypeKind.values()) {
-                                for (TypeKind thrownType : TypeKind.values()) {
-                                    new LambdaConversionTest(samPkg, modKind, samKind,
-                                            meth, retType, argType, thrownType).test();
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    PackageKind samPkg;
-    ModifierKind modKind;
-    SamKind samKind;
-    MethodKind meth;
-    TypeKind retType;
-    TypeKind argType;
-    TypeKind thrownType;
-
-    SourceFile samSourceFile = new SourceFile("Sam.java", "#P \n #C") {
-        public String toString() {
-            return template.replaceAll("#P", samPkg.getPkgDecl()).
-                    replaceAll("#C", samKind.getSam(meth.getMethod(retType, argType, thrownType)));
-        }
-    };
-
-    SourceFile pkgClassSourceFile = new SourceFile("PackageClass.java",
-                                                   "#P\n #M class PackageClass extends Exception { }") {
-        public String toString() {
-            return template.replaceAll("#P", samPkg.getPkgDecl()).
-                    replaceAll("#M", modKind.modifier_str);
-        }
-    };
-
-    SourceFile clientSourceFile = new SourceFile("Client.java",
-                                                 "#I\n class Client { Sam s = x -> null; }") {
-        public String toString() {
-            return template.replaceAll("#I", samPkg.getImportStat());
-        }
-    };
-
-    LambdaConversionTest(PackageKind samPkg, ModifierKind modKind, SamKind samKind,
-            MethodKind meth, TypeKind retType, TypeKind argType, TypeKind thrownType) {
-        this.samPkg = samPkg;
-        this.modKind = modKind;
-        this.samKind = samKind;
-        this.meth = meth;
-        this.retType = retType;
-        this.argType = argType;
-        this.thrownType = thrownType;
-    }
-
-    void test() throws Exception {
-        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
-        DiagnosticChecker dc = new DiagnosticChecker();
-        JavacTask ct = (JavacTask)tool.getTask(null, null, dc,
-                null, null, Arrays.asList(samSourceFile, pkgClassSourceFile, clientSourceFile));
-        ct.analyze();
-        if (dc.errorFound == checkSamConversion()) {
-            throw new AssertionError(samSourceFile + "\n\n" + pkgClassSourceFile + "\n\n" + clientSourceFile);
-        }
-    }
-
-    boolean checkSamConversion() {
-        if (samKind != SamKind.INTERFACE) {
-            //sam type must be an interface
-            return false;
-        } else if (meth != MethodKind.NON_GENERIC) {
-            //target method must be non-generic
-            return false;
-        } else if (samPkg != PackageKind.NO_PKG &&
-                modKind != ModifierKind.PUBLIC &&
-                (retType == TypeKind.PKG_CLASS ||
-                argType == TypeKind.PKG_CLASS ||
-                thrownType == TypeKind.PKG_CLASS)) {
-            //target must not contain inaccessible types
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    abstract class SourceFile extends SimpleJavaFileObject {
-
-        protected String template;
-
-        public SourceFile(String filename, String template) {
-            super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
-            this.template = template;
-        }
-
-        @Override
-        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
-            return toString();
-        }
-
-        public abstract String toString();
-    }
-
-    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
-
-        boolean errorFound = false;
-
-        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
-            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
-                errorFound = true;
-            }
-        }
-    }
-}
--- a/langtools/test/tools/javac/lambda/LambdaParserTest.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/test/tools/javac/lambda/LambdaParserTest.java	Mon Dec 10 20:59:38 2012 -0800
@@ -90,9 +90,14 @@
     enum LambdaParameterKind {
         IMPLICIT(""),
         EXPLIICT_SIMPLE("A"),
+        EXPLIICT_SIMPLE_ARR1("A[]"),
+        EXPLIICT_SIMPLE_ARR2("A[][]"),
         EXPLICIT_VARARGS("A..."),
         EXPLICIT_GENERIC1("A<X>"),
-        EXPLICIT_GENERIC3("A<? extends X, ? super Y>");
+        EXPLICIT_GENERIC2("A<? extends X, ? super Y>"),
+        EXPLICIT_GENERIC2_VARARGS("A<? extends X, ? super Y>..."),
+        EXPLICIT_GENERIC2_ARR1("A<? extends X, ? super Y>[]"),
+        EXPLICIT_GENERIC2_ARR2("A<? extends X, ? super Y>[][]");
 
         String parameterType;
 
@@ -103,6 +108,11 @@
         boolean explicit() {
             return this != IMPLICIT;
         }
+
+        boolean isVarargs() {
+            return this == EXPLICIT_VARARGS ||
+                    this == EXPLICIT_GENERIC2_VARARGS;
+        }
     }
 
     enum ModifierKind {
@@ -253,7 +263,7 @@
 
         if (lk.arity() == 2 &&
                 (pk1.explicit() != pk2.explicit() ||
-                pk1 == LambdaParameterKind.EXPLICIT_VARARGS)) {
+                pk1.isVarargs())) {
             errorExpected = true;
         }
 
--- a/langtools/test/tools/javac/lambda/MethodReference30.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/test/tools/javac/lambda/MethodReference30.java	Mon Dec 10 20:59:38 2012 -0800
@@ -46,7 +46,7 @@
         assertTrue(true);
     }
 
-   static void m() { }
+   void m() { }
 
    public static void main(String[] args) {
       SAM s = new MethodReference30()::m;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference55.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * 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
+ * @bug 8004101
+ * @summary Add checks for method reference well-formedness
+ * @compile/fail/ref=MethodReference55.out -XDrawDiagnostics MethodReference55.java
+ */
+class MethodReference55<X> {
+
+    interface V {
+        void m(Object o);
+    }
+
+    V v = new MethodReference55<String>()::m;
+
+    void test() {
+        g(new MethodReference55<String>()::m);
+    }
+
+    void g(V v) { }
+
+    static void m(Object o) { };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference55.out	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,3 @@
+MethodReference55.java:36:11: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.bound.mref)
+MethodReference55.java:39:11: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.bound.mref)
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference56.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,45 @@
+/*
+ * 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
+ * @bug 8004101
+ * @summary Add checks for method reference well-formedness
+ * @compile/fail/ref=MethodReference56.out -XDrawDiagnostics MethodReference56.java
+ */
+class MethodReference56<X> {
+
+    interface V {
+        void m(Object o);
+    }
+
+    V v = MethodReference56<String>::m;
+
+    void test() {
+        g(MethodReference56<String>::m);
+    }
+
+    void g(V v) { }
+
+    static void m(Object o) { };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference56.out	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,3 @@
+MethodReference56.java:36:28: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.mref.with.targs)
+MethodReference56.java:39:28: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.mref.with.targs)
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference57.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,41 @@
+/*
+ * 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
+ * @bug 8004102
+ * @summary Add support for generic functional descriptors
+ * @compile MethodReference57.java
+ */
+class MethodReference57 {
+
+    interface F {
+        <X> void m();
+    }
+
+    void test() {
+        F f = this::g; //ok
+    }
+
+    void g() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference58.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,46 @@
+/*
+ * 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
+ * @bug 8004102
+ * @summary Add support for generic functional descriptors
+ * @compile/fail/ref=MethodReference58.out -XDrawDiagnostics MethodReference58.java
+ */
+class MethodReference58 {
+
+    interface F_Object {
+        <X> void m(X x);
+    }
+
+    interface F_Integer {
+        <X extends Integer> void m(X x);
+    }
+
+    void test() {
+        F_Object f1 = this::g; //incompatible bounds
+        F_Integer f2 = this::g; //ok
+    }
+
+    <Z extends Number> void g(Z z) { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/MethodReference58.out	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,2 @@
+MethodReference58.java:41:23: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, g, Z, X, kindname.class, MethodReference58, (compiler.misc.inferred.do.not.conform.to.upper.bounds: X, java.lang.Number)))
+1 error
--- a/langtools/test/tools/javac/lambda/VoidCompatibility.out	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/test/tools/javac/lambda/VoidCompatibility.out	Mon Dec 10 20:59:38 2012 -0800
@@ -1,2 +1,3 @@
+VoidCompatibility.java:17:9: compiler.err.ref.ambiguous: schedule, kindname.method, schedule(VoidCompatibility.Runnable), VoidCompatibility, kindname.method, schedule(VoidCompatibility.Thunk<?>), VoidCompatibility
 VoidCompatibility.java:23:9: compiler.err.ref.ambiguous: schedule, kindname.method, schedule(VoidCompatibility.Runnable), VoidCompatibility, kindname.method, schedule(VoidCompatibility.Thunk<?>), VoidCompatibility
-1 error
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,294 @@
+/*
+ * 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
+ * @bug 8002099
+ * @summary Add support for intersection types in cast expression
+ */
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class IntersectionTargetTypeTest {
+
+    static int checkCount = 0;
+
+    enum BoundKind {
+        INTF,
+        CLASS,
+        SAM,
+        ZAM;
+    }
+
+    enum MethodKind {
+        NONE,
+        ABSTRACT,
+        DEFAULT;
+    }
+
+    enum TypeKind {
+        A("interface A { }\n", "A", BoundKind.ZAM),
+        B("interface B { default void m() { } }\n", "B", BoundKind.ZAM),
+        C("interface C { void m(); }\n", "C", BoundKind.SAM),
+        D("interface D extends B { }\n", "D", BoundKind.ZAM),
+        E("interface E extends C { }\n", "E", BoundKind.SAM),
+        F("interface F extends C { void g(); }\n", "F", BoundKind.INTF),
+        G("interface G extends B { void g(); }\n", "G", BoundKind.SAM),
+        H("interface H extends A { void g(); }\n", "H", BoundKind.SAM),
+        OBJECT("", "Object", BoundKind.CLASS),
+        STRING("", "String", BoundKind.CLASS);
+
+        String declStr;
+        String typeStr;
+        BoundKind boundKind;
+
+        private TypeKind(String declStr, String typeStr, BoundKind boundKind) {
+            this.declStr = declStr;
+            this.typeStr = typeStr;
+            this.boundKind = boundKind;
+        }
+
+        boolean compatibleSupertype(TypeKind tk) {
+            if (tk == this) return true;
+            switch (tk) {
+                case B:
+                    return this != C && this != E && this != F;
+                case C:
+                    return this != B && this != C && this != D && this != G;
+                case D: return compatibleSupertype(B);
+                case E:
+                case F: return compatibleSupertype(C);
+                case G: return compatibleSupertype(B);
+                case H: return compatibleSupertype(A);
+                default:
+                    return true;
+            }
+        }
+    }
+
+    enum CastKind {
+        ONE_ARY("(#B0)", 1),
+        TWO_ARY("(#B0 & #B1)", 2),
+        THREE_ARY("(#B0 & #B1 & #B2)", 3);
+
+        String castTemplate;
+        int nbounds;
+
+        CastKind(String castTemplate, int nbounds) {
+            this.castTemplate = castTemplate;
+            this.nbounds = nbounds;
+        }
+    }
+
+    enum ExpressionKind {
+        LAMBDA("()->{}", true),
+        MREF("this::m", true),
+        //COND_LAMBDA("(true ? ()->{} : ()->{})", true), re-enable if spec allows this
+        //COND_MREF("(true ? this::m : this::m)", true),
+        STANDALONE("null", false);
+
+        String exprString;
+        boolean isFunctional;
+
+        private ExpressionKind(String exprString, boolean isFunctional) {
+            this.exprString = exprString;
+            this.isFunctional = isFunctional;
+        }
+    }
+
+    static class CastInfo {
+        CastKind kind;
+        TypeKind[] types;
+
+        CastInfo(CastKind kind, TypeKind... types) {
+            this.kind = kind;
+            this.types = types;
+        }
+
+        String getCast() {
+            String temp = kind.castTemplate;
+            for (int i = 0; i < kind.nbounds ; i++) {
+                temp = temp.replace(String.format("#B%d", i), types[i].typeStr);
+            }
+            return temp;
+        }
+
+        boolean wellFormed() {
+            //check for duplicate types
+            for (int i = 0 ; i < types.length ; i++) {
+                for (int j = 0 ; j < types.length ; j++) {
+                    if (i != j && types[i] == types[j]) {
+                        return false;
+                    }
+                }
+            }
+            //check that classes only appear as first bound
+            boolean classOk = true;
+            for (int i = 0 ; i < types.length ; i++) {
+                if (types[i].boundKind == BoundKind.CLASS &&
+                        !classOk) {
+                    return false;
+                }
+                classOk = false;
+            }
+            //check that supertypes are mutually compatible
+            for (int i = 0 ; i < types.length ; i++) {
+                for (int j = 0 ; j < types.length ; j++) {
+                    if (!types[i].compatibleSupertype(types[j]) && i != j) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        //create default shared JavaCompiler - reused across multiple compilations
+        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+        StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+        for (CastInfo cInfo : allCastInfo()) {
+            for (ExpressionKind ek : ExpressionKind.values()) {
+                new IntersectionTargetTypeTest(cInfo, ek).run(comp, fm);
+            }
+        }
+        System.out.println("Total check executed: " + checkCount);
+    }
+
+    static List<CastInfo> allCastInfo() {
+        ListBuffer<CastInfo> buf = ListBuffer.lb();
+        for (CastKind kind : CastKind.values()) {
+            for (TypeKind b1 : TypeKind.values()) {
+                if (kind.nbounds == 1) {
+                    buf.append(new CastInfo(kind, b1));
+                    continue;
+                } else {
+                    for (TypeKind b2 : TypeKind.values()) {
+                        if (kind.nbounds == 2) {
+                            buf.append(new CastInfo(kind, b1, b2));
+                            continue;
+                        } else {
+                            for (TypeKind b3 : TypeKind.values()) {
+                                buf.append(new CastInfo(kind, b1, b2, b3));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return buf.toList();
+    }
+
+    CastInfo cInfo;
+    ExpressionKind ek;
+    JavaSource source;
+    DiagnosticChecker diagChecker;
+
+    IntersectionTargetTypeTest(CastInfo cInfo, ExpressionKind ek) {
+        this.cInfo = cInfo;
+        this.ek = ek;
+        this.source = new JavaSource();
+        this.diagChecker = new DiagnosticChecker();
+    }
+
+    class JavaSource extends SimpleJavaFileObject {
+
+        String bodyTemplate = "class Test {\n" +
+                              "   void m() { }\n" +
+                              "   void test() {\n" +
+                              "      Object o = #C#E;\n" +
+                              "   } }";
+
+        String source = "";
+
+        public JavaSource() {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            for (TypeKind tk : TypeKind.values()) {
+                source += tk.declStr;
+            }
+            source += bodyTemplate.replaceAll("#C", cInfo.getCast()).replaceAll("#E", ek.exprString);
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return source;
+        }
+    }
+
+    void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+        JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+                Arrays.asList("-XDallowIntersectionTypes"), null, Arrays.asList(source));
+        try {
+            ct.analyze();
+        } catch (Throwable ex) {
+            throw new AssertionError("Error thrown when compiling the following code:\n" + source.getCharContent(true));
+        }
+        check();
+    }
+
+    void check() {
+        checkCount++;
+
+        boolean errorExpected = !cInfo.wellFormed();
+
+        if (ek.isFunctional) {
+            //first bound must be a SAM
+            errorExpected |= cInfo.types[0].boundKind != BoundKind.SAM;
+            if (cInfo.types.length > 1) {
+                //additional bounds must be ZAMs
+                for (int i = 1; i < cInfo.types.length; i++) {
+                    errorExpected |= cInfo.types[i].boundKind != BoundKind.ZAM;
+                }
+            }
+        }
+
+        if (errorExpected != diagChecker.errorFound) {
+            throw new Error("invalid diagnostics for source:\n" +
+                source.getCharContent(true) +
+                "\nFound error: " + diagChecker.errorFound +
+                "\nExpected error: " + errorExpected);
+        }
+    }
+
+    static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+        boolean errorFound;
+
+        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+            if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+                errorFound = true;
+            }
+        }
+    }
+}
--- a/langtools/test/tools/javac/lambda/methodReference/MethodRef1.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/test/tools/javac/lambda/methodReference/MethodRef1.java	Mon Dec 10 20:59:38 2012 -0800
@@ -70,9 +70,6 @@
         b = MethodRef1::foo; //static reference to foo(int)
         b.m(1);
 
-        b = new MethodRef1()::foo; //instance reference to static methods, supported for now
-        b.m(1);
-
         b = MethodRef1::bar; //static reference to bar(int)
         b.m(2);
 
--- a/langtools/test/tools/javac/lambda/methodReference/SamConversion.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/test/tools/javac/lambda/methodReference/SamConversion.java	Mon Dec 10 20:59:38 2012 -0800
@@ -133,15 +133,6 @@
         } catch (Exception e) {
             assertTrue(false);
         }
-
-        bar = new A()::method6;
-        try {
-            bar.m(1);
-            assertTrue(false);
-        } catch (MyException e) {
-        } catch (Exception e) {
-            assertTrue(false);
-        }
     }
 
     /**
--- a/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestKinds.java	Thu Dec 06 12:04:44 2012 -0800
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestKinds.java	Mon Dec 10 20:59:38 2012 -0800
@@ -119,20 +119,6 @@
         assertEquals(var.get(inst("arg")), "SM:1-MethodReferenceTestKinds(arg)");
     }
 
-    public void testMRStaticEval() {
-        MethodReferenceTestKinds evalCheck;
-        S0 var = (evalCheck = inst("discard"))::staticMethod0;
-        assertEquals(evalCheck.toString(), "MethodReferenceTestKinds(discard)");
-        assertEquals(var.get(), "SM:0");
-    }
-
-    public void testMRStaticEvalArg() {
-        MethodReferenceTestKinds evalCheck;
-        S1 var = (evalCheck = inst("discard"))::staticMethod1;
-        assertEquals(evalCheck.toString(), "MethodReferenceTestKinds(discard)");
-        assertEquals(var.get(inst("arg")), "SM:1-MethodReferenceTestKinds(arg)");
-    }
-
     public void testMRTopLevel() {
         SN0 var = MethodReferenceTestKindsBase::new;
         assertEquals(var.make().toString(), "MethodReferenceTestKindsBase(blank)");
@@ -142,17 +128,7 @@
         SN1 var = MethodReferenceTestKindsBase::new;
         assertEquals(var.make("name").toString(), "MethodReferenceTestKindsBase(name)");
     }
-/* unbound inner case not supported anymore (dropped by EG)
-    public void testMRUnboundInner() {
-        SXN0 var = MethodReferenceTestKinds.In::new;
-        assertEquals(var.make(inst("out")).toString(), "In(blank)");
-    }
 
-   public void testMRUnboundInnerArg() {
-        SXN1 var = MethodReferenceTestKinds.In::new;
-        assertEquals(var.make(inst("out"), "name").toString(), "In(name)");
-    }
-*/
     public void testMRImplicitInner() {
         SN0 var = MethodReferenceTestKinds.In::new;
         assertEquals(var.make().toString(), "In(blank)");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/T7190862.java	Mon Dec 10 20:59:38 2012 -0800
@@ -0,0 +1,157 @@
+
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7190862 7109747
+ * @summary javap shows an incorrect type for operands if the 'wide' prefix is used
+ */
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.javap.JavapFileManager;
+import com.sun.tools.javap.JavapTask;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.ToolProvider;
+
+public class T7190862 {
+
+    enum TypeWideInstructionMap {
+        INT("int", new String[]{"istore_w", "iload_w"}),
+        LONG("long", new String[]{"lstore_w", "lload_w"}),
+        FLOAT("float", new String[]{"fstore_w", "fload_w"}),
+        DOUBLE("double", new String[]{"dstore_w", "dload_w"}),
+        OBJECT("Object", new String[]{"astore_w", "aload_w"});
+
+        String type;
+        String[] instructions;
+
+        TypeWideInstructionMap(String type, String[] instructions) {
+            this.type = type;
+            this.instructions = instructions;
+        }
+    }
+
+    JavaSource source;
+
+    public static void main(String[] args) {
+        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+        new T7190862().run(comp);
+    }
+
+    private void run(JavaCompiler comp) {
+        String code;
+        for (TypeWideInstructionMap typeInstructionMap: TypeWideInstructionMap.values()) {
+            if (typeInstructionMap != TypeWideInstructionMap.OBJECT) {
+                code = createWideLocalSource(typeInstructionMap.type, 300);
+            } else {
+                code = createWideLocalSourceForObject(300);
+            }
+            source = new JavaSource(code);
+            compile(comp);
+            check(typeInstructionMap.instructions);
+        }
+
+        //an extra test for the iinc instruction
+        code = createIincSource();
+        source = new JavaSource(code);
+        compile(comp);
+        check(new String[]{"iinc_w"});
+    }
+
+    private void compile(JavaCompiler comp) {
+        JavacTask ct = (JavacTask)comp.getTask(null, null, null, null, null, Arrays.asList(source));
+        try {
+            if (!ct.call()) {
+                throw new AssertionError("Error thrown when compiling the following source:\n" + source.getCharContent(true));
+            }
+        } catch (Throwable ex) {
+            throw new AssertionError("Error thrown when compiling the following source:\n" + source.getCharContent(true));
+        }
+    }
+
+    private void check(String[] instructions) {
+        String out = javap(Arrays.asList("-c"), Arrays.asList("Test.class"));
+        for (String line: out.split(System.getProperty("line.separator"))) {
+            line = line.trim();
+            for (String instruction: instructions) {
+                if (line.contains(instruction) && line.contains("#")) {
+                    throw new Error("incorrect type for operands for instruction " + instruction);
+                }
+            }
+        }
+    }
+
+    private String javap(List<String> args, List<String> classes) {
+        DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<JavaFileObject>();
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        JavaFileManager fm = JavapFileManager.create(dc, pw);
+        JavapTask t = new JavapTask(pw, fm, dc, args, classes);
+        boolean ok = t.run();
+        if (!ok)
+            throw new Error("javap failed unexpectedly");
+
+        List<Diagnostic<? extends JavaFileObject>> diags = dc.getDiagnostics();
+        for (Diagnostic<? extends JavaFileObject> d: diags) {
+            if (d.getKind() == Diagnostic.Kind.ERROR)
+                throw new Error(d.getMessage(Locale.ENGLISH));
+        }
+        return sw.toString();
+
+    }
+
+    private String createWideLocalSource(String type, int numberOfVars) {
+        String result = "    " + type + " x0 = 0;\n";
+        for (int i = 1; i < numberOfVars; i++) {
+            result += "        " + type + " x" + i + " = x" + (i - 1) + " + 1;\n";
+        }
+        return result;
+    }
+
+    private String createWideLocalSourceForObject(int numberOfVars) {
+        String result = "    Object x0 = new Object();\n";
+        for (int i = 1; i < numberOfVars; i++) {
+            result += "        Object x" + i + " = x0;\n";
+        }
+        return result;
+    }
+
+    private String createIincSource() {
+        return "    int i = 0;\n"
+                + "        i += 1;\n"
+                + "        i += 51;\n"
+                + "        i += 101;\n"
+                + "        i += 151;\n";
+    }
+
+    class JavaSource extends SimpleJavaFileObject {
+
+        String template = "class Test {\n" +
+                          "    public static void main(String[] args)\n" +
+                          "    {\n" +
+                          "        #C" +
+                          "    }\n" +
+                          "}";
+
+        String source;
+
+        public JavaSource(String code) {
+            super(URI.create("Test.java"), JavaFileObject.Kind.SOURCE);
+            source = template.replaceAll("#C", code);
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return source;
+        }
+    }
+}