changeset 848:2f2ead61db06

Merge
author bpatel
date Mon, 13 Dec 2010 14:08:01 -0800
parents ffbf2b2a8611 2199365892b1
children 7b99f98b3035
files src/share/classes/com/sun/tools/apt/main/JavaCompiler.java
diffstat 12 files changed, 1298 insertions(+), 322 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon Dec 13 13:44:47 2010 -0800
+++ b/.hgtags	Mon Dec 13 14:08:01 2010 -0800
@@ -95,3 +95,4 @@
 c491eec0acc73fa41b77e1619ed03e56d8a75b83 jdk7-b118
 814561077c448292f78de461b6de5d78d57c2089 jdk7-b119
 1dd813a529cfa06d850ee7dc42da42efb8f6af0e jdk7-b120
+1bf969e9792f977a8593496681539840a54fe644 jdk7-b121
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/apt/main/AptJavaCompiler.java	Mon Dec 13 14:08:01 2010 -0800
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2004, 2010, 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.tools.apt.main;
+
+import java.io.*;
+import java.util.Map;
+
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.jvm.*;
+
+import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.tree.JCTree.*;
+
+import com.sun.tools.apt.comp.*;
+import com.sun.tools.apt.util.Bark;
+import com.sun.mirror.apt.AnnotationProcessorFactory;
+import com.sun.tools.javac.parser.DocCommentScanner;
+
+/**
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own
+ *  risk.  This code and its internal interfaces are subject to change
+ *  or deletion without notice.</b>
+ */
+@SuppressWarnings("deprecation")
+public class AptJavaCompiler extends com.sun.tools.javac.main.JavaCompiler {
+    /** The context key for the compiler. */
+    protected static final Context.Key<AptJavaCompiler> compilerKey =
+        new Context.Key<AptJavaCompiler>();
+
+    /** Get the JavaCompiler instance for this context. */
+    public static AptJavaCompiler instance(Context context) {
+        AptJavaCompiler instance = context.get(compilerKey);
+        if (instance == null)
+            instance = new AptJavaCompiler(context);
+        return instance;
+    }
+
+
+    java.util.Set<String> genSourceFileNames;
+    java.util.Set<String> genClassFileNames;
+
+    public java.util.Set<String> getSourceFileNames() {
+        return genSourceFileNames;
+    }
+
+    /** List of names of generated class files.
+     */
+    public java.util.Set<String> getClassFileNames() {
+        return genClassFileNames;
+    }
+
+    java.util.Set<java.io.File> aggregateGenFiles = java.util.Collections.emptySet();
+
+    public java.util.Set<java.io.File> getAggregateGenFiles() {
+        return aggregateGenFiles;
+    }
+
+    /** The bark to be used for error reporting.
+     */
+    Bark bark;
+
+    /** The log to be used for error reporting.
+     */
+    Log log;
+
+    /** The annotation framework
+     */
+    Apt apt;
+
+    private static Context preRegister(Context context) {
+        Bark.preRegister(context);
+
+        if (context.get(JavaFileManager.class) == null)
+            JavacFileManager.preRegister(context);
+
+        return context;
+    }
+
+    /** Construct a new compiler from a shared context.
+     */
+    public AptJavaCompiler(Context context) {
+        super(preRegister(context));
+
+        context.put(compilerKey, this);
+        apt = Apt.instance(context);
+
+        ClassReader classReader = ClassReader.instance(context);
+        classReader.preferSource = true;
+
+        // TEMPORARY NOTE: bark==log, but while refactoring, we maintain their
+        // original identities, to remember the original intent.
+        log = Log.instance(context);
+        bark = Bark.instance(context);
+
+        Options options = Options.instance(context);
+        classOutput   = options.get("-retrofit")      == null;
+        nocompile     = options.get("-nocompile")     != null;
+        print         = options.get("-print")         != null;
+        classesAsDecls= options.get("-XclassesAsDecls") != null;
+
+        genSourceFileNames = new java.util.LinkedHashSet<String>();
+        genClassFileNames  = new java.util.LinkedHashSet<String>();
+
+        // this forces a copy of the line map to be kept in the tree,
+        // for use by com.sun.mirror.util.SourcePosition.
+        lineDebugInfo = true;
+    }
+
+    /* Switches:
+     */
+
+    /** Emit class files. This switch is always set, except for the first
+     *  phase of retrofitting, where signatures are parsed.
+     */
+    public boolean classOutput;
+
+    /** The internal printing annotation processor should be used.
+     */
+    public boolean print;
+
+    /** Compilation should not be done after annotation processing.
+     */
+    public boolean nocompile;
+
+    /** Are class files being treated as declarations
+     */
+    public boolean classesAsDecls;
+
+    /** Try to open input stream with given name.
+     *  Report an error if this fails.
+     *  @param filename   The file name of the input stream to be opened.
+     */
+    // PROVIDED FOR EXTREME BACKWARDS COMPATIBILITY
+    // There are some very obscure errors that can arise while translating
+    // the contents of a file from bytes to characters. In Tiger, these
+    // diagnostics were ignored. This method provides compatibility with
+    // that behavior. It would be better to honor those diagnostics, in which
+    // case, this method can be deleted.
+    @Override
+    public CharSequence readSource(JavaFileObject filename) {
+        try {
+            inputFiles.add(filename);
+            boolean prev = bark.setDiagnosticsIgnored(true);
+            try {
+                return filename.getCharContent(false);
+            }
+            finally {
+                bark.setDiagnosticsIgnored(prev);
+            }
+        } catch (IOException e) {
+            bark.error(Position.NOPOS, "cant.read.file", filename);
+            return null;
+        }
+    }
+
+    /** Parse contents of input stream.
+     *  @param filename     The name of the file from which input stream comes.
+     *  @param input        The input stream to be parsed.
+     */
+    // PROVIDED FOR BACKWARDS COMPATIBILITY
+    // In Tiger, diagnostics from the scanner and parser were ignored.
+    // This method provides compatibility with that behavior.
+    // It would be better to honor those diagnostics, in which
+    // case, this method can be deleted.
+    @Override
+    protected JCCompilationUnit parse(JavaFileObject filename, CharSequence content) {
+        boolean prev = bark.setDiagnosticsIgnored(true);
+        try {
+            return super.parse(filename, content);
+        }
+        finally {
+            bark.setDiagnosticsIgnored(prev);
+        }
+    }
+
+    @Override
+    protected boolean keepComments() {
+        return true;  // make doc comments available to mirror API impl.
+    }
+
+    /** Track when the JavaCompiler has been used to compile something. */
+    private boolean hasBeenUsed = false;
+
+    /** Main method: compile a list of files, return all compiled classes
+     *  @param filenames     The names of all files to be compiled.
+     */
+    public List<ClassSymbol> compile(List<String> filenames,
+                                     Map<String, String> origOptions,
+                                     ClassLoader aptCL,
+                                     AnnotationProcessorFactory providedFactory,
+                                     java.util.Set<Class<? extends AnnotationProcessorFactory> > productiveFactories,
+                                     java.util.Set<java.io.File> aggregateGenFiles)
+        throws Throwable {
+        // as a JavaCompiler can only be used once, throw an exception if
+        // it has been used before.
+        assert !hasBeenUsed : "attempt to reuse JavaCompiler";
+        hasBeenUsed = true;
+
+        this.aggregateGenFiles = aggregateGenFiles;
+
+        long msec = System.currentTimeMillis();
+
+        ListBuffer<ClassSymbol> classes = new ListBuffer<ClassSymbol>();
+        try {
+            JavacFileManager fm = (JavacFileManager)fileManager;
+            //parse all files
+            ListBuffer<JCCompilationUnit> trees = new ListBuffer<JCCompilationUnit>();
+            for (List<String> l = filenames; l.nonEmpty(); l = l.tail) {
+                if (classesAsDecls) {
+                    if (! l.head.endsWith(".java") ) { // process as class file
+                        ClassSymbol cs = reader.enterClass(names.fromString(l.head));
+                        try {
+                            cs.complete();
+                        } catch(Symbol.CompletionFailure cf) {
+                            bark.aptError("CantFindClass", l);
+                            continue;
+                        }
+
+                        classes.append(cs); // add to list of classes
+                        continue;
+                    }
+                }
+                JavaFileObject fo = fm.getJavaFileObjectsFromStrings(List.of(l.head)).iterator().next();
+                trees.append(parse(fo));
+            }
+
+            //enter symbols for all files
+            List<JCCompilationUnit> roots = trees.toList();
+
+            if (errorCount() == 0) {
+                boolean prev = bark.setDiagnosticsIgnored(true);
+                try {
+                    enter.main(roots);
+                }
+                finally {
+                    bark.setDiagnosticsIgnored(prev);
+                }
+            }
+
+            if (errorCount() == 0) {
+                apt.main(roots,
+                         classes,
+                         origOptions, aptCL,
+                         providedFactory,
+                         productiveFactories);
+                genSourceFileNames.addAll(apt.getSourceFileNames());
+                genClassFileNames.addAll(apt.getClassFileNames());
+            }
+
+        } catch (Abort ex) {
+        }
+
+        if (verbose)
+            printVerbose("total", Long.toString(System.currentTimeMillis() - msec));
+
+        chk.reportDeferredDiagnostics();
+
+        printCount("error", errorCount());
+        printCount("warn", warningCount());
+
+        return classes.toList();
+    }
+}
--- a/src/share/classes/com/sun/tools/apt/main/JavaCompiler.java	Mon Dec 13 13:44:47 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,292 +0,0 @@
-/*
- * Copyright (c) 2004, 2010, 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.tools.apt.main;
-
-import java.io.*;
-import java.util.Map;
-
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.code.*;
-import com.sun.tools.javac.jvm.*;
-
-import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.tree.JCTree.*;
-
-import com.sun.tools.apt.comp.*;
-import com.sun.tools.apt.util.Bark;
-import com.sun.mirror.apt.AnnotationProcessorFactory;
-import com.sun.tools.javac.parser.DocCommentScanner;
-
-/**
- *  <p><b>This is NOT part of any supported API.
- *  If you write code that depends on this, you do so at your own
- *  risk.  This code and its internal interfaces are subject to change
- *  or deletion without notice.</b>
- */
-@SuppressWarnings("deprecation")
-public class JavaCompiler extends com.sun.tools.javac.main.JavaCompiler {
-    /** The context key for the compiler. */
-    protected static final Context.Key<JavaCompiler> compilerKey =
-        new Context.Key<JavaCompiler>();
-
-    /** Get the JavaCompiler instance for this context. */
-    public static JavaCompiler instance(Context context) {
-        JavaCompiler instance = context.get(compilerKey);
-        if (instance == null)
-            instance = new JavaCompiler(context);
-        return instance;
-    }
-
-
-    java.util.Set<String> genSourceFileNames;
-    java.util.Set<String> genClassFileNames;
-
-    public java.util.Set<String> getSourceFileNames() {
-        return genSourceFileNames;
-    }
-
-    /** List of names of generated class files.
-     */
-    public java.util.Set<String> getClassFileNames() {
-        return genClassFileNames;
-    }
-
-    java.util.Set<java.io.File> aggregateGenFiles = java.util.Collections.emptySet();
-
-    public java.util.Set<java.io.File> getAggregateGenFiles() {
-        return aggregateGenFiles;
-    }
-
-    /** The bark to be used for error reporting.
-     */
-    Bark bark;
-
-    /** The log to be used for error reporting.
-     */
-    Log log;
-
-    /** The annotation framework
-     */
-    Apt apt;
-
-    private static Context preRegister(Context context) {
-        Bark.preRegister(context);
-
-        if (context.get(JavaFileManager.class) == null)
-            JavacFileManager.preRegister(context);
-
-        return context;
-    }
-
-    /** Construct a new compiler from a shared context.
-     */
-    public JavaCompiler(Context context) {
-        super(preRegister(context));
-
-        context.put(compilerKey, this);
-        apt = Apt.instance(context);
-
-        ClassReader classReader = ClassReader.instance(context);
-        classReader.preferSource = true;
-
-        // TEMPORARY NOTE: bark==log, but while refactoring, we maintain their
-        // original identities, to remember the original intent.
-        log = Log.instance(context);
-        bark = Bark.instance(context);
-
-        Options options = Options.instance(context);
-        classOutput   = options.get("-retrofit")      == null;
-        nocompile     = options.get("-nocompile")     != null;
-        print         = options.get("-print")         != null;
-        classesAsDecls= options.get("-XclassesAsDecls") != null;
-
-        genSourceFileNames = new java.util.LinkedHashSet<String>();
-        genClassFileNames  = new java.util.LinkedHashSet<String>();
-
-        // this forces a copy of the line map to be kept in the tree,
-        // for use by com.sun.mirror.util.SourcePosition.
-        lineDebugInfo = true;
-    }
-
-    /* Switches:
-     */
-
-    /** Emit class files. This switch is always set, except for the first
-     *  phase of retrofitting, where signatures are parsed.
-     */
-    public boolean classOutput;
-
-    /** The internal printing annotation processor should be used.
-     */
-    public boolean print;
-
-    /** Compilation should not be done after annotation processing.
-     */
-    public boolean nocompile;
-
-    /** Are class files being treated as declarations
-     */
-    public boolean classesAsDecls;
-
-    /** Try to open input stream with given name.
-     *  Report an error if this fails.
-     *  @param filename   The file name of the input stream to be opened.
-     */
-    // PROVIDED FOR EXTREME BACKWARDS COMPATIBILITY
-    // There are some very obscure errors that can arise while translating
-    // the contents of a file from bytes to characters. In Tiger, these
-    // diagnostics were ignored. This method provides compatibility with
-    // that behavior. It would be better to honor those diagnostics, in which
-    // case, this method can be deleted.
-    @Override
-    public CharSequence readSource(JavaFileObject filename) {
-        try {
-            inputFiles.add(filename);
-            boolean prev = bark.setDiagnosticsIgnored(true);
-            try {
-                return filename.getCharContent(false);
-            }
-            finally {
-                bark.setDiagnosticsIgnored(prev);
-            }
-        } catch (IOException e) {
-            bark.error(Position.NOPOS, "cant.read.file", filename);
-            return null;
-        }
-    }
-
-    /** Parse contents of input stream.
-     *  @param filename     The name of the file from which input stream comes.
-     *  @param input        The input stream to be parsed.
-     */
-    // PROVIDED FOR BACKWARDS COMPATIBILITY
-    // In Tiger, diagnostics from the scanner and parser were ignored.
-    // This method provides compatibility with that behavior.
-    // It would be better to honor those diagnostics, in which
-    // case, this method can be deleted.
-    @Override
-    protected JCCompilationUnit parse(JavaFileObject filename, CharSequence content) {
-        boolean prev = bark.setDiagnosticsIgnored(true);
-        try {
-            return super.parse(filename, content);
-        }
-        finally {
-            bark.setDiagnosticsIgnored(prev);
-        }
-    }
-
-    @Override
-    protected boolean keepComments() {
-        return true;  // make doc comments available to mirror API impl.
-    }
-
-    /** Track when the JavaCompiler has been used to compile something. */
-    private boolean hasBeenUsed = false;
-
-    /** Main method: compile a list of files, return all compiled classes
-     *  @param filenames     The names of all files to be compiled.
-     */
-    public List<ClassSymbol> compile(List<String> filenames,
-                                     Map<String, String> origOptions,
-                                     ClassLoader aptCL,
-                                     AnnotationProcessorFactory providedFactory,
-                                     java.util.Set<Class<? extends AnnotationProcessorFactory> > productiveFactories,
-                                     java.util.Set<java.io.File> aggregateGenFiles)
-        throws Throwable {
-        // as a JavaCompiler can only be used once, throw an exception if
-        // it has been used before.
-        assert !hasBeenUsed : "attempt to reuse JavaCompiler";
-        hasBeenUsed = true;
-
-        this.aggregateGenFiles = aggregateGenFiles;
-
-        long msec = System.currentTimeMillis();
-
-        ListBuffer<ClassSymbol> classes = new ListBuffer<ClassSymbol>();
-        try {
-            JavacFileManager fm = (JavacFileManager)fileManager;
-            //parse all files
-            ListBuffer<JCCompilationUnit> trees = new ListBuffer<JCCompilationUnit>();
-            for (List<String> l = filenames; l.nonEmpty(); l = l.tail) {
-                if (classesAsDecls) {
-                    if (! l.head.endsWith(".java") ) { // process as class file
-                        ClassSymbol cs = reader.enterClass(names.fromString(l.head));
-                        try {
-                            cs.complete();
-                        } catch(Symbol.CompletionFailure cf) {
-                            bark.aptError("CantFindClass", l);
-                            continue;
-                        }
-
-                        classes.append(cs); // add to list of classes
-                        continue;
-                    }
-                }
-                JavaFileObject fo = fm.getJavaFileObjectsFromStrings(List.of(l.head)).iterator().next();
-                trees.append(parse(fo));
-            }
-
-            //enter symbols for all files
-            List<JCCompilationUnit> roots = trees.toList();
-
-            if (errorCount() == 0) {
-                boolean prev = bark.setDiagnosticsIgnored(true);
-                try {
-                    enter.main(roots);
-                }
-                finally {
-                    bark.setDiagnosticsIgnored(prev);
-                }
-            }
-
-            if (errorCount() == 0) {
-                apt.main(roots,
-                         classes,
-                         origOptions, aptCL,
-                         providedFactory,
-                         productiveFactories);
-                genSourceFileNames.addAll(apt.getSourceFileNames());
-                genClassFileNames.addAll(apt.getClassFileNames());
-            }
-
-        } catch (Abort ex) {
-        }
-
-        if (verbose)
-            printVerbose("total", Long.toString(System.currentTimeMillis() - msec));
-
-        chk.reportDeferredDiagnostics();
-
-        printCount("error", errorCount());
-        printCount("warn", warningCount());
-
-        return classes.toList();
-    }
-}
--- a/src/share/classes/com/sun/tools/apt/main/Main.java	Mon Dec 13 13:44:47 2010 -0800
+++ b/src/share/classes/com/sun/tools/apt/main/Main.java	Mon Dec 13 14:08:01 2010 -0800
@@ -421,7 +421,7 @@
         },
         new AptOption("-version",               "opt.version") {
             boolean process(String option) {
-                Bark.printLines(out, ownName + " " + JavaCompiler.version());
+                Bark.printLines(out, ownName + " " + AptJavaCompiler.version());
                 return super.process(option);
             }
         },
@@ -1111,11 +1111,11 @@
         }
         int exitCode = EXIT_OK;
 
-        JavaCompiler comp = null;
+        AptJavaCompiler comp = null;
         try {
             context.put(Bark.outKey, out);
 
-            comp = JavaCompiler.instance(context);
+            comp = AptJavaCompiler.instance(context);
             if (comp == null)
                 return EXIT_SYSERR;
 
@@ -1184,7 +1184,7 @@
      */
     void bugMessage(Throwable ex) {
         Bark.printLines(out, getLocalizedString("msg.bug",
-                                               JavaCompiler.version()));
+                                               AptJavaCompiler.version()));
         ex.printStackTrace(out);
     }
 
--- a/src/share/classes/com/sun/tools/apt/mirror/apt/FilerImpl.java	Mon Dec 13 13:44:47 2010 -0800
+++ b/src/share/classes/com/sun/tools/apt/mirror/apt/FilerImpl.java	Mon Dec 13 14:08:01 2010 -0800
@@ -120,7 +120,7 @@
 
     private final Options opts;
     private final DeclarationMaker declMaker;
-    private final com.sun.tools.apt.main.JavaCompiler comp;
+    private final com.sun.tools.apt.main.AptJavaCompiler comp;
 
     // Platform's default encoding
     private final static String DEFAULT_ENCODING =
@@ -177,7 +177,7 @@
         opts = Options.instance(context);
         declMaker = DeclarationMaker.instance(context);
         bark = Bark.instance(context);
-        comp = com.sun.tools.apt.main.JavaCompiler.instance(context);
+        comp = com.sun.tools.apt.main.AptJavaCompiler.instance(context);
         roundOver = false;
         this.filesCreated = comp.getAggregateGenFiles();
 
--- a/src/share/classes/com/sun/tools/javac/code/Type.java	Mon Dec 13 13:44:47 2010 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Mon Dec 13 14:08:01 2010 -0800
@@ -245,7 +245,7 @@
     public String argtypes(boolean varargs) {
         List<Type> args = getParameterTypes();
         if (!varargs) return args.toString();
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         while (args.tail.nonEmpty()) {
             buf.append(args.head);
             args = args.tail;
@@ -935,7 +935,7 @@
 
     public static class TypeVar extends Type implements TypeVariable {
 
-        /** The bound of this type variable; set from outside.
+        /** The upper bound of this type variable; set from outside.
          *  Must be nonempty once it is set.
          *  For a bound, `bound' is the bound type itself.
          *  Multiple bounds are expressed as a single class type which has the
@@ -946,6 +946,12 @@
          *  points to the first class or interface bound.
          */
         public Type bound = null;
+
+        /** The lower bound of this type variable.
+         *  TypeVars don't normally have a lower bound, so it is normally set
+         *  to syms.botType.
+         *  Subtypes, such as CapturedType, may provide a different value.
+         */
         public Type lower;
 
         public TypeVar(Name name, Symbol owner, Type lower) {
@@ -965,10 +971,12 @@
             return v.visitTypeVar(this, s);
         }
 
+        @Override
         public Type getUpperBound() { return bound; }
 
         int rank_field = -1;
 
+        @Override
         public Type getLowerBound() {
             return lower;
         }
@@ -992,7 +1000,6 @@
      */
     public static class CapturedType extends TypeVar {
 
-        public Type lower;
         public WildcardType wildcard;
 
         public CapturedType(Name name,
@@ -1012,10 +1019,6 @@
             return v.visitCapturedType(this, s);
         }
 
-        public Type getLowerBound() {
-            return lower;
-        }
-
         @Override
         public boolean isCaptured() {
             return true;
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Dec 13 13:44:47 2010 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Dec 13 14:08:01 2010 -0800
@@ -641,7 +641,7 @@
                         if (!set.remove(new SingletonType(x)))
                             return false;
                     }
-                    return (set.size() == 0);
+                    return (set.isEmpty());
                 }
                 return t.tsym == s.tsym
                     && visit(t.getEnclosingType(), s.getEnclosingType())
@@ -838,26 +838,26 @@
                     return isSameType(t, s);
             }
 
-            void debugContainsType(WildcardType t, Type s) {
-                System.err.println();
-                System.err.format(" does %s contain %s?%n", t, s);
-                System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
-                                  upperBound(s), s, t, U(t),
-                                  t.isSuperBound()
-                                  || isSubtypeNoCapture(upperBound(s), U(t)));
-                System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
-                                  L(t), t, s, lowerBound(s),
-                                  t.isExtendsBound()
-                                  || isSubtypeNoCapture(L(t), lowerBound(s)));
-                System.err.println();
-            }
+//            void debugContainsType(WildcardType t, Type s) {
+//                System.err.println();
+//                System.err.format(" does %s contain %s?%n", t, s);
+//                System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
+//                                  upperBound(s), s, t, U(t),
+//                                  t.isSuperBound()
+//                                  || isSubtypeNoCapture(upperBound(s), U(t)));
+//                System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
+//                                  L(t), t, s, lowerBound(s),
+//                                  t.isExtendsBound()
+//                                  || isSubtypeNoCapture(L(t), lowerBound(s)));
+//                System.err.println();
+//            }
 
             @Override
             public Boolean visitWildcardType(WildcardType t, Type s) {
                 if (s.tag >= firstPartialTag)
                     return containedBy(s, t);
                 else {
-                    // debugContainsType(t, s);
+//                    debugContainsType(t, s);
                     return isSameWildcard(t, s)
                         || isCaptureOf(s, t)
                         || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) &&
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Dec 13 13:44:47 2010 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Dec 13 14:08:01 2010 -0800
@@ -197,7 +197,7 @@
         }
         return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
             isAccessible :
-            isAccessible & isAccessible(env, c.type.getEnclosingType(), checkInner);
+            isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
     }
     //where
         /** Is given class a subclass of given base class, or an inner class
@@ -234,7 +234,6 @@
     }
     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
         if (sym.name == names.init && sym.owner != site.tsym) return false;
-        ClassSymbol sub;
         switch ((short)(sym.flags() & AccessFlags)) {
         case PRIVATE:
             return
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/types/BoxingConversionTest.java	Mon Dec 13 14:08:01 2010 -0800
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2010, 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 7006109
+ * @summary Add test library to simplify the task of writing automated type-system tests
+ * @author mcimadamore
+ * @library .
+ * @run main BoxingConversionTest
+ */
+
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.Symbol.*;
+import java.lang.reflect.Array;
+import java.util.EnumSet;
+
+/**
+ * Check invariants in assignment/method conversion involving boxing conversions
+ */
+public class BoxingConversionTest extends TypeHarness {
+
+    Type[] types1;
+    Type[] types2;
+    Type[] types3;
+
+    enum Result {
+        OK_BOTH(true),
+        FAIL_BOTH(false),
+        OK_ASSIGN_ONLY(true);
+
+        boolean value;
+
+        Result(boolean value) {
+            this.value = value;
+        }
+    }
+
+    enum ConversionKind {
+        ASSIGNMENT_CONVERSION(EnumSet.of(Result.OK_BOTH, Result.OK_ASSIGN_ONLY)) {
+            @Override
+            void check(TypeHarness harness, Type from, Type to, Result expected) {
+                harness.assertAssignable(from, to, resSet.contains(expected));
+            }
+        },
+        METHOD_CONVERSION(EnumSet.of(Result.OK_BOTH)) {
+            @Override
+            void check(TypeHarness harness, Type from, Type to, Result expected) {
+                harness.assertConvertible(from, to, resSet.contains(expected));
+            }
+        };
+
+        EnumSet<Result> resSet;
+
+        private ConversionKind(EnumSet<Result> resSet) {
+            this.resSet = resSet;
+        }
+
+        abstract void check(TypeHarness harness, Type from, Type to, Result expected);
+    }
+
+    enum TestKind {
+        SIMPLE {
+            @Override
+            Type[] getFromTypes(BoxingConversionTest harness) {
+                return harness.types1;
+            }
+            @Override
+            Type[] getToTypes(BoxingConversionTest harness) {
+                return harness.types1;
+            }
+            @Override
+            Result[][] getResults(BoxingConversionTest harness) {
+                return harness.results1;
+            }
+        },
+        CONSTANT_TYPES {
+            @Override
+            Type[] getFromTypes(BoxingConversionTest harness) {
+                return harness.types2;
+            }
+            @Override
+            Type[] getToTypes(BoxingConversionTest harness) {
+                return harness.types3;
+            }
+            @Override
+            Result[][] getResults(BoxingConversionTest harness) {
+                return harness.results2;
+            }
+        };
+
+        abstract Type[] getFromTypes(BoxingConversionTest harness);
+        abstract Type[] getToTypes(BoxingConversionTest harness);
+        abstract Result[][] getResults(BoxingConversionTest harness);
+    }
+
+    static final Result T = Result.OK_BOTH;
+    static final Result F = Result.FAIL_BOTH;
+    static final Result A = Result.OK_ASSIGN_ONLY;
+    static final Result X = Result.FAIL_BOTH.FAIL_BOTH;
+
+    Result[][] results1 = {
+                   //byte, short, int, long, float, double, char, bool, Byte, Short, Integer, Long, Float, Double, Character, Boolean
+    /*byte*/       { T   , T    , T  , T   , T    , T     , F   , F   , T   , F    , F      , F   , F    , F     , F        , F },
+    /*short*/      { F   , T    , T  , T   , T    , T     , F   , F   , F   , T    , F      , F   , F    , F     , F        , F },
+    /*int*/        { F   , F    , T  , T   , T    , T     , F   , F   , F   , F    , T      , F   , F    , F     , F        , F },
+    /*long*/       { F   , F    , F  , T   , T    , T     , F   , F   , F   , F    , F      , T   , F    , F     , F        , F },
+    /*float*/      { F   , F    , F  , F   , T    , T     , F   , F   , F   , F    , F      , F   , T    , F     , F        , F },
+    /*double*/     { F   , F    , F  , F   , F    , T     , F   , F   , F   , F    , F      , F   , F    , T     , F        , F },
+    /*char*/       { F   , F    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , F     , T        , F },
+    /*bool*/       { F   , F    , F  , F   , F    , F     , F   , T   , F   , F    , F      , F   , F    , F     , F        , T },
+    /*Byte*/       { T   , T    , T  , T   , T    , T     , F   , F   , T   , F    , F      , F   , F    , F     , F        , F },
+    /*Short*/      { F   , T    , T  , T   , T    , T     , F   , F   , F   , T    , F      , F   , F    , F     , F        , F },
+    /*Integer*/    { F   , F    , T  , T   , T    , T     , F   , F   , F   , F    , T      , F   , F    , F     , F        , F },
+    /*Long*/       { F   , F    , F  , T   , T    , T     , F   , F   , F   , F    , F      , T   , F    , F     , F        , F },
+    /*Float*/      { F   , F    , F  , F   , T    , T     , F   , F   , F   , F    , F      , F   , T    , F     , F        , F },
+    /*Double*/     { F   , F    , F  , F   , F    , T     , F   , F   , F   , F    , F      , F   , F    , T     , F        , F },
+    /*Character*/  { F   , F    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , F     , T        , F },
+    /*Boolean*/    { F   , F    , F  , F   , F    , F     , F   , T   , F   , F    , F      , F   , F    , F     , F        , T }};
+
+    Result[][] results2 = {
+                //Byte, Short, Integer, Long, Float, Double, Chararacter, Boolean
+    /*byte*/    { T   , F    , F      , F   , F    , F     , F          , F },
+    /*short*/   { F   , T    , F      , F   , F    , F     , F          , F },
+    /*short1*/  { A   , T    , F      , F   , F    , F     , A          , F },
+    /*short2*/  { F   , T    , F      , F   , F    , F     , A          , F },
+    /*int*/     { F   , F    , T      , F   , F    , F     , F          , F },
+    /*int1*/    { A   , A    , T      , F   , F    , F     , A          , F },
+    /*int2*/    { F   , A    , T      , F   , F    , F     , A          , F },
+    /*int4*/    { F   , F    , T      , F   , F    , F     , F          , F },
+    /*long*/    { F   , F    , F      , T   , F    , F     , F          , F },
+    /*long1*/   { F   , F    , F      , T   , F    , F     , F          , F },
+    /*long2*/   { F   , F    , F      , T   , F    , F     , F          , F },
+    /*long4*/   { F   , F    , F      , T   , F    , F     , F          , F },
+    /*long8*/   { F   , F    , F      , T   , F    , F     , F          , F },
+    /*float*/   { F   , F    , F      , F   , T    , F     , F          , F },
+    /*float1*/  { F   , F    , F      , F   , T    , F     , F          , F },
+    /*float2*/  { F   , F    , F      , F   , T    , F     , F          , F },
+    /*float4*/  { F   , F    , F      , F   , T    , F     , F          , F },
+    /*double*/  { F   , F    , F      , F   , F    , T     , F          , F },
+    /*double1*/ { F   , F    , F      , F   , F    , T     , F          , F },
+    /*double2*/ { F   , F    , F      , F   , F    , T     , F          , F },
+    /*double4*/ { F   , F    , F      , F   , F    , T     , F          , F },
+    /*double8*/ { F   , F    , F      , F   , F    , T     , F          , F },
+    /*char*/    { F   , F    , F      , F   , F    , F     , T          , F },
+    /*char1*/   { A   , A    , F      , F   , F    , F     , T          , F },
+    /*char2*/   { F   , A    , F      , F   , F    , F     , T          , F },
+    /*bool*/    { F   , F    , F      , F   , F    , F     , F          , T }};
+
+    BoxingConversionTest() {
+        Type[] primitiveTypes = new Type[] {
+            predef.byteType,
+            predef.shortType,
+            predef.intType,
+            predef.longType,
+            predef.floatType,
+            predef.doubleType,
+            predef.charType,
+            predef.booleanType };
+
+        Type[] boxedTypes = new Type[primitiveTypes.length];
+        for (int i = 0 ; i < primitiveTypes.length ; i++) {
+            boxedTypes[i] = box(primitiveTypes[i]);
+        }
+
+        types1 = join(Type.class, primitiveTypes, boxedTypes);
+
+        types2 = new Type[] {
+            predef.byteType,
+            predef.shortType,
+            fac.Constant((short)0x0001),
+            fac.Constant((short)0x0100),
+            predef.intType,
+            fac.Constant((int)0x0000_0001),
+            fac.Constant((int)0x0000_0100),
+            fac.Constant((int)0x0001_0000),
+            predef.longType,
+            fac.Constant((long)0x0000_0000_0000_0001L),
+            fac.Constant((long)0x0000_0000_0000_0100L),
+            fac.Constant((long)0x0000_0000_0001_0000L),
+            fac.Constant((long)0x0001_0000_0000_0000L),
+            predef.floatType,
+            fac.Constant((float)0x0000_0001),
+            fac.Constant((float)0x0000_0100),
+            fac.Constant((float)0x0001_0000),
+            predef.doubleType,
+            fac.Constant((double)0x0000_0000_0000_0001L),
+            fac.Constant((double)0x0000_0000_0000_0100L),
+            fac.Constant((double)0x0000_0000_0001_0000L),
+            fac.Constant((double)0x0001_0000_0000_0000L),
+            predef.charType,
+            fac.Constant((char)0x0001),
+            fac.Constant((char)0x0100),
+            predef.booleanType
+        };
+
+        types3 = boxedTypes;
+    }
+
+    void testConversion(ConversionKind convKind, TestKind testKind) {
+        Type[] rows = testKind.getFromTypes(this);
+        Type[] cols = testKind.getToTypes(this);
+        for (int i = 0; i < rows.length ; i++) {
+            for (int j = 0; j < cols.length ; j++) {
+                convKind.check(this, rows[i], cols[j], testKind.getResults(this)[i][j]);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    <T> T[] join(Class<T> type, T[]... args) {
+        int totalLength = 0;
+        for (T[] arr : args) {
+            totalLength += arr.length;
+        }
+        T[] new_arr = (T[])Array.newInstance(type, totalLength);
+        int idx = 0;
+        for (T[] arr : args) {
+            System.arraycopy(arr, 0, new_arr, idx, arr.length);
+            idx += arr.length;
+        }
+        return new_arr;
+    }
+
+    public static void main(String[] args) {
+        BoxingConversionTest harness = new BoxingConversionTest();
+        for (ConversionKind convKind : ConversionKind.values()) {
+            for (TestKind testKind : TestKind.values()) {
+                harness.testConversion(convKind, testKind);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/types/CastTest.java	Mon Dec 13 14:08:01 2010 -0800
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2010, 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 7006109
+ * @summary Add test library to simplify the task of writing automated type-system tests
+ * @author mcimadamore
+ * @library .
+ * @run main CastTest
+ */
+
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.Symbol.*;
+import java.lang.reflect.Array;
+
+import static com.sun.tools.javac.code.Flags.*;
+
+/**
+ * Check invariants in cast conversion involving primitive types and arrays
+ */
+public class CastTest extends TypeHarness {
+
+    Type[] allTypes;
+
+    static final boolean T = true;
+    static final boolean F = false;
+
+    boolean[][] cast_result = {
+                //byte, short, int, long, float, double, char, bool, C, +C, I, T, byte[], short[], int[], long[], float[], double[], char[], bool[], C[], +C[], I[], T[]
+    /*byte*/    { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*short*/   { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*int*/     { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*long*/    { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*float*/   { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*double*/  { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*char*/    { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*bool*/    { F   , F    , F  , F   , F    , F     , F   , T   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*C*/       { F   , F    , F  , F   , F    , F     , F   , F   , T, F , T, T, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*+C*/      { F   , F    , F  , F   , F    , F     , F   , F   , F, T , F, T, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*I*/       { F   , F    , F  , F   , F    , F     , F   , F   , T, F , T, T, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*T*/       { F   , F    , F  , F   , F    , F     , F   , F   , T, T , T, T, T     , T      , T    , T     , T      , T       , T     , T     , T  , T   , T  , T },
+    /*byte[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, T     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*short[]*/ { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , T      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*int[]*/   { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , T    , F     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*long[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , T     , F      , F       , F     , F     , F  , F   , F  , F },
+    /*float[]*/ { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , T      , F       , F     , F     , F  , F   , F  , F },
+    /*double[]*/{ F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , T       , F     , F     , F  , F   , F  , F },
+    /*char[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , T     , F     , F  , F   , F  , F },
+    /*bool[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , T     , F  , F   , F  , F },
+    /*C[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , T  , F   , T  , T },
+    /*+C[]*/    { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , F  , T   , F  , T },
+    /*I[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , T  , F   , T  , T },
+    /*T[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , T  , T   , T  , T }};
+
+    CastTest() {
+        Type[] primitiveTypes = {
+            predef.byteType,
+            predef.shortType,
+            predef.intType,
+            predef.longType,
+            predef.floatType,
+            predef.doubleType,
+            predef.charType,
+            predef.booleanType };
+
+        Type[] referenceTypes = {
+            fac.Class(),
+            fac.Class(FINAL),
+            fac.Interface(),
+            fac.TypeVariable() };
+
+        Type[] arrayTypes = new Type[primitiveTypes.length + referenceTypes.length];
+        int idx = 0;
+        for (Type t : join(Type.class, primitiveTypes, referenceTypes)) {
+            arrayTypes[idx++] = fac.Array(t);
+        }
+
+        allTypes = join(Type.class, primitiveTypes, referenceTypes, arrayTypes);
+    }
+
+    void test() {
+        for (int i = 0; i < allTypes.length ; i++) {
+            for (int j = 0; j < allTypes.length ; j++) {
+                assertCastable(allTypes[i], allTypes[j], cast_result[i][j]);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    <T> T[] join(Class<T> type, T[]... args) {
+        int totalLength = 0;
+        for (T[] arr : args) {
+            totalLength += arr.length;
+        }
+        T[] new_arr = (T[])Array.newInstance(type, totalLength);
+        int idx = 0;
+        for (T[] arr : args) {
+            System.arraycopy(arr, 0, new_arr, idx, arr.length);
+            idx += arr.length;
+        }
+        return new_arr;
+    }
+
+    public static void main(String[] args) {
+        new CastTest().test();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/types/PrimitiveConversionTest.java	Mon Dec 13 14:08:01 2010 -0800
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2010, 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 7006109
+ * @summary Add test library to simplify the task of writing automated type-system tests
+ * @author mcimadamore
+ * @library .
+ * @run main PrimitiveConversionTest
+ */
+
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.Symbol.*;
+import java.lang.reflect.Array;
+import java.util.EnumSet;
+
+/**
+ * Check invariants in assignment/method conversion involving primitive types and arrays
+ */
+public class PrimitiveConversionTest extends TypeHarness {
+
+    Type[] types1;
+    Type[] types2;
+    Type[] types3;
+
+    enum Result {
+        OK_BOTH(true),
+        FAIL_BOTH(false),
+        OK_ASSIGN_ONLY(true);
+
+        boolean value;
+
+        Result(boolean value) {
+            this.value = value;
+        }
+    }
+
+    enum ConversionKind {
+        ASSIGNMENT_CONVERSION(EnumSet.of(Result.OK_BOTH, Result.OK_ASSIGN_ONLY)) {
+            @Override
+            void check(TypeHarness harness, Type from, Type to, Result expected) {
+                harness.assertAssignable(from, to, resSet.contains(expected));
+            }
+        },
+        METHOD_CONVERSION(EnumSet.of(Result.OK_BOTH)) {
+            @Override
+            void check(TypeHarness harness, Type from, Type to, Result expected) {
+                harness.assertConvertible(from, to, resSet.contains(expected));
+            }
+        };
+
+        EnumSet<Result> resSet;
+
+        private ConversionKind(EnumSet<Result> resSet) {
+            this.resSet = resSet;
+        }
+
+        abstract void check(TypeHarness harness, Type from, Type to, Result expected);
+    }
+
+    enum TestKind {
+        SIMPLE {
+            @Override
+            Type[] getFromTypes(PrimitiveConversionTest harness) {
+                return harness.types1;
+            }
+            @Override
+            Type[] getToTypes(PrimitiveConversionTest harness) {
+                return harness.types1;
+            }
+            @Override
+            Result[][] getResults(PrimitiveConversionTest harness) {
+                return harness.results1;
+            }
+        },
+        CONSTANT_TYPES {
+            @Override
+            Type[] getFromTypes(PrimitiveConversionTest harness) {
+                return harness.types2;
+            }
+            @Override
+            Type[] getToTypes(PrimitiveConversionTest harness) {
+                return harness.types3;
+            }
+            @Override
+            Result[][] getResults(PrimitiveConversionTest harness) {
+                return harness.results2;
+            }
+        };
+
+        abstract Type[] getFromTypes(PrimitiveConversionTest harness);
+        abstract Type[] getToTypes(PrimitiveConversionTest harness);
+        abstract Result[][] getResults(PrimitiveConversionTest harness);
+    }
+
+    static final Result T = Result.OK_BOTH;
+    static final Result F = Result.FAIL_BOTH;
+    static final Result A = Result.OK_ASSIGN_ONLY;
+
+    Result[][] results1 = {
+                //byte, short, int, long, float, double, char, bool, C1, C2, C3, T , byte[], short[], int[], long[], float[], double[], char[], bool[], C1[], C2[], C3[], T[]
+    /*byte*/    { T   , T    , T  , T   , T    , T     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*short*/   { F   , T    , T  , T   , T    , T     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*int*/     { F   , F    , T  , T   , T    , T     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*long*/    { F   , F    , F  , T   , T    , T     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*float*/   { F   , F    , F  , F   , T    , T     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*double*/  { F   , F    , F  , F   , F    , T     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*char*/    { F   , F    , T  , T   , T    , T     , T   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*bool*/    { F   , F    , F  , F   , F    , F     , F   , T   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*C1*/      { F   , F    , F  , F   , F    , F     , F   , F   , T , F , T , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*C2*/      { F   , F    , F  , F   , F    , F     , F   , F   , T , T , T , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*C3*/      { F   , F    , F  , F   , F    , F     , F   , F   , T , F , T , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*T*/       { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , T , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*byte[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , T     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*short[]*/ { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , T      , F    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*int[]*/   { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , T    , F     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*long[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , T     , F      , F       , F     , F     , F   , F   , F   , F },
+    /*float[]*/ { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , T      , F       , F     , F     , F   , F   , F   , F },
+    /*double[]*/{ F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , T       , F     , F     , F   , F   , F   , F },
+    /*char[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , T     , F     , F   , F   , F   , F },
+    /*bool[]*/  { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , T     , F   , F   , F   , F },
+    /*C1[]*/    { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , T   , F   , T   , F },
+    /*C2[]*/    { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , T   , T   , T   , F },
+    /*C3[]*/    { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , T   , F   , T   , F },
+    /*T[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F , F , F , F , F     , F      , F    , F     , F      , F       , F     , F     , F   , F   , F   , T }};
+
+    Result[][] results2 = {
+                //byte, short, int, long, float, double, char, bool
+    /*byte*/    { T   , T    , T  , T   , T    , T     , F   , F },
+    /*short*/   { F   , T    , T  , T   , T    , T     , F   , F },
+    /*short1*/  { A   , T    , T  , T   , T    , T     , A   , F },
+    /*short2*/  { F   , T    , T  , T   , T    , T     , A   , F },
+    /*int*/     { F   , F    , T  , T   , T    , T     , F   , F },
+    /*int1*/    { A   , A    , T  , T   , T    , T     , A   , F },
+    /*int2*/    { F   , A    , T  , T   , T    , T     , A   , F },
+    /*int4*/    { F   , F    , T  , T   , T    , T     , F   , F },
+    /*long*/    { F   , F    , F  , T   , T    , T     , F   , F },
+    /*long1*/   { F   , F    , F  , T   , T    , T     , F   , F },
+    /*long2*/   { F   , F    , F  , T   , T    , T     , F   , F },
+    /*long4*/   { F   , F    , F  , T   , T    , T     , F   , F },
+    /*long8*/   { F   , F    , F  , T   , T    , T     , F   , F },
+    /*float*/   { F   , F    , F  , F   , T    , T     , F   , F },
+    /*float1*/  { F   , F    , F  , F   , T    , T     , F   , F },
+    /*float2*/  { F   , F    , F  , F   , T    , T     , F   , F },
+    /*float4*/  { F   , F    , F  , F   , T    , T     , F   , F },
+    /*double*/  { F   , F    , F  , F   , F    , T     , F   , F },
+    /*double1*/ { F   , F    , F  , F   , F    , T     , F   , F },
+    /*double2*/ { F   , F    , F  , F   , F    , T     , F   , F },
+    /*double4*/ { F   , F    , F  , F   , F    , T     , F   , F },
+    /*double8*/ { F   , F    , F  , F   , F    , T     , F   , F },
+    /*char*/    { F   , F    , T  , T   , T    , T     , T   , F },
+    /*char1*/   { A   , A    , T  , T   , T    , T     , T   , F },
+    /*char2*/   { F   , A    , T  , T   , T    , T     , T   , F },
+    /*bool*/    { F   , F    , F  , F   , F    , F     , F   , T }};
+
+    PrimitiveConversionTest() {
+        Type[] primitiveTypes = new Type[] {
+            predef.byteType,
+            predef.shortType,
+            predef.intType,
+            predef.longType,
+            predef.floatType,
+            predef.doubleType,
+            predef.charType,
+            predef.booleanType };
+
+        ClassType c1 = fac.Class(fac.TypeVariable());
+        ClassType c2 = fac.Class();
+        c2.supertype_field = subst(c1,
+                Mapping(c1.getTypeArguments().head, predef.stringType));
+        Type c3 = erasure(c1);
+
+        Type[] referenceTypes = {
+            subst(c1,
+                    Mapping(c1.getTypeArguments().head, predef.stringType)),
+            c2,
+            c3,
+            fac.TypeVariable() };
+
+        Type[] arrayTypes = new Type[primitiveTypes.length + referenceTypes.length];
+        int idx = 0;
+        for (Type t : join(Type.class, primitiveTypes, referenceTypes)) {
+            arrayTypes[idx++] = fac.Array(t);
+        }
+
+        types1 = join(Type.class, primitiveTypes, referenceTypes, arrayTypes);
+
+        types2 = new Type[] {
+            predef.byteType,
+            predef.shortType,
+            fac.Constant((short)0x0001),
+            fac.Constant((short)0x0100),
+            predef.intType,
+            fac.Constant((int)0x0000_0001),
+            fac.Constant((int)0x0000_0100),
+            fac.Constant((int)0x0001_0000),
+            predef.longType,
+            fac.Constant((long)0x0000_0000_0000_0001L),
+            fac.Constant((long)0x0000_0000_0000_0100L),
+            fac.Constant((long)0x0000_0000_0001_0000L),
+            fac.Constant((long)0x0001_0000_0000_0000L),
+            predef.floatType,
+            fac.Constant((float)0x0000_0001),
+            fac.Constant((float)0x0000_0100),
+            fac.Constant((float)0x0001_0000),
+            predef.doubleType,
+            fac.Constant((double)0x0000_0000_0000_0001L),
+            fac.Constant((double)0x0000_0000_0000_0100L),
+            fac.Constant((double)0x0000_0000_0001_0000L),
+            fac.Constant((double)0x0001_0000_0000_0000L),
+            predef.charType,
+            fac.Constant((char)0x0001),
+            fac.Constant((char)0x0100),
+            predef.booleanType
+        };
+
+        types3 = primitiveTypes;
+    }
+
+    void testConversion(ConversionKind convKind, TestKind testKind) {
+        Type[] rows = testKind.getFromTypes(this);
+        Type[] cols = testKind.getToTypes(this);
+        for (int i = 0; i < rows.length ; i++) {
+            for (int j = 0; j < cols.length ; j++) {
+                convKind.check(this, rows[i], cols[j], testKind.getResults(this)[i][j]);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    <T> T[] join(Class<T> type, T[]... args) {
+        int totalLength = 0;
+        for (T[] arr : args) {
+            totalLength += arr.length;
+        }
+        T[] new_arr = (T[])Array.newInstance(type, totalLength);
+        int idx = 0;
+        for (T[] arr : args) {
+            System.arraycopy(arr, 0, new_arr, idx, arr.length);
+            idx += arr.length;
+        }
+        return new_arr;
+    }
+
+    public static void main(String[] args) {
+        PrimitiveConversionTest harness = new PrimitiveConversionTest();
+        for (ConversionKind convKind : ConversionKind.values()) {
+            for (TestKind testKind : TestKind.values()) {
+                harness.testConversion(convKind, testKind);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/types/TypeHarness.java	Mon Dec 13 14:08:01 2010 -0800
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2010, 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.tools.javac.code.BoundKind;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.*;
+import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
+import com.sun.tools.javac.file.JavacFileManager;
+
+/**
+ * Test harness whose goal is to simplify the task of writing type-system
+ * regression test. It provides functionalities to build custom types as well
+ * as to access the underlying javac's symbol table in order to retrieve
+ * predefined types. Among the features supported by the harness are: type
+ * substitution, type containment, subtyping, cast-conversion, assigment
+ * conversion.
+ *
+ * This class is meant to be a common super class for all concrete type test
+ * classes. A subclass can access the type-factory and the test methods so as
+ * to write compact tests. An example is reported below:
+ *
+ * <pre>
+ * Type X = fac.TypeVariable();
+ * Type Y = fac.TypeVariable();
+ * Type A_X_Y = fac.Class(0, X, Y);
+ * Type A_Obj_Obj = fac.Class(0,
+ *           predef.objectType,
+ *           predef.objectType);
+ * checkSameType(A_Obj_Obj, subst(A_X_Y,
+ *           Mapping(X, predef.objectType),
+ *           Mapping(Y, predef.objectType)));
+ * </pre>
+ *
+ * The above code is used to create two class types, namely {@code A<X,Y>} and
+ * {@code A<Object,Object>} where both {@code X} and {@code Y} are type-variables.
+ * The code then verifies that {@code [X:=Object,Y:=Object]A<X,Y> == A<Object,Object>}.
+ *
+ * @author mcimadamore
+ */
+public class TypeHarness {
+
+    protected Types types;
+    protected Symtab predef;
+    protected Names names;
+    protected Factory fac;
+
+    protected TypeHarness() {
+        Context ctx = new Context();
+        JavacFileManager.preRegister(ctx);
+        types = Types.instance(ctx);
+        predef = Symtab.instance(ctx);
+        names = Names.instance(ctx);
+        fac = new Factory();
+    }
+
+    // <editor-fold defaultstate="collapsed" desc="type assertions">
+
+    /** assert that 's' is a subtype of 't' */
+    public void assertSubtype(Type s, Type t) {
+        assertSubtype(s, t, true);
+    }
+
+    /** assert that 's' is/is not a subtype of 't' */
+    public void assertSubtype(Type s, Type t, boolean expected) {
+        if (types.isSubtype(s, t) != expected) {
+            String msg = expected ?
+                " is not a subtype of " :
+                " is a subtype of ";
+            error(s + msg + t);
+        }
+    }
+
+    /** assert that 's' is the same type as 't' */
+    public void assertSameType(Type s, Type t) {
+        assertSameType(s, t, true);
+    }
+
+    /** assert that 's' is/is not the same type as 't' */
+    public void assertSameType(Type s, Type t, boolean expected) {
+        if (types.isSameType(s, t) != expected) {
+            String msg = expected ?
+                " is not the same type as " :
+                " is the same type as ";
+            error(s + msg + t);
+        }
+    }
+
+    /** assert that 's' is castable to 't' */
+    public void assertCastable(Type s, Type t) {
+        assertCastable(s, t, true);
+    }
+
+    /** assert that 's' is/is not castable to 't' */
+    public void assertCastable(Type s, Type t, boolean expected) {
+        if (types.isCastable(s, t) != expected) {
+            String msg = expected ?
+                " is not castable to " :
+                " is castable to ";
+            error(s + msg + t);
+        }
+    }
+
+    /** assert that 's' is convertible (method invocation conversion) to 't' */
+    public void assertConvertible(Type s, Type t) {
+        assertCastable(s, t, true);
+    }
+
+    /** assert that 's' is/is not convertible (method invocation conversion) to 't' */
+    public void assertConvertible(Type s, Type t, boolean expected) {
+        if (types.isConvertible(s, t) != expected) {
+            String msg = expected ?
+                " is not convertible to " :
+                " is convertible to ";
+            error(s + msg + t);
+        }
+    }
+
+    /** assert that 's' is assignable to 't' */
+    public void assertAssignable(Type s, Type t) {
+        assertCastable(s, t, true);
+    }
+
+    /** assert that 's' is/is not assignable to 't' */
+    public void assertAssignable(Type s, Type t, boolean expected) {
+        if (types.isAssignable(s, t) != expected) {
+            String msg = expected ?
+                " is not assignable to " :
+                " is assignable to ";
+            error(s + msg + t);
+        }
+    }
+    // </editor-fold>
+
+    private void error(String msg) {
+        throw new AssertionError("Unexpected result: " + msg);
+    }
+
+    // <editor-fold defaultstate="collapsed" desc="type functions">
+
+    /** compute the erasure of a type 't' */
+    public Type erasure(Type t) {
+        return types.erasure(t);
+    }
+
+    /** compute the capture of a type 't' */
+    public Type capture(Type t) {
+        return types.capture(t);
+    }
+
+    /** compute the boxed type associated with 't' */
+    public Type box(Type t) {
+        if (!t.isPrimitive()) {
+            throw new AssertionError("Cannot box non-primitive type: " + t);
+        }
+        return types.boxedClass(t).type;
+    }
+
+    /** compute the unboxed type associated with 't' */
+    public Type unbox(Type t) {
+        Type u = types.unboxedType(t);
+        if (t == null) {
+            throw new AssertionError("Cannot unbox reference type: " + t);
+        } else {
+            return u;
+        }
+    }
+
+    /** compute a type substitution on 't' given a list of type mappings */
+    public Type subst(Type t, Mapping... maps) {
+        ListBuffer<Type> from = ListBuffer.lb();
+        ListBuffer<Type> to = ListBuffer.lb();
+        for (Mapping tm : maps) {
+            from.append(tm.from);
+            to.append(tm.to);
+        }
+        return types.subst(t, from.toList(), to.toList());
+    }
+
+    /** create a fresh type mapping from a type to another */
+    public Mapping Mapping(Type from, Type to) {
+        return new Mapping(from, to);
+    }
+
+    public static class Mapping {
+        Type from;
+        Type to;
+        private Mapping(Type from, Type to) {
+            this.from = from;
+            this.to = to;
+        }
+    }
+    // </editor-fold>
+
+    // <editor-fold defaultstate="collapsed" desc="type factory">
+
+    /**
+     * This class is used to create Java types in a simple way. All main
+     * kinds of type are supported: primitive, reference, non-denotable. The
+     * factory also supports creation of constant types (used by the compiler
+     * to represent the type of a literal).
+     */
+    public class Factory {
+
+        private int synthNameCount = 0;
+
+        private Name syntheticName() {
+            return names.fromString("A$" + synthNameCount++);
+        }
+
+        public ClassType Class(long flags, Type... typeArgs) {
+            ClassSymbol csym = new ClassSymbol(flags, syntheticName(), predef.noSymbol);
+            csym.type = new ClassType(Type.noType, List.from(typeArgs), csym);
+            ((ClassType)csym.type).supertype_field = predef.objectType;
+            return (ClassType)csym.type;
+        }
+
+        public ClassType Class(Type... typeArgs) {
+            return Class(0, typeArgs);
+        }
+
+        public ClassType Interface(Type... typeArgs) {
+            return Class(Flags.INTERFACE, typeArgs);
+        }
+
+        public ClassType Interface(long flags, Type... typeArgs) {
+            return Class(Flags.INTERFACE | flags, typeArgs);
+        }
+
+        public Type Constant(byte b) {
+            return predef.byteType.constType(b);
+        }
+
+        public Type Constant(short s) {
+            return predef.shortType.constType(s);
+        }
+
+        public Type Constant(int i) {
+            return predef.intType.constType(i);
+        }
+
+        public Type Constant(long l) {
+            return predef.longType.constType(l);
+        }
+
+        public Type Constant(float f) {
+            return predef.floatType.constType(f);
+        }
+
+        public Type Constant(double d) {
+            return predef.doubleType.constType(d);
+        }
+
+        public Type Constant(char c) {
+            return predef.charType.constType(c + 0);
+        }
+
+        public ArrayType Array(Type elemType) {
+            return new ArrayType(elemType, predef.arrayClass);
+        }
+
+        public TypeVar TypeVariable() {
+            return TypeVariable(predef.objectType);
+        }
+
+        public TypeVar TypeVariable(Type bound) {
+            TypeSymbol tvsym = new TypeSymbol(0, syntheticName(), null, predef.noSymbol);
+            tvsym.type = new TypeVar(tvsym, bound, null);
+            return (TypeVar)tvsym.type;
+        }
+
+        public WildcardType Wildcard(BoundKind bk, Type bound) {
+            return new WildcardType(bound, bk, predef.boundClass);
+        }
+
+        public CapturedType CapturedVariable(Type upper, Type lower) {
+            return new CapturedType(syntheticName(), predef.noSymbol, upper, lower, null);
+        }
+
+        public ClassType Intersection(Type classBound, Type... intfBounds) {
+            ClassType ct = Class(Flags.COMPOUND);
+            ct.supertype_field = classBound;
+            ct.interfaces_field = List.from(intfBounds);
+            return ct;
+        }
+    }
+    // </editor-fold>
+}